Path: utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!bloom-beacon!godzilla.ele.toronto.EDU!moraes From: moraes@godzilla.ele.toronto.EDU (Mark Moraes) Newsgroups: comp.windows.x Subject: Re: Bugs in twm, wm, xprop, and xplaces (or my ignorance) Message-ID: <8806280637.AA08968@godzilla.ele.toronto.edu> Date: 28 Jun 88 02:37:39 GMT References: <6562@jhunix.HCF.JHU.EDU> <6910001@hpfcdc.HP.COM> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: moraes%csri.toronto.edu@relay.cs.net Organization: EECG, University of Toronto Lines: 188 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);