fixed unmanaged windows on subsquent desktop switches
svn path=/trunk/kdebase/kwin/; revision=68087
This commit is contained in:
parent
5dd80c3b56
commit
8ba0c8171f
3 changed files with 101 additions and 57 deletions
113
client.cpp
113
client.cpp
|
@ -268,7 +268,30 @@ void WindowWrapper::resizeEvent( QResizeEvent * )
|
|||
}
|
||||
}
|
||||
|
||||
void WindowWrapper::showEvent( QShowEvent* )
|
||||
/*!
|
||||
Reimplemented to do map() as well
|
||||
*/
|
||||
void WindowWrapper::show()
|
||||
{
|
||||
map();
|
||||
QWidget::show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Reimplemented to do unmap() as well
|
||||
*/
|
||||
void WindowWrapper::hide()
|
||||
{
|
||||
QWidget::hide();
|
||||
unmap();
|
||||
}
|
||||
|
||||
/*!
|
||||
Maps the managed window.
|
||||
*/
|
||||
void WindowWrapper::map()
|
||||
{
|
||||
if ( win ) {
|
||||
if ( !reparented ) {
|
||||
|
@ -284,12 +307,20 @@ void WindowWrapper::showEvent( QShowEvent* )
|
|||
XMapRaised( qt_xdisplay(), win );
|
||||
}
|
||||
}
|
||||
void WindowWrapper::hideEvent( QHideEvent* )
|
||||
|
||||
/*!
|
||||
Unmaps the managed window.
|
||||
*/
|
||||
void WindowWrapper::unmap()
|
||||
{
|
||||
if ( win )
|
||||
XUnmapWindow( qt_xdisplay(), win );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Invalidates the managed window. After that, window() returns 0.
|
||||
*/
|
||||
void WindowWrapper::invalidateWindow()
|
||||
{
|
||||
win = 0;
|
||||
|
@ -405,7 +436,6 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
|
||||
info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties );
|
||||
|
||||
mapped = 0;
|
||||
wwrap = new WindowWrapper( w, this );
|
||||
wwrap->installEventFilter( this );
|
||||
|
||||
|
@ -491,7 +521,7 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
|
|||
original_geometry.setRect(attr.x, attr.y, attr.width, attr.height );
|
||||
}
|
||||
|
||||
QRect geom( original_geometry );
|
||||
geom = original_geometry;
|
||||
bool placementDone = FALSE;
|
||||
|
||||
SessionInfo* session = workspace()->takeSessionInfo( this );
|
||||
|
@ -588,7 +618,7 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
|
|||
if ( desk <= 0 ) {
|
||||
// assume window wants to be visible on the current desktop
|
||||
desk = workspace()->currentDesktop();
|
||||
} else if ( !isMapped && !doNotShow && desk != workspace()->currentDesktop()
|
||||
} else if ( !isMapped && !doNotShow && desk != workspace()->currentDesktop()
|
||||
&& !isMenu() ) {
|
||||
//window didn't specify any specific desktop but will appear
|
||||
//somewhere else. This happens for example with "save data?"
|
||||
|
@ -759,17 +789,7 @@ 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:
|
||||
|
@ -853,8 +873,9 @@ bool Client::unmapNotify( XUnmapEvent& e )
|
|||
withdraw();
|
||||
break;
|
||||
case NormalState:
|
||||
if ( ( !mapped || !windowWrapper()->isVisibleTo( this )) && !e.send_event )
|
||||
if ( !windowWrapper()->isVisibleTo( 0 ) && !e.send_event )
|
||||
return TRUE; // this event was produced by us as well
|
||||
qDebug("UnmapNotify for %s.", caption().latin1() );
|
||||
|
||||
// maybe we will be destroyed soon. Check this first.
|
||||
XEvent ev;
|
||||
|
@ -936,12 +957,28 @@ bool Client::configureRequest( XConfigureRequestEvent& e )
|
|||
ox = windowWrapper()->x();
|
||||
oy = windowWrapper()->y();
|
||||
}
|
||||
|
||||
int nx = x() + ox;
|
||||
int ny = y() + oy;
|
||||
|
||||
if ( e.value_mask & CWX )
|
||||
nx = e.x;
|
||||
if ( e.value_mask & CWY )
|
||||
ny = e.y;
|
||||
|
||||
|
||||
// clever workaround for applications like xv that want to set
|
||||
// the location to the current location but miscalculate the
|
||||
// frame size due to kwin being a double-reparenting window
|
||||
// manager
|
||||
if ( ox == 0 && oy == 0 &&
|
||||
nx == x() + windowWrapper()->x() &&
|
||||
ny == y() + windowWrapper()->y() ) {
|
||||
nx = x();
|
||||
ny = y();
|
||||
}
|
||||
|
||||
|
||||
QPoint np( nx-ox, ny-oy);
|
||||
#if 0
|
||||
if ( windowType() == NET::Normal && may_move ) {
|
||||
|
@ -1481,24 +1518,30 @@ void Client::move( int x, int y )
|
|||
}
|
||||
|
||||
|
||||
/*!\reimp
|
||||
/*!
|
||||
Reimplemented to set the mapping state and to map the managed
|
||||
window in the window wrapper. Alo takes care of deiconification of
|
||||
transients.
|
||||
*/
|
||||
void Client::showEvent( QShowEvent* )
|
||||
void Client::show()
|
||||
{
|
||||
QWidget::show();
|
||||
if ( isIconified() && !isTransient() )
|
||||
animateIconifyOrDeiconify( FALSE );
|
||||
setMappingState( NormalState );
|
||||
}
|
||||
|
||||
/*!
|
||||
Reimplemented to hide the window wrapper as well. Also informs the
|
||||
workspace.
|
||||
*/
|
||||
void Client::hideEvent( QHideEvent* )
|
||||
{
|
||||
workspace()->clientHidden( this );
|
||||
windowWrapper()->map();
|
||||
}
|
||||
|
||||
/*!
|
||||
Reimplemented to unmap the managed window in the window
|
||||
wrapper. Also informs the workspace.
|
||||
*/
|
||||
void Client::hide()
|
||||
{
|
||||
QWidget::hide();
|
||||
workspace()->clientHidden( this );
|
||||
windowWrapper()->unmap();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -1838,7 +1881,7 @@ bool Client::x11Event( XEvent * e)
|
|||
if ( options->focusPolicy == Options::ClickToFocus )
|
||||
return TRUE;
|
||||
|
||||
if ( options->autoRaise && !isDesktop() && !isDock() && !isMenu() && workspace()->focusChangeEnabled()
|
||||
if ( options->autoRaise && !isDesktop() && !isDock() && !isMenu() && workspace()->focusChangeEnabled()
|
||||
&& workspace()->topClientOnDesktop() != this ) {
|
||||
delete autoRaiseTimer;
|
||||
autoRaiseTimer = new QTimer( this );
|
||||
|
@ -1978,11 +2021,9 @@ void Client::setShade( bool s )
|
|||
if ( !wasNorthWest )
|
||||
clearWFlags( WNorthWestGravity );
|
||||
resize (s );
|
||||
XEvent tmpE;
|
||||
do {
|
||||
XWindowEvent (qt_xdisplay(), windowWrapper()->winId(),
|
||||
SubstructureNotifyMask, &tmpE);
|
||||
} while ( tmpE.type != UnmapNotify || tmpE.xunmap.window != win );
|
||||
XEvent tmpE;
|
||||
while ( XCheckTypedWindowEvent( qt_xdisplay(), windowWrapper()->winId(), UnmapNotify, &tmpE ) )
|
||||
; // eat event
|
||||
} else {
|
||||
int h = height();
|
||||
QSize s( sizeForWindowSize( windowWrapper()->size(), TRUE ) );
|
||||
|
@ -2003,6 +2044,9 @@ void Client::setShade( bool s )
|
|||
repaint();
|
||||
if ( isActive() )
|
||||
workspace()->requestFocus( this );
|
||||
XEvent tmpE;
|
||||
while ( XCheckTypedWindowEvent( qt_xdisplay(), windowWrapper()->winId(), MapNotify, &tmpE ) )
|
||||
; // eat event
|
||||
}
|
||||
|
||||
workspace()->iconifyOrDeiconifyTransientsOf( this );
|
||||
|
@ -2251,7 +2295,7 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo
|
|||
break;
|
||||
mode = Center;
|
||||
moveResizeMode = TRUE;
|
||||
geom=geometry();
|
||||
geom=geometry();
|
||||
if ( isMaximized() ) {
|
||||
// in case we were maximized, reset state
|
||||
max_mode = MaximizeRestore;
|
||||
|
@ -2697,7 +2741,6 @@ void Client::cloneMode(Client *client)
|
|||
shaded = client->shaded;
|
||||
geom_restore = client->geom_restore;
|
||||
max_mode = client->max_mode;
|
||||
// cmap = client->cmap;
|
||||
state = client->state;
|
||||
setCaption(client->caption());
|
||||
}
|
||||
|
|
14
client.h
14
client.h
|
@ -36,10 +36,14 @@ public:
|
|||
|
||||
void setActive( bool );
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
void map();
|
||||
void unmap();
|
||||
|
||||
protected:
|
||||
void resizeEvent( QResizeEvent * );
|
||||
void showEvent( QShowEvent* );
|
||||
void hideEvent( QHideEvent* );
|
||||
bool x11Event( XEvent * ); // X11 event
|
||||
|
||||
|
||||
|
@ -174,6 +178,9 @@ public:
|
|||
|
||||
void cloneMode(Client *);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
void closeWindow();
|
||||
|
@ -195,8 +202,6 @@ protected:
|
|||
virtual void windowWrapperHideEvent( QHideEvent* ){}
|
||||
void enterEvent( QEvent * );
|
||||
void leaveEvent( QEvent * );
|
||||
void showEvent( QShowEvent* );
|
||||
void hideEvent( QHideEvent* );
|
||||
bool x11Event( XEvent * ); // X11 event
|
||||
|
||||
virtual void activateLayout();
|
||||
|
@ -275,7 +280,6 @@ private:
|
|||
uint Ptakefocus :1;// does the window understand the TakeFocus protocol?
|
||||
uint Pcontexthelp : 1; // does the window understand the ContextHelp protocol?
|
||||
uint input :1; // does the window want input in its wm_hints
|
||||
uint mapped :1; // keeps track of our visiblity within the asynchronous event flow
|
||||
void getWMHints();
|
||||
void getWindowProtocols();
|
||||
QPixmap icon_pix;
|
||||
|
|
|
@ -420,27 +420,10 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
if ( removeSystemTrayWin( 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 )
|
||||
(void) c->windowEvent( e );
|
||||
}
|
||||
|
||||
return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt
|
||||
|
||||
case MapNotify:
|
||||
|
||||
if ( e->xmap.event == root ) {
|
||||
// keep track of map/unmap for own own windows to avoid
|
||||
// race conditions
|
||||
c = findClientWidthId( e->xmap.window );
|
||||
if ( c )
|
||||
(void) c->windowEvent( e );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt
|
||||
|
||||
case ReparentNotify:
|
||||
|
@ -1816,6 +1799,9 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
Client* old_active_client = active_client;
|
||||
active_client = 0;
|
||||
block_focus = TRUE;
|
||||
|
||||
ClientList mapList;
|
||||
ClientList unmapList;
|
||||
|
||||
if (new_desktop != current_desktop) {
|
||||
/*
|
||||
|
@ -1826,6 +1812,7 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
|
||||
if ( (*it)->isVisible() && !(*it)->isOnDesktop( new_desktop ) ) {
|
||||
(*it)->hide();
|
||||
unmapList += (*it);
|
||||
}
|
||||
}
|
||||
current_desktop = new_desktop;
|
||||
|
@ -1834,6 +1821,7 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
if ( (*it)->isOnDesktop( new_desktop ) && !(*it)->isIconified() ) {
|
||||
(*it)->show();
|
||||
mapList += (*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1892,6 +1880,15 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
}
|
||||
|
||||
QApplication::syncX();
|
||||
XEvent tmpE;
|
||||
for ( ClientList::ConstIterator it = mapList.begin(); it != mapList.end(); ++it) {
|
||||
while ( XCheckTypedWindowEvent( qt_xdisplay(), (*it)->windowWrapper()->winId(), UnmapNotify, &tmpE ) )
|
||||
; // eat event
|
||||
}
|
||||
for ( ClientList::ConstIterator it = unmapList.begin(); it != unmapList.end(); ++it) {
|
||||
while ( XCheckTypedWindowEvent( qt_xdisplay(), (*it)->windowWrapper()->winId(), MapNotify, &tmpE ) )
|
||||
; // eat event
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue