From: Dana Jansens Date: Tue, 7 Jan 2003 20:20:14 +0000 (+0000) Subject: better reparent handling, dont fux with the event stack.. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=f11bd1b0cc5973590d1ee547736ac00f50447efa;p=chaz%2Fopenbox better reparent handling, dont fux with the event stack.. --- diff --git a/src/client.cc b/src/client.cc index 9234a188..026f4f2f 100644 --- a/src/client.cc +++ b/src/client.cc @@ -1269,14 +1269,8 @@ void OBClient::reparentHandler(const XReparentEvent &e) 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 - Openbox::instance->screen(_screen)->unmanageWindow(this); + Openbox::instance->screen(_screen)->unmanageWindow(this, true); } } diff --git a/src/frame.cc b/src/frame.cc index 9c24689d..ac631d01 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -56,14 +56,11 @@ OBFrame::OBFrame(OBClient *client, otk::Style *style) otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk _plate.show(); // the other stuff is shown based on decor settings - - grabClient(); } OBFrame::~OBFrame() { - releaseClient(); } @@ -432,24 +429,13 @@ void OBFrame::grabClient() void OBFrame::releaseClient() { - // check if the app has already reparented its window to the root window - XEvent ev; - if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(), - ReparentNotify, &ev)) { - /* - If the app reparented itself, then we unmanage the window. This causes - the window to be unmapped, so to be nice to it, we remap the window - 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()); - } + // XXX: check for a reparent before reparenting? + + // 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()); } diff --git a/src/frame.hh b/src/frame.hh index b204567e..e6236830 100644 --- a/src/frame.hh +++ b/src/frame.hh @@ -67,11 +67,6 @@ private: */ 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: //! Constructs an OBFrame object, and reparents the client to itself /*! @@ -95,6 +90,14 @@ public: 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 void adjustSize(); //! Update the frame's position to match the client diff --git a/src/openbox_wrap.cc b/src/openbox_wrap.cc index dfa50d66..9422823c 100644 --- a/src/openbox_wrap.cc +++ b/src/openbox_wrap.cc @@ -1604,13 +1604,19 @@ static PyObject *_wrap_OBScreen_unmanageWindow(PyObject *self, PyObject *args) { PyObject *resultobj; ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; ob::OBClient *arg2 = (ob::OBClient *) 0 ; + bool arg3 = (bool) false ; PyObject * obj0 = 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(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; return resultobj; diff --git a/src/screen.cc b/src/screen.cc index 3c364b4c..09f57d64 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -519,6 +519,9 @@ void OBScreen::manageWindow(Window window) Openbox::instance->addClient(client->frame->grip_left(), 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 (client->desktop() == _desktop || 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; @@ -587,6 +590,14 @@ void OBScreen::unmanageWindow(OBClient *client) // give the client its border back 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; client->frame = 0; diff --git a/src/screen.hh b/src/screen.hh index 933fc20d..9292c60f 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -177,8 +177,11 @@ public: /*! This removes the window's frame, reparents it to root, unselects events on 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 //! layer