diff --git a/atoms.cpp b/atoms.cpp index 565d979d3f..dc9217a382 100644 --- a/atoms.cpp +++ b/atoms.cpp @@ -36,6 +36,9 @@ Atoms::Atoms() atoms[n] = &net_wm_context_help; names[n++] = (char *) "_NET_WM_CONTEXT_HELP"; + atoms[n] = &kde_wm_change_state; + names[n++] = (char *) "_KDE_WM_CHANGE_STATE"; + XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return ); for (int i = 0; i < n; i++ ) *atoms[i] = atoms_return[i]; diff --git a/atoms.h b/atoms.h index eb87dc0118..15e2bcb009 100644 --- a/atoms.h +++ b/atoms.h @@ -20,6 +20,7 @@ public: Atom motif_wm_hints; Atom net_wm_context_help; + Atom kde_wm_change_state; }; diff --git a/client.cpp b/client.cpp index 8e436c90ad..7e13f8d0be 100644 --- a/client.cpp +++ b/client.cpp @@ -36,6 +36,8 @@ extern Time kwin_time; static bool resizeHorizontalDirectionFixed = FALSE; static bool resizeVerticalDirectionFixed = FALSE; +static bool blockAnimation = FALSE; + static QRect* visible_bound = 0; @@ -685,7 +687,11 @@ bool Client::mapRequest( XMapRequestEvent& /* e */ ) manage(); break; case IconicState: - show(); + // only show window if we're on current desktop + if ( isOnDesktop( workspace()->currentDesktop() ) ) + show(); + else + setMappingState( NormalState ); break; case NormalState: // only show window if we're on current desktop @@ -856,8 +862,24 @@ bool Client::propertyNotify( XPropertyEvent& e ) */ bool Client::clientMessage( XClientMessageEvent& e ) { - if ( e.message_type == atoms->wm_change_state) { - if ( e.data.l[0] == IconicState && isNormal() ) + + if ( e.message_type == atoms->kde_wm_change_state ) { + if ( e.data.l[0] == IconicState && isNormal() ) { + if ( e.data.l[1] ) + blockAnimation = TRUE; + iconify(); + } else if ( e.data.l[1] == NormalState && isIconified() ) { + if ( e.data.l[1] ) + blockAnimation = TRUE; + // only show window if we're on current desktop + if ( isOnDesktop( workspace()->currentDesktop() ) ) + show(); + else + setMappingState( NormalState ); + } + blockAnimation = FALSE; + } else if ( e.message_type == atoms->wm_change_state) { + if ( e.data.l[0] == IconicState && isNormal() ) iconify(); return TRUE; } @@ -2159,6 +2181,8 @@ QRect Client::adjustedClientArea( const QRect& area ) const void Client::animateIconifyOrDeiconify( bool iconify) { + if ( blockAnimation ) + return; // the function is a bit tricky since it will ensure that an // animation action needs always the same time regardless of the // performance of the machine or the X-Server. diff --git a/workspace.cpp b/workspace.cpp index 085bc87a1b..11d1aa76c3 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1648,15 +1648,15 @@ void Workspace::setCurrentDesktop( int new_desktop ){ (*it)->hide(); } } + current_desktop = new_desktop; + rootInfo->setCurrentDesktop( current_desktop ); // propagate befor the shows below + for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) { if ( (*it)->isOnDesktop( new_desktop ) && !(*it)->isIconified() ) { (*it)->show(); } } } - current_desktop = new_desktop; - - rootInfo->setCurrentDesktop( current_desktop ); // restore the focus on this desktop block_focus = FALSE; @@ -2017,7 +2017,7 @@ void Workspace::clientPopupAboutToShow() /*! Sends client \a c to desktop \a desk. - + Takes care of transients as well. */ void Workspace::sendClientToDesktop( Client* c, int desk ) @@ -2040,7 +2040,7 @@ void Workspace::sendClientToDesktop( Client* c, int desk ) /*! Sends the popup client to desktop \a desk - + Internal slot for the window operation menu */ void Workspace::sendToDesktop( int desk ) @@ -2051,7 +2051,7 @@ void Workspace::sendToDesktop( int desk ) popup_client->setSticky( !popup_client->isSticky() ); return; } - + sendClientToDesktop( popup_client, desk ); }