fixed unmanaged windows on subsquent desktop switches

svn path=/trunk/kdebase/kwin/; revision=68087
This commit is contained in:
Matthias Ettrich 2000-10-17 12:51:39 +00:00
parent 5dd80c3b56
commit 8ba0c8171f
3 changed files with 101 additions and 57 deletions

View file

@ -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());
}

View file

@ -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;

View file

@ -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
}
}