From c4a1fac49da32250dc4567880b385feb7feaa908 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 11 Nov 2002 11:25:40 +0000 Subject: [PATCH] manages windows that exist before running. --- otk/display.cc | 16 ++++++++++++++++ otk/display.hh | 7 +++++++ src/client.cc | 2 ++ src/client.hh | 6 ++++-- src/frame.cc | 15 +++------------ src/frame.hh | 4 ++-- src/screen.cc | 31 +++++++++++++++++-------------- src/screen.hh | 2 +- src/xeventhandler.cc | 7 +++++-- 9 files changed, 57 insertions(+), 33 deletions(-) diff --git a/otk/display.cc b/otk/display.cc index 4613b9ba..77111d3c 100644 --- a/otk/display.cc +++ b/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 @@ const ScreenInfo* OBDisplay::screenInfo(int 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); +} diff --git a/otk/display.hh b/otk/display.hh index e8f91ae9..7f5ab02d 100644 --- a/otk/display.hh +++ b/otk/display.hh @@ -42,6 +42,9 @@ private: //! 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 @@ public: //! 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(); diff --git a/src/client.cc b/src/client.cc index 32532f20..57bf5161 100644 --- a/src/client.cc +++ b/src/client.cc @@ -27,6 +27,8 @@ OBClient::OBClient(int 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 diff --git a/src/client.hh b/src/client.hh index b4e01eff..5ccf5fd5 100644 --- a/src/client.hh +++ b/src/client.hh @@ -119,9 +119,11 @@ public: }; //! 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; diff --git a/src/frame.cc b/src/frame.cc index 1fed1768..20e81ebd 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -18,7 +18,7 @@ extern "C" { 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::updateShape() 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); } diff --git a/src/frame.hh b/src/frame.hh index f1632981..0c3a93f2 100644 --- a/src/frame.hh +++ b/src/frame.hh @@ -24,7 +24,7 @@ namespace ob { */ 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 @@ public: @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(); diff --git a/src/screen.cc b/src/screen.cc index 9d316ce4..7413b163 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -101,7 +101,7 @@ OBScreen::~OBScreen() // unmanage all windows while (!_clients.empty()) - unmanageWindow(_clients[0]); + unmanageWindow(_clients.front()); delete _image_control; } @@ -338,6 +338,8 @@ void OBScreen::manageWindow(Window window) 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 @@ void OBScreen::manageWindow(Window window) // 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 @@ void OBScreen::manageWindow(Window window) 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 @@ void OBScreen::unmanageWindow(OBClient *client) 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(); } diff --git a/src/screen.hh b/src/screen.hh index 516632ac..8d7bc6b0 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -29,7 +29,7 @@ class OBClient; class OBScreen { public: //! Holds a list of OBClient objects - typedef std::vector ClientList; + typedef std::list ClientList; //! Holds a list of otk::Strut objects typedef std::list StrutList; diff --git a/src/xeventhandler.cc b/src/xeventhandler.cc index 7cd5257a..5d527377 100644 --- a/src/xeventhandler.cc +++ b/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--; } -- 2.39.2