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