only keep fullscreen windows in the top layer when they or a relative is focused
@@ -402,7 +402,6 @@ delete [] state;
} } - void Client::getShaped() { _shaped = false;@@ -421,12 +420,40 @@ }
#endif // SHAPE } +Client *Client::searchFocusTree(Client *node, Client *skip) +{ + List::const_iterator it, end = node->_transients.end(); + Client *ret; + + for (it = node->_transients.begin(); it != end; ++it) { + if (*it == skip) continue; // circular? + if ((ret = searchModalTree(*it, skip))) return ret; // got one + if ((*it)->_focused) return *it; // got one + } + return 0; +} void Client::calcLayer() { StackLayer l; + bool fs = false; + // are we fullscreen, or do we have a fullscreen transient parent? + Client *c = this; + while (c) { + if (c->_fullscreen) { + fs =true; + break; + } + c = c->_transient_for; + } + if (!fs) { + // is one of our transients focused? + c = searchFocusTree(this, this); + if (c) fs = true; + } + if (_iconic) l = Layer_Icon; - else if (_fullscreen) l = Layer_Fullscreen; + else if (fs) l = Layer_Fullscreen; else if (_type == Type_Desktop) l = Layer_Desktop; else if (_type == Type_Dock) { if (!_below) l = Layer_Top;@@ -448,7 +475,6 @@ }
} } - void Client::updateProtocols() { Atom *proto;@@ -470,7 +496,6 @@ }
XFree(proto); } } - void Client::updateNormalHints() {@@ -522,7 +547,6 @@ _size_inc = otk::Size(size.width_inc, size.height_inc);
} } - void Client::updateWMHints(bool initstate) { XWMHints *hints;@@ -566,7 +590,6 @@ if (frame)
fireUrgent(); } } - void Client::updateTitle() {@@ -587,7 +610,6 @@ if (frame)
frame->adjustTitle(); } - void Client::updateIconTitle() { _icon_title = "";@@ -603,7 +625,6 @@
if (_title.empty()) _icon_title = _("Unnamed Window"); } - void Client::updateClass() {@@ -626,7 +647,6 @@ otk::Property::ascii, &num, &v)) {
if (num > 0) _role = v[0].c_str(); } } - void Client::updateStrut() {@@ -651,7 +671,6 @@
delete [] data; } - void Client::updateTransientFor() { Window t = 0;@@ -683,7 +702,6 @@ if (_transient_for)
_transient_for->_transients.push_back(this); // add to new parent } } - void Client::updateIcons() {@@ -740,7 +758,6 @@
if (frame) frame->adjustIcon(); } - void Client::propertyHandler(const XPropertyEvent &e) { otk::EventHandler::propertyHandler(e);@@ -788,7 +805,6 @@ else if (e.atom == otk::Property::atoms.net_wm_icon)
updateIcons(); } - void Client::setWMState(long state) { if (state == _wmstate) return; // no change@@ -802,7 +818,6 @@ iconify(false);
break; } } - void Client::setDesktop(unsigned int target) {@@ -823,7 +838,6 @@ // 'move' the window to the new desktop
showhide(); openbox->screen(_screen)->updateStruts(); } - void Client::showhide() {@@ -840,7 +854,6 @@ if (show) frame->show();
else frame->hide(); } - void Client::setState(StateAction action, long data1, long data2) { bool shadestate = _shaded;@@ -954,7 +967,6 @@ calcLayer();
changeState(); // change the hint to relect these changes } - void Client::toggleClientBorder(bool addborder) { // adjust our idea of where the client is, based on its border. When the@@ -1017,7 +1029,6 @@ XMoveWindow(**otk::display, _window, x, y);
} else XSetWindowBorderWidth(**otk::display, _window, 0); } - void Client::clientMessageHandler(const XClientMessageEvent &e) {@@ -1105,7 +1116,6 @@ openbox->screen(_screen)->raiseWindow(this);
} } - #if defined(SHAPE) void Client::shapeHandler(const XShapeEvent &e) {@@ -1117,7 +1127,6 @@ frame->adjustShape();
} } #endif - void Client::resize(Corner anchor, int w, int h) {@@ -1125,7 +1134,6 @@ if (!(_functions & Func_Resize)) return;
internal_resize(anchor, w, h); } - void Client::internal_resize(Corner anchor, int w, int h, bool user, int x, int y) {@@ -1238,7 +1246,6 @@ // frame
internal_move(x, y); } - void Client::internal_move(int x, int y) { _area = otk::Rect(otk::Point(x, y), _area.size());@@ -1274,7 +1281,6 @@ #endif
} } - void Client::close() { XEvent ce;@@ -1299,7 +1305,6 @@ ce.xclient.data.l[3] = 0l;
ce.xclient.data.l[4] = 0l; XSendEvent(**otk::display, _window, false, NoEventMask, &ce); } - void Client::changeState() {@@ -1340,7 +1345,6 @@ if (frame)
frame->adjustState(); } - void Client::changeAllowedActions(void) { Atom actions[9];@@ -1384,7 +1388,6 @@ if (frame) maximize(false, 0);
else _max_vert = _max_horz = false; } - void Client::remaximize() { int dir;@@ -1399,7 +1402,6 @@ return; // not maximized
_max_horz = _max_vert = false; maximize(true, dir, false); } - void Client::applyStartupState() {@@ -1438,14 +1440,12 @@ if (_above); // nothing to do for this
if (_below); // nothing to do for this } - void Client::fireUrgent() { // call the python UrgentWindow callbacks EventData data(_screen, this, EventAction::UrgentWindow, 0); openbox->bindings()->fireEvent(&data); } - void Client::shade(bool shade) {@@ -1460,7 +1460,6 @@ changeState();
frame->adjustSize(); } - void Client::maximize(bool max, int dir, bool savearea) { assert(dir == 0 || dir == 1 || dir == 2);@@ -1567,7 +1566,6 @@ frame->frameGravity(x, y); // figure out where the client should be going
internal_resize(TopLeft, w, h, true, x, y); } - void Client::fullscreen(bool fs, bool savearea) { static FunctionFlags saved_func;@@ -1642,7 +1640,6 @@ // try focus us when we go into fullscreen mode
if (fs) focus(); } - void Client::iconify(bool iconic, bool curdesk) { if (_iconic == iconic) return; // nothing to do@@ -1669,7 +1666,6 @@ changeState();
showhide(); openbox->screen(_screen)->updateStruts(); } - void Client::disableDecorations(DecorationFlags flags) {@@ -1677,7 +1673,6 @@ _disabled_decorations = flags;
setupDecorAndFunctions(); } - void Client::installColormap(bool install) const { XWindowAttributes wa;@@ -1689,9 +1684,6 @@ XUninstallColormap(**otk::display, wa.colormap);
} } - -// recursively searches the client 'tree' for a modal client, always skips the -// topmost node (the window you're starting with) Client *Client::searchModalTree(Client *node, Client *skip) { List::const_iterator it, end = node->_transients.end();@@ -1784,6 +1776,8 @@
_focused = true; frame->adjustFocus(); + calcLayer(); // focus state can affect the stacking layer + openbox->setFocusedClient(this); }@@ -1798,6 +1792,8 @@ otk::EventHandler::unfocusHandler(e);
_focused = false; frame->adjustFocus(); + + calcLayer(); // focus state can affect the stacking layer if (openbox->focusedClient() == this) openbox->setFocusedClient(0);
@@ -434,6 +434,10 @@ //! Recursively searches the client 'tree' for a modal client, always skips
//! the topmost node (the window you're starting with). Client *Client::searchModalTree(Client *node, Client *skip); + //! Recursively searches the client 'tree' for a focused client, always skips + //! the topmost node (the window you're starting with). + Client *Client::searchFocusTree(Client *node, Client *skip); + //! Fires the urgent callbacks which lets the user do what they want with //! urgent windows void fireUrgent();