Jonathan Marten writes:
Anyway, here's the patch - adapted to return the result as a
string,
as suggested by Aidan Kehoe.
I'm not sure this is necessary after all, given what is actually being
returned (AIUI a small integer identifying the desktop). I really
don't see a problem with stating that XEmacs doesn't necessarily
support as many as 2^30 desktops. ;-) For portability, test using
NUMBER_FITS_IN_AN_EMACS_INT (from src/lisp.h).
--- frame-x.c.orig 2006-05-06 18:56:00.000000000 +0100
+++ frame-x.c 2008-11-20 12:38:58.000000000 +0000
@@ -2241,6 +2249,96 @@
return build_intstring (str);
}
+DEFUN ("x-on-desktop", Fx_on_desktop, 0, 1, 0, /*
+Get the ID of the desktop on which the FRAME is displayed, by reading
+the _NET_WM_DESKTOP property of its top level window.
+
+The format of this depends on the desktop system and window manager
+in use. With an ICCCM-compliant window manager the result returned
+is an integer value (returned as a string) representing the desktop
+("0" being the first), t for all desktops, or nil if the desktop
+cannot be determined.
+*/
I smell a rat here. Have there been window managers which support
virtual desktops and participate in this protocol, but don't conform
to it? If so, you might want to include some sanity-checking, wrapped
in ERROR_CHECK_STRUCTURES (not a very good name, but it's the one
advertised as used for "not elsewhere classified"). For example, use
warn_when_safe() to post a warning if the desktop returned is > 20 or
< -2.
Is this really an ICCCM protocol? Or is it from freedesktop.org? fdo
is as good as X.org as far as I'm concerned, but precision is a good
thing.
+ (frame))
+{
+ struct frame *f = decode_x_frame (frame);
+ Widget w = FRAME_X_SHELL_WIDGET(f);
+ Display *dpy = XtDisplay(w);
+ Window win = XtWindow(w);
+
+ Atom desk = XInternAtom(dpy,"_NET_WM_DESKTOP",False);
+
+ Atom actual_type; /* results from
XGetWindowProperty */
Please keep lines to 80 characters. I think this comment is
unnecessary anyway.
+ int actual_format;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char *prop;
You can assume Xt is available if X support is built in. I'm not sure
about nitems and bytes_after, but prop should probably be declared
String.
+ INT_32_BIT result = -2;
Doesn't X11/Xt provide a type for INT_32_BIT? If so, use it -- the
use of the Xt type documents why this isn't EMACS_INT (although it
might make sense to use that instead). Also, that initialization
should have a comment that -2 is being used as a sentinel.
+ if (XGetWindowProperty(dpy,win,desk,0,1,False,XA_CARDINAL,
+ &actual_type,&actual_format,
+ &nitems,&bytes_after,&prop)==Success &&
+ actual_type==XA_CARDINAL)
+ {
+ result = *((INT_32_BIT *) prop); /* get returned result */
80 columns, please. Boy, gotta love that cast! X is scary, isn't it?
+ XFree(prop); /* free
result memory */
+ }
+
In the following conditional, I think I would prefer
if (result == -2)
return Qnil; /* could not identify */
else if (result == -1)
return Qt; /* all desktops */
else if (result >= 0)
{
/* return a valid desktop */
}
else /* Trust X? Are you out of your cotton-picking mind? */
{
warn_when_safe (Qwarning, Qx, "Invalid desktop index: %ld", result);
return Qnil;
}
You could also add a case for !NUMBER_FITS_IN_AN_EMACS_INT instead of
creating a string, as mentioned above.
You might want to factor that out as a separate function since the
same kind of thing needs to be done for x-current-desktop.
Note the remarkably ugly placement of the braces. That's where they
belong according to the GNU style manual. We don't *have* to follow
that manual since we're not a GNU project, but we do get a lot of code
from them (though not in this module). Consensus has long been that
we should follow the GNU style.
XEmacs is distributed with an (incomplete) Internals manual, as well
as the GNU coding style manual. Advice on style etc can be found
there.
+ if (result==-1) return Qt; /* all
desktops */
+ else if (result!=-2)
+ {
+ Ibyte buf[255];
+ qxesprintf (buf, "%lu", (unsigned long) result);
+ return build_intstring (buf); /* desktop number as a string */
+ }
+ else return Qnil; /* could not identify */
+}
+
+DEFUN ("x-current-desktop", Fx_current_desktop, 0, 1, 0, /*
+Get the ID of the current desktop for the display on which the FRAME
+appears, by reading the _NET_CURRENT_DESKTOP property of the root window.
+
+The format of this depends on the desktop system and window manager
+in use. With an ICCCM-compliant window manager the result returned
+is an integer value (returned as a string) representing the desktop
+("0" being the first), or nil if the desktop cannot be determined.
+*/
+ (frame))
+{
+ struct frame *f = decode_x_frame (frame);
+ Widget w = FRAME_X_SHELL_WIDGET(f);
Ah, OK. This is not supposed to be visible to Lisp (although it's not
clear to me why not, maybe that discussion should be revisited in view
of clarifying the interface to Xlib and Xt). So it makes sense for
this function to be in C.
The rest looks OK. I'm too tired to actually build it and try it out,
so an approval from me will have to wait a couple days.
_______________________________________________
XEmacs-Beta mailing list
XEmacs-Beta(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-beta