all repos — openbox @ 83b6c9bfa0ccc8088e4c65e5a2cf139933959565

openbox fork - make it a bit more like ryudo

sync with bb-cvs
Dana Jansens danakj@orodu.net
commit

83b6c9bfa0ccc8088e4c65e5a2cf139933959565

parent

cd6c4ebcb27b796b214296aefd78a41235dd8640

6 files changed, 246 insertions(+), 119 deletions(-)

jump to
M src/Screen.ccsrc/Screen.cc

@@ -283,7 +283,7 @@ }

// manage shown windows for (i = 0; i < nchild; ++i) { - if (children[i] == None || (! blackbox->validateWindow(children[i]))) + if (children[i] == None || ! blackbox->validateWindow(children[i])) continue; XWindowAttributes attrib;

@@ -1232,6 +1232,14 @@ addSystrayWindow(w);

return; } + // is the window a docking app + XWMHints *wmhint = XGetWMHints(blackbox->getXDisplay(), w); + if (wmhint && (wmhint->flags & StateHint) && + wmhint->initial_state == WithdrawnState) { + slit->addClient(w); + return; + } + new BlackboxWindow(blackbox, w, this); BlackboxWindow *win = blackbox->searchWindow(w);

@@ -1763,7 +1771,7 @@

break; case 421: // exec - if ((! *label) && (! *command)) { + if (! (*label || *command)) { fprintf(stderr, i18n(ScreenSet, ScreenEXECError, "BScreen::parseMenuFile: [exec] error, " "no menu label and/or command defined\n"));

@@ -1786,21 +1794,19 @@ menu->insert(label, BScreen::Exit);

break; - case 561: // style - { - if ((! *label) || (! *command)) { - fprintf(stderr, - i18n(ScreenSet, ScreenSTYLEError, - "BScreen::parseMenuFile: [style] error, " - "no menu label and/or filename defined\n")); - continue; - } - - string style = expandTilde(command); - - menu->insert(label, BScreen::SetStyle, style.c_str()); + case 561: { // style + if (! (*label && *command)) { + fprintf(stderr, + i18n(ScreenSet, ScreenSTYLEError, + "BScreen::parseMenuFile: [style] error, " + "no menu label and/or filename defined\n")); + continue; } + string style = expandTilde(command); + + menu->insert(label, BScreen::SetStyle, style.c_str()); + } break; case 630: // config

@@ -1830,7 +1836,7 @@

if (submenufile) { struct stat buf; if (fstat(fileno(submenufile), &buf) || - (! S_ISREG(buf.st_mode))) { + ! S_ISREG(buf.st_mode)) { fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEErrorReg, "BScreen::parseMenuFile: [include] error: "

@@ -1912,7 +1918,7 @@ case 1113: // stylesmenu

{ bool newmenu = ((key == 1113) ? True : False); - if ((! *label) || ((! *command) && newmenu)) { + if (! *label || (! *command && newmenu)) { fprintf(stderr, i18n(ScreenSet, ScreenSTYLESDIRError, "BScreen::parseMenuFile: [stylesdir/stylesmenu]"

@@ -1958,7 +1964,7 @@ string style = stylesdir;

style += '/'; style += fname; - if ((! stat(style.c_str(), &statbuf)) && + if (! stat(style.c_str(), &statbuf) && S_ISREG(statbuf.st_mode)) stylesmenu->insert(fname, BScreen::SetStyle, style); }
M src/Slit.ccsrc/Slit.cc

@@ -133,6 +133,17 @@ } else {

client->rect.setSize(64, 64); } + Atom *proto; + int num_return = 0; + if (XGetWMProtocols(display, client->window, &proto, &num_return)) { + for (int i = 0; i < num_return; ++i) { + if (proto[i] == + blackbox->getXAtom()->getAtom(XAtom::blackbox_structure_messages)) { + screen->addNetizen(new Netizen(screen, client->window)); + } + } + } + XSetWindowBorderWidth(display, client->window, 0); XGrabServer(display);

@@ -466,12 +477,17 @@ switch (placement) {

case TopCenter: case TopLeft: case TopRight: - strut.top = getExposedHeight() + border_width; + strut.top = frame.rect.top() + getExposedHeight() + border_width; break; case BottomCenter: case BottomLeft: case BottomRight: - strut.bottom = getExposedHeight() + border_width; + int pos; + if (do_auto_hide) + pos = frame.y_hidden; + else + pos = frame.rect.y(); + strut.bottom = (screen->getRect().bottom() - pos); break; case CenterLeft: strut.left = getExposedWidth() + border_width;
M src/Util.ccsrc/Util.cc

@@ -26,6 +26,8 @@ # include "../config.h"

#endif // HAVE_CONFIG_H extern "C" { +#include <X11/Xatom.h> + #ifdef HAVE_STRING_H #include <string.h> #endif

@@ -48,11 +50,9 @@ #endif // HAVE_UNISTD_H

#if defined(HAVE_PROCESS_H) && defined(__EMX__) # include <process.h> #endif // HAVE_PROCESS_H __EMX__ -} - -#include <X11/Xatom.h> #include <assert.h> +} #include <algorithm>

@@ -171,8 +171,8 @@ int ret = putenv(const_cast<char *>(displaystring.c_str()));

assert(ret != -1); string cmd = "exec "; cmd += command; - execl("/bin/sh", "/bin/sh", "-c", cmd.c_str(), NULL); - exit(0); + ret = execl("/bin/sh", "/bin/sh", "-c", cmd.c_str(), NULL); + exit(ret); } #else // __EMX__ spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", command, NULL);

@@ -249,10 +249,8 @@ }

string itostring(long i) { - if (i < 0) { - std::string tmp = itostring( (unsigned long) -i); + std::string tmp = itostring( (unsigned long) std::abs(i)); + if (i < 0) tmp.insert(tmp.begin(), '-'); - return tmp; - } else - return itostring( (unsigned long) i); + return tmp; }
M src/Window.ccsrc/Window.cc

@@ -38,9 +38,11 @@ # ifdef HAVE_STDIO_H

# include <stdio.h> # endif // HAVE_STDIO_H #endif // DEBUG -} -#include <cstdlib> +#ifdef HAVE_STDLIB_H + #include <stdlib.h> +#endif // HAVE_STDLIB_H +} #include "i18n.hh" #include "blackbox.hh"

@@ -55,9 +57,9 @@ #include "Util.hh"

#include "Window.hh" #include "Windowmenu.hh" #include "Workspace.hh" -#include "Slit.hh" using std::string; +using std::abs; // change this to change what modifier keys openbox uses for mouse bindings // for example: Mod1Mask | ControlMask

@@ -91,21 +93,11 @@ delete this;

return; } - // set the eventmask early in the game so that we make sure we get - // all the events we are interested in - XSetWindowAttributes attrib_set; - attrib_set.event_mask = PropertyChangeMask | FocusChangeMask | - StructureNotifyMask; - attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask; - XChangeWindowAttributes(blackbox->getXDisplay(), client.window, - CWEventMask|CWDontPropagate, &attrib_set); - // fetch client size and placement XWindowAttributes wattrib; - if ((! XGetWindowAttributes(blackbox->getXDisplay(), - client.window, &wattrib)) || - (! wattrib.screen) || wattrib.override_redirect) { + if (! XGetWindowAttributes(blackbox->getXDisplay(), + client.window, &wattrib) || + ! wattrib.screen || wattrib.override_redirect) { #ifdef DEBUG fprintf(stderr, "BlackboxWindow::BlackboxWindow(): XGetWindowAttributes failed\n");

@@ -115,6 +107,21 @@ delete this;

return; } +#ifdef DEBUG + fprintf(stderr, "0x%lx: initial (%d, %d) w: %d, h: %d\n", client.window, + wattrib.x, wattrib.y, wattrib.width, wattrib.height); +#endif // DEBUG + + // set the eventmask early in the game so that we make sure we get + // all the events we are interested in + XSetWindowAttributes attrib_set; + attrib_set.event_mask = PropertyChangeMask | FocusChangeMask | + StructureNotifyMask; + attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask; + XChangeWindowAttributes(blackbox->getXDisplay(), client.window, + CWEventMask|CWDontPropagate, &attrib_set); + flags.moving = flags.resizing = flags.shaded = flags.visible = flags.iconic = flags.focused = flags.stuck = flags.modal = flags.send_focus_message = flags.shaped = flags.skip_taskbar =

@@ -146,9 +153,11 @@ decorations = Decor_Titlebar | Decor_Border | Decor_Handle |

Decor_Iconify | Decor_Maximize; functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize; - client.wm_hint_flags = client.normal_hint_flags = 0; + client.normal_hint_flags = 0; client.window_group = None; client.transient_for = 0; + + current_state = NormalState; /* get the initial size and location of client window (relative to the

@@ -175,11 +184,11 @@ getWMProtocols();

getWMHints(); getWMNormalHints(); - if (client.initial_state == WithdrawnState) { - screen->getSlit()->addClient(client.window); - delete this; - return; - } +#ifdef DEBUG + fprintf(stderr, "0x%lx: after hints (%d, %d) w: %d, h: %d\n", client.window, + client.rect.x(), client.rect.y(), + client.rect.width(), client.rect.height()); +#endif // DEBUG frame.window = createToplevelWindow(); frame.plate = createChildWindow(frame.window);

@@ -232,6 +241,14 @@ functions &= ~(Func_Resize | Func_Maximize);

} upsize(); +#ifdef DFEBUG + fprintf(stderr, "0x%lx: sizes reflect the frame from now on\n", + client.window); + fprintf(stderr, "0x%lx: after upsize (%d, %d) w: %d, h: %d\n", client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG + setAllowedActions(); bool place_window = True;

@@ -242,6 +259,13 @@

if (blackbox->isStartup() || client.rect.intersects(screen->getRect())) place_window = False; } + +#ifdef DEBUG + fprintf(stderr, "0x%lx: after gravity (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG // add the window's strut. note this is done *after* placing the window. screen->addStrut(&client.strut);

@@ -272,16 +296,20 @@ // don't need to call configure if we are letting the workspace

// place the window configure(frame.rect.x(), frame.rect.y(), frame.rect.width(), frame.rect.height()); + +#ifdef DEBUG + fprintf(stderr, "0x%lx: after configure (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG } // preserve the window's initial state on first map, and its current state // across a restart - if (! getState()) { - if (client.wm_hint_flags & StateHint) - current_state = client.initial_state; - else - current_state = NormalState; - } + unsigned long initial_state = current_state; + if (! getState()) + current_state = initial_state; // get sticky state from our parent window if we've got one if (isTransient() && client.transient_for != (BlackboxWindow *) ~0ul &&

@@ -290,14 +318,14 @@ stick();

if (flags.shaded) { flags.shaded = False; - unsigned long orig_state = current_state; + initial_state = current_state; shade(); /* At this point in the life of a window, current_state should only be set to IconicState if the window was an *icon*, not if it was shaded. */ - if (orig_state != IconicState) + if (initial_state != IconicState) current_state = NormalState; }

@@ -306,9 +334,8 @@ flags.stuck = False;

stick(); } - if (flags.maximized && (functions & Func_Maximize)) { + if (flags.maximized && (functions & Func_Maximize)) remaximize(); - } /* When the window is mapped (and also when its attributes are restored), the

@@ -327,6 +354,13 @@

XMapSubwindows(blackbox->getXDisplay(), frame.window); redrawWindowFrame(); + +#ifdef DEBUG + fprintf(stderr, "0x%lx: end of constructor (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG }

@@ -849,7 +883,7 @@ }

void BlackboxWindow::ungrabButtons(void) { - if ((! screen->isSloppyFocus()) || screen->doClickRaise()) + if (! screen->isSloppyFocus() || screen->doClickRaise()) blackbox->ungrabButton(Button1, 0, frame.plate); blackbox->ungrabButton(Button1, ModMask, frame.window);

@@ -1033,10 +1067,9 @@ for (int i = 0; i < num_return; ++i) {

if (proto[i] == xatom->getAtom(XAtom::wm_delete_window)) { decorations |= Decor_Close; functions |= Func_Close; - } else if (proto[i] == xatom->getAtom(XAtom::wm_take_focus)) + } else if (proto[i] == xatom->getAtom(XAtom::wm_take_focus)) { flags.send_focus_message = True; - else if (proto[i] == xatom->getAtom(XAtom::blackbox_structure_messages)) - screen->addNetizen(new Netizen(screen, client.window)); + } } XFree(proto);

@@ -1050,7 +1083,6 @@ * If the property is not set, then use a set of default values.

*/ void BlackboxWindow::getWMHints(void) { focus_mode = F_Passive; - client.initial_state = NormalState; // remove from current window group if (client.window_group) {

@@ -1077,7 +1109,7 @@ }

} if (wmhint->flags & StateHint) - client.initial_state = wmhint->initial_state; + current_state = wmhint->initial_state; if (wmhint->flags & WindowGroupHint) { client.window_group = wmhint->window_group;

@@ -1092,7 +1124,6 @@ if (group)

group->addWindow(this); } - client.wm_hint_flags = wmhint->flags; XFree(wmhint); }

@@ -1332,17 +1363,12 @@

if (blackbox_hint->flags & AttribDecoration) { switch (blackbox_hint->decoration) { case DecorNone: - // clear all decorations except close - decorations &= Decor_Close; - // clear all functions except close - functions &= Func_Close; - + decorations = 0; break; case DecorTiny: decorations |= Decor_Titlebar | Decor_Iconify; decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize); - functions |= Func_Move | Func_Iconify; functions &= ~(Func_Resize | Func_Maximize); break;

@@ -1350,7 +1376,6 @@

case DecorTool: decorations |= Decor_Titlebar; decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle); - functions |= Func_Move; functions &= ~(Func_Resize | Func_Maximize | Func_Iconify); break;

@@ -1359,8 +1384,6 @@ case DecorNormal:

default: decorations |= Decor_Titlebar | Decor_Border | Decor_Handle | Decor_Iconify | Decor_Maximize; - functions |= Func_Resize | Func_Move | Func_Iconify | Func_Maximize; - break; }

@@ -1376,8 +1399,7 @@

void BlackboxWindow::getTransientInfo(void) { if (client.transient_for && client.transient_for != (BlackboxWindow *) ~0ul) { - // the transient for hint was removed, so we need to tell our - // previous transient_for that we are going away + // reset transient_for in preparation of looking for a new owner client.transient_for->client.transientList.remove(this); }

@@ -1548,15 +1570,7 @@

assert(! flags.iconic && (flags.stuck || // window must be on the current workspace or sticky blackbox_attrib.workspace == screen->getCurrentWorkspaceID())); -#if 0 - // if the window is not visible, mark the window as wanting focus rather - // than give it focus. - if (! flags.visible) { - Workspace *wkspc = screen->getWorkspace(blackbox_attrib.workspace); - wkspc->setLastFocusedWindow(this); - return True; - } -#endif + /* We only do this check for normal windows and dialogs because other windows do this on purpose, such as kde's kicker, and we don't want to go moving

@@ -1855,6 +1869,27 @@

// re-maximizes the window to take into account availableArea changes void BlackboxWindow::remaximize(void) { + if (flags.shaded) { + // we only update the window's attributes otherwise we lose the shade bit + switch(flags.maximized) { + case 1: + blackbox_attrib.flags |= AttribMaxHoriz | AttribMaxVert; + blackbox_attrib.attrib |= AttribMaxHoriz | AttribMaxVert; + break; + + case 2: + blackbox_attrib.flags |= AttribMaxVert; + blackbox_attrib.attrib |= AttribMaxVert; + break; + + case 3: + blackbox_attrib.flags |= AttribMaxHoriz; + blackbox_attrib.attrib |= AttribMaxHoriz; + break; + } + return; + } + // save the original dimensions because maximize will wipe them out int premax_x = blackbox_attrib.premax_x, premax_y = blackbox_attrib.premax_y,

@@ -2236,6 +2271,56 @@ blackbox_attrib.premax_w = w;

blackbox_attrib.premax_h = h; } + if (net->flags & AttribDecoration) { + switch (net->decoration) { + case DecorNone: + decorations = 0; + + break; + + default: + case DecorNormal: + decorations |= Decor_Titlebar | Decor_Handle | Decor_Border | + Decor_Iconify | Decor_Maximize; + + break; + + case DecorTiny: + decorations |= Decor_Titlebar | Decor_Iconify; + decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize); + + break; + + case DecorTool: + decorations |= Decor_Titlebar; + decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle); + + break; + } + + // sanity check the new decor + if (! (functions & Func_Resize) || isTransient()) + decorations &= ~(Decor_Maximize | Decor_Handle); + if (! (functions & Func_Maximize)) + decorations &= ~Decor_Maximize; + + if (decorations & Decor_Titlebar) { + if (functions & Func_Close) // close button is controlled by function + decorations |= Decor_Close; // not decor type + } else { + if (flags.shaded) // we can not be shaded if we lack a titlebar + shade(); + } + + if (flags.visible && frame.window) { + XMapSubwindows(blackbox->getXDisplay(), frame.window); + XMapWindow(blackbox->getXDisplay(), frame.window); + } + + reconfigure(); + setState(current_state); + } + // with the state set it will then be the map event's job to read the // window's state and behave accordingly

@@ -2531,6 +2616,12 @@ case NormalState:

case InactiveState: case ZoomState: default: +#ifdef DEBUG + fprintf(stderr, "0x%lx: just before show (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG show(); screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); if (isNormal()) {

@@ -2624,6 +2715,12 @@ setAllowedActions();

} reconfigure(); +#ifdef DEBUG + fprintf(stderr, "0x%lx: transient hint (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif } break;

@@ -2676,6 +2773,12 @@

if (old_rect != frame.rect) reconfigure(); +#ifdef DEBUG + fprintf(stderr, "0x%lx: normal hint (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG break; }

@@ -2735,11 +2838,19 @@

applyGravity(req); } - if (cr->value_mask & CWWidth) + if (cr->value_mask & CWWidth) { req.setWidth(cr->width + frame.margin.left + frame.margin.right); +#ifdef DEBUG + fprintf(stderr, "0x%lx: new width - %d\n", client.window, cr->width); +#endif // DEBUG + } - if (cr->value_mask & CWHeight) + if (cr->value_mask & CWHeight) { req.setHeight(cr->height + frame.margin.top + frame.margin.bottom); +#ifdef DEBUG + fprintf(stderr, "0x%lx: new height - %d\n", client.window, cr->height); +#endif // DEBUG + } configure(req.x(), req.y(), req.width(), req.height()); }

@@ -2758,6 +2869,13 @@ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);

break; } } + +#ifdef DEBUG + fprintf(stderr, "0x%lx: change request (%d, %d) w: %d, h: %d\n", + client.window, + frame.rect.x(), frame.rect.y(), + frame.rect.width(), frame.rect.height()); +#endif // DEBUG }

@@ -3030,10 +3148,10 @@

bool snapped = False; const Rect &winrect = snapwin->frameRect(); - int dleft = std::abs(wright - winrect.left()), - dright = std::abs(wleft - winrect.right()), - dtop = std::abs(wbottom - winrect.top()), - dbottom = std::abs(wtop - winrect.bottom()); + int dleft = abs(wright - winrect.left()), + dright = abs(wleft - winrect.right()), + dtop = abs(wbottom - winrect.top()), + dbottom = abs(wtop - winrect.bottom()); if (wtop >= (signed)(winrect.y() - frame.rect.height() + 1) && wtop < (signed)(winrect.y() + winrect.height() - 1)) {

@@ -3052,8 +3170,8 @@

if (snapped) { if (screen->getWindowCornerSnap()) { // try corner-snap to its other sides - dtop = std::abs(wtop - winrect.top()); - dbottom = std::abs(wbottom - winrect.bottom()); + dtop = abs(wtop - winrect.top()); + dbottom = abs(wbottom - winrect.bottom()); if (dtop < snap_distance && dtop <= dbottom) dy = winrect.top(); else if (dbottom < snap_distance)

@@ -3081,8 +3199,8 @@

if (snapped) { if (screen->getWindowCornerSnap()) { // try corner-snap to its other sides - dleft = std::abs(wleft - winrect.left()); - dright = std::abs(wright - winrect.right()); + dleft = abs(wleft - winrect.left()); + dright = abs(wright - winrect.right()); if (dleft < snap_distance && dleft <= dright) dx = winrect.left(); else if (dright < snap_distance)

@@ -3128,10 +3246,10 @@ if (! srect.intersects(Rect(wleft, wtop, frame.rect.width(),

frame.rect.height()))) continue; - int dleft = std::abs(wleft - srect.left()), - dright = std::abs(wright - srect.right()), - dtop = std::abs(wtop - srect.top()), - dbottom = std::abs(wbottom - srect.bottom()); + int dleft = abs(wleft - srect.left()), + dright = abs(wright - srect.right()), + dtop = abs(wtop - srect.top()), + dbottom = abs(wbottom - srect.bottom()); // snap left? if (dleft < snap_distance && dleft <= dright)

@@ -3466,7 +3584,7 @@ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);

} -void BlackboxWindow::changeBlackboxHints(BlackboxHints *net) { +void BlackboxWindow::changeBlackboxHints(const BlackboxHints *net) { if ((net->flags & AttribShaded) && ((blackbox_attrib.attrib & AttribShaded) != (net->attrib & AttribShaded)))

@@ -3512,8 +3630,7 @@

if (net->flags & AttribDecoration) { switch (net->decoration) { case DecorNone: - // clear all decorations except close - decorations &= Decor_Close; + decorations = 0; break;
M src/Window.hhsrc/Window.hh

@@ -183,7 +183,7 @@ #endif

base_width, base_height, win_gravity; - unsigned long initial_state, normal_hint_flags, wm_hint_flags; + unsigned long initial_state, normal_hint_flags; } client; FunctionFlags functions;

@@ -390,7 +390,7 @@ void installColormap(bool install);

void restore(bool remap); void configure(int dx, int dy, unsigned int dw, unsigned int dh); void setWorkspace(unsigned int n); - void changeBlackboxHints(BlackboxHints *net); + void changeBlackboxHints(const BlackboxHints *net); void restoreAttributes(void); void buttonPressEvent(const XButtonEvent *be);
M src/blackbox.ccsrc/blackbox.cc

@@ -282,16 +282,6 @@ break;

} case ConfigureRequest: { - // compress configure requests... - XEvent realevent; - unsigned int i = 0; - while(XCheckTypedWindowEvent(getXDisplay(), e->xconfigurerequest.window, - ConfigureRequest, &realevent)) { - i++; - } - if ( i > 0 ) - e = &realevent; - BlackboxWindow *win = (BlackboxWindow *) 0; Slit *slit = (Slit *) 0;

@@ -496,7 +486,7 @@ } else if ((win = searchWindow(e->xcrossing.window))) {

if (win->getScreen()->isSloppyFocus() && (! win->isFocused()) && (! no_focus) && win->isNormal()) { // don't focus non-normal windows with mouseover - if (((! sa.leave) || sa.inferior) && win->isVisible()) { + if ((! sa.leave || sa.inferior) && win->isVisible()) { if (win->setInputFocus()) win->installColormap(True); // XXX: shouldnt we honour no install? }