From: Dana Jansens Date: Wed, 7 Aug 2002 00:24:58 +0000 (+0000) Subject: sync with blackbox X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=72c56d793b21cb0dae7a6a3d0baf580dacc4a34f;p=chaz%2Fopenbox sync with blackbox --- diff --git a/src/Screen.cc b/src/Screen.cc index b24c514a..3d51a2d2 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -1129,7 +1129,8 @@ void BScreen::removeIcon(BlackboxWindow *w) { BlackboxWindow *BScreen::getIcon(unsigned int index) { if (index < iconList.size()) { BlackboxWindowList::iterator it = iconList.begin(); - for (; index > 0; --index, ++it) ; /* increment to index */ + while (index-- > 0) // increment to index + ++it; return *it; } @@ -1185,38 +1186,20 @@ unsigned int BScreen::removeLastWorkspace(void) { void BScreen::changeWorkspaceID(unsigned int id) { if (! current_workspace || id == current_workspace->getID()) return; - BlackboxWindow *focused = blackbox->getFocusedWindow(); - if (focused && focused->getScreen() == this) { - assert(focused->isStuck() || - focused->getWorkspaceNumber() == current_workspace->getID()); - - current_workspace->setLastFocusedWindow(focused); - } else { - // if no window had focus, no need to store a last focus - current_workspace->setLastFocusedWindow((BlackboxWindow *) 0); - } + current_workspace->hide(); - // when we switch workspaces, unfocus whatever was focused - blackbox->setFocusedWindow((BlackboxWindow *) 0); - - current_workspace->hideAll(); workspacemenu->setItemSelected(current_workspace->getID() + 2, False); current_workspace = getWorkspace(id); + current_workspace->show(); + xatom->setValue(getRootWindow(), XAtom::net_current_desktop, XAtom::cardinal, id); workspacemenu->setItemSelected(current_workspace->getID() + 2, True); toolbar->redrawWorkspaceLabel(True); - current_workspace->showAll(); - - if (resource.focus_last && current_workspace->getLastFocusedWindow()) { - XSync(blackbox->getXDisplay(), False); - current_workspace->getLastFocusedWindow()->setInputFocus(); - } - updateNetizenCurrentWorkspace(); } @@ -1790,12 +1773,13 @@ void BScreen::InitMenu(void) { static -void string_within(char begin, char end, const char *input, size_t length, - char *output) { +size_t string_within(char begin, char end, + const char *input, size_t start_at, size_t length, + char *output) { bool parse = False; size_t index = 0; - - for (size_t i = 0; i < length; ++i) { + size_t i = start_at; + for (; i < length; ++i) { if (input[i] == begin) { parse = True; } else if (input[i] == end) { @@ -1810,6 +1794,8 @@ void string_within(char begin, char end, const char *input, size_t length, output[index] = '\0'; else output[0] = '\0'; + + return i; } @@ -1832,7 +1818,7 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) { unsigned int key = 0; // get the keyword enclosed in []'s - string_within('[', ']', line, line_length, keyword); + size_t pos = string_within('[', ']', line, 0, line_length, keyword); if (keyword[0] == '\0') { // no keyword, no menu entry continue; @@ -1845,10 +1831,10 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) { } // get the label enclosed in ()'s - string_within('(', ')', line, line_length, label); + pos = string_within('(', ')', line, pos, line_length, label); // get the command enclosed in {}'s - string_within('{', '}', line, line_length, command); + pos = string_within('{', '}', line, pos, line_length, command); switch (key) { case 311: // end diff --git a/src/Toolbar.cc b/src/Toolbar.cc index a1a6e118..955eb5a0 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -53,16 +53,14 @@ using std::string; #include "i18n.hh" #include "blackbox.hh" -#include "Clientmenu.hh" #include "Font.hh" #include "GCCache.hh" -#include "Iconmenu.hh" #include "Image.hh" -#include "Rootmenu.hh" #include "Screen.hh" #include "Toolbar.hh" #include "Window.hh" #include "Workspace.hh" +#include "Clientmenu.hh" #include "Workspacemenu.hh" #include "Slit.hh" @@ -910,11 +908,10 @@ void Toolbar::keyPressEvent(const XKeyEvent *ke) { editing = False; blackbox->setNoFocus(False); - if (blackbox->getFocusedWindow()) { + if (blackbox->getFocusedWindow()) blackbox->getFocusedWindow()->setInputFocus(); - } else { + else blackbox->setFocusedWindow(0); - } // the toolbar will be reconfigured when the change to the workspace name // gets caught in the PropertyNotify event handler diff --git a/src/Window.cc b/src/Window.cc index fa49ec21..46bd644d 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -155,6 +155,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { current_state = NormalState; + windowmenu = 0; + /* get the initial size and location of client window (relative to the _root window_). This position is the reference point used with the @@ -168,8 +170,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { timer = new BTimer(blackbox, this); timer->setTimeout(blackbox->getAutoRaiseDelay()); - windowmenu = new Windowmenu(this); - // get size, aspect, minimum/maximum size and other hints set by the // client @@ -257,21 +257,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { screen->addStrut(&client.strut); updateStrut(); -#ifdef SHAPE - if (blackbox->hasShapeExtensions() && flags.shaped) - configureShape(); -#endif // SHAPE - - // get the window's title before adding it to the workspace - getWMName(); - getWMIconName(); - - if (blackbox_attrib.workspace >= screen->getWorkspaceCount()) - screen->getCurrentWorkspace()->addWindow(this, place_window); - else - screen->getWorkspace(blackbox_attrib.workspace)-> - addWindow(this, place_window); - /* the server needs to be grabbed here to prevent client's from sending events while we are in the process of configuring their window. @@ -284,6 +269,12 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { blackbox->saveWindowSearch(client.window, this); + if (blackbox_attrib.workspace >= screen->getWorkspaceCount()) + screen->getCurrentWorkspace()->addWindow(this, place_window); + else + screen->getWorkspace(blackbox_attrib.workspace)-> + addWindow(this, place_window); + if (! place_window) { // don't need to call configure if we are letting the workspace // place the window @@ -296,6 +287,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { XUngrabServer(blackbox->getXDisplay()); +#ifdef SHAPE + if (blackbox->hasShapeExtensions() && flags.shaped) + configureShape(); +#endif // SHAPE + // now that we know where to put the window and what it should look like // we apply the decorations decorate(); @@ -338,6 +334,9 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { if (flags.maximized && (functions & Func_Maximize)) remaximize(); + + // create this last so it only needs to be configured once + windowmenu = new Windowmenu(this); } @@ -369,18 +368,16 @@ BlackboxWindow::~BlackboxWindow(void) { // remove ourselves from our transient_for if (isTransient()) { - if (client.transient_for != (BlackboxWindow *) ~0ul) { + if (client.transient_for != (BlackboxWindow *) ~0ul) client.transient_for->client.transientList.remove(this); - } client.transient_for = (BlackboxWindow*) 0; } if (client.transientList.size() > 0) { // reset transient_for for all transients BlackboxWindowList::iterator it, end = client.transientList.end(); - for (it = client.transientList.begin(); it != end; ++it) { + for (it = client.transientList.begin(); it != end; ++it) (*it)->client.transient_for = (BlackboxWindow*) 0; - } } if (frame.title) @@ -417,7 +414,8 @@ Window BlackboxWindow::createToplevelWindow(void) { attrib_create.colormap = screen->getColormap(); attrib_create.override_redirect = True; attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | EnterWindowMask; + ButtonMotionMask | + EnterWindowMask | LeaveWindowMask; return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(), 0, 0, 1, 1, frame.border_w, screen->getDepth(), @@ -452,6 +450,8 @@ Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) { void BlackboxWindow::associateClientWindow(void) { XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0); + getWMName(); + getWMIconName(); XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert); @@ -1417,9 +1417,22 @@ void BlackboxWindow::getTransientInfo(void) { return; } - // register ourselves with our new transient_for - client.transient_for->client.transientList.push_back(this); - flags.stuck = client.transient_for->flags.stuck; + // Check for a circular transient state: this can lock up Blackbox + // when it tries to find the non-transient window for a transient. + BlackboxWindow *w = this; + while(w->client.transient_for) { + if(w->client.transient_for == this) { + client.transient_for = (BlackboxWindow*) 0; + break; + } + w = w->client.transient_for; + } + + if (client.transient_for) { + // register ourselves with our new transient_for + client.transient_for->client.transientList.push_back(this); + flags.stuck = client.transient_for->flags.stuck; + } } @@ -1559,9 +1572,8 @@ bool BlackboxWindow::setInputFocus(void) { if (client.transientList.size() > 0) { // transfer focus to any modal transients BlackboxWindowList::iterator it, end = client.transientList.end(); - for (it = client.transientList.begin(); it != end; ++it) { + for (it = client.transientList.begin(); it != end; ++it) if ((*it)->flags.modal) return (*it)->setInputFocus(); - } } bool ret = True; @@ -1692,9 +1704,8 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) { // reassociate and deiconify all transients if (reassoc && client.transientList.size() > 0) { BlackboxWindowList::iterator it, end = client.transientList.end(); - for (it = client.transientList.begin(); it != end; ++it) { + for (it = client.transientList.begin(); it != end; ++it) (*it)->deiconify(True, False); - } } if (raise) @@ -2064,18 +2075,13 @@ void BlackboxWindow::redrawWindowFrame(void) const { void BlackboxWindow::setFocusFlag(bool focus) { // only focus a window if it is visible - if (focus && !flags.visible) + if (focus && ! flags.visible) return; flags.focused = focus; redrawWindowFrame(); - if (screen->isSloppyFocus() && screen->doAutoRaise()) { - if (isFocused()) timer->start(); - else timer->stop(); - } - if (flags.focused) blackbox->setFocusedWindow(this); @@ -3487,7 +3493,7 @@ void BlackboxWindow::beginResize(int x_root, int y_root, Corner dir) { flags.resizing = True; blackbox->setChangingWindow(this); - int gw, gh; + unsigned int gw, gh; frame.changing = frame.rect; constrain(anchor, &gw, &gh); @@ -3511,7 +3517,7 @@ void BlackboxWindow::doResize(int x_root, int y_root) { screen->getOpGC(), frame.changing.x(), frame.changing.y(), frame.changing.width() - 1, frame.changing.height() - 1); - int gw, gh; + unsigned int gw, gh; Corner anchor; switch (resize_dir) { @@ -3627,6 +3633,43 @@ void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) { } +void BlackboxWindow::enterNotifyEvent(const XCrossingEvent* ce) { + if (! (screen->isSloppyFocus() && isVisible() && isNormal())) + return; + + XEvent e; + bool leave = False, inferior = False; + + while (XCheckTypedWindowEvent(blackbox->getXDisplay(), ce->window, + LeaveNotify, &e)) { + if (e.type == LeaveNotify && e.xcrossing.mode == NotifyNormal) { + leave = True; + inferior = (e.xcrossing.detail == NotifyInferior); + } + } + + if ((! leave || inferior) && ! isFocused()) { + bool success = setInputFocus(); + if (success) // if focus succeeded install the colormap + installColormap(True); // XXX: shouldnt we honour no install? + } + + if (screen->doAutoRaise()) + timer->start(); +} + + +void BlackboxWindow::leaveNotifyEvent(const XCrossingEvent*) { + if (! (screen->isSloppyFocus() && screen->doAutoRaise() && isNormal())) + return; + + installColormap(False); + + if (timer->isTiming()) + timer->stop(); +} + + #ifdef SHAPE void BlackboxWindow::shapeEvent(XShapeEvent *) { if (blackbox->hasShapeExtensions() && flags.shaped) { @@ -3878,11 +3921,14 @@ void BlackboxWindow::upsize(void) { * The logical width and height are placed into pw and ph, if they * are non-zero. Logical size refers to the users perception of * the window size (for example an xterm resizes in cells, not in pixels). + * pw and ph are then used to display the geometry during window moves, resize, + * etc. * * The physical geometry is placed into frame.changing_{x,y,width,height}. * Physical geometry refers to the geometry of the window in pixels. */ -void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) { +void BlackboxWindow::constrain(Corner anchor, + unsigned int *pw, unsigned int *ph) { // frame.changing represents the requested frame size, we need to // strip the frame margin off and constrain the client size frame.changing.setCoords(frame.changing.left() + frame.margin.left, @@ -3890,39 +3936,42 @@ void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) { frame.changing.right() - frame.margin.right, frame.changing.bottom() - frame.margin.bottom); - int dw = frame.changing.width(), dh = frame.changing.height(), + unsigned int dw = frame.changing.width(), dh = frame.changing.height(), base_width = (client.base_width) ? client.base_width : client.min_width, base_height = (client.base_height) ? client.base_height : client.min_height; // constrain - if (dw < static_cast(client.min_width)) dw = client.min_width; - if (dh < static_cast(client.min_height)) dh = client.min_height; - if (dw > static_cast(client.max_width)) dw = client.max_width; - if (dh > static_cast(client.max_height)) dh = client.max_height; - - dw -= base_width; - dw /= client.width_inc; - dh -= base_height; - dh /= client.height_inc; - - if (pw) { - if (client.width_inc == 1) - *pw = dw + base_width; - else - *pw = dw; + if (dw < client.min_width) dw = client.min_width; + if (dh < client.min_height) dh = client.min_height; + if (dw > client.max_width) dw = client.max_width; + if (dh > client.max_height) dh = client.max_height; + + assert(dw >= base_width && dh >= base_height); + + if (client.width_inc > 1) { + dw -= base_width; + dw /= client.width_inc; } - if (ph) { - if (client.height_inc == 1) - *ph = dh + base_height; - else - *ph = dh; + if (client.height_inc > 1) { + dh -= base_height; + dh /= client.height_inc; } - dw *= client.width_inc; - dw += base_width; - dh *= client.height_inc; - dh += base_height; + if (pw) + *pw = dw; + + if (ph) + *ph = dh; + + if (client.width_inc > 1) { + dw *= client.width_inc; + dw += base_width; + } + if (client.height_inc > 1) { + dh *= client.height_inc; + dh += base_height; + } frame.changing.setSize(dw, dh); @@ -4011,13 +4060,10 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const { BlackboxWindow *ret = blackbox->getFocusedWindow(); // does the focus window match (or any transient_fors)? - while (ret) { - if (ret->getScreen() == screen && ret->getGroupWindow() == group) { - if (ret->isTransient() && allow_transients) break; - else if (! ret->isTransient()) break; - } - - ret = ret->getTransientFor(); + for (; ret; ret = ret->getTransientFor()) { + if (ret->getScreen() == screen && ret->getGroupWindow() == group && + (! ret->isTransient() || allow_transients)) + break; } if (ret) return ret; @@ -4026,10 +4072,9 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const { BlackboxWindowList::const_iterator it, end = windowList.end(); for (it = windowList.begin(); it != end; ++it) { ret = *it; - if (ret->getScreen() == screen && ret->getGroupWindow() == group) { - if (ret->isTransient() && allow_transients) break; - else if (! ret->isTransient()) break; - } + if (ret->getScreen() == screen && ret->getGroupWindow() == group && + (! ret->isTransient() || allow_transients)) + break; } return ret; diff --git a/src/Window.hh b/src/Window.hh index 46bc2662..105aef16 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -301,7 +301,7 @@ private: void doResize(int x_root, int y_root); void endResize(void); - void constrain(Corner anchor, int *pw = 0, int *ph = 0); + void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0); public: BlackboxWindow(Blackbox *b, Window w, BScreen *s); @@ -398,13 +398,15 @@ public: void buttonPressEvent(const XButtonEvent *be); void buttonReleaseEvent(const XButtonEvent *re); void motionNotifyEvent(const XMotionEvent *me); - void destroyNotifyEvent(const XDestroyWindowEvent */*unused*/); + void destroyNotifyEvent(const XDestroyWindowEvent* /*unused*/); void mapRequestEvent(const XMapRequestEvent *mre); - void unmapNotifyEvent(const XUnmapEvent */*unused*/); - void reparentNotifyEvent(const XReparentEvent */*unused*/); + void unmapNotifyEvent(const XUnmapEvent* /*unused*/); + void reparentNotifyEvent(const XReparentEvent* /*unused*/); void propertyNotifyEvent(const XPropertyEvent *pe); void exposeEvent(const XExposeEvent *ee); void configureRequestEvent(const XConfigureRequestEvent *cr); + void enterNotifyEvent(const XCrossingEvent *ce); + void leaveNotifyEvent(const XCrossingEvent* /*unused*/); #ifdef SHAPE void configureShape(void); diff --git a/src/Workspace.cc b/src/Workspace.cc index 85f9cdca..7cd21f1c 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -222,36 +222,6 @@ void Workspace::setFocused(const BlackboxWindow *w, bool focused) { } -void Workspace::showAll(void) { - BlackboxWindowList::iterator it = stackingList.begin(); - const BlackboxWindowList::iterator end = stackingList.end(); - for (; it != end; ++it) { - BlackboxWindow *bw = *it; - // not normal windows cant focus from mouse enters anyways, so we dont - // need to unmap/remap them on workspace changes - if (! bw->isStuck() || bw->isNormal()) - bw->show(); - } -} - - -void Workspace::hideAll(void) { - // withdraw in reverse order to minimize the number of Expose events - - BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend()); - - BlackboxWindowList::iterator it = lst.begin(); - const BlackboxWindowList::iterator end = lst.end(); - for (; it != end; ++it) { - BlackboxWindow *bw = *it; - // not normal windows cant focus from mouse enters anyways, so we dont - // need to unmap/remap them on workspace changes - if (! bw->isStuck() || bw->isNormal()) - bw->withdraw(); - } -} - - void Workspace::removeAll(void) { while (! windowList.empty()) windowList.front()->iconify(); @@ -262,14 +232,16 @@ void Workspace::removeAll(void) { * returns the number of transients for win, plus the number of transients * associated with each transient of win */ -static int countTransients(const BlackboxWindow * const win) { - int ret = win->getTransients().size(); - if (ret > 0) { - BlackboxWindowList::const_iterator it, end = win->getTransients().end(); - for (it = win->getTransients().begin(); it != end; ++it) { - ret += countTransients(*it); - } - } +static unsigned int countTransients(const BlackboxWindow * const win) { + BlackboxWindowList transients = win->getTransients(); + if (transients.empty()) return 0; + + unsigned int ret = transients.size(); + BlackboxWindowList::const_iterator it = transients.begin(), + end = transients.end(); + for (; it != end; ++it) + ret += countTransients(*it); + return ret; } @@ -282,48 +254,48 @@ static int countTransients(const BlackboxWindow * const win) { */ void Workspace::raiseTransients(const BlackboxWindow * const win, StackVector::iterator &stack) { - if (win->getTransients().size() == 0) return; // nothing to do + if (win->getTransients().empty()) return; // nothing to do // put win's transients in the stack BlackboxWindowList::const_iterator it, end = win->getTransients().end(); for (it = win->getTransients().begin(); it != end; ++it) { - *stack++ = (*it)->getFrameWindow(); - screen->updateNetizenWindowRaise((*it)->getClientWindow()); - - if (! (*it)->isIconic()) { - Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); - wkspc->stackingList.remove((*it)); - wkspc->stackingList.push_front((*it)); + BlackboxWindow *w = *it; + *stack++ = w->getFrameWindow(); + screen->updateNetizenWindowRaise(w->getClientWindow()); + + if (! w->isIconic()) { + Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber()); + wkspc->stackingList.remove(w); + wkspc->stackingList.push_front(w); } } // put transients of win's transients in the stack - for (it = win->getTransients().begin(); it != end; ++it) { + for (it = win->getTransients().begin(); it != end; ++it) raiseTransients(*it, stack); - } } void Workspace::lowerTransients(const BlackboxWindow * const win, StackVector::iterator &stack) { - if (win->getTransients().size() == 0) return; // nothing to do + if (win->getTransients().empty()) return; // nothing to do // put transients of win's transients in the stack BlackboxWindowList::const_reverse_iterator it, end = win->getTransients().rend(); - for (it = win->getTransients().rbegin(); it != end; ++it) { + for (it = win->getTransients().rbegin(); it != end; ++it) lowerTransients(*it, stack); - } // put win's transients in the stack for (it = win->getTransients().rbegin(); it != end; ++it) { - *stack++ = (*it)->getFrameWindow(); - screen->updateNetizenWindowLower((*it)->getClientWindow()); - - if (! (*it)->isIconic()) { - Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); - wkspc->stackingList.remove((*it)); - wkspc->stackingList.push_back((*it)); + BlackboxWindow *w = *it; + *stack++ = w->getFrameWindow(); + screen->updateNetizenWindowLower(w->getClientWindow()); + + if (! w->isIconic()) { + Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber()); + wkspc->stackingList.remove(w); + wkspc->stackingList.push_back(w); } } } @@ -335,10 +307,8 @@ void Workspace::raiseWindow(BlackboxWindow *w) { if (win->isDesktop()) return; // walk up the transient_for's to the window that is not a transient - while (win->isTransient() && ! win->isDesktop()) { - if (! win->getTransientFor()) break; + while (win->isTransient() && win->getTransientFor()) win = win->getTransientFor(); - } // get the total window count (win and all transients) unsigned int i = 1 + countTransients(win); @@ -365,10 +335,8 @@ void Workspace::lowerWindow(BlackboxWindow *w) { BlackboxWindow *win = w; // walk up the transient_for's to the window that is not a transient - while (win->isTransient() && ! win->isDesktop()) { - if (! win->getTransientFor()) break; + while (win->isTransient() && win->getTransientFor()) win = win->getTransientFor(); - } // get the total window count (win and all transients) unsigned int i = 1 + countTransients(win); @@ -401,9 +369,11 @@ void Workspace::reconfigure(void) { BlackboxWindow *Workspace::getWindow(unsigned int index) { if (index < windowList.size()) { BlackboxWindowList::iterator it = windowList.begin(); - for(; index > 0; --index, ++it); /* increment to index */ + while (index-- > 0) // increment to index + ++it; return *it; } + return 0; } @@ -435,6 +405,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) { BlackboxWindow* Workspace::getTopWindowOnStack(void) const { + assert(! stackingList.empty()); return stackingList.front(); } @@ -461,6 +432,50 @@ void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const { } +void Workspace::hide(void) { + BlackboxWindow *focused = screen->getBlackbox()->getFocusedWindow(); + if (focused && focused->getScreen() == screen) { + assert(focused->isStuck() || focused->getWorkspaceNumber() == id); + + lastfocus = focused; + } else { + // if no window had focus, no need to store a last focus + lastfocus = (BlackboxWindow *) 0; + } + + // when we switch workspaces, unfocus whatever was focused + screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0); + + // withdraw windows in reverse order to minimize the number of Expose events + + BlackboxWindowList::reverse_iterator it = stackingList.rbegin(); + const BlackboxWindowList::reverse_iterator end = stackingList.rend(); + for (; it != end; ++it) { + BlackboxWindow *bw = *it; + // not normal windows cant focus from mouse enters anyways, so we dont + // need to unmap/remap them on workspace changes + if (! bw->isStuck() || bw->isNormal()) + bw->withdraw(); + } +} + + +void Workspace::show(void) { + std::for_each(stackingList.begin(), stackingList.end(), + std::mem_fun(&BlackboxWindow::show)); + + XSync(screen->getBlackbox()->getXDisplay(), False); + + if (screen->doFocusLast()) { + if (! screen->isSloppyFocus() && ! lastfocus && ! stackingList.empty()) + lastfocus = stackingList.front(); + + if (lastfocus) + lastfocus->setInputFocus(); + } +} + + bool Workspace::isCurrent(void) const { return (id == screen->getCurrentWorkspaceID()); } diff --git a/src/Workspace.hh b/src/Workspace.hh index 72203f2d..e0295e29 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -104,8 +104,8 @@ public: unsigned int getCount(void) const; void appendStackOrder(BlackboxWindowList &stack_order) const; - void showAll(void); - void hideAll(void); + void show(void); + void hide(void); void removeAll(void); void raiseWindow(BlackboxWindow *w); void lowerWindow(BlackboxWindow *w); diff --git a/src/blackbox.cc b/src/blackbox.cc index 04e68bb1..6995c0b5 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -112,26 +112,6 @@ using std::string; #include "Workspacemenu.hh" #include "XAtom.hh" -// X event scanner for enter/leave notifies - adapted from twm -struct scanargs { - Window w; - bool leave, inferior, enter; -}; - -static Bool queueScanner(Display *, XEvent *e, char *args) { - scanargs *scan = (scanargs *) args; - if ((e->type == LeaveNotify) && - (e->xcrossing.window == scan->w) && - (e->xcrossing.mode == NotifyNormal)) { - scan->leave = True; - scan->inferior = (e->xcrossing.detail == NotifyInferior); - } else if ((e->type == EnterNotify) && (e->xcrossing.mode == NotifyUngrab)) { - scan->enter = True; - } - - return False; -} - Blackbox *blackbox; @@ -474,24 +454,12 @@ void Blackbox::process_event(XEvent *e) { if (e->xcrossing.mode == NotifyGrab) break; - XEvent dummy; - scanargs sa; - sa.w = e->xcrossing.window; - sa.enter = sa.leave = False; - XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa); - if ((e->xcrossing.window == e->xcrossing.root) && (screen = searchScreen(e->xcrossing.window))) { screen->getImageControl()->installRootColormap(); } 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 (win->setInputFocus()) - win->installColormap(True); // XXX: shouldnt we honour no install? - } - } + if (! no_focus) + win->enterNotifyEvent(&e->xcrossing); } else if ((menu = searchMenu(e->xcrossing.window))) { menu->enterNotifyEvent(&e->xcrossing); } else if ((tbar = searchToolbar(e->xcrossing.window))) { @@ -513,7 +481,7 @@ void Blackbox::process_event(XEvent *e) { if ((menu = searchMenu(e->xcrossing.window))) menu->leaveNotifyEvent(&e->xcrossing); else if ((win = searchWindow(e->xcrossing.window))) - win->installColormap(False); + win->leaveNotifyEvent(&e->xcrossing); else if ((tbar = searchToolbar(e->xcrossing.window))) tbar->leaveNotifyEvent(&e->xcrossing); else if ((slit = searchSlit(e->xcrossing.window)))