handle modal windows better (bugfixes).
handle client-installed colormaps.
This commit is contained in:
parent
5dfd87b085
commit
1cd253f468
5 changed files with 85 additions and 37 deletions
|
@ -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
|
||||||
|
|
|
@ -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 *);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue