From e15e4a9e03dd7b64004b76ca84b07c12c251f67b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 5 Jul 2002 01:24:32 +0000 Subject: [PATCH] make iconified windows uniconify on an XMapRequestEvent. sync with blackbox cvs. --- src/BaseDisplay.cc | 7 +- src/Configmenu.cc | 3 +- src/Screen.cc | 17 ++- src/Screen.hh | 3 +- src/Slit.cc | 10 +- src/Slit.hh | 10 +- src/Toolbar.cc | 14 +-- src/Toolbar.hh | 12 +-- src/Window.cc | 250 +++++++++++++++++++++++++-------------------- src/Window.hh | 5 +- src/Workspace.cc | 15 ++- src/Workspace.hh | 1 - src/blackbox.cc | 17 +-- 13 files changed, 198 insertions(+), 166 deletions(-) diff --git a/src/BaseDisplay.cc b/src/BaseDisplay.cc index 21f9ab53..aa2d974e 100644 --- a/src/BaseDisplay.cc +++ b/src/BaseDisplay.cc @@ -78,7 +78,7 @@ extern "C" { #endif // HAVE_SYS_WAIT_H } -#include +#include using std::string; #include "i18n.hh" @@ -468,7 +468,6 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) { 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(screen_number)); } diff --git a/src/Configmenu.cc b/src/Configmenu.cc index 3a8a6e45..d78d3da9 100644 --- a/src/Configmenu.cc +++ b/src/Configmenu.cc @@ -200,7 +200,8 @@ void Configmenu::Focusmenu::itemSelected(int button, unsigned int index) { 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(); diff --git a/src/Screen.cc b/src/Screen.cc index a05c2386..1879976f 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -132,6 +132,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { 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 @@ Workspace* BScreen::getWorkspace(unsigned int 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::buttonPressEvent(XButtonEvent *xbutton) { 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 @@ void BScreen::toggleFocusModel(FocusModel model) { 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)); } diff --git a/src/Screen.hh b/src/Screen.hh index 60418cd7..3ce57db3 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -331,14 +331,13 @@ public: 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); diff --git a/src/Slit.cc b/src/Slit.cc index 171432af..336daeb3 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -625,7 +625,7 @@ void Slit::shutdown(void) { } -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::buttonPressEvent(XButtonEvent *e) { } -void Slit::enterNotifyEvent(XCrossingEvent *) { +void Slit::enterNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -671,7 +671,7 @@ void Slit::enterNotifyEvent(XCrossingEvent *) { } -void Slit::leaveNotifyEvent(XCrossingEvent *) { +void Slit::leaveNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -683,7 +683,7 @@ void Slit::leaveNotifyEvent(XCrossingEvent *) { } -void Slit::configureRequestEvent(XConfigureRequestEvent *e) { +void Slit::configureRequestEvent(const XConfigureRequestEvent *e) { if (! blackbox->validateWindow(e->window)) return; @@ -737,7 +737,7 @@ void Slit::toggleAutoHide(void) { } -void Slit::unmapNotifyEvent(XUnmapEvent *e) { +void Slit::unmapNotifyEvent(const XUnmapEvent *e) { removeClient(e->window); } diff --git a/src/Slit.hh b/src/Slit.hh index 85b49d7d..798ccb24 100644 --- a/src/Slit.hh +++ b/src/Slit.hh @@ -188,11 +188,11 @@ public: 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); diff --git a/src/Toolbar.cc b/src/Toolbar.cc index f6ff130a..2890fa26 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -777,7 +777,7 @@ void Toolbar::edit(void) { } -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::buttonPressEvent(XButtonEvent *be) { -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::buttonReleaseEvent(XButtonEvent *re) { } -void Toolbar::enterNotifyEvent(XCrossingEvent *) { +void Toolbar::enterNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -884,7 +884,7 @@ void Toolbar::enterNotifyEvent(XCrossingEvent *) { } } -void Toolbar::leaveNotifyEvent(XCrossingEvent *) { +void Toolbar::leaveNotifyEvent(const XCrossingEvent *) { if (! do_auto_hide) return; @@ -896,7 +896,7 @@ void Toolbar::leaveNotifyEvent(XCrossingEvent *) { } -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 @@ void Toolbar::exposeEvent(XExposeEvent *ee) { } -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 @@ void Toolbar::keyPressEvent(XKeyEvent *ke) { KeySym ks; char keychar[1]; - XLookupString(ke, keychar, 1, &ks, 0); + XLookupString(const_cast(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) { diff --git a/src/Toolbar.hh b/src/Toolbar.hh index f9dd5481..ae8353ba 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -172,12 +172,12 @@ public: 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); diff --git a/src/Window.cc b/src/Window.cc index 803cd9af..f1dfe6e8 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -134,13 +134,14 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { 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 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { } #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 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { 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 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { 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::positionButtons(bool redecorate_label) { 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::reconfigure(void) { } -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 @@ void BlackboxWindow::positionWindows(void) { 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 @@ BlackboxWindow *BlackboxWindow::getTransientFor(void) const { } +/* + * 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 @@ void BlackboxWindow::configure(int dx, int dy, 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 @@ void BlackboxWindow::configure(int dx, int dy, } 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 @@ void BlackboxWindow::configure(int dx, int dy, XSendEvent(blackbox->getXDisplay(), client.window, False, StructureNotifyMask, &event); - screen->updateNetizenConfigNotify(&event); } } @@ -1532,8 +1532,10 @@ void BlackboxWindow::configureShape(void) { 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 @@ bool BlackboxWindow::setInputFocus(void) { 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 @@ void BlackboxWindow::show(void) { 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 @@ void BlackboxWindow::restoreAttributes(void) { 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 @@ void BlackboxWindow::reparentNotifyEvent(const XReparentEvent *re) { } -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 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) { 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 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) { decorations |= Decor_Maximize | Decor_Handle; functions |= Func_Resize | Func_Maximize; } + grabButtons(); setAllowedActions(); } @@ -2589,7 +2613,7 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) { } 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 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) { } 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::propertyNotifyEvent(Atom atom) { 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::configureRequestEvent(const XConfigureRequestEvent *cr) { 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 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { } 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); - - if (be->y <= static_cast(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 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(windowmenu->getWidth())) - mx = frame.rect.right() - windowmenu->getWidth() - frame.border_w + 1; - if (mx < client.rect.left()) - mx = frame.rect.x(); - - if (my > client.rect.bottom() - - static_cast(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 (windowmenu) { - if (! windowmenu->isVisible()) { - windowmenu->move(mx, my); - windowmenu->show(); - XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID()); - XRaiseWindow(blackbox->getXDisplay(), - windowmenu->getSendToMenu()->getWindowID()); - } else { - windowmenu->hide(); - } + int mx = be->x_root - windowmenu->getWidth() / 2, + 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; + + /* + 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 (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; + + 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::buttonPressEvent(const XButtonEvent *be) { 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(frame.button_w)) && (re->y >= 0 && re->y <= static_cast(frame.button_w))) { @@ -2791,9 +2820,6 @@ void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) { 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::endResize(void) { 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) { @@ -3244,6 +3275,9 @@ void BlackboxWindow::restore(bool remap) { 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); XUnmapWindow(blackbox->getXDisplay(), frame.window); diff --git a/src/Window.hh b/src/Window.hh index 0f3fb14d..64ad1c34 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -379,7 +379,8 @@ public: 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 @@ public: 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); diff --git a/src/Workspace.cc b/src/Workspace.cc index 60efba1e..90a83b26 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -103,8 +103,13 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { 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 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) { 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) { /* @@ -320,12 +325,6 @@ void Workspace::reconfigure(void) { } -void Workspace::updateFocusModel(void) { - std::for_each(windowList.begin(), windowList.end(), - std::mem_fun(&BlackboxWindow::updateFocusModel)); -} - - BlackboxWindow *Workspace::getWindow(unsigned int index) { if (index < windowList.size()) { BlackboxWindowList::iterator it = windowList.begin(); diff --git a/src/Workspace.hh b/src/Workspace.hh index 31ddace8..0059e293 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -102,7 +102,6 @@ public: void raiseWindow(BlackboxWindow *w); void lowerWindow(BlackboxWindow *w); void reconfigure(void); - void updateFocusModel(void); void setCurrent(void); void setName(const std::string& new_name); }; diff --git a/src/blackbox.cc b/src/blackbox.cc index 6af1d2d3..0865b681 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -322,7 +322,12 @@ void Blackbox::process_event(XEvent *e) { 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 @@ void Blackbox::process_event(XEvent *e) { 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; } -- 2.39.2