bph_cwjb@jhunix.HCF.JHU.EDU (William J. Bogstad) (06/18/88)
When using the "twm" or "wm" window manager the commands xprop and xplaces seem to be unable to obtain useful information about my windows. Is this a problem with the programs/managers in question or a consequence of the way that X works? Please note my ignorance of X is high at this point. I'm just trying to figure out how things work or don't work. Thanks, Bill -- Bill Bogstad bogstad@cs.jhu.edu Work: (301)338-8019 bill@green.bph.jhu.edu
jkh@ardent.UUCP (06/18/88)
That's because twm and wm don't set the class hints on the outer "frame" window they reparent your windows to. xprop/xplaces look at this frame window and see, of course, nothing. Jordan
stroyan@hpfcdc.HP.COM (Mike Stroyan) (06/19/88)
> That's because twm and wm don't set the class hints on the outer "frame" > window they reparent your windows to. xprop/xplaces look at this frame window > and see, of course, nothing. > > Jordan That's one way to look at it. It seems to me that the problem is that xprop/xplaces are just using the window id of the first child window under root, as returned with the button event. The programs could take the screen coordinates of the button event and find the smallest window by examining the window tree. Xprop could report data on the smallest subwindow or on that window and its ancestors. That gives an xprop user the power to indicate and get data about a window manager's border area, or an application's window, or some subwindow. Mike Stroyan
moraes@godzilla.ele.toronto.EDU (Mark Moraes) (06/28/88)
One way to fix the problem (twm reparenting the application top-level window with a frame that has no properties) is to have twm copy all the properties from the application top level to the frame. The code to this is fairly straightforward. On PropertyNotify events, it would have to change the changed property application in the frame. I've implemented this for twm, and it seems to work. (diffs enclosed below). It seems inefficient to have to do this - particularly, as the properties of the frame are inaccurate in size hints. One other way that comes to mind is another property for window managers, something like WM_CHILD which the frame would set to the window id of the reparented window, so that applications like xprop would know which window to query for application property information. A window having a WM_CHILD property would also indicate that it is a frame created by a window manager, and would avoid the need to keep copying properties from the application top-level to the window manager frame. Finally, session managers implemented separately from window managers (if we ever see such beasts) would be able to tell which windows placement information should be saved - not the frames, but rather the application top-level windows. Is this a better solution? If so, can someone please consider it for the next ICCC draft? Window manager authors? Fixes to get twm to work with xprop: *** /tmp/,RCSt1a25414 Fri Jun 24 03:26:21 1988 --- add_window.c Fri Jun 24 03:22:20 1988 *************** *** 93,98 XWindowChanges xwc; /* change window structure */ unsigned int xwcm; /* change window mask */ int dont_know; /* don't know where to put the window */ XColor blob, cret; #ifdef DEBUG --- 93,99 ----- XWindowChanges xwc; /* change window structure */ unsigned int xwcm; /* change window mask */ int dont_know; /* don't know where to put the window */ + void CopyWindowProperties(); XColor blob, cret; #ifdef DEBUG *************** *** 297,304 /* XSetWindowBorderPixmap(dpy, tmp_win->frame, GrayTile); */ tmp_win->title_w = XCreateSimpleWindow(dpy, tmp_win->frame, -BorderWidth, -BorderWidth, --- 302,309 ----- /* XSetWindowBorderPixmap(dpy, tmp_win->frame, GrayTile); */ + CopyWindowProperties(tmp_win->w, tmp_win->frame); tmp_win->title_w = XCreateSimpleWindow(dpy, tmp_win->frame, -BorderWidth, -BorderWidth, *************** *** 614,619 XGetWindowAttributes(dpy, w, &wa); return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); } /*********************************************************************** --- 616,687 ----- XGetWindowAttributes(dpy, w, &wa); return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); + } + + /* + * Copies the property 'prop' from Window 'wfrom' to 'wto'. Should work + * correctly for an arbitrary lenth property. + */ + void + CopyProperty(wfrom, wto, prop) + Window wfrom, wto; + Atom *prop; + { + Atom actual_type; + int actual_format; + long nitems; + long bytes_after; + int status; + long offset; + int mode; + char *propdata; + + actual_type = AnyPropertyType; + offset = 0; + mode = PropModeReplace; + bytes_after = 1024; + do { + status = XGetWindowProperty(dpy, wfrom, + *prop, offset, (long) (bytes_after+3/4), + False, actual_type, &actual_type, &actual_format, + &nitems, &bytes_after, &propdata); + if (status==BadWindow) { + fprintf(stderr, "window id # 0x%lx does not exists!\n", + wfrom); + return; + } + if (status!=Success) { + fprintf(stderr, "XGetWindowProperty failed!\n"); + return; + } + if (bytes_after != 0) { + #ifdef DEBUG + fprintf(stderr, "Only got the first %d items. %d bytes remain\n", + nitems, bytes_after); + #endif + offset = (nitems * actual_format)/32; + mode = PropModeAppend; + } + + status = XChangeProperty(dpy, wto, *prop, actual_type, + actual_format, mode , propdata, nitems); + XFree(propdata); + } while (bytes_after != 0); + } + + + void + CopyWindowProperties(wfrom, wto) + Window wfrom, wto; + { + int num_prop, i; + Atom *properties, *prop; + + properties = XListProperties(dpy, wfrom, &num_prop); + for (i = 0, prop = properties; i < num_prop; i++, prop++) { + CopyProperty(wfrom, wto, prop); + } + XFree(properties); } /*********************************************************************** *** /tmp/,RCSt1a25414 Fri Jun 24 03:26:23 1988 --- events.c Fri Jun 24 03:22:20 1988 *************** *** 179,184 unsigned long valuemask; /* mask for create windows */ XSetWindowAttributes attributes; /* attributes for create windows */ Pixmap pm; #ifdef DEBUG fprintf(stderr, "PropertyNotify\n"); --- 179,185 ----- unsigned long valuemask; /* mask for create windows */ XSetWindowAttributes attributes; /* attributes for create windows */ Pixmap pm; + extern void CopyProperty(); #ifdef DEBUG fprintf(stderr, "PropertyNotify\n"); *************** *** 187,192 if (tmp_win == NULL) return; XGetWindowProperty(dpy, w, event.xproperty.atom, 0, 200, False, AnyPropertyType, &junk1, &junk2, &junk3, &len, &prop); --- 188,200 ----- if (tmp_win == NULL) return; + /* + * hmm - we could save a GetProperty if we used the info from + * CopyProperty - unfortunately, CopyProperty loops around if the + * bytes aren't returned in one go, which means that it doesn't get + * the whole property. That should be changed. - moraes + */ + CopyProperty(tmp_win->w, tmp_win->frame, &event.xproperty.atom); XGetWindowProperty(dpy, w, event.xproperty.atom, 0, 200, False, AnyPropertyType, &junk1, &junk2, &junk3, &len, &prop);
msm@jumbo.dec.com (Mark S. Manasse) (06/29/88)
The current draft ICCCM includes a property WM_STATE which is supposed to be present on all top-level windows, at least whenever there's a window manager running. This property should appear only on the top-level client windows. Thus, a client window is one which either has the WM_STATE property on it, or a mapped child of the root which doesn't contain any window with WM_STATE on its property list. The only way this goes wrong is in the case of a window manager which isn't managing any clients, but which maps a subwindow as a sort-of pseudoroot, which hardly seems like an important enough case to get all that worried about. Some window managers don't put the frame windows on the root, but instead add an extra window or two between the root and the frames. This lets you select for SubstructureNotify on the root without hearing about all the things that happen because the window manager asked for them to happen. Thus, some windows other than the root may contain multiple application windows. Don't be fooled, use recursion. Mark