all repos — openbox @ e15e4a9e03dd7b64004b76ca84b07c12c251f67b

openbox fork - make it a bit more like ryudo

make iconified windows uniconify on an XMapRequestEvent.
sync with blackbox cvs.
Dana Jansens danakj@orodu.net
commit

e15e4a9e03dd7b64004b76ca84b07c12c251f67b

parent

be2f47223c17c399e05436a34ba4140f2fc44fc9

M src/BaseDisplay.ccsrc/BaseDisplay.cc

@@ -78,7 +78,7 @@ # include <sys/wait.h>

#endif // HAVE_SYS_WAIT_H } -#include <sstream> +#include <string> using std::string; #include "i18n.hh"

@@ -468,7 +468,6 @@ const string::size_type pos = default_string.rfind(".");

if (pos != string::npos) default_string.resize(pos); - std::ostringstream formatter; - formatter << "DISPLAY=" << default_string << '.' << screen_number; - display_string = formatter.str(); + display_string = string("DISPLAY=") + default_string + '.' + + itostring(static_cast<unsigned long>(screen_number)); }
M src/Configmenu.ccsrc/Configmenu.cc

@@ -200,7 +200,8 @@ break;

case 4: // click raise with sloppy focus getScreen()->saveClickRaise(! getScreen()->doClickRaise()); - getScreen()->updateFocusModel(); + // make sure the appropriate mouse buttons are grabbed on the windows + getScreen()->toggleFocusModel(BScreen::SloppyFocus); break; } setValues();
M src/Screen.ccsrc/Screen.cc

@@ -132,6 +132,8 @@

resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font = resource.wstyle.font = (BFont *) 0; + geom_pixmap = None; + xatom->setSupported(this); // set-up netwm support #ifdef HAVE_GETPID xatom->setValue(getRootWindow(), XAtom::blackbox_pid, XAtom::cardinal,

@@ -2006,7 +2008,7 @@ return workspacesList[index];

} -void BScreen::buttonPressEvent(XButtonEvent *xbutton) { +void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { if (xbutton->button == 1) { if (! isRootColormapInstalled()) image_control->installRootColormap();

@@ -2071,6 +2073,9 @@ }

void BScreen::toggleFocusModel(FocusModel model) { + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::ungrabButtons)); + if (model == SloppyFocus) { saveSloppyFocus(True); } else {

@@ -2080,14 +2085,8 @@ resource.click_raise = False;

saveSloppyFocus(False); } - updateFocusModel(); -} - - -void BScreen::updateFocusModel() -{ - std::for_each(workspacesList.begin(), workspacesList.end(), - std::mem_fun(&Workspace::updateFocusModel)); + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::grabButtons)); }
M src/Screen.hhsrc/Screen.hh

@@ -331,14 +331,13 @@ void load_rc(void);

void save_rc(void); void reconfigure(void); void toggleFocusModel(FocusModel model); - void updateFocusModel(void); void rereadMenu(void); void shutdown(void); void showPosition(int x, int y); void showGeometry(unsigned int gx, unsigned int gy); void hideGeometry(void); - void buttonPressEvent(XButtonEvent *xbutton); + void buttonPressEvent(const XButtonEvent *xbutton); void updateNetizenCurrentWorkspace(void); void updateNetizenWorkspaceCount(void);
M src/Slit.ccsrc/Slit.cc

@@ -625,7 +625,7 @@ removeClient(clientList.front());

} -void Slit::buttonPressEvent(XButtonEvent *e) { +void Slit::buttonPressEvent(const XButtonEvent *e) { if (e->window != frame.window) return; if (e->button == Button1 && (! on_top)) {

@@ -659,7 +659,7 @@ }

} -void Slit::enterNotifyEvent(XCrossingEvent *) { +void Slit::enterNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return;

@@ -671,7 +671,7 @@ }

} -void Slit::leaveNotifyEvent(XCrossingEvent *) { +void Slit::leaveNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return;

@@ -683,7 +683,7 @@ }

} -void Slit::configureRequestEvent(XConfigureRequestEvent *e) { +void Slit::configureRequestEvent(const XConfigureRequestEvent *e) { if (! blackbox->validateWindow(e->window)) return;

@@ -737,7 +737,7 @@ }

} -void Slit::unmapNotifyEvent(XUnmapEvent *e) { +void Slit::unmapNotifyEvent(const XUnmapEvent *e) { removeClient(e->window); }
M src/Slit.hhsrc/Slit.hh

@@ -188,11 +188,11 @@ void reposition(void);

void shutdown(void); void toggleAutoHide(void); - void buttonPressEvent(XButtonEvent *e); - void enterNotifyEvent(XCrossingEvent * /*unused*/); - void leaveNotifyEvent(XCrossingEvent * /*unused*/); - void configureRequestEvent(XConfigureRequestEvent *e); - void unmapNotifyEvent(XUnmapEvent *e); + void buttonPressEvent(const XButtonEvent *e); + void enterNotifyEvent(const XCrossingEvent * /*unused*/); + void leaveNotifyEvent(const XCrossingEvent * /*unused*/); + void configureRequestEvent(const XConfigureRequestEvent *e); + void unmapNotifyEvent(const XUnmapEvent *e); virtual void timeout(void);
M src/Toolbar.ccsrc/Toolbar.cc

@@ -777,7 +777,7 @@ XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);

} -void Toolbar::buttonPressEvent(XButtonEvent *be) { +void Toolbar::buttonPressEvent(const XButtonEvent *be) { if (be->button == 1) { if (be->window == frame.psbutton) redrawPrevWorkspaceButton(True, True);

@@ -826,7 +826,7 @@ }

-void Toolbar::buttonReleaseEvent(XButtonEvent *re) { +void Toolbar::buttonReleaseEvent(const XButtonEvent *re) { if (re->button == 1) { if (re->window == frame.psbutton) { redrawPrevWorkspaceButton(False, True);

@@ -873,7 +873,7 @@ }

} -void Toolbar::enterNotifyEvent(XCrossingEvent *) { +void Toolbar::enterNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return;

@@ -884,7 +884,7 @@ if (hide_timer->isTiming()) hide_timer->stop();

} } -void Toolbar::leaveNotifyEvent(XCrossingEvent *) { +void Toolbar::leaveNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return;

@@ -896,7 +896,7 @@ }

} -void Toolbar::exposeEvent(XExposeEvent *ee) { +void Toolbar::exposeEvent(const XExposeEvent *ee) { if (ee->window == frame.clock) checkClock(True); else if (ee->window == frame.workspace_label && (! editing)) redrawWorkspaceLabel();

@@ -908,7 +908,7 @@ else if (ee->window == frame.nwbutton) redrawNextWindowButton();

} -void Toolbar::keyPressEvent(XKeyEvent *ke) { +void Toolbar::keyPressEvent(const XKeyEvent *ke) { if (ke->window == frame.workspace_label && editing) { if (new_workspace_name.empty()) { new_name_pos = 0;

@@ -916,7 +916,7 @@ }

KeySym ks; char keychar[1]; - XLookupString(ke, keychar, 1, &ks, 0); + XLookupString(const_cast<XKeyEvent*>(ke), keychar, 1, &ks, 0); // either we are told to end with a return or we hit 127 chars if (ks == XK_Return || new_name_pos == 127) {
M src/Toolbar.hhsrc/Toolbar.hh

@@ -172,12 +172,12 @@ { return ((hidden) ? frame.x_hidden : frame.rect.x()); }

inline int getY(void) const { return ((hidden) ? frame.y_hidden : frame.rect.y()); } - void buttonPressEvent(XButtonEvent *be); - void buttonReleaseEvent(XButtonEvent *re); - void enterNotifyEvent(XCrossingEvent * /*unused*/); - void leaveNotifyEvent(XCrossingEvent * /*unused*/); - void exposeEvent(XExposeEvent *ee); - void keyPressEvent(XKeyEvent *ke); + void buttonPressEvent(const XButtonEvent *be); + void buttonReleaseEvent(const XButtonEvent *re); + void enterNotifyEvent(const XCrossingEvent * /*unused*/); + void leaveNotifyEvent(const XCrossingEvent * /*unused*/); + void exposeEvent(const XExposeEvent *ee); + void keyPressEvent(const XKeyEvent *ke); void edit(void); void reconfigure(void);
M src/Window.ccsrc/Window.cc

@@ -134,13 +134,14 @@ frame.uborder_pixel = frame.fborder_pixel = frame.ugrip_pixel =

frame.fgrip_pixel = 0; frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None; frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None; - frame.pbutton = frame.ugrip = frame.fgrip = decorations; + frame.pbutton = frame.ugrip = frame.fgrip = None; 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.window_group = None; client.transient_for = 0; /*

@@ -271,32 +272,7 @@ configureShape();

} #endif // SHAPE - if ((! screen->isSloppyFocus()) || screen->doClickRaise()) { - // grab button 1 for changing focus/raising - blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask, - GrabModeSync, GrabModeSync, None, None); - } - - if (functions & Func_Move) - blackbox->grabButton(Button1, Mod1Mask, frame.window, True, - ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, frame.window, - blackbox->getMoveCursor()); - blackbox->grabButton(Button2, Mod1Mask, frame.window, True, - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - None, None); - if (functions & Func_Resize) - blackbox->grabButton(Button3, Mod1Mask, frame.window, True, - ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, None, - blackbox->getLowerRightAngleCursor()); - - positionWindows(); - decorate(); - - if (decorations & Decor_Titlebar) - XMapSubwindows(blackbox->getXDisplay(), frame.title); - XMapSubwindows(blackbox->getXDisplay(), frame.window); + grabButtons(); windowmenu = new Windowmenu(this);

@@ -329,16 +305,15 @@ stick();

if (flags.shaded) { flags.shaded = False; + unsigned long orig_state = current_state; shade(); /* - Because the iconic'ness of shaded windows is lost, we need to set the - state to NormalState so that shaded windows on other workspaces will not - get shown on the first workspace. 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. */ - current_state = NormalState; + if (orig_state != IconicState) + current_state = NormalState; } if (flags.stuck) {

@@ -359,6 +334,11 @@ *Note* that for sticky windows, the same rules apply here, they are in

fact never set to Iconic since there is no way for us to tell if a sticky window was iconified previously. */ + + positionWindows(); + decorate(); + + XMapSubwindows(blackbox->getXDisplay(), frame.window); redrawWindowFrame(); }

@@ -838,17 +818,11 @@

void BlackboxWindow::reconfigure(void) { upsize(); - client.rect.setPos(frame.rect.left() + frame.margin.left, - frame.rect.top() + frame.margin.top); - positionWindows(); decorate(); redrawWindowFrame(); - configure(frame.rect.x(), frame.rect.y(), - frame.rect.width(), frame.rect.height()); - if (windowmenu) { windowmenu->move(windowmenu->getX(), frame.rect.y() + frame.title_h); windowmenu->reconfigure();

@@ -856,14 +830,31 @@ }

} -void BlackboxWindow::updateFocusModel(void) { - if ((! screen->isSloppyFocus()) || screen->doClickRaise()) { +void BlackboxWindow::grabButtons(void) { + if ((! screen->isSloppyFocus()) || screen->doClickRaise()) // grab button 1 for changing focus/raising blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask, - GrabModeSync, GrabModeSync, None, None); - } else { + GrabModeSync, GrabModeSync, frame.plate, None); + + if (functions & Func_Move) + blackbox->grabButton(Button1, Mod1Mask, frame.window, True, + ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, + GrabModeAsync, frame.window, + blackbox->getMoveCursor()); + if (functions & Func_Resize) + blackbox->grabButton(Button3, Mod1Mask, frame.window, True, + ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, + GrabModeAsync, frame.window, + blackbox->getLowerRightAngleCursor()); +} + + +void BlackboxWindow::ungrabButtons(void) { + if ((! screen->isSloppyFocus()) || screen->doClickRaise()) blackbox->ungrabButton(Button1, 0, frame.plate); - } + + blackbox->ungrabButton(Button1, Mod1Mask, frame.window); + blackbox->ungrabButton(Button3, Mod1Mask, frame.window); }

@@ -881,6 +872,11 @@ frame.margin.top - frame.mwm_border_w - frame.border_w,

client.rect.width(), client.rect.height()); XMoveResizeWindow(blackbox->getXDisplay(), client.window, 0, 0, client.rect.width(), client.rect.height()); + // ensure client.rect contains the real location + client.rect.setCoords(frame.rect.left() + frame.margin.left, + frame.rect.top() + frame.margin.top, + frame.rect.right() - frame.margin.right, + frame.rect.bottom() - frame.margin.bottom); if (decorations & Decor_Titlebar) { if (frame.title == None) createTitlebar();

@@ -1435,9 +1431,15 @@ return 0;

} +/* + * This function is responsible for updating both the client and the frame + * rectangles. + * According to the ICCCM a client message is not sent for a resize, only a + * move. + */ void BlackboxWindow::configure(int dx, int dy, unsigned int dw, unsigned int dh) { - bool send_event = False; + bool send_event = (frame.rect.x() != dx || frame.rect.y() != dy); if (dw != frame.rect.width() || dh != frame.rect.height()) { frame.rect.setRect(dx, dy, dw, dh);

@@ -1461,9 +1463,7 @@

positionWindows(); decorate(); redrawWindowFrame(); - } else if (frame.rect.x() != dx || frame.rect.y() != dy) { - send_event = True; - + } else { frame.rect.setPos(dx, dy); XMoveWindow(blackbox->getXDisplay(), frame.window,

@@ -1471,6 +1471,7 @@ frame.rect.x(), frame.rect.y());

} if (send_event && ! flags.moving) { + // if moving, the update and event will occur when the move finishes client.rect.setPos(frame.rect.left() + frame.margin.left, frame.rect.top() + frame.margin.top);

@@ -1490,7 +1491,6 @@ event.xconfigure.override_redirect = False;

XSendEvent(blackbox->getXDisplay(), client.window, False, StructureNotifyMask, &event); - screen->updateNetizenConfigNotify(&event); } }

@@ -1532,8 +1532,10 @@

bool BlackboxWindow::setInputFocus(void) { if (flags.focused) return True; - assert(! flags.iconic); - + 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) {

@@ -1541,7 +1543,7 @@ Workspace *wkspc = screen->getWorkspace(blackbox_attrib.workspace);

wkspc->setLastFocusedWindow(this); return True; } - +#endif if (! frame.rect.intersects(screen->getRect())) { // client is outside the screen, move it to the center configure((screen->getWidth() - frame.rect.width()) / 2,

@@ -1653,13 +1655,24 @@

XMapWindow(blackbox->getXDisplay(), client.window); XMapSubwindows(blackbox->getXDisplay(), frame.window); XMapWindow(blackbox->getXDisplay(), frame.window); + +#ifdef DEBUG + int real_x, real_y; + Window child; + XTranslateCoordinates(blackbox->getXDisplay(), client.window, + screen->getRootWindow(), + 0, 0, &real_x, &real_y, &child); + fprintf(stderr, "%s -- assumed: (%d, %d), real: (%d, %d)\n", getTitle(), + client.rect.left(), client.rect.top(), real_x, real_y); + assert(client.rect.left() == real_x && client.rect.top() == real_y); +#endif } void BlackboxWindow::deiconify(bool reassoc, bool raise) { if (flags.iconic || reassoc) screen->reassociateWindow(this, BSENTINEL, False); - else if (blackbox_attrib.workspace != screen->getCurrentWorkspace()->getID()) + else if (blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) return; show();

@@ -2116,20 +2129,19 @@ }

if (net->flags & AttribShaded && net->attrib & AttribShaded) { flags.shaded = False; + unsigned long orig_state = current_state; shade(); /* - Because the iconic'ness of shaded windows is lost, we need to set the - state to NormalState so that shaded windows on other workspaces will not - get shown on the first workspace. 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. */ - current_state = NormalState; + if (orig_state != IconicState) + current_state = WithdrawnState; } - if ((net->workspace != screen->getCurrentWorkspaceID()) && - (net->workspace < screen->getWorkspaceCount())) + if (net->workspace != screen->getCurrentWorkspaceID() && + net->workspace < screen->getWorkspaceCount()) screen->reassociateWindow(this, net->workspace, True); if ((blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) &&

@@ -2521,8 +2533,16 @@ screen->unmanageWindow(this, True);

} -void BlackboxWindow::propertyNotifyEvent(Atom atom) { - switch(atom) { +void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) { + if (pe->state == PropertyDelete) + return; + +#ifdef DEBUG + fprintf(stderr, "BlackboxWindow::propertyNotifyEvent(): for 0x%lx\n", + client.window); +#endif + + switch(pe->atom) { case XA_WM_CLASS: case XA_WM_CLIENT_MACHINE: case XA_WM_COMMAND:

@@ -2567,6 +2587,9 @@ getWMNormalHints();

if ((client.normal_hint_flags & PMinSize) && (client.normal_hint_flags & PMaxSize)) { + // the window now can/can't resize itself, so the buttons need to be + // regrabbed. + ungrabButtons(); if (client.max_width <= client.min_width && client.max_height <= client.min_height) { decorations &= ~(Decor_Maximize | Decor_Handle);

@@ -2575,6 +2598,7 @@ } else {

decorations |= Decor_Maximize | Decor_Handle; functions |= Func_Resize | Func_Maximize; } + grabButtons(); setAllowedActions(); }

@@ -2589,7 +2613,7 @@ break;

} default: - if (atom == xatom->getAtom(XAtom::wm_protocols)) { + if (pe->atom == xatom->getAtom(XAtom::wm_protocols)) { getWMProtocols(); if ((decorations & Decor_Close) && (! frame.close_button)) {

@@ -2600,7 +2624,7 @@ XMapSubwindows(blackbox->getXDisplay(), frame.title);

} if (windowmenu) windowmenu->reconfigure(); } - } else if (atom == xatom->getAtom(XAtom::net_wm_strut)) { + } else if (pe->atom == xatom->getAtom(XAtom::net_wm_strut)) { updateStrut(); }

@@ -2610,6 +2634,10 @@ }

void BlackboxWindow::exposeEvent(const XExposeEvent *ee) { +#ifdef DEBUG + fprintf(stderr, "BlackboxWindow::exposeEvent() for 0x%lx\n", client.window); +#endif + if (frame.label == ee->window && (decorations & Decor_Titlebar)) redrawLabel(); else if (frame.close_button == ee->window)

@@ -2667,6 +2695,11 @@ }

void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { +#ifdef DEBUG + fprintf(stderr, "BlackboxWindow::buttonPressEvent() for 0x%lx\n", + client.window); +#endif + if (frame.maximize_button == be->window) { redrawMaximizeButton(True); } else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {

@@ -2705,51 +2738,42 @@ screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);

} else if (windowmenu && be->button == 3 && (frame.title == be->window || frame.label == be->window || frame.handle == be->window || frame.window == be->window)) { - int mx = 0, my = 0; - - if (frame.title == be->window || frame.label == be->window) { - mx = be->x_root - (windowmenu->getWidth() / 2); - my = frame.rect.y() + frame.title_h + frame.border_w; - } else if (frame.handle == be->window) { - mx = be->x_root - (windowmenu->getWidth() / 2); - my = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) - - windowmenu->getHeight(); + if (windowmenu->isVisible()) { + windowmenu->hide(); } else { - mx = be->x_root - (windowmenu->getWidth() / 2); + int mx = be->x_root - windowmenu->getWidth() / 2, + my = be->y_root - windowmenu->getHeight() / 2; - if (be->y <= static_cast<signed>(frame.bevel_w)) - my = frame.rect.y() + frame.title_h; - else - my = be->y_root - (windowmenu->getHeight() / 2); - } + // snap the window menu into a corner/side if necessary + int left_edge, right_edge, top_edge, bottom_edge; - // snap the window menu into a corner if necessary - we check the - // position of the menu with the coordinates of the client to - // make the comparisions easier. - // XXX: this needs some work! - if (mx > client.rect.right() - - static_cast<signed>(windowmenu->getWidth())) - mx = frame.rect.right() - windowmenu->getWidth() - frame.border_w + 1; - if (mx < client.rect.left()) - mx = frame.rect.x(); + /* + the " + (frame.border_w * 2) - 1" bits are to get the proper width + and height of the menu, as the sizes returned by it do not include + the borders. + */ + left_edge = frame.rect.x(); + right_edge = frame.rect.right() - + (windowmenu->getWidth() + (frame.border_w * 2) - 1); + top_edge = client.rect.top() - (frame.border_w + frame.mwm_border_w); + bottom_edge = client.rect.bottom() - + (windowmenu->getHeight() + (frame.border_w * 2) - 1) + + (frame.border_w + frame.mwm_border_w); - if (my > client.rect.bottom() - - static_cast<signed>(windowmenu->getHeight())) - my = frame.rect.bottom() - windowmenu->getHeight() - frame.border_w + 1; - if (my < client.rect.top()) - my = frame.rect.y() + ((decorations & Decor_Titlebar) ? - frame.title_h : 0); + if (mx < left_edge) + mx = left_edge; + if (mx > right_edge) + mx = right_edge; + if (my < top_edge) + my = top_edge; + if (my > bottom_edge) + my = bottom_edge; - if (windowmenu) { - if (! windowmenu->isVisible()) { - windowmenu->move(mx, my); - windowmenu->show(); - XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID()); - XRaiseWindow(blackbox->getXDisplay(), - windowmenu->getSendToMenu()->getWindowID()); - } else { - windowmenu->hide(); - } + windowmenu->move(mx, my); + windowmenu->show(); + XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID()); + XRaiseWindow(blackbox->getXDisplay(), + windowmenu->getSendToMenu()->getWindowID()); } // mouse wheel up } else if (be->button == 4) {

@@ -2768,6 +2792,11 @@ }

void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) { +#ifdef DEBUG + fprintf(stderr, "BlackboxWindow::buttonReleaseEvent() for 0x%lx\n", + client.window); +#endif + if (re->window == frame.maximize_button) { if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) && (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {

@@ -2791,9 +2820,6 @@ } else if (flags.moving) {

endMove(); } else if (flags.resizing) { endResize(); - } else if (re->window == frame.window) { - if (re->button == 2 && re->state == Mod1Mask) - XUngrabPointer(blackbox->getXDisplay(), CurrentTime); } }

@@ -3190,6 +3216,11 @@ }

void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) { +#ifdef DEBUG + fprintf(stderr, "BlackboxWindow::motionNotifyEvent() for 0x%lx\n", + client.window); +#endif + if (flags.moving) { doMove(me->x_root, me->y_root); } else if (flags.resizing) {

@@ -3243,6 +3274,9 @@ void BlackboxWindow::restore(bool remap) {

XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeDelete); XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask); XSelectInput(blackbox->getXDisplay(), frame.plate, NoEventMask); + + // do not leave a shaded window as an icon unless it was an icon + if (flags.shaded && ! flags.iconic) setState(NormalState); restoreGravity(client.rect);
M src/Window.hhsrc/Window.hh

@@ -379,7 +379,8 @@ void remaximize(void);

void shade(void); void stick(void); void reconfigure(void); - void updateFocusModel(void); + void grabButtons(void); + void ungrabButtons(void); void installColormap(bool install); void restore(bool remap); void configure(int dx, int dy, unsigned int dw, unsigned int dh);

@@ -394,7 +395,7 @@ void destroyNotifyEvent(const XDestroyWindowEvent */*unused*/);

void mapRequestEvent(const XMapRequestEvent *mre); void unmapNotifyEvent(const XUnmapEvent */*unused*/); void reparentNotifyEvent(const XReparentEvent */*unused*/); - void propertyNotifyEvent(Atom atom); + void propertyNotifyEvent(const XPropertyEvent *pe); void exposeEvent(const XExposeEvent *ee); void configureRequestEvent(const XConfigureRequestEvent *cr);
M src/Workspace.ccsrc/Workspace.cc

@@ -103,8 +103,13 @@ // pass focus to the next appropriate window

if ((w->isFocused() || w == lastfocus) && ! screen->getBlackbox()->doShutdown()) { BlackboxWindow *newfocus = 0; - if (w->isTransient()) + if (w->isTransient()) { newfocus = w->getTransientFor(); + if (newfocus && + (newfocus->isIconic() || // do not focus icons + newfocus->getWorkspaceNumber() != id)) // or other workspaces + newfocus = 0; + } if (! newfocus && ! stackingList.empty()) newfocus = stackingList.front();

@@ -115,7 +120,7 @@ /*

if the window is on the visible workspace, then try focus it, and fall back to the default focus target if the window won't focus. */ - if (! newfocus || ! newfocus->setInputFocus()) + if (! (newfocus && newfocus->setInputFocus())) screen->getBlackbox()->setFocusedWindow(0); } else if (lastfocus == w) { /*

@@ -317,12 +322,6 @@ void Workspace::reconfigure(void) {

clientmenu->reconfigure(); std::for_each(windowList.begin(), windowList.end(), std::mem_fun(&BlackboxWindow::reconfigure)); -} - - -void Workspace::updateFocusModel(void) { - std::for_each(windowList.begin(), windowList.end(), - std::mem_fun(&BlackboxWindow::updateFocusModel)); }
M src/Workspace.hhsrc/Workspace.hh

@@ -102,7 +102,6 @@ void removeAll(void);

void raiseWindow(BlackboxWindow *w); void lowerWindow(BlackboxWindow *w); void reconfigure(void); - void updateFocusModel(void); void setCurrent(void); void setName(const std::string& new_name); };
M src/blackbox.ccsrc/blackbox.cc

@@ -322,7 +322,12 @@ #endif // DEBUG

BlackboxWindow *win = searchWindow(e->xmaprequest.window); - if (! win) { + if (win) { + if (win->isIconic()) { + win->deiconify(); + win->setInputFocus(); + } + } else { BScreen *screen = searchScreen(e->xmaprequest.parent); if (! screen) {

@@ -444,13 +449,9 @@

case PropertyNotify: { last_time = e->xproperty.time; - if (e->xproperty.state != PropertyDelete) { - BlackboxWindow *win = searchWindow(e->xproperty.window); - - if (win) - win->propertyNotifyEvent(e->xproperty.atom); - } - + BlackboxWindow *win = searchWindow(e->xproperty.window); + if (win) + win->propertyNotifyEvent(&e->xproperty); break; }