OK, I spent a little while looking through the blackbox code
today, and I think I came up with a better way to do what
yesterday's patch intended. The patch also makes a few other
changes to the way focus acts that I only noticed when I
started using ClickToFocus to test this stuff.
Anyway, the patch is attached -- it needs to be applied to
a clean blackbox (i.e. one without the patch I sent out
yesterday, since they conflict -- other patches probably
won't interfere). If you feel like living on the edge,
try it out and let me know how it fares.
Now for a description of the changes...
1. Changes to Icon.cc :
I only noticed this today, but when you deiconify
something by selecting it on a workspace menu, it is raised
and given the focus. However, if you deiconify something off
of the icons menu, it is only raised. Sort of a strange
disparity, so I added a line to Icon.cc that will cause
a window selected via the icons menu to also get the focus.
2. Changes to Window.cc :
My model for ClickToFocus is basically Windows (since
I suspect that's the reason most people use it), and if I recall
correctly, when you iconify a window there, the next window gets
the keyboard focus. So I added a line or two so that under the
ClickToFocus model when you iconify a window the next window gets
the focus.
3. Changes to Workspace.cc :
The big part, even though it's still only a few lines.
Tracking through the code led me to conclude that the place to
deal with this whole 'how to deal with the focus when a window
disappears' problem was in Workspace::removeWindow(). Any time
a window is destroyed, unmapped or even just moved to another
workspace we need to deal with where to send the focus, and
it's precisely in all these situations that we also call
Workspace::removeWindow().
Previously, removeWindow() just set the focused window
to null when appropriate. Now, depending on the focusing model
and whether the current window is transient, it will either set
it to null, to its parent or to the next window in the cycle.
Now, lest anyone ask, I still haven't hit the memory problem
people have been talking about, but I've been rebooting blackbox
so much to test my changes (I really gotta start using xnest)
that I haven't had a chance to watch for it.
Again, if you use the patch, let me know what you think of it.
Jeff Raven
[EMAIL PROTECTED]
diff -ur blackbox-0.60.0/src/Icon.cc blackbox-0.60.0-focusfix/src/Icon.cc
--- blackbox-0.60.0/src/Icon.cc Thu Mar 16 20:04:12 2000
+++ blackbox-0.60.0-focusfix/src/Icon.cc Thu May 11 18:17:21 2000
@@ -98,6 +98,9 @@
screen->getWorkspace(window->getWorkspaceNumber())->raiseWindow(window);
window->deiconify();
+ // Jeff Raven (2000-05-11)
+ window->setInputFocus();
+
if (! (screen->getWorkspacemenu()->isTorn() || isTorn()))
hide();
}
diff -ur blackbox-0.60.0/src/Window.cc blackbox-0.60.0-focusfix/src/Window.cc
--- blackbox-0.60.0/src/Window.cc Sun Mar 19 20:05:40 2000
+++ blackbox-0.60.0-focusfix/src/Window.cc Thu May 11 18:04:28 2000
@@ -1183,9 +1183,8 @@
else {
if (! focused) {
if (focus_mode == F_LocallyActive || focus_mode == F_Passive)
- XSetInputFocus(display, client.window,
- ((screen->isSloppyFocus()) ? RevertToPointerRoot :
- RevertToParent), CurrentTime);
+ // Jeff Raven (2000-05-11)
+ XSetInputFocus(display, client.window, RevertToPointerRoot, CurrentTime);
else
XSetInputFocus(display, screen->getRootWindow(),
RevertToNone, CurrentTime);
@@ -1234,6 +1233,14 @@
XUnmapWindow(display, frame.window);
visible = False;
iconic = True;
+
+ // Jeff Raven (2000-05-11)
+ if (focused) {
+ if (screen->isSloppyFocus())
+ screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0);
+ else
+ screen->nextFocus();
+ }
setFocusFlag(False);
if (transient && client.transient_for) {
diff -ur blackbox-0.60.0/src/Workspace.cc blackbox-0.60.0-focusfix/src/Workspace.cc
--- blackbox-0.60.0/src/Workspace.cc Sun Mar 19 20:11:07 2000
+++ blackbox-0.60.0-focusfix/src/Workspace.cc Thu May 11 17:47:18 2000
@@ -131,8 +131,16 @@
windowList->remove((const int) w->getWindowNumber());
- if (w->isFocused())
- screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0);
+ // Jeff Raven (2000-05-11)
+ if (w->isFocused()) {
+ if (screen->isSloppyFocus())
+ screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0);
+ else if (w->isTransient() && w->getTransientFor() &&
+ w->getTransientFor()->isVisible())
+ w->getTransientFor()->setInputFocus();
+ else
+ screen->nextFocus();
+ }
clientmenu->remove(w->getWindowNumber());
clientmenu->update();