guy@auspex.auspex.com (Guy Harris) (02/03/90)
Yes, I know, the manual page says "twm" doesn't support it. This is, however: 1) rude of it, since it apparently *can* support it (it apparently attempts to handle the IconPixmapHint as well, which the manual page claims it doesn't; methinks the manual page needs cleaning up) and 2) incorrect, since it doesn't ignore the IconWindowHint, it just half-heartedly recognizes it - sometimes it works, and sometimes it doesn't. X Window System Bug Report xbugs@expo.lcs.mit.edu VERSION: R4 CLIENT MACHINE and OPERATING SYSTEM: all DISPLAY TYPE: all WINDOW MANAGER: twm AREA: twm SYNOPSIS: If an application changes the XA_WM_HINTS property and provides an IconWindowHint, "twm" doesn't properly grab (partial) control of the icon window, nor does it position it properly. DESCRIPTION: If you run an application that changes the icon window as above - for instance, an XView "shelltool", which accepts an escape sequences to specify a file from which the icon should be taken (note: the current XView has a bug that keeps this from working; a fix exists, which I can provide if necessary) - the new icon window will *not* be properly treated as an icon window by "twm". For example, if your ".twmrc" is set up to bring up a menu on a button press when the cursor is in an icon window, the menu won't appear. Furthermore, if you try to change the icon title for an icon whose window was supplied by the application, "twm" completely screws up, changing the size of the window as would be appropriate were it to contain *only* the icon title, but not painting anything in it. REPEAT BY: Run such an application, with such a ".twmrc", and note that the menu doesn't pop up. For the second problem, run an application that provides its own icon window and allows you to set the icon title - again, the XView "shelltool" has an escape sequence to let you set the icon title. SAMPLE FIX: Basically, you change it so that: 1) if the property changes and an icon window *hasn't* yet been created, it just remembers the property change, and doesn't do anything with the new window (CreateIconWindow will do what's appropriate the first time the window is iconified); 2) if the property changes and an icon window *has* been created, move the new window atop the old one, unmap or destroy the old one, and set up the new one so that input events will be handled by "twm"; 3) flag windows whose icon window was supplied by the application, and don't do anything if the icon title changes for windows like that. *** twm.h.dist Thu Dec 14 11:51:29 1989 --- twm.h Wed Jan 31 15:30:34 1990 *************** *** 251,256 **** --- 251,257 ---- short mapped; /* is the window mapped ? */ short auto_raise; /* should we auto-raise this window ? */ short forced; /* has had an icon forced upon it */ + short icon_not_ours; /* icon pixmap or window supplied to us */ short highlight; /* should highlight this window */ short iconify_by_unmapping; /* unmap window to iconify it */ short iconmgr; /* this is an icon manager window */ *** events.c.dist Thu Dec 14 11:52:19 1989 --- events.c Fri Feb 2 11:41:00 1990 *************** *** 737,745 **** Tmp_win->group = Tmp_win->wmhints->window_group; if (!Tmp_win->forced && Tmp_win->wmhints && ! Tmp_win->wmhints->flags & IconWindowHint) ! Tmp_win->icon_w = Tmp_win->wmhints->icon_window; if (Tmp_win->icon_w && !Tmp_win->forced && Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconPixmapHint)) { if (!XGetGeometry (dpy, Tmp_win->wmhints->icon_pixmap, &JunkRoot, --- 737,796 ---- Tmp_win->group = Tmp_win->wmhints->window_group; if (!Tmp_win->forced && Tmp_win->wmhints && ! Tmp_win->wmhints->flags & IconWindowHint) { ! if (Tmp_win->icon_w) { ! int icon_x, icon_y; + /* + * There's already an icon window. + * Try to find out where it is; if we succeed, move the new + * window to where the old one is. + */ + if (XGetGeometry (dpy, Tmp_win->icon_w, &JunkRoot, &icon_x, + &icon_y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { + /* + * Move the new icon window to where the old one was. + */ + XMoveWindow(dpy, Tmp_win->wmhints->icon_window, icon_x, + icon_y); + } + + /* + * If the window is iconic, map the new icon window. + */ + if (Tmp_win->icon) + XMapWindow(dpy, Tmp_win->wmhints->icon_window); + + /* + * Now, if the old window isn't ours, unmap it, otherwise + * just get rid of it completely. + */ + if (Tmp_win->icon_not_ours) + XUnmapWindow(dpy, Tmp_win->icon_w); + else + XDestroyWindow(dpy, Tmp_win->icon_w); + + /* + * The new icon window isn't our window, so note that fact + * so that we don't treat it as ours. + */ + Tmp_win->icon_not_ours = TRUE; + + /* + * Now make the new window the icon window for this window, + * and set it up to work as such (select for key presses + * and button presses/releases, set up the contexts for it, + * and define the cursor for it). + */ + Tmp_win->icon_w = Tmp_win->wmhints->icon_window; + XSelectInput (dpy, Tmp_win->icon_w, + KeyPressMask | ButtonPressMask | ButtonReleaseMask); + XSaveContext(dpy, Tmp_win->icon_w, TwmContext, (caddr_t)Tmp_win); + XSaveContext(dpy, Tmp_win->icon_w, ScreenContext, (caddr_t)Scr); + XDefineCursor(dpy, Tmp_win->icon_w, Scr->IconCursor); + } + } + if (Tmp_win->icon_w && !Tmp_win->forced && Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconPixmapHint)) { if (!XGetGeometry (dpy, Tmp_win->wmhints->icon_pixmap, &JunkRoot, *************** *** 812,817 **** --- 863,871 ---- } if (Tmp_win->icon_w == NULL) + return; + + if (Tmp_win->icon_not_ours) return; Tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font, *** icons.c.dist Sun Dec 10 16:20:06 1989 --- icons.c Thu Feb 1 14:41:33 1990 *************** *** 321,326 **** --- 321,327 ---- FB(tmp_win->iconc.fore, tmp_win->iconc.back); tmp_win->forced = FALSE; + tmp_win->icon_not_ours = FALSE; /* now go through the steps to get an icon window, if ForceIcon is * set, then no matter what else is defined, the bitmap from the *************** *** 476,481 **** --- 477,486 ---- { tmp_win->icon_w = NULL; tmp_win->wmhints->flags &= ~IconWindowHint; + } + else + { + tmp_win->icon_not_ours = TRUE; } } else