manage and unmanage windows in OBScreen

This commit is contained in:
Dana Jansens 2002-11-11 10:26:08 +00:00
parent cee3052446
commit 06a80ce2c7
6 changed files with 144 additions and 125 deletions

View file

@ -128,8 +128,7 @@ Openbox::Openbox(int argc, char **argv)
_cursors.ur_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ur_angle);
// initialize all the screens
_screens.push_back(new OBScreen(0));
_screens[0]->loadStyle(_config);
_screens.push_back(new OBScreen(0, _config));
_state = State_Normal; // done starting
}
@ -139,10 +138,6 @@ Openbox::~Openbox()
{
_state = State_Exiting; // time to kill everything
// unmanage all windows
while (!_clients.empty())
_xeventhandler.unmanageWindow(_clients.begin()->second);
std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
// close the X display

View file

@ -155,7 +155,7 @@ public:
inline const otk::OBProperty *property() const { return _property; }
//! Returns a managed screen
inline const OBScreen *screen(int num) const {
inline OBScreen *screen(int num) {
assert(num >= 0); assert(num < (signed)_screens.size());
return _screens[num];
}

View file

@ -21,6 +21,7 @@ extern "C" {
#include "screen.hh"
#include "client.hh"
#include "openbox.hh"
#include "frame.hh"
#include "otk/display.hh"
static bool running;
@ -35,7 +36,7 @@ static int anotherWMRunning(Display *display, XErrorEvent *) {
namespace ob {
OBScreen::OBScreen(int screen)
OBScreen::OBScreen(int screen, const otk::Configuration &config)
: _number(screen)
{
assert(screen >= 0); assert(screen < ScreenCount(otk::OBDisplay::display));
@ -62,13 +63,16 @@ OBScreen::OBScreen(int screen)
// set the mouse cursor for the root window (the default cursor)
XDefineCursor(otk::OBDisplay::display, _info->getRootWindow(),
Openbox::instance->cursors().session);
// initialize the shit that is used for all drawing on the screen
_image_control = new otk::BImageControl(Openbox::instance->timerManager(),
_info, true);
_image_control->installRootColormap();
_root_cmap_installed = True;
// initialize the screen's style
_style.setImageControl(_image_control);
_style.load(config);
// Set the netwm atoms for geomtery and viewport
@ -99,6 +103,10 @@ OBScreen::~OBScreen()
{
if (! _managed) return;
// unmanage all windows
while (!_clients.empty())
unmanageWindow(_clients[0]);
delete _image_control;
}
@ -142,7 +150,7 @@ void OBScreen::manageExisting()
if (attrib.override_redirect) continue;
if (attrib.map_state != IsUnmapped) {
// XXX: manageWindow(children[i]);
manageWindow(children[i]);
}
}
}
@ -312,11 +320,121 @@ void OBScreen::setWorkArea() {
void OBScreen::loadStyle(const otk::Configuration &config)
{
_style.load(config);
if (Openbox::instance->state() == Openbox::State_Starting)
return;
// XXX: make stuff redraw!
}
void OBScreen::manageWindow(Window window)
{
OBClient *client = 0;
XWMHints *wmhint;
XSetWindowAttributes attrib_set;
// XXX: manage the window, i.e. grab events n shit
// is the window a docking app
if ((wmhint = XGetWMHints(otk::OBDisplay::display, window))) {
if ((wmhint->flags & StateHint) &&
wmhint->initial_state == WithdrawnState) {
//slit->addClient(w); // XXX: make dock apps work!
XFree(wmhint);
return;
}
XFree(wmhint);
}
// 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 |
ButtonMotionMask;
XChangeWindowAttributes(otk::OBDisplay::display, window,
CWEventMask|CWDontPropagate, &attrib_set);
// create the OBClient class, which gets all of the hints on the window
Openbox::instance->addClient(window, client = new OBClient(_number, window));
// we dont want a border on the client
XSetWindowBorderWidth(otk::OBDisplay::display, window, 0);
// specify that if we exit, the window should not be destroyed and should be
// reparented back to root automatically
XChangeSaveSet(otk::OBDisplay::display, window, SetModeInsert);
if (!client->positionRequested()) {
// XXX: position the window intelligenty
}
// 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
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->buttonMax(), client);
Openbox::instance->addClient(client->frame->buttonStick(), client);
Openbox::instance->addClient(client->frame->buttonClose(), client);
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
_clients.push_back(client);
setClientList();
}
void OBScreen::unmanageWindow(OBClient *client)
{
OBFrame *frame = client->frame;
// XXX: pass around focus if this window was focused
// remove the window from our save set
XChangeSaveSet(otk::OBDisplay::display, client->window(), SetModeDelete);
// we dont want events no more
XSelectInput(otk::OBDisplay::display, client->window(), NoEventMask);
XUnmapWindow(otk::OBDisplay::display, frame->window());
// we dont want a border on the client
XSetWindowBorderWidth(otk::OBDisplay::display, client->window(),
client->borderWidth());
// remove the client class from the search list
Openbox::instance->removeClient(client->window());
// remove the frame's decor elements as event handlers for the client
Openbox::instance->removeClient(frame->window());
Openbox::instance->removeClient(frame->titlebar());
Openbox::instance->removeClient(frame->buttonIconify());
Openbox::instance->removeClient(frame->buttonMax());
Openbox::instance->removeClient(frame->buttonStick());
Openbox::instance->removeClient(frame->buttonClose());
Openbox::instance->removeClient(frame->label());
Openbox::instance->removeClient(frame->handle());
Openbox::instance->removeClient(frame->gripLeft());
Openbox::instance->removeClient(frame->gripRight());
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;
}
delete client;
setClientList();
}
}

View file

@ -97,7 +97,7 @@ private:
public:
//! Constructs a new OBScreen object
OBScreen(int screen);
OBScreen(int screen, const otk::Configuration &config);
//! Destroys the OBScreen object
virtual ~OBScreen();
@ -107,6 +107,9 @@ public:
inline const otk::Point &size() const { return _size; }
//! Returns the area of the screen not reserved by applications' Struts
inline const otk::Rect &area() const { return _area; }
//! Returns the style in use on the screen
inline const otk::Style *style() const { return &_style; }
//! Adds a window's strut to the screen's list of reserved spaces
void addStrut(otk::Strut *strut);
@ -116,7 +119,17 @@ public:
//! Loads a new style on the screen
void loadStyle(const otk::Configuration &config);
inline const otk::Style *style() const { return &_style; }
//! Manage a client window
/*!
This gives the window a frame, reparents it, selects events on it, etc.
*/
void manageWindow(Window window);
//! Unmanage a client
/*!
This removes the window's frame, reparents it to root, unselects events on
it, etc.
*/
void unmanageWindow(OBClient *client);
};
}

View file

@ -6,9 +6,9 @@
#include "xeventhandler.hh"
#include "client.hh"
#include "frame.hh"
#include "openbox.hh"
#include "screen.hh"
#include "frame.hh"
#include "otk/display.hh"
#include "otk/rect.hh"
@ -124,108 +124,6 @@ void OBXEventHandler::configureRequest(const XConfigureRequestEvent &e)
}
// XXX: put this into the OBScreen or OBClient class!
void OBXEventHandler::manageWindow(int screen, Window window)
{
OBClient *client = 0;
XWMHints *wmhint;
XSetWindowAttributes attrib_set;
// XXX: manage the window, i.e. grab events n shit
// is the window a docking app
if ((wmhint = XGetWMHints(otk::OBDisplay::display, window))) {
if ((wmhint->flags & StateHint) &&
wmhint->initial_state == WithdrawnState) {
//slit->addClient(w); // XXX: make dock apps work!
XFree(wmhint);
return;
}
XFree(wmhint);
}
// 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 |
ButtonMotionMask;
XChangeWindowAttributes(otk::OBDisplay::display, window,
CWEventMask|CWDontPropagate, &attrib_set);
// create the OBClient class, which gets all of the hints on the window
Openbox::instance->addClient(window, client = new OBClient(screen, window));
// we dont want a border on the client
XSetWindowBorderWidth(otk::OBDisplay::display, window, 0);
// specify that if we exit, the window should not be destroyed and should be
// reparented back to root automatically
XChangeSaveSet(otk::OBDisplay::display, window, SetModeInsert);
if (!client->positionRequested()) {
// XXX: position the window intelligenty
}
// create the decoration frame for the client window
client->frame = new OBFrame(client,
Openbox::instance->screen(screen)->style());
// add all the client's decoration windows as event handlers for the 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->buttonMax(), client);
Openbox::instance->addClient(client->frame->buttonStick(), client);
Openbox::instance->addClient(client->frame->buttonClose(), client);
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
}
// XXX: move this to the OBScreen or OBClient class!
void OBXEventHandler::unmanageWindow(OBClient *client)
{
OBFrame *frame = client->frame;
// XXX: pass around focus if this window was focused
// remove the window from our save set
XChangeSaveSet(otk::OBDisplay::display, client->window(), SetModeDelete);
// we dont want events no more
XSelectInput(otk::OBDisplay::display, client->window(), NoEventMask);
XUnmapWindow(otk::OBDisplay::display, frame->window());
// we dont want a border on the client
XSetWindowBorderWidth(otk::OBDisplay::display, client->window(),
client->borderWidth());
// remove the client class from the search list
Openbox::instance->removeClient(client->window());
// remove the frame's decor elements as event handlers for the client
Openbox::instance->removeClient(frame->window());
Openbox::instance->removeClient(frame->titlebar());
Openbox::instance->removeClient(frame->buttonIconify());
Openbox::instance->removeClient(frame->buttonMax());
Openbox::instance->removeClient(frame->buttonStick());
Openbox::instance->removeClient(frame->buttonClose());
Openbox::instance->removeClient(frame->label());
Openbox::instance->removeClient(frame->handle());
Openbox::instance->removeClient(frame->gripLeft());
Openbox::instance->removeClient(frame->gripRight());
delete client->frame;
client->frame = 0;
delete client;
}
void OBXEventHandler::mapRequest(const XMapRequestEvent &e)
{
#ifdef DEBUG
@ -274,7 +172,7 @@ void OBXEventHandler::mapRequest(const XMapRequestEvent &e)
assert(screen < ScreenCount(otk::OBDisplay::display));
manageWindow(screen, e.window);
Openbox::instance->screen(screen)->manageWindow(e.window);
}
/*
@ -334,7 +232,7 @@ void OBXEventHandler::unmapNotify(const XUnmapEvent &e)
OBClient *client = Openbox::instance->findClient(e.window);
if (!client) return;
unmanageWindow(client);
Openbox::instance->screen(client->screen())->unmanageWindow(client);
}
@ -345,7 +243,7 @@ void OBXEventHandler::destroyNotify(const XDestroyWindowEvent &e)
OBClient *client = Openbox::instance->findClient(e.window);
if (!client) return;
unmanageWindow(client);
Openbox::instance->screen(client->screen())->unmanageWindow(client);
}

View file

@ -150,11 +150,6 @@ public:
@param e The XEvent to handle
*/
void handle(const XEvent &e);
// XXX: TEMPORARY MOVE TO A SCREEN CLASS OR SOMETHING
void manageWindow(int, Window);
void unmanageWindow(OBClient*);
};
}