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)
}
+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);
+}
//! 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;
//! 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();
{
assert(window);
+ ignore_unmaps = 0;
+
// update EVERYTHING the first time!!
// the state is kinda assumed to be normal. is this right? XXX
};
//! 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;
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()))
{
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);
}
*/
class OBFrame {
private:
- const OBClient *_client;
+ OBClient *_client;
const otk::ScreenInfo *_screen;
//! The style to use for size and display the decorations
@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();
// unmanage all windows
while (!_clients.empty())
- unmanageWindow(_clients[0]);
+ unmanageWindow(_clients.front());
delete _image_control;
}
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 |
// 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);
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();
}
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();
}
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;
{
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--;
}