Implement _NET_SHOWING_DESKTOP, giving control of the 'show desktop'

feature to KWin. There shouldn't hopefully be any visible user
difference other than fixed bugs.
BUG: 78109
BUG: 99524


svn path=/trunk/KDE/kdebase/kwin/; revision=413066
This commit is contained in:
Luboš Luňák 2005-05-13 08:57:21 +00:00
parent aed91ffc39
commit 5722d3fac8
5 changed files with 101 additions and 4 deletions

View file

@ -858,6 +858,8 @@ void Client::updateVisibility()
rawHide();
show = false;
}
if( show )
info->setState( 0, NET::Hidden );
if( !isOnCurrentDesktop())
{
setMappingState( IconicState );
@ -866,7 +868,8 @@ void Client::updateVisibility()
}
if( show )
{
info->setState( 0, NET::Hidden );
if( workspace()->showingDesktop())
workspace()->resetShowingDesktop( true );
if( isShade())
setMappingState( IconicState );
else

View file

@ -90,7 +90,7 @@ void WinInfo::changeState( unsigned long state, unsigned long mask )
// ****************************************
RootInfo::RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr )
: NETRootInfo3( dpy, w, name, pr, pr_num, scr )
: NETRootInfo4( dpy, w, name, pr, pr_num, scr )
{
workspace = ws;
}
@ -180,6 +180,11 @@ void RootInfo::gotPing( Window w, Time timestamp )
c->gotPing( timestamp );
}
void RootInfo::changeShowingDesktop( bool showing )
{
workspace->setShowingDesktop( showing );
}
// ****************************************
// Workspace
// ****************************************

View file

@ -443,6 +443,9 @@ bool Client::manage( Window w, bool isMapped )
if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || workspace()->sessionSaving()))
workspace()->setCurrentDesktop( desktop());
if( workspace()->showingDesktop())
workspace()->resetShowingDesktop( false );
if( isOnCurrentDesktop() && !isMapped && !allow )
workspace()->restackClientUnderActive( this );
else

View file

@ -79,6 +79,8 @@ Workspace::Workspace( bool restore )
movingClient(0),
pending_take_activity ( NULL ),
delayfocus_client (0),
showing_desktop( false ),
block_showing_desktop( 0 ),
was_user_interaction (false),
session_saving (false),
control_grab (false),
@ -281,6 +283,7 @@ void Workspace::init()
NET::WM2MoveResizeWindow |
NET::WM2ExtendedStrut |
NET::WM2KDETemporaryRules |
NET::WM2ShowingDesktop |
0
,
NET::ActionMove |
@ -389,6 +392,7 @@ void Workspace::init()
desktop_geometry.height = geom.height();
// TODO update also after gaining XRANDR support
rootInfo->setDesktopGeometry( -1, desktop_geometry );
setShowingDesktop( false );
} // end updates blocker block
@ -1082,6 +1086,7 @@ bool Workspace::setCurrentDesktop( int new_desktop )
int old_desktop = current_desktop;
if (new_desktop != current_desktop)
{
++block_showing_desktop;
/*
optimized Desktop switching: unmapping done from back to front
mapping done from front to back => less exposure events
@ -1108,6 +1113,10 @@ bool Workspace::setCurrentDesktop( int new_desktop )
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
if ( (*it)->isOnDesktop( new_desktop ) )
(*it)->updateVisibility();
--block_showing_desktop;
if( showingDesktop()) // do this only after desktop change to avoid flicker
resetShowingDesktop( false );
}
// restore the focus on this desktop
@ -2482,7 +2491,71 @@ void Workspace::setUnshadowed(unsigned long winId)
return;
}
}
void Workspace::setShowingDesktop( bool showing )
{
rootInfo->setShowingDesktop( showing );
showing_desktop = showing;
++block_showing_desktop;
if( showing_desktop )
{
showing_desktop_clients.clear();
++block_focus;
ClientList cls = stackingOrder();
// find them first, then minimize, otherwise transients may get minimized with the window
// they're transient for
for( ClientList::ConstIterator it = cls.begin();
it != cls.end();
++it )
{
if( (*it)->isOnCurrentDesktop() && (*it)->isShown( true ) && !(*it)->isSpecialWindow())
showing_desktop_clients.prepend( *it ); // topmost first to reduce flicker
}
for( ClientList::ConstIterator it = showing_desktop_clients.begin();
it != showing_desktop_clients.end();
++it )
(*it)->minimize();
--block_focus;
if( Client* desk = findDesktop( true, currentDesktop()))
requestFocus( desk );
}
else
{
for( ClientList::ConstIterator it = showing_desktop_clients.begin();
it != showing_desktop_clients.end();
++it )
(*it)->unminimize();
if( showing_desktop_clients.count() > 0 )
requestFocus( showing_desktop_clients.first());
showing_desktop_clients.clear();
}
--block_showing_desktop;
}
// Following Kicker's behavior:
// Changing a virtual desktop resets the state and shows the windows again.
// Unminimizing a window resets the state but keeps the windows hidden (except
// the one that was unminimized).
// A new window resets the state and shows the windows again, with the new window
// being active.
void Workspace::resetShowingDesktop( bool keep_hidden )
{
if( block_showing_desktop > 0 )
return;
rootInfo->setShowingDesktop( false );
showing_desktop = false;
++block_showing_desktop;
if( !keep_hidden )
{
for( ClientList::ConstIterator it = showing_desktop_clients.begin();
it != showing_desktop_clients.end();
++it )
(*it)->unminimize();
}
showing_desktop_clients.clear();
--block_showing_desktop;
}
} // namespace
#include "workspace.moc"

View file

@ -223,6 +223,9 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
QString desktopName( int desk ) const;
void setDesktopLayout(int o, int x, int y);
void setShowingDesktop( bool showing );
void resetShowingDesktop( bool keep_hidden );
bool showingDesktop() const;
bool isNotManaged( const QString& title ); // ### setter or getter ?
@ -501,6 +504,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
ClientList focus_chain;
ClientList should_get_focus; // last is most recent
ClientList attention_chain;
bool showing_desktop;
ClientList showing_desktop_clients;
int block_showing_desktop;
GroupList groups;
@ -624,7 +631,7 @@ class StackingUpdatesBlocker
};
// NET WM Protocol handler class
class RootInfo : public NETRootInfo3
class RootInfo : public NETRootInfo4
{
private:
typedef KWinInternal::Client Client; // because of NET::Client
@ -641,6 +648,7 @@ class RootInfo : public NETRootInfo3
virtual void gotPing(Window w, Time timestamp);
virtual void restackWindow(Window w, RequestSource source, Window above, int detail, Time timestamp);
virtual void gotTakeActivity(Window w, Time timestamp, long flags );
virtual void changeShowingDesktop( bool showing );
private:
Workspace* workspace;
};
@ -740,6 +748,11 @@ inline bool Workspace::forcedGlobalMouseGrab() const
return forced_global_mouse_grab;
}
inline bool Workspace::showingDesktop() const
{
return showing_desktop;
}
template< typename T >
inline Client* Workspace::findClient( T predicate )
{