[Rd] GUI hooks in R [Was: assignInNamespace and new bindings]

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Wed Jun 1 19:50:01 CEST 2011


On Wednesday 01 June 2011, Simon Urbanek wrote:
> I suppose, yes, it's possible, but I see somewhat of an asymmetry if done
> that way : GUIs are like plug-ins in that there is a set of functions they
> have to implement to work properly. In the current state this is done
> using the C-level hooks, but they are incomplete in that some of the
> required hooks are not available on all platforms. However, if you
> introduce an additional layer of R function hooks, there will be two sets
> of competing ways for the GUI so register and some of them are simply not
> feasible on the R level (console handling, for example, which is why we
> have C-level hooks).

Well we already have both, at least in some parts. See e.g. options() "pager" 
and "editor" (which have dupes on the C level, some of which are not cross-
platform, again), and "browser" (which is a likely candidate for GUI-
customization, and does not have a C equivalent). Possibly options("error"), 
too, and perhaps some others.

Options on the R level have some obvious advantages, e.g. it is not quite as 
impossible to change the function signature at a later point of time. Also 
keep in mind that GUIs will almost certainly comprise some R code, but do not 
necessarily have to have C code. Think tcltk or RGtk based UIs, for instance. 
Why shouldn't these have an easy way to customize select.list(), for instance. 
Finally, having this in options() will allow power-users to utilize selected 
GUI elements, whereever they like (or to disable their GUIs graphical dialogs 
for some features).

Also, I can give you a bunch more UI functions that I would like to be able to 
customize cross-platform. From the top of my head:
- Yes / no / cancel questions (graphical only on Windows, currently, but why 
not let the hosting GUI decide?)
- readline()
- Progress bars
- Adding menus (several GUIs bring their own functions for this, but there is 
no standard API. Thus packages have a hard time integrating with more than 
just one GUI.)

Do you seriously want to have a C API for all of these?

> It also makes the GUI unnecessary messy, since they
> will need to provide both C code and R code, where the R code essentially
> just points to C code, practically replicating what the C-level hooks
> would do (just more complicated as it requires embedded symbol
> registrations etc.).

Personally, I find that easier than even setting the C pointers cross-platform 
(because the way to set these is platform specific).
 
> Currently I'm more inclined to make the hooks cross-platform (maybe
> conditional on the GUI type set to "custom" or something like that). But
> if someone wants to devise some nice way of customizing parts using R
> callback, I won't oppose it.

Well, if that stands *real* chances of being included, I will happily make a 
start (and take the discussion to R-SIG-GUI).

> If you have issues with stdout buffer before the pipe, use can use
> setvbuf() to disable buffering.

Well, actually I capture the stdout in a separate process (RKWard uses two 
processes, anyway). Perhaps moving all output capturing to one process might 
fix my interleaving issues without the need to mess with system[2](). I'll give 
that a try.
 
> Cautiously I would argue you have to the moment you're outside R,
> essentially since the built-in graphics devices are not guaranteed to work
> when embedded. In practice, I think if you write a GUI, you have to
> provide a GD - that is the only reasonable way you can seamlessly
> incorporate R graphics into your GUI.

Not on Windows and X11, at least. Try RKWard on one of these platforms, and 
see if you can find any seams. Then check your dev.list() to see the underlying 
devices.

Admittedly, we do not have support for the Quartz device, yet, and this may be 
harder than Windows and X11, but I'm still optimistic.
 
> That said, there is a precedent for graphics hooks. The problem I see is
> the same that became apparent with grid last time we added hooks - there
> are potentially multiple ways to get to the same C level point, and they
> are either easily forgotten, or even hard to enumerate. For example,
> dev.set() is not the only way to activate a device - it can be activated
> from the menu and other means via selectDevice() which is at C level, so
> there is no R code involved at all, thus setting a hook on dev.set() is
> will work only in a  subset of cases and thus you cannot expect
> consistency in your GUI.

Well, in our particular use case, we can query the window manager for 
everything else we need to know. But of course there are several more use-
cases, where adding hooks at the R level would not be good enough (one would 
be multi-device plot history feature).

However, *if* such hooks are going to be integrated into base R, then it 
_think_, it should be no problem to root these hooks at the C level, rather 
than the R level.

> (Note: none of my comments are specific to RKWard, since it is not even
> available for OS X so I don't know anything about it)

Well, I can't blame you for not trying it, since compilation on the Mac does 
take ages, and we don't promise the result is any useful, ATM. We simply don't 
have a developer with a Mac in the project. But most of the time, you *can* 
compile RKWard on Mac OS X, and it is known to work at least some of the time.

Regards
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20110601/00a96ee3/attachment.bin>


More information about the R-devel mailing list