handle modal windows better (bugfixes).

handle client-installed colormaps.
This commit is contained in:
Dana Jansens 2003-02-03 20:18:30 +00:00
parent 5dfd87b085
commit 1cd253f468
5 changed files with 85 additions and 37 deletions

View file

@ -107,8 +107,6 @@ Client::~Client()
} }
// clean up parents reference to this // clean up parents reference to this
if (_modal)
setModal(false);
if (_transient_for) if (_transient_for)
_transient_for->_transients.remove(this); // remove from old parent _transient_for->_transients.remove(this); // remove from old parent
@ -825,6 +823,8 @@ Client *Client::findModalChild(Client *skip) const
void Client::setModal(bool modal) void Client::setModal(bool modal)
{ {
if (modal == _modal) return;
if (modal) { if (modal) {
Client *c = this; Client *c = this;
while (c->_transient_for) { 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() bool Client::focus()
{ {
// if we have a modal child, then focus it, not us // if we have a modal child, then focus it, not us

View file

@ -7,6 +7,7 @@
property changes on the window and some client messages property changes on the window and some client messages
*/ */
#include "screen.hh"
#include "widgetbase.hh" #include "widgetbase.hh"
#include "otk/point.hh" #include "otk/point.hh"
#include "otk/strut.hh" #include "otk/strut.hh"
@ -28,6 +29,7 @@ extern "C" {
namespace ob { namespace ob {
class Frame; class Frame;
class Screen;
//! The MWM Hints as retrieved from the window property //! 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. //! Attempts to find and return a modal child of this window, recursively.
Client *findModalChild(Client *skip = 0) const; 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: public:
#ifndef SWIG #ifndef SWIG
//! Constructs a new Client object around a specified window id //! 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; } 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 //! Returns the position and size of the client relative to the root window
inline const otk::Rect &area() const { return _area; } inline const otk::Rect &area() const { return _area; }
@ -696,6 +698,9 @@ BB @param window The window id that the Client class should handle
#if defined(SHAPE) #if defined(SHAPE)
virtual void shapeHandler(const XShapeEvent &e); virtual void shapeHandler(const XShapeEvent &e);
#endif // SHAPE #endif // SHAPE
friend void Screen::manageWindow(Window);
friend void Screen::unmanageWindow(Client *);
}; };
} }

View file

@ -360,13 +360,27 @@ Client *Openbox::findClient(Window window)
void Openbox::setFocusedClient(Client *c) 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; _focused_client = c;
if (c) { if (c) {
_focused_screen = _screens[c->screen()]; _focused_screen = _screens[c->screen()];
// install the client's colormap
c->installColormap(true);
} else { } else {
assert(_focused_screen);
XSetInputFocus(**otk::display, _focused_screen->focuswindow(), XSetInputFocus(**otk::display, _focused_screen->focuswindow(),
RevertToNone, CurrentTime); RevertToNone, CurrentTime);
// install the root window colormap
_focused_screen->installColormap(true);
} }
// set the NET_ACTIVE_WINDOW hint for all screens // set the NET_ACTIVE_WINDOW hint for all screens
ScreenList::iterator it, end = _screens.end(); ScreenList::iterator it, end = _screens.end();

View file

@ -211,7 +211,7 @@ void Screen::updateStrut()
{ {
_strut.left = _strut.right = _strut.top = _strut.bottom = 0; _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) { for (it = clients.begin(); it != end; ++it) {
const otk::Strut &s = (*it)->strut(); const otk::Strut &s = (*it)->strut();
_strut.left = std::max(_strut.left, s.left); _strut.left = std::max(_strut.left, s.left);
@ -264,7 +264,7 @@ void Screen::calcArea()
if (old_area != _area) { if (old_area != _area) {
// the area has changed, adjust all the maximized windows // 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) for (it = clients.begin(); it != end; ++it)
(*it)->remaximize(); (*it)->remaximize();
} }
@ -371,8 +371,8 @@ void Screen::changeClientList()
windows = new Window[size]; windows = new Window[size];
win_it = windows; win_it = windows;
Client::List::const_iterator it = clients.begin(); ClientList::const_iterator it = clients.begin();
const Client::List::const_iterator end = clients.end(); const ClientList::const_iterator end = clients.end();
for (; it != end; ++it, ++win_it) for (; it != end; ++it, ++win_it)
*win_it = (*it)->window(); *win_it = (*it)->window();
} else } else
@ -402,8 +402,8 @@ void Screen::changeStackingList()
windows = new Window[size]; windows = new Window[size];
win_it = windows; win_it = windows;
Client::List::const_reverse_iterator it = _stacking.rbegin(); ClientList::const_reverse_iterator it = _stacking.rbegin();
const Client::List::const_reverse_iterator end = _stacking.rend(); const ClientList::const_reverse_iterator end = _stacking.rend();
for (; it != end; ++it, ++win_it) for (; it != end; ++it, ++win_it)
*win_it = (*it)->window(); *win_it = (*it)->window();
} else } else
@ -615,6 +615,9 @@ void Screen::unmanageWindow(Client *client)
// influence // influence
updateStrut(); updateStrut();
// unset modal before dropping our focus
client->setModal(false);
// unfocus the client (calls the focus callbacks) // unfocus the client (calls the focus callbacks)
client->unfocus(); client->unfocus();
@ -634,8 +637,8 @@ void Screen::lowerWindow(Client *client)
assert(!_stacking.empty()); // this would be bad assert(!_stacking.empty()); // this would be bad
Client::List::iterator it = --_stacking.end(); ClientList::iterator it = --_stacking.end();
const Client::List::iterator end = _stacking.begin(); const ClientList::iterator end = _stacking.begin();
if (client->modal() && client->transientFor()) { if (client->modal() && client->transientFor()) {
// don't let a modal window lower below its transient_for // don't let a modal window lower below its transient_for
@ -643,7 +646,7 @@ void Screen::lowerWindow(Client *client)
assert(it != _stacking.end()); assert(it != _stacking.end());
wins[0] = (it == _stacking.begin() ? _focuswindow : wins[0] = (it == _stacking.begin() ? _focuswindow :
((*(--Client::List::const_iterator(it)))->frame->window())); ((*(--ClientList::const_iterator(it)))->frame->window()));
wins[1] = client->frame->window(); wins[1] = client->frame->window();
if (wins[0] == wins[1]) return; // already right above the 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 // remove the client before looking so we can't run into ourselves
_stacking.remove(client); _stacking.remove(client);
Client::List::iterator it = _stacking.begin(); ClientList::iterator it = _stacking.begin();
const Client::List::iterator end = _stacking.end(); const ClientList::iterator end = _stacking.end();
// the stacking list is from highest to lowest // the stacking list is from highest to lowest
for (; it != end && (*it)->layer() > client->layer(); ++it); 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. otherwise, we want to stack under the previous window in the stack.
*/ */
wins[0] = (it == _stacking.begin() ? _focuswindow : wins[0] = (it == _stacking.begin() ? _focuswindow :
((*(--Client::List::const_iterator(it)))->frame->window())); ((*(--ClientList::const_iterator(it)))->frame->window()));
wins[1] = client->frame->window(); wins[1] = client->frame->window();
_stacking.insert(it, client); _stacking.insert(it, client);
@ -713,7 +716,7 @@ void Screen::changeDesktop(long desktop)
if (old == _desktop) return; if (old == _desktop) return;
Client::List::iterator it, end = clients.end(); ClientList::iterator it, end = clients.end();
for (it = clients.begin(); it != end; ++it) { for (it = clients.begin(); it != end; ++it) {
if ((*it)->desktop() == old) { if ((*it)->desktop() == old) {
(*it)->frame->hide(); (*it)->frame->hide();
@ -734,7 +737,7 @@ void Screen::changeNumDesktops(long num)
if (!(num > 0)) return; if (!(num > 0)) return;
// move windows on desktops that will no longer exist! // 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) { for (it = clients.begin(); it != end; ++it) {
int d = (*it)->desktop(); int d = (*it)->desktop();
if (d >= num && !(d == (signed) 0xffffffff || 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) void Screen::propertyHandler(const XPropertyEvent &e)
{ {
otk::EventHandler::propertyHandler(e); otk::EventHandler::propertyHandler(e);

View file

@ -10,7 +10,6 @@ extern "C" {
#include <X11/Xlib.h> #include <X11/Xlib.h>
} }
#include "client.hh"
#include "widgetbase.hh" #include "widgetbase.hh"
#include "otk/renderstyle.hh" #include "otk/renderstyle.hh"
#include "otk/strut.hh" #include "otk/strut.hh"
@ -44,8 +43,10 @@ public:
ButtonPressMask | ButtonPressMask |
ButtonReleaseMask; ButtonReleaseMask;
//! Holds a list of Clients
typedef std::list<Client*> ClientList;
//! All managed clients on the screen (in order of being mapped) //! All managed clients on the screen (in order of being mapped)
Client::List clients; ClientList clients;
private: private:
//! Was %Openbox able to manage the screen? //! Was %Openbox able to manage the screen?
@ -77,7 +78,7 @@ private:
Window _supportwindow; Window _supportwindow;
//! A list of all managed clients on the screen, in their stacking order //! A list of all managed clients on the screen, in their stacking order
Client::List _stacking; ClientList _stacking;
//! The desktop currently being displayed //! The desktop currently being displayed
long _desktop; long _desktop;
@ -196,6 +197,8 @@ public:
*/ */
void setDesktopName(long i, const otk::ustring &name); void setDesktopName(long i, const otk::ustring &name);
void installColormap(bool install) const;
virtual void propertyHandler(const XPropertyEvent &e); virtual void propertyHandler(const XPropertyEvent &e);
virtual void clientMessageHandler(const XClientMessageEvent &e); virtual void clientMessageHandler(const XClientMessageEvent &e);
virtual void mapRequestHandler(const XMapRequestEvent &e); virtual void mapRequestHandler(const XMapRequestEvent &e);