----- Forwarded message from Rhialto <[EMAIL PROTECTED]> -----
Date: Tue, 21 Dec 2004 02:27:00 +0100
From: Rhialto <[EMAIL PROTECTED]>
Subject: Re: [repository.lp.se #103] ctwm-3.7-alpha* forgets icon positions
To: Rhialto via RT <[EMAIL PROTECTED]>
On Sun 04 Jul 2004 at 09:25:38 +0200, Rhialto via RT wrote:
> When you have some iconified windows (but the Workspace Manager does not
> seem to count), switch to another workspace, and then come back, the
> iconified windows have forgotten their position. They are now all in the
> top-left corner (on top of each other).
>
> I'm pretty sure that some previous versions didn't do this.
I did some more research on this. 3.6 didn't do it. The "virtual
screens" patch has introduced the problem. Since I don't use them, they
obviously should not make a difference.
Here is what seems to happen, although I don't understand the logic
behind it (which may well be why it is incorrect of course).
I have re-indented this code for clarity - the original code is truely a
mess and should be run trough indent(1). The explanation is approximate,
as I said I'm not sure I understand it.
in workmgr.c:
void GotoWorkSpace (virtualScreen *vs, WorkSpace *ws)
...
for (twmWin = &(Scr->TwmRoot); twmWin != NULL; twmWin = twmWin->next) {
if (twmWin->vs == vs) {
if (!OCCUPY (twmWin, newws)) {
virtualScreen *tvs;
Vanish (vs, twmWin);
for (tvs = Scr->vScreenList; tvs != NULL; tvs = tvs->next) {
if (tvs == vs) continue;
if (OCCUPY (twmWin, tvs->wsw->currentwspc)) {
DisplayWin (tvs, twmWin);
break;
}
}
} else
...
}
}
This loop effectively calls Vanish() for my icon.
It seems that this loop unmaps windows that are not in the new current
workspace and it displays them in another virtual screen again, if
applicable.
Note that Vanish() sets twmWin->vs to NULL. So when we leave our
original workspace with the icon, it loses its vs.
A bit further down, windows are mapped again. See this in the context
when we come back into that workspace:
/* Iconise in reverse order */
for (twmWin = last_twmWin; twmWin != NULL; twmWin = twmWin->prev) {
if (OCCUPY (twmWin, newws) && !twmWin->vs) {
DisplayWin (vs, twmWin);
}
}
windows that are not having a vs get displayed.
The comment seems either very cryptic or just plain wrong.
static void DisplayWin (virtualScreen *vs, TwmWindow *tmp_win)
{
XWindowAttributes winattrs;
unsigned long eventMask;
printf("DisplayWin: vs=%p, tmp_win=%p mapped=%d isicon=%d icon_on=%d
icon=%p\n",
vs, tmp_win,tmp_win->mapped, tmp_win->isicon, tmp_win->icon_on,
tmp_win->icon );
if (vs && tmp_win->vs) return;
tmp_win->vs = vs;
if (!tmp_win->mapped) {
if (tmp_win->isicon) {
if (tmp_win->icon_on) {
if (tmp_win->icon && tmp_win->icon->w) {
printf("icon->w=%p, vs->window=%p\n", tmp_win->icon->w,
vs ? vs->window : -1);
----> if (vs) XReparentWindow (dpy, tmp_win->icon->w, vs->window,
0, 0);
IconUp (tmp_win);
XMapWindow (dpy, tmp_win->icon->w);
return;
}
}
}
return;
}
The line with XReparentWindow is executed and it moves all icons to the
origin. And these conditions are indeed true for our icons. Why all
these complicated conditions? I don't know. Stuff should be simplified.
I think the solution is to change this around line 1275 of workmgr.c
if (vs) XReparentWindow (dpy, tmp_win->icon->w, vs->window, 0, 0);
to
if (vs && vs != tmp_win->oldvs)
XReparentWindow (dpy, tmp_win->icon->w, vs->window, 0, 0);
as it more or less happens 22 lines down.
I think a bit part of the complexity with these virtual screens is that
apparently you are not allowed to see the same window twice, on the two
displayed workspaces. I say to that: why the *** not? Just show the
window twice, let it get input from 2 mice and keyboards even if that's
how the system is configured (and if that is possible, I don't know).
The user can cope with that, and it seems a lot simpler for the window
manager.
-Olaf.
--
-- Ceterum censeo "authored[1]" delendum esse.
___ Olaf 'Rhialto' Seibert -- [1] Ugly English neologism[2].
\X/ rhialto/at/xs4all.nl -- [2] For lawyers whose English/Latin is below par.
----- End forwarded message -----