found a smart way to get rid of the race conditions (that sometimes
made windows lose their decorations) svn path=/trunk/kdebase/kwin/; revision=33867
This commit is contained in:
parent
49eb95bd94
commit
3293927ed4
4 changed files with 56 additions and 16 deletions
31
client.cpp
31
client.cpp
|
@ -117,15 +117,15 @@ WindowWrapper::WindowWrapper( WId w, Client *parent, const char* name)
|
|||
EnterWindowMask | LeaveWindowMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
StructureNotifyMask |
|
||||
StructureNotifyMask |
|
||||
SubstructureRedirectMask |
|
||||
SubstructureNotifyMask
|
||||
);
|
||||
|
||||
XSelectInput( qt_xdisplay(), w,
|
||||
FocusChangeMask |
|
||||
PropertyChangeMask |
|
||||
StructureNotifyMask
|
||||
PropertyChangeMask
|
||||
// StructureNotifyMask
|
||||
);
|
||||
|
||||
// install a passive grab to catch mouse button events
|
||||
|
@ -172,7 +172,7 @@ void WindowWrapper::showEvent( QShowEvent* )
|
|||
void WindowWrapper::hideEvent( QHideEvent* )
|
||||
{
|
||||
if ( win )
|
||||
XUnmapWindow( qt_xdisplay(), win );
|
||||
XUnmapWindow( qt_xdisplay(), win );
|
||||
}
|
||||
|
||||
void WindowWrapper::invalidateWindow()
|
||||
|
@ -253,13 +253,13 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
: QWidget( parent, name, f | WStyle_Customize | WStyle_NoBorder )
|
||||
{
|
||||
|
||||
reparented = FALSE;
|
||||
wspace = ws;
|
||||
win = w;
|
||||
XWindowAttributes attr;
|
||||
if (XGetWindowAttributes(qt_xdisplay(), win, &attr)){
|
||||
original_geometry.setRect(attr.x, attr.y, attr.width, attr.height );
|
||||
}
|
||||
mapped = 0;
|
||||
wwrap = new WindowWrapper( w, this );
|
||||
wwrap->installEventFilter( this );
|
||||
|
||||
|
@ -417,7 +417,17 @@ bool Client::windowEvent( XEvent * e)
|
|||
{
|
||||
switch (e->type) {
|
||||
case UnmapNotify:
|
||||
if ( e->xunmap.window == winId() ) {
|
||||
mapped = 0;
|
||||
return FALSE;
|
||||
}
|
||||
return unmapNotify( e->xunmap );
|
||||
case MapNotify:
|
||||
if ( e->xmap.window == winId() ) {
|
||||
mapped = 1;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case MapRequest:
|
||||
return mapRequest( e->xmaprequest );
|
||||
case ConfigureRequest:
|
||||
|
@ -445,7 +455,6 @@ bool Client::windowEvent( XEvent * e)
|
|||
setActive( FALSE );
|
||||
break;
|
||||
case ReparentNotify:
|
||||
reparented = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -482,6 +491,9 @@ bool Client::mapRequest( XMapRequestEvent& /* e */ )
|
|||
bool Client::unmapNotify( XUnmapEvent& e )
|
||||
{
|
||||
|
||||
if ( e.event != windowWrapper()->winId() && !e.send_event )
|
||||
return TRUE;
|
||||
|
||||
switch ( mappingState() ) {
|
||||
case IconicState:
|
||||
// only react on sent events, all others are produced by us
|
||||
|
@ -489,14 +501,11 @@ bool Client::unmapNotify( XUnmapEvent& e )
|
|||
withdraw();
|
||||
break;
|
||||
case NormalState:
|
||||
if ( !reparented )
|
||||
return TRUE; // we produced this event
|
||||
if ( !windowWrapper()->isVisible() && !e.send_event )
|
||||
return TRUE; // this event was produced by us as well
|
||||
if ( !mapped && !e.send_event )
|
||||
return TRUE; // this event was produced by us as well
|
||||
|
||||
// maybe we will be destroyed soon. Check this first.
|
||||
XEvent ev;
|
||||
QApplication::syncX();
|
||||
if ( XCheckTypedWindowEvent (qt_xdisplay(), win,
|
||||
DestroyNotify, &ev) ){
|
||||
workspace()->destroyClient( this );
|
||||
|
|
6
client.h
6
client.h
|
@ -130,8 +130,8 @@ public:
|
|||
void move( int x, int y );
|
||||
void move( const QPoint & p )
|
||||
{ move( p.x(), p.y() ); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
|
@ -203,7 +203,6 @@ private:
|
|||
void sendSynteticConfigureNotify();
|
||||
int state;
|
||||
bool active;
|
||||
bool reparented;
|
||||
QRect original_geometry;
|
||||
QRect geom; //### TODO
|
||||
bool shaded;
|
||||
|
@ -214,6 +213,7 @@ private:
|
|||
void getWindowProtocols();
|
||||
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
|
||||
uint Ptakefocus :1;// does the window understand the TakeFocus protocol?
|
||||
uint mapped :1; // keeps track of our visiblity within the asynchronous event flow
|
||||
QPixmap icon_pix;
|
||||
QPixmap miniicon_pix;
|
||||
QRect geom_restore;
|
||||
|
|
|
@ -222,7 +222,7 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
break;
|
||||
case UnmapNotify:
|
||||
// this is special due to
|
||||
// SubstructureRedirectMask. e->xany.window is the window the
|
||||
// SubstructureNotifyMask. e->xany.window is the window the
|
||||
// event is reported to. Take care not to confuse Qt.
|
||||
c = findClient( e->xunmap.window );
|
||||
|
||||
|
@ -233,8 +233,24 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
if ( removeDockwin( e->xunmap.window ) )
|
||||
return TRUE;
|
||||
|
||||
if ( e->xunmap.event == root ) {
|
||||
// keep track of map/unmap for own own windows to avoid
|
||||
// race conditions
|
||||
c = findClientWidthId( e->xunmap.window );
|
||||
if ( c )
|
||||
return c->windowEvent( e );
|
||||
}
|
||||
|
||||
if ( e->xunmap.event != e->xunmap.window ) // hide wm typical event from Qt
|
||||
return TRUE;
|
||||
case MapNotify:
|
||||
if ( e->xunmap.event == root ) {
|
||||
// keep track of map/unmap for own own windows to avoid
|
||||
// race conditions
|
||||
c = findClientWidthId( e->xmap.window );
|
||||
if ( c )
|
||||
return c->windowEvent( e );
|
||||
}
|
||||
case ReparentNotify:
|
||||
c = findClient( e->xreparent.window );
|
||||
if ( c )
|
||||
|
@ -337,6 +353,18 @@ Client* Workspace::findClient( WId w ) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Finds the client with window id \a w
|
||||
*/
|
||||
Client* Workspace::findClientWidthId( WId w ) const
|
||||
{
|
||||
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it) {
|
||||
if ( (*it)->winId() == w )
|
||||
return *it;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the workspace's geometry
|
||||
|
@ -980,6 +1008,8 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_current_desktop, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)¤t_desktop, 1);
|
||||
|
||||
QApplication::syncX();
|
||||
KWM::switchToDesktop( current_desktop ); // ### compatibility
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
DockWindow( WId w, WId wf )
|
||||
: dockWin(w),dockFor(wf)
|
||||
{}
|
||||
|
||||
|
||||
bool operator==( const DockWindow& other )
|
||||
{ return dockWin == other.dockWin; }
|
||||
WId dockWin;
|
||||
|
@ -138,6 +138,7 @@ private:
|
|||
Client* desktop_client;
|
||||
int current_desktop;
|
||||
int number_of_desktops;
|
||||
Client* findClientWidthId( WId w ) const;
|
||||
|
||||
Client* popup_client;
|
||||
QWidget* desktop_widget;
|
||||
|
|
Loading…
Reference in a new issue