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];
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);
}

View file

@ -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();

View file

@ -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

View file

@ -119,8 +119,10 @@ 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

View file

@ -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);
}

View file

@ -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();

View file

@ -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);
@ -374,13 +384,9 @@ void OBScreen::manageWindow(Window window)
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();
}

View file

@ -29,7 +29,7 @@ class OBClient;
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;

View file

@ -232,7 +232,10 @@ void OBXEventHandler::unmapNotify(const XUnmapEvent &e)
OBClient *client = Openbox::instance->findClient(e.window);
if (!client) return;
if (client->ignore_unmaps == 0)
Openbox::instance->screen(client->screen())->unmanageWindow(client);
else
client->ignore_unmaps--;
}