better reparent handling, dont fux with the event stack..
This commit is contained in:
parent
2ae5aaca65
commit
f11bd1b0cc
6 changed files with 40 additions and 37 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
18
src/frame.cc
18
src/frame.cc
|
@ -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,25 +429,14 @@ 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(),
|
|
||||||
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
|
// according to the ICCCM - if the client doesn't reparent to
|
||||||
// root, then we have to do it for them
|
// root, then we have to do it for them
|
||||||
XReparentWindow(otk::OBDisplay::display, _client->window(),
|
XReparentWindow(otk::OBDisplay::display, _client->window(),
|
||||||
_screen->rootWindow(),
|
_screen->rootWindow(),
|
||||||
_client->area().x(), _client->area().y());
|
_client->area().x(), _client->area().y());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OBFrame::clientGravity(int &x, int &y)
|
void OBFrame::clientGravity(int &x, int &y)
|
||||||
|
|
13
src/frame.hh
13
src/frame.hh
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue