manages windows that exist before running.
Dana Jansens danakj@orodu.net
9 files changed,
57 insertions(+),
33 deletions(-)
M
otk/display.cc
→
otk/display.cc
@@ -51,6 +51,7 @@ int OBDisplay::_xinerama_event_basep = 0;
unsigned int OBDisplay::_mask_list[8]; OBDisplay::ScreenInfoList OBDisplay::_screenInfoList; BGCCache *OBDisplay::_gccache = (BGCCache*) 0; +int OBDisplay::_grab_count = 0; int OBDisplay::xerrorHandler(Display *d, XErrorEvent *e)@@ -172,6 +173,21 @@ return &_screenInfoList[snum];
} +void OBDisplay::grab() +{ + if (_grab_count == 0) + XGrabServer(display); + _grab_count++; +} + + +void OBDisplay::ungrab() +{ + if (_grab_count == 0) return; + _grab_count--; + if (_grab_count == 0) + XUngrabServer(display); +}
M
otk/display.hh
→
otk/display.hh
@@ -42,6 +42,9 @@
//! A list of all possible combinations of keyboard lock masks static unsigned int _mask_list[8]; + //! The number of requested grabs on the display + static int _grab_count; + //! A list of information for all screens on the display static ScreenInfoList _screenInfoList;@@ -94,7 +97,11 @@ inline static int shapeEventBase() { return _shape_event_basep; }
//! Returns if the display has the xinerama extention available inline static bool xinerama() { return _xinerama; } + //! Grabs the display + static void grab(); + //! Ungrabs the display + static void ungrab();
M
src/client.cc
→
src/client.cc
@@ -27,6 +27,8 @@ : _screen(screen), _window(window)
{ assert(window); + ignore_unmaps = 0; + // update EVERYTHING the first time!! // the state is kinda assumed to be normal. is this right? XXX
M
src/client.hh
→
src/client.hh
@@ -119,9 +119,11 @@ State_Toggle //!< _NET_WM_STATE_TOGGLE
}; //! The event mask to grab on client windows - static const long event_mask = PropertyChangeMask | FocusChangeMask | - StructureNotifyMask; + static const long event_mask = PropertyChangeMask | FocusChangeMask; + //! The number of unmap events to ignore on the window + int ignore_unmaps; + private: //! The screen number on which the client resides int _screen;
M
src/frame.cc
→
src/frame.cc
@@ -18,7 +18,7 @@ #include <string>
namespace ob { -OBFrame::OBFrame(const OBClient *client, const otk::Style *style) +OBFrame::OBFrame(OBClient *client, const otk::Style *style) : _client(client), _screen(otk::OBDisplay::screenInfo(client->screen())) {@@ -392,28 +392,19 @@
void OBFrame::grabClient() { - XGrabServer(otk::OBDisplay::display); - // select the event mask on the frame - XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask); + //XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask); // reparent the client to the frame - XSelectInput(otk::OBDisplay::display, _client->window(), - OBClient::event_mask & ~StructureNotifyMask); XReparentWindow(otk::OBDisplay::display, _client->window(), _window, 0, 0); - XSelectInput(otk::OBDisplay::display, _client->window(), - OBClient::event_mask); + _client->ignore_unmaps++; // raise the client above the frame //XRaiseWindow(otk::OBDisplay::display, _client->window()); // map the client so it maps when the frame does XMapWindow(otk::OBDisplay::display, _client->window()); - XUngrabServer(otk::OBDisplay::display); - update(); - - XMapWindow(otk::OBDisplay::display, _window); }
M
src/frame.hh
→
src/frame.hh
@@ -24,7 +24,7 @@ /*!
*/ class OBFrame { private: - const OBClient *_client; + OBClient *_client; const otk::ScreenInfo *_screen; //! The style to use for size and display the decorations@@ -89,7 +89,7 @@ /*!
@param client The client window which will be decorated by the new OBFrame @param style The style to use to decorate the frame */ - OBFrame(const OBClient *client, const otk::Style *style); + OBFrame(OBClient *client, const otk::Style *style); //! Destroys the OBFrame object virtual ~OBFrame();
M
src/screen.cc
→
src/screen.cc
@@ -101,7 +101,7 @@ if (! _managed) return;
// unmanage all windows while (!_clients.empty()) - unmanageWindow(_clients[0]); + unmanageWindow(_clients.front()); delete _image_control; }@@ -338,6 +338,8 @@ }
XFree(wmhint); } + otk::OBDisplay::grab(); + // choose the events we want to receive on the CLIENT window attrib_set.event_mask = OBClient::event_mask; attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |@@ -362,7 +364,15 @@
// create the decoration frame for the client window client->frame = new OBFrame(client, &_style); - // add all the client's decoration windows as event handlers for the client + // XXX: if on the current desktop.. + XMapWindow(otk::OBDisplay::display, client->frame->window()); + + // XXX: handle any requested states such as shaded/maximized + + otk::OBDisplay::ungrab(); + + // add all the client's windows as event handlers for the client + Openbox::instance->addClient(window, client); Openbox::instance->addClient(client->frame->window(), client); Openbox::instance->addClient(client->frame->titlebar(), client); Openbox::instance->addClient(client->frame->buttonIconify(), client);@@ -373,14 +383,10 @@ Openbox::instance->addClient(client->frame->label(), client);
Openbox::instance->addClient(client->frame->handle(), client); Openbox::instance->addClient(client->frame->gripLeft(), client); Openbox::instance->addClient(client->frame->gripRight(), client); - - // XXX: if on the current desktop.. - XMapWindow(otk::OBDisplay::display, client->frame->window()); - - // XXX: handle any requested states such as shaded/maximized - + // add to the screen's list _clients.push_back(client); + // update the root properties setClientList(); }@@ -420,14 +426,11 @@
delete client->frame; client->frame = 0; - ClientList::iterator it = _clients.begin(), end = _clients.end(); - for (; it != end; ++it) - if (*it == client) { - _clients.erase(it); - break; - } + // remove from the screen's list + _clients.remove(client); delete client; + // update the root properties setClientList(); }
M
src/screen.hh
→
src/screen.hh
@@ -29,7 +29,7 @@ */
class OBScreen { public: //! Holds a list of OBClient objects - typedef std::vector<OBClient*> ClientList; + typedef std::list<OBClient*> ClientList; //! Holds a list of otk::Strut objects typedef std::list<otk::Strut*> StrutList;
M
src/xeventhandler.cc
→
src/xeventhandler.cc
@@ -231,8 +231,11 @@ void OBXEventHandler::unmapNotify(const XUnmapEvent &e)
{ OBClient *client = Openbox::instance->findClient(e.window); if (!client) return; - - Openbox::instance->screen(client->screen())->unmanageWindow(client); + + if (client->ignore_unmaps == 0) + Openbox::instance->screen(client->screen())->unmanageWindow(client); + else + client->ignore_unmaps--; }