all repos — openbox @ 1cd253f4684ee126340fae38094b637f1b0010ea

openbox fork - make it a bit more like ryudo

handle modal windows better (bugfixes).
handle client-installed colormaps.
Dana Jansens danakj@orodu.net
commit

1cd253f4684ee126340fae38094b637f1b0010ea

parent

5dfd87b08505554688640357f3a07593f3bd9ec2

5 files changed, 85 insertions(+), 37 deletions(-)

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

@@ -105,10 +105,8 @@ while (!_transients.empty()) {

_transients.front()->_transient_for = 0; _transients.pop_front(); } - + // clean up parents reference to this - if (_modal) - setModal(false); if (_transient_for) _transient_for->_transients.remove(this); // remove from old parent

@@ -825,6 +823,8 @@

void Client::setModal(bool modal) { + if (modal == _modal) return; + if (modal) { Client *c = this; while (c->_transient_for) {

@@ -1613,6 +1613,19 @@ void Client::disableDecorations(DecorationFlags flags)

{ _disabled_decorations = flags; setupDecorAndFunctions(); +} + + +void Client::installColormap(bool install) const +{ + XWindowAttributes wa; + if (XGetWindowAttributes(**otk::display, _window, &wa)) { + printf("%snstalling Window Colormap 0x%lx!\n", install ? "I" : "Uni", _window); + if (install) + XInstallColormap(**otk::display, wa.colormap); + else + XUninstallColormap(**otk::display, wa.colormap); + } }
M src/client.hhsrc/client.hh

@@ -7,6 +7,7 @@ @brief The Client class maintains the state of a client window by handling

property changes on the window and some client messages */ +#include "screen.hh" #include "widgetbase.hh" #include "otk/point.hh" #include "otk/strut.hh"

@@ -28,6 +29,7 @@

namespace ob { class Frame; +class Screen; //! The MWM Hints as retrieved from the window property /*!

@@ -483,6 +485,21 @@

//! Attempts to find and return a modal child of this window, recursively. Client *findModalChild(Client *skip = 0) const; + //! Removes or reapplies the client's border to its window + /*! + Used when managing and unmanaging a window. + @param addborder true if adding the border to the client; false if removing + from the client + */ + void toggleClientBorder(bool addborder); + + //! Applies the states requested when the window mapped + /*! + This should be called only once, during the window mapping process. It + applies things like maximized, and fullscreen. + */ + void applyStartupState(); + public: #ifndef SWIG //! Constructs a new Client object around a specified window id

@@ -612,21 +629,6 @@ displayed in the terminal, instead of the number of pixels.

*/ const otk::Point &logicalSize() const { return _logical_size; } - //! Applies the states requested when the window mapped - /*! - This should be called only once, during the window mapping process. It - applies things like maximized, and fullscreen. - */ - void applyStartupState(); - - //! Removes or reapplies the client's border to its window - /*! - Used when managing and unmanaging a window. - @param addborder true if adding the border to the client; false if removing - from the client - */ - void toggleClientBorder(bool addborder); - //! Returns the position and size of the client relative to the root window inline const otk::Rect &area() const { return _area; }

@@ -695,7 +697,10 @@ virtual void reparentHandler(const XReparentEvent &e);

virtual void mapRequestHandler(const XMapRequestEvent &e); #if defined(SHAPE) virtual void shapeHandler(const XShapeEvent &e); -#endif // SHAPE +#endif // SHAPE + + friend void Screen::manageWindow(Window); + friend void Screen::unmanageWindow(Client *); }; }
M src/openbox.ccsrc/openbox.cc

@@ -360,13 +360,27 @@

void Openbox::setFocusedClient(Client *c) { + if (c == _focused_client) return; + assert(_focused_screen); + + // uninstall the old colormap + if (_focused_client) + _focused_client->installColormap(false); + else + _focused_screen->installColormap(false); + _focused_client = c; if (c) { _focused_screen = _screens[c->screen()]; + + // install the client's colormap + c->installColormap(true); } else { - assert(_focused_screen); XSetInputFocus(**otk::display, _focused_screen->focuswindow(), RevertToNone, CurrentTime); + + // install the root window colormap + _focused_screen->installColormap(true); } // set the NET_ACTIVE_WINDOW hint for all screens ScreenList::iterator it, end = _screens.end();
M src/screen.ccsrc/screen.cc

@@ -211,7 +211,7 @@ void Screen::updateStrut()

{ _strut.left = _strut.right = _strut.top = _strut.bottom = 0; - Client::List::iterator it, end = clients.end(); + ClientList::iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) { const otk::Strut &s = (*it)->strut(); _strut.left = std::max(_strut.left, s.left);

@@ -264,7 +264,7 @@ */

if (old_area != _area) { // the area has changed, adjust all the maximized windows - Client::List::iterator it, end = clients.end(); + ClientList::iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) (*it)->remaximize(); }

@@ -371,8 +371,8 @@ Window *win_it;

windows = new Window[size]; win_it = windows; - Client::List::const_iterator it = clients.begin(); - const Client::List::const_iterator end = clients.end(); + ClientList::const_iterator it = clients.begin(); + const ClientList::const_iterator end = clients.end(); for (; it != end; ++it, ++win_it) *win_it = (*it)->window(); } else

@@ -402,8 +402,8 @@ Window *win_it;

windows = new Window[size]; win_it = windows; - Client::List::const_reverse_iterator it = _stacking.rbegin(); - const Client::List::const_reverse_iterator end = _stacking.rend(); + ClientList::const_reverse_iterator it = _stacking.rbegin(); + const ClientList::const_reverse_iterator end = _stacking.rend(); for (; it != end; ++it, ++win_it) *win_it = (*it)->window(); } else

@@ -615,6 +615,9 @@ // once the client is out of the list, update our strut to remove it's

// influence updateStrut(); + // unset modal before dropping our focus + client->setModal(false); + // unfocus the client (calls the focus callbacks) client->unfocus();

@@ -634,8 +637,8 @@ Window wins[2]; // only ever restack 2 windows.

assert(!_stacking.empty()); // this would be bad - Client::List::iterator it = --_stacking.end(); - const Client::List::iterator end = _stacking.begin(); + ClientList::iterator it = --_stacking.end(); + const ClientList::iterator end = _stacking.begin(); if (client->modal() && client->transientFor()) { // don't let a modal window lower below its transient_for

@@ -643,7 +646,7 @@ it = std::find(_stacking.begin(), _stacking.end(), client->transientFor());

assert(it != _stacking.end()); wins[0] = (it == _stacking.begin() ? _focuswindow : - ((*(--Client::List::const_iterator(it)))->frame->window())); + ((*(--ClientList::const_iterator(it)))->frame->window())); wins[1] = client->frame->window(); if (wins[0] == wins[1]) return; // already right above the window

@@ -673,8 +676,8 @@

// remove the client before looking so we can't run into ourselves _stacking.remove(client); - Client::List::iterator it = _stacking.begin(); - const Client::List::iterator end = _stacking.end(); + ClientList::iterator it = _stacking.begin(); + const ClientList::iterator end = _stacking.end(); // the stacking list is from highest to lowest for (; it != end && (*it)->layer() > client->layer(); ++it);

@@ -684,7 +687,7 @@ if our new position is the top, we want to stack under the _focuswindow

otherwise, we want to stack under the previous window in the stack. */ wins[0] = (it == _stacking.begin() ? _focuswindow : - ((*(--Client::List::const_iterator(it)))->frame->window())); + ((*(--ClientList::const_iterator(it)))->frame->window())); wins[1] = client->frame->window(); _stacking.insert(it, client);

@@ -713,7 +716,7 @@ otk::Property::atoms.cardinal, _desktop);

if (old == _desktop) return; - Client::List::iterator it, end = clients.end(); + ClientList::iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) { if ((*it)->desktop() == old) { (*it)->frame->hide();

@@ -734,7 +737,7 @@

if (!(num > 0)) return; // move windows on desktops that will no longer exist! - Client::List::iterator it, end = clients.end(); + ClientList::iterator it, end = clients.end(); for (it = clients.begin(); it != end; ++it) { int d = (*it)->desktop(); if (d >= num && !(d == (signed) 0xffffffff ||

@@ -798,6 +801,16 @@ newnames[i] = name;

otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_desktop_names, otk::Property::utf8, newnames); +} + + +void Screen::installColormap(bool install) const +{ + printf("%snstalling Root Colormap!\n", install ? "I" : "Uni"); + if (install) + XInstallColormap(**otk::display, _info->colormap()); + else + XUninstallColormap(**otk::display, _info->colormap()); }
M src/screen.hhsrc/screen.hh

@@ -10,7 +10,6 @@ extern "C" {

#include <X11/Xlib.h> } -#include "client.hh" #include "widgetbase.hh" #include "otk/renderstyle.hh" #include "otk/strut.hh"

@@ -44,8 +43,10 @@ SubstructureRedirectMask |

ButtonPressMask | ButtonReleaseMask; + //! Holds a list of Clients + typedef std::list<Client*> ClientList; //! All managed clients on the screen (in order of being mapped) - Client::List clients; + ClientList clients; private: //! Was %Openbox able to manage the screen?

@@ -77,7 +78,7 @@ //! running

Window _supportwindow; //! A list of all managed clients on the screen, in their stacking order - Client::List _stacking; + ClientList _stacking; //! The desktop currently being displayed long _desktop;

@@ -195,6 +196,8 @@ @param name The name to set for the desktop

If the index is too large, it is simply ignored. */ void setDesktopName(long i, const otk::ustring &name); + + void installColormap(bool install) const; virtual void propertyHandler(const XPropertyEvent &e); virtual void clientMessageHandler(const XClientMessageEvent &e);