From: Dana Jansens Date: Mon, 3 Feb 2003 20:18:30 +0000 (+0000) Subject: handle modal windows better (bugfixes). X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=1cd253f4684ee126340fae38094b637f1b0010ea;p=chaz%2Fopenbox handle modal windows better (bugfixes). handle client-installed colormaps. --- diff --git a/src/client.cc b/src/client.cc index 95c49877..51c987d3 100644 --- a/src/client.cc +++ b/src/client.cc @@ -105,10 +105,8 @@ Client::~Client() _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 @@ Client *Client::findModalChild(Client *skip) const void Client::setModal(bool modal) { + if (modal == _modal) return; + if (modal) { Client *c = this; while (c->_transient_for) { @@ -1616,6 +1616,19 @@ void Client::disableDecorations(DecorationFlags flags) } +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); + } +} + + bool Client::focus() { // if we have a modal child, then focus it, not us diff --git a/src/client.hh b/src/client.hh index 3e8652d8..a9fe9427 100644 --- a/src/client.hh +++ b/src/client.hh @@ -7,6 +7,7 @@ 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 @@ extern "C" { namespace ob { class Frame; +class Screen; //! The MWM Hints as retrieved from the window property /*! @@ -483,6 +485,21 @@ private: //! 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 @@ BB @param window The window id that the Client class should handle */ 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 @@ BB @param window The window id that the Client class should handle 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 *); }; } diff --git a/src/openbox.cc b/src/openbox.cc index 727b403e..50146e27 100644 --- a/src/openbox.cc +++ b/src/openbox.cc @@ -360,13 +360,27 @@ Client *Openbox::findClient(Window window) 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(); diff --git a/src/screen.cc b/src/screen.cc index c1814341..56aa99d9 100644 --- a/src/screen.cc +++ b/src/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 @@ void Screen::calcArea() 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 @@ void Screen::changeClientList() 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 @@ void Screen::changeStackingList() 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 @@ void Screen::unmanageWindow(Client *client) // influence updateStrut(); + // unset modal before dropping our focus + client->setModal(false); + // unfocus the client (calls the focus callbacks) client->unfocus(); @@ -634,8 +637,8 @@ void Screen::lowerWindow(Client *client) 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 @@ void Screen::lowerWindow(Client *client) 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 @@ void Screen::raiseWindow(Client *client) // 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 @@ void Screen::raiseWindow(Client *client) 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 @@ void Screen::changeDesktop(long 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 @@ void Screen::changeNumDesktops(long num) 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 || @@ -801,6 +804,16 @@ void Screen::setDesktopName(long i, const otk::ustring &name) } +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()); +} + + void Screen::propertyHandler(const XPropertyEvent &e) { otk::EventHandler::propertyHandler(e); diff --git a/src/screen.hh b/src/screen.hh index b64a5199..ab0bc25a 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -10,7 +10,6 @@ extern "C" { #include } -#include "client.hh" #include "widgetbase.hh" #include "otk/renderstyle.hh" #include "otk/strut.hh" @@ -44,8 +43,10 @@ public: ButtonPressMask | ButtonReleaseMask; + //! Holds a list of Clients + typedef std::list 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 @@ private: 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; @@ -196,6 +197,8 @@ public: */ 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); virtual void mapRequestHandler(const XMapRequestEvent &e);