manages windows that exist before running.

This commit is contained in:
Dana Jansens 2002-11-11 11:25:40 +00:00
parent 24dd636f73
commit c4a1fac49d
9 changed files with 57 additions and 33 deletions

View file

@ -51,6 +51,7 @@ int OBDisplay::_xinerama_event_basep = 0;
unsigned int OBDisplay::_mask_list[8]; unsigned int OBDisplay::_mask_list[8];
OBDisplay::ScreenInfoList OBDisplay::_screenInfoList; OBDisplay::ScreenInfoList OBDisplay::_screenInfoList;
BGCCache *OBDisplay::_gccache = (BGCCache*) 0; BGCCache *OBDisplay::_gccache = (BGCCache*) 0;
int OBDisplay::_grab_count = 0;
int OBDisplay::xerrorHandler(Display *d, XErrorEvent *e) 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);
}

View file

@ -42,6 +42,9 @@ private:
//! A list of all possible combinations of keyboard lock masks //! A list of all possible combinations of keyboard lock masks
static unsigned int _mask_list[8]; 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 //! A list of information for all screens on the display
static ScreenInfoList _screenInfoList; static ScreenInfoList _screenInfoList;
@ -94,7 +97,11 @@ public:
//! Returns if the display has the xinerama extention available //! Returns if the display has the xinerama extention available
inline static bool xinerama() { return _xinerama; } inline static bool xinerama() { return _xinerama; }
//! Grabs the display
static void grab();
//! Ungrabs the display
static void ungrab();

View file

@ -27,6 +27,8 @@ OBClient::OBClient(int screen, Window window)
{ {
assert(window); assert(window);
ignore_unmaps = 0;
// update EVERYTHING the first time!! // update EVERYTHING the first time!!
// the state is kinda assumed to be normal. is this right? XXX // the state is kinda assumed to be normal. is this right? XXX

View file

@ -119,9 +119,11 @@ public:
}; };
//! The event mask to grab on client windows //! The event mask to grab on client windows
static const long event_mask = PropertyChangeMask | FocusChangeMask | static const long event_mask = PropertyChangeMask | FocusChangeMask;
StructureNotifyMask;
//! The number of unmap events to ignore on the window
int ignore_unmaps;
private: private:
//! The screen number on which the client resides //! The screen number on which the client resides
int _screen; int _screen;

View file

@ -18,7 +18,7 @@ extern "C" {
namespace ob { namespace ob {
OBFrame::OBFrame(const OBClient *client, const otk::Style *style) OBFrame::OBFrame(OBClient *client, const otk::Style *style)
: _client(client), : _client(client),
_screen(otk::OBDisplay::screenInfo(client->screen())) _screen(otk::OBDisplay::screenInfo(client->screen()))
{ {
@ -392,28 +392,19 @@ void OBFrame::updateShape()
void OBFrame::grabClient() void OBFrame::grabClient()
{ {
XGrabServer(otk::OBDisplay::display);
// select the event mask on the frame // 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 // 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); XReparentWindow(otk::OBDisplay::display, _client->window(), _window, 0, 0);
XSelectInput(otk::OBDisplay::display, _client->window(), _client->ignore_unmaps++;
OBClient::event_mask);
// raise the client above the frame // raise the client above the frame
//XRaiseWindow(otk::OBDisplay::display, _client->window()); //XRaiseWindow(otk::OBDisplay::display, _client->window());
// map the client so it maps when the frame does // map the client so it maps when the frame does
XMapWindow(otk::OBDisplay::display, _client->window()); XMapWindow(otk::OBDisplay::display, _client->window());
XUngrabServer(otk::OBDisplay::display);
update(); update();
XMapWindow(otk::OBDisplay::display, _window);
} }

View file

@ -24,7 +24,7 @@ namespace ob {
*/ */
class OBFrame { class OBFrame {
private: private:
const OBClient *_client; OBClient *_client;
const otk::ScreenInfo *_screen; const otk::ScreenInfo *_screen;
//! The style to use for size and display the decorations //! 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 client The client window which will be decorated by the new OBFrame
@param style The style to use to decorate the frame @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 //! Destroys the OBFrame object
virtual ~OBFrame(); virtual ~OBFrame();

View file

@ -101,7 +101,7 @@ OBScreen::~OBScreen()
// unmanage all windows // unmanage all windows
while (!_clients.empty()) while (!_clients.empty())
unmanageWindow(_clients[0]); unmanageWindow(_clients.front());
delete _image_control; delete _image_control;
} }
@ -338,6 +338,8 @@ void OBScreen::manageWindow(Window window)
XFree(wmhint); XFree(wmhint);
} }
otk::OBDisplay::grab();
// choose the events we want to receive on the CLIENT window // choose the events we want to receive on the CLIENT window
attrib_set.event_mask = OBClient::event_mask; attrib_set.event_mask = OBClient::event_mask;
attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | 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 // create the decoration frame for the client window
client->frame = new OBFrame(client, &_style); 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->window(), client);
Openbox::instance->addClient(client->frame->titlebar(), client); Openbox::instance->addClient(client->frame->titlebar(), client);
Openbox::instance->addClient(client->frame->buttonIconify(), 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->handle(), client);
Openbox::instance->addClient(client->frame->gripLeft(), client); Openbox::instance->addClient(client->frame->gripLeft(), client);
Openbox::instance->addClient(client->frame->gripRight(), 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); _clients.push_back(client);
// update the root properties
setClientList(); setClientList();
} }
@ -420,14 +426,11 @@ void OBScreen::unmanageWindow(OBClient *client)
delete client->frame; delete client->frame;
client->frame = 0; client->frame = 0;
ClientList::iterator it = _clients.begin(), end = _clients.end(); // remove from the screen's list
for (; it != end; ++it) _clients.remove(client);
if (*it == client) {
_clients.erase(it);
break;
}
delete client; delete client;
// update the root properties
setClientList(); setClientList();
} }

View file

@ -29,7 +29,7 @@ class OBClient;
class OBScreen { class OBScreen {
public: public:
//! Holds a list of OBClient objects //! Holds a list of OBClient objects
typedef std::vector<OBClient*> ClientList; typedef std::list<OBClient*> ClientList;
//! Holds a list of otk::Strut objects //! Holds a list of otk::Strut objects
typedef std::list<otk::Strut*> StrutList; typedef std::list<otk::Strut*> StrutList;

View file

@ -231,8 +231,11 @@ void OBXEventHandler::unmapNotify(const XUnmapEvent &e)
{ {
OBClient *client = Openbox::instance->findClient(e.window); OBClient *client = Openbox::instance->findClient(e.window);
if (!client) return; 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--;
} }