better reparent handling, dont fux with the event stack..

This commit is contained in:
Dana Jansens 2003-01-07 20:20:14 +00:00
parent 2ae5aaca65
commit f11bd1b0cc
6 changed files with 40 additions and 37 deletions

View file

@ -1269,14 +1269,8 @@ void OBClient::reparentHandler(const XReparentEvent &e)
to an already unmapped window. to an already unmapped window.
*/ */
// put another copy of this event on the stack (for the frame reparent
// process)
XEvent ev;
ev.xreparent = e;
XPutBackEvent(otk::OBDisplay::display, &ev);
// this deletes us etc // this deletes us etc
Openbox::instance->screen(_screen)->unmanageWindow(this); Openbox::instance->screen(_screen)->unmanageWindow(this, true);
} }
} }

View file

@ -56,14 +56,11 @@ OBFrame::OBFrame(OBClient *client, otk::Style *style)
otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk
_plate.show(); // the other stuff is shown based on decor settings _plate.show(); // the other stuff is shown based on decor settings
grabClient();
} }
OBFrame::~OBFrame() OBFrame::~OBFrame()
{ {
releaseClient();
} }
@ -432,24 +429,13 @@ void OBFrame::grabClient()
void OBFrame::releaseClient() void OBFrame::releaseClient()
{ {
// check if the app has already reparented its window to the root window // XXX: check for a reparent before reparenting?
XEvent ev;
if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(), // according to the ICCCM - if the client doesn't reparent to
ReparentNotify, &ev)) { // root, then we have to do it for them
/* XReparentWindow(otk::OBDisplay::display, _client->window(),
If the app reparented itself, then we unmanage the window. This causes _screen->rootWindow(),
the window to be unmapped, so to be nice to it, we remap the window _client->area().x(), _client->area().y());
here. We don't put the event back onto the stack because we put it there
in the first place.
*/
XMapWindow(otk::OBDisplay::display, _client->window());
} else {
// according to the ICCCM - if the client doesn't reparent to
// root, then we have to do it for them
XReparentWindow(otk::OBDisplay::display, _client->window(),
_screen->rootWindow(),
_client->area().x(), _client->area().y());
}
} }

View file

@ -67,11 +67,6 @@ private:
*/ */
OBClient::DecorationFlags _decorations; OBClient::DecorationFlags _decorations;
//! Reparents the client window from the root window onto the frame
void grabClient();
//! Reparents the client window back to the root window
void releaseClient();
public: public:
//! Constructs an OBFrame object, and reparents the client to itself //! Constructs an OBFrame object, and reparents the client to itself
/*! /*!
@ -95,6 +90,14 @@ public:
void setTitle(const std::string &text); void setTitle(const std::string &text);
//! Reparents the client window from the root window onto the frame
void grabClient();
//! Reparents the client window back to the root window
/*!
This is not to be called if the client has already reparented itself.
*/
void releaseClient();
//! Update the frame's size to match the client //! Update the frame's size to match the client
void adjustSize(); void adjustSize();
//! Update the frame's position to match the client //! Update the frame's position to match the client

View file

@ -1604,13 +1604,19 @@ static PyObject *_wrap_OBScreen_unmanageWindow(PyObject *self, PyObject *args) {
PyObject *resultobj; PyObject *resultobj;
ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; ob::OBScreen *arg1 = (ob::OBScreen *) 0 ;
ob::OBClient *arg2 = (ob::OBClient *) 0 ; ob::OBClient *arg2 = (ob::OBClient *) 0 ;
bool arg3 = (bool) false ;
PyObject * obj0 = 0 ; PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ; PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
if(!PyArg_ParseTuple(args,(char *)"OO:OBScreen_unmanageWindow",&obj0,&obj1)) goto fail; if(!PyArg_ParseTuple(args,(char *)"OO|O:OBScreen_unmanageWindow",&obj0,&obj1,&obj2)) goto fail;
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
(arg1)->unmanageWindow(arg2); if (obj2) {
arg3 = (bool) PyInt_AsLong(obj2);
if (PyErr_Occurred()) SWIG_fail;
}
(arg1)->unmanageWindow(arg2,arg3);
Py_INCREF(Py_None); resultobj = Py_None; Py_INCREF(Py_None); resultobj = Py_None;
return resultobj; return resultobj;

View file

@ -519,6 +519,9 @@ void OBScreen::manageWindow(Window window)
Openbox::instance->addClient(client->frame->grip_left(), client); Openbox::instance->addClient(client->frame->grip_left(), client);
Openbox::instance->addClient(client->frame->grip_right(), client); Openbox::instance->addClient(client->frame->grip_right(), client);
// reparent the client to the frame
client->frame->grabClient();
// if on the current desktop.. (or all desktops) // if on the current desktop.. (or all desktops)
if (client->desktop() == _desktop || if (client->desktop() == _desktop ||
client->desktop() == (signed)0xffffffff) { client->desktop() == (signed)0xffffffff) {
@ -548,7 +551,7 @@ void OBScreen::manageWindow(Window window)
} }
void OBScreen::unmanageWindow(OBClient *client) void OBScreen::unmanageWindow(OBClient *client, bool reparented)
{ {
OBFrame *frame = client->frame; OBFrame *frame = client->frame;
@ -587,6 +590,14 @@ void OBScreen::unmanageWindow(OBClient *client)
// give the client its border back // give the client its border back
client->toggleClientBorder(true); client->toggleClientBorder(true);
if (!reparented)
// reparent the window out of the frame
frame->releaseClient();
else
// the client is already reparented, so, since we unmapped the window
// above, we remap it here. aren't we nice? :)
XMapWindow(otk::OBDisplay::display, client->window());
delete client->frame; delete client->frame;
client->frame = 0; client->frame = 0;

View file

@ -177,8 +177,11 @@ public:
/*! /*!
This removes the window's frame, reparents it to root, unselects events on This removes the window's frame, reparents it to root, unselects events on
it, etc. it, etc.
@param client The client to unmanage
@param reparented true if the client's window has already reparented
itself; false if it has not.
*/ */
void unmanageWindow(OBClient *client); void unmanageWindow(OBClient *client, bool reparented = false);
//! Raises/Lowers a client window above/below all others in its stacking //! Raises/Lowers a client window above/below all others in its stacking
//! layer //! layer