diff --git a/CMakeLists.txt b/CMakeLists.txt
index d426a7f203..04d057755c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/effects
${CMAKE_CURRENT_SOURCE_DIR}/tabbox
${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kephal
+ ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace
)
@@ -129,7 +130,7 @@ qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml workspace.h KWin::Works
kde4_add_kdeinit_executable( kwin ${kwin_KDEINIT_SRCS})
-target_link_libraries(kdeinit_kwin ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTXML_LIBRARY} kephal kdecorations kwineffects ${X11_LIBRARIES})
+target_link_libraries(kdeinit_kwin ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTXML_LIBRARY} kephal kworkspace kdecorations kwineffects ${X11_LIBRARIES})
if(OPENGL_FOUND)
add_subdirectory(opengltest)
diff --git a/activation.cpp b/activation.cpp
index 03988dda1d..eea49369e0 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -400,7 +400,7 @@ void Workspace::handleTakeActivity( Client* c, Time /*timestamp*/, int flags )
*/
void Workspace::clientHidden( Client* c )
{
- assert( !c->isShown( true ) || !c->isOnCurrentDesktop());
+ assert( !c->isShown( true ) || !c->isOnCurrentDesktop() || !c->isOnCurrentActivity());
activateNextClient( c );
}
@@ -431,7 +431,7 @@ bool Workspace::activateNextClient( Client* c )
{
Client* ci = focus_chain[ currentDesktop() ].at( i );
if( c == ci || !ci->isShown( false )
- || !ci->isOnCurrentDesktop())
+ || !ci->isOnCurrentDesktop() || !ci->isOnCurrentActivity())
continue;
if( options->separateScreenFocus )
{
@@ -478,7 +478,7 @@ void Workspace::setCurrentScreen( int new_screen )
--i )
{
Client* ci = focus_chain[ currentDesktop() ].at( i );
- if( !ci->isShown( false ) || !ci->isOnCurrentDesktop())
+ if( !ci->isShown( false ) || !ci->isOnCurrentDesktop() || !ci->isOnCurrentActivity())
continue;
if( !ci->screen() == new_screen )
continue;
diff --git a/client.cpp b/client.cpp
index a415007d29..b815f1bf84 100644
--- a/client.cpp
+++ b/client.cpp
@@ -1090,6 +1090,14 @@ void Client::updateVisibility()
internalHide( Allowed );
return;
}
+ if( !isOnCurrentActivity())
+ {
+ if( compositing() && options->hiddenPreviews != HiddenPreviewsNever )
+ internalKeep( Allowed );
+ else
+ internalHide( Allowed );
+ return;
+ }
bool belongs_to_desktop = false;
for( ClientList::ConstIterator it = group()->members().constBegin();
it != group()->members().constEnd();
@@ -1476,6 +1484,52 @@ void Client::setDesktop( int desktop )
clientGroup()->updateStates( this );
}
+/**
+ * Sets whether the client is on @p activity.
+ * If you remove it from its last activity, then it's on all activities.
+ *
+ * Note: If it was on all activities and you try to remove it from one, nothing will happen;
+ * I don't think that's an important enough use case to handle here.
+ */
+void Client::setOnActivity( const QString &activity, bool enable )
+ {
+ if( activityList.contains(activity) == enable ) //nothing to do
+ return;
+ KActivityConsumer c;
+ QStringList allActivities = c.availableActivities();
+ if( !allActivities.contains(activity) ) //bogus ID
+ return;
+ //check whether we should set it to all activities
+ QStringList newActivitiesList = activityList;
+ if (enable)
+ newActivitiesList.append(activity);
+ else
+ newActivitiesList.removeOne(activity);
+ if( newActivitiesList.size() == allActivities.size() || newActivitiesList.isEmpty() )
+ {
+ setOnAllActivities(true);
+ return;
+ }
+ activityList = newActivitiesList;
+ /* FIXME I don't think I need the transients but what about the rest?
+ if(( was_desk == NET::OnAllDesktops ) != ( desktop == NET::OnAllDesktops ))
+ { // onAllDesktops changed
+ if( isShown( true ))
+ Notify::raise( isOnAllDesktops() ? Notify::OnAllDesktops : Notify::NotOnAllDesktops );
+ workspace()->updateOnAllDesktopsOfTransients( this );
+ }
+ if( decoration != NULL )
+ decoration->desktopChange();
+ */
+ workspace()->updateFocusChains( this, Workspace::FocusChainMakeFirst );
+ updateVisibility();
+ updateWindowRules();
+
+ // Update states of all other windows in this group
+ if( clientGroup() )
+ clientGroup()->updateStates( this );
+ }
+
/**
* Returns the virtual desktop within the workspace() the client window
* is located in, 0 if it isn't located on any special desktop (not mapped yet),
@@ -1487,6 +1541,17 @@ int Client::desktop() const
return desk;
}
+/**
+ * Returns the list of activities the client window is on.
+ * if it's on all activities, the list will be empty.
+ * Don't use this, use isOnActivity() and friends (from class Toplevel)
+ * FIXME do I need to consider if it's not mapped yet?
+ */
+QStringList Client::activities() const
+ {
+ return activityList;
+ }
+
void Client::setOnAllDesktops( bool b )
{
if(( b && isOnAllDesktops() ) ||
@@ -1502,6 +1567,33 @@ void Client::setOnAllDesktops( bool b )
clientGroup()->updateStates( this );
}
+/**
+ * if @p b is true, sets on all activities.
+ * if it's false, sets it to only be on the current activity
+ */
+void Client::setOnAllActivities( bool b )
+ {
+ if( b == isOnAllActivities() )
+ return;
+ if( b ) {
+ activityList.clear();
+ //FIXME update transients
+ } else {
+ KActivityConsumer c;
+ setOnActivity(c.currentActivity(), true);
+ //FIXME update transients
+ return;
+ }
+
+ //FIXME c&p'd from setOnActivity, I probably need more code and should probably factor it out
+ workspace()->updateFocusChains( this, Workspace::FocusChainMakeFirst );
+ updateVisibility();
+ updateWindowRules();
+ // Update states of all other windows in this group
+ if( clientGroup() )
+ clientGroup()->updateStates( this );
+ }
+
/**
* Performs activation and/or raising of the window
*/
diff --git a/client.h b/client.h
index 4bd480085e..ade0f411f8 100644
--- a/client.h
+++ b/client.h
@@ -143,6 +143,10 @@ class Client
void setDesktop( int );
void setOnAllDesktops( bool set );
+ virtual QStringList activities() const;
+ void setOnActivity( const QString &activity, bool enable );
+ void setOnAllActivities( bool set );
+
/// Is not minimized and not hidden. I.e. normally visible on some virtual desktop.
bool isShown( bool shaded_is_shown ) const;
bool isHiddenInternal() const; // For compositing
@@ -506,6 +510,7 @@ class Client
KDecoration* decoration;
Bridge* bridge;
int desk;
+ QStringList activityList;
bool buttonDown;
bool moveResizeMode;
bool move_faked_activity;
diff --git a/deleted.cpp b/deleted.cpp
index cde2c34bc2..6c1297ff00 100644
--- a/deleted.cpp
+++ b/deleted.cpp
@@ -67,6 +67,7 @@ void Deleted::copyToDeleted( Toplevel* c )
assert( dynamic_cast< Deleted* >( c ) == NULL );
Toplevel::copyToDeleted( c );
desk = c->desktop();
+ activityList = c->activities();
contentsRect = QRect( c->clientPos(), c->clientSize());
transparent_rect = c->transparentRect();
if( WinInfo* cinfo = dynamic_cast< WinInfo* >( info ))
@@ -111,6 +112,11 @@ int Deleted::desktop() const
return desk;
}
+QStringList Deleted::activities() const
+ {
+ return activityList;
+ }
+
QPoint Deleted::clientPos() const
{
return contentsRect.topLeft();
diff --git a/deleted.h b/deleted.h
index 94fda09b3f..e7f70b1511 100644
--- a/deleted.h
+++ b/deleted.h
@@ -37,6 +37,7 @@ class Deleted
void unrefWindow( bool delay = false );
void discard( allowed_t );
virtual int desktop() const;
+ virtual QStringList activities() const;
virtual QPoint clientPos() const;
virtual QSize clientSize() const;
virtual QRect transparentRect() const;
@@ -58,6 +59,7 @@ class Deleted
int delete_refcount;
double window_opacity;
int desk;
+ QStringList activityList;
QRect contentsRect; // for clientPos()/clientSize()
QRect transparent_rect;
diff --git a/toplevel.h b/toplevel.h
index b8ebfc268e..1348b8e595 100644
--- a/toplevel.h
+++ b/toplevel.h
@@ -28,6 +28,8 @@ along with this program. If not, see .
#include
#include
+#include "kactivityconsumer.h"
+
#include "utils.h"
#include "workspace.h"
@@ -90,9 +92,13 @@ class Toplevel
bool isDNDIcon() const;
virtual int desktop() const = 0;
+ virtual QStringList activities() const = 0;
bool isOnDesktop( int d ) const;
+ bool isOnActivity( const QString &activity ) const;
bool isOnCurrentDesktop() const;
+ bool isOnCurrentActivity() const;
bool isOnAllDesktops() const;
+ bool isOnAllActivities() const;
QByteArray windowRole() const;
QByteArray sessionId();
@@ -386,16 +392,31 @@ inline bool Toplevel::isOnAllDesktops() const
return desktop() == NET::OnAllDesktops;
}
+inline bool Toplevel::isOnAllActivities() const
+ {
+ return activities().isEmpty();
+ }
+
inline bool Toplevel::isOnDesktop( int d ) const
{
return desktop() == d || /*desk == 0 ||*/ isOnAllDesktops();
}
+inline bool Toplevel::isOnActivity( const QString &activity ) const
+ {
+ return activities().isEmpty() || activities().contains(activity);
+ }
+
inline bool Toplevel::isOnCurrentDesktop() const
{
return isOnDesktop( workspace()->currentDesktop());
}
+inline bool Toplevel::isOnCurrentActivity() const
+ {
+ return isOnActivity( KActivityConsumer().currentActivity());
+ }
+
inline QByteArray Toplevel::resourceName() const
{
return resource_name; // it is always lowercase
diff --git a/unmanaged.cpp b/unmanaged.cpp
index 31ceb7187f..5c13cf0a6d 100644
--- a/unmanaged.cpp
+++ b/unmanaged.cpp
@@ -112,6 +112,11 @@ int Unmanaged::desktop() const
return NET::OnAllDesktops; // TODO for some window types should be the current desktop?
}
+QStringList Unmanaged::activities() const
+ {
+ return QStringList();
+ }
+
QPoint Unmanaged::clientPos() const
{
return QPoint( 0, 0 ); // unmanaged windows don't have decorations
diff --git a/unmanaged.h b/unmanaged.h
index 708d339d0b..e92a6afd90 100644
--- a/unmanaged.h
+++ b/unmanaged.h
@@ -39,6 +39,7 @@ class Unmanaged
bool track( Window w );
static void deleteUnmanaged( Unmanaged* c, allowed_t );
virtual int desktop() const;
+ virtual QStringList activities() const;
virtual QPoint clientPos() const;
virtual QSize clientSize() const;
virtual QRect transparentRect() const;
diff --git a/useractions.cpp b/useractions.cpp
index 0a6672e832..7de07d89a0 100644
--- a/useractions.cpp
+++ b/useractions.cpp
@@ -33,6 +33,8 @@ along with this program. If not, see .
#include "tile.h"
#include "tilinglayout.h"
+#include "kactivityinfo.h"
+
#include
#include
#include
@@ -237,6 +239,7 @@ void Workspace::discardPopup()
delete popup;
popup = NULL;
desk_popup = NULL;
+ activity_popup = NULL;
switch_to_tab_popup = NULL;
add_tabs_popup = NULL;
}
@@ -268,6 +271,17 @@ void Workspace::clientPopupAboutToShow()
{
initDesktopPopup();
}
+ QStringList act = activityController_.availableActivities();
+ kDebug() << "activities:" << act.size();
+ if ( act.size() < 2 )
+ {
+ delete activity_popup;
+ activity_popup = 0;
+ }
+ else
+ {
+ initActivityPopup();
+ }
mResizeOpAction->setEnabled( active_popup_client->isResizable() );
mMoveOpAction->setEnabled( active_popup_client->isMovableAcrossScreens() );
@@ -455,6 +469,29 @@ void Workspace::initDesktopPopup()
action->setText( i18n("To &Desktop") );
}
+/*!
+ Creates activity popup.
+ I'm going with checkable ones instead of "copy to" and "move to" menus; I *think* it's an easier way.
+ Oh, and an 'all' option too of course
+ */
+void Workspace::initActivityPopup()
+ {
+ if (activity_popup)
+ return;
+
+ activity_popup = new QMenu( popup );
+ activity_popup->setFont(KGlobalSettings::menuFont());
+ connect( activity_popup, SIGNAL( triggered(QAction*) ),
+ this, SLOT( slotToggleOnActivity(QAction*) ) );
+ connect( activity_popup, SIGNAL( aboutToShow() ),
+ this, SLOT( activityPopupAboutToShow() ) );
+
+ QAction *action = activity_popup->menuAction();
+ // set it as the first item
+ popup->insertAction( trans_popup ? trans_popup->menuAction() : mMoveOpAction, action);
+ action->setText( i18n("Ac&tivities") ); //FIXME is that a good string?
+ }
+
/*!
Adjusts the desktop popup to the current values and the location of
the popup client.
@@ -489,6 +526,37 @@ void Workspace::desktopPopupAboutToShow()
}
}
+/*!
+ Adjusts the activity popup to the current values and the location of
+ the popup client.
+ */
+void Workspace::activityPopupAboutToShow()
+ {
+ if ( !activity_popup )
+ return;
+
+ activity_popup->clear();
+ QAction *action = activity_popup->addAction( i18n("&All Activities") );
+ action->setData( 0 );
+ action->setCheckable( true );
+
+ if ( active_popup_client && active_popup_client->isOnAllActivities() )
+ action->setChecked( true );
+ activity_popup->addSeparator();
+
+ foreach (const QString &activity, activityController_.availableActivities()) {
+ QString name = KActivityInfo::name(activity);
+ name.replace('&', "&&");
+ action = activity_popup->addAction( name );
+ action->setData( activity );
+ action->setCheckable( true );
+
+ if ( active_popup_client &&
+ !active_popup_client->isOnAllActivities() && active_popup_client->isOnActivity(activity) )
+ action->setChecked( true );
+ }
+ }
+
void Workspace::closeActivePopup()
{
if( active_popup )
@@ -1505,6 +1573,26 @@ void Workspace::slotSendToDesktop( QAction *action )
}
+/*!
+ Toggles whether the popup client is on the \a activity
+
+ Internal slot for the window operation menu
+ */
+void Workspace::slotToggleOnActivity( QAction *action )
+ {
+ QString activity = action->data().toString();
+ if ( !active_popup_client )
+ return;
+ if ( activity.isEmpty() )
+ { // the 'on_all_activities' menu entry
+ active_popup_client->setOnAllActivities( !active_popup_client->isOnAllActivities());
+ return;
+ }
+
+ toggleClientOnActivity( active_popup_client, activity, false );
+
+ }
+
/*!
Switches to the nearest window in given direction
*/
diff --git a/workspace.cpp b/workspace.cpp
index bdc7863a1b..1509af6ea3 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -125,6 +125,7 @@ Workspace::Workspace( bool restore )
, advanced_popup( 0 )
, trans_popup( 0 )
, desk_popup( 0 )
+ , activity_popup( 0 )
, add_tabs_popup( 0 )
, switch_to_tab_popup( 0 )
, keys( 0 )
@@ -240,6 +241,8 @@ Workspace::Workspace( bool restore )
connect( Kephal::Screens::self(), SIGNAL( screenRemoved(int) ), SLOT( desktopResized() ));
connect( Kephal::Screens::self(), SIGNAL( screenResized(Kephal::Screen*, QSize, QSize) ), SLOT( desktopResized() ));
connect( Kephal::Screens::self(), SIGNAL( screenMoved(Kephal::Screen*, QPoint, QPoint) ), SLOT( desktopResized() ));
+
+ connect( &activityController_, SIGNAL( currentActivityChanged(QString) ), SLOT( updateCurrentActivity(QString) ));
}
void Workspace::init()
@@ -1514,6 +1517,135 @@ bool Workspace::setCurrentDesktop( int new_desktop )
return true;
}
+/**
+ * Updates the current activity when it changes
+ * do *not* call this directly; it does not set the activity.
+ *
+ * Shows/Hides windows according to the stacking order
+ */
+void Workspace::updateCurrentActivity(const QString &new_activity)
+ {
+
+ //closeActivePopup();
+ ++block_focus;
+ // TODO: Q_ASSERT( block_stacking_updates == 0 ); // Make sure stacking_order is up to date
+ StackingUpdatesBlocker blocker( this );
+
+ if ( new_activity != activity_ )
+ {
+ ++block_showing_desktop; //FIXME should I be using that?
+ // Optimized Desktop switching: unmapping done from back to front
+ // mapping done from front to back => less exposure events
+ //Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
+
+ ObscuringWindows obs_wins;
+
+ QString old_activity = activity_;
+ activity_ = new_activity;
+
+ for( ClientList::ConstIterator it = stacking_order.constBegin();
+ it != stacking_order.constEnd();
+ ++it )
+ if( !(*it)->isOnActivity( new_activity ) && (*it) != movingClient )
+ {
+ if( (*it)->isShown( true ) && (*it)->isOnActivity( old_activity ))
+ obs_wins.create( *it );
+ (*it)->updateVisibility();
+ }
+
+ // Now propagate the change, after hiding, before showing
+ //rootInfo->setCurrentDesktop( currentDesktop() );
+
+ /* TODO someday enable dragging windows to other activities
+ if( movingClient && !movingClient->isOnDesktop( new_desktop ))
+ {
+ int old_desktop = movingClient->desktop();
+ movingClient->setDesktop( new_desktop );
+ if( tilingEnabled() )
+ {
+ notifyWindowDesktopChanged( movingClient, old_desktop );
+ }
+ }
+ */
+
+ for( int i = stacking_order.size() - 1; i >= 0 ; --i )
+ if( stacking_order.at( i )->isOnActivity( new_activity ))
+ stacking_order.at( i )->updateVisibility();
+
+ --block_showing_desktop;
+ //FIXME not sure if I should do this either
+ if( showingDesktop() ) // Do this only after desktop change to avoid flicker
+ resetShowingDesktop( false );
+ }
+
+ // Restore the focus on this desktop
+ --block_focus;
+ Client* c = 0;
+
+ //FIXME below here is a lot of focuschain stuff, probably all wrong now
+ if( options->focusPolicyIsReasonable() )
+ { // Search in focus chain
+ if( movingClient != NULL && active_client == movingClient &&
+ focus_chain[currentDesktop()].contains( active_client ) &&
+ active_client->isShown( true ) && active_client->isOnCurrentDesktop())
+ c = active_client; // The requestFocus below will fail, as the client is already active
+ if( !c )
+ {
+ for( int i = focus_chain[currentDesktop()].size() - 1; i >= 0; --i )
+ {
+ if( focus_chain[currentDesktop()].at( i )->isShown( false ) &&
+ focus_chain[currentDesktop()].at( i )->isOnCurrentDesktop() )
+ {
+ c = focus_chain[currentDesktop()].at( i );
+ break;
+ }
+ }
+ }
+ }
+ // If "unreasonable focus policy" and active_client is on_all_desktops and
+ // under mouse (Hence == old_active_client), conserve focus.
+ // (Thanks to Volker Schatz )
+ else if( active_client && active_client->isShown( true ) && active_client->isOnCurrentDesktop() )
+ c = active_client;
+
+ if( c == NULL && !desktops.isEmpty() )
+ c = findDesktop( true, currentDesktop() );
+
+ if( c != active_client )
+ setActiveClient( NULL, Allowed );
+
+ if ( c )
+ requestFocus( c );
+ else if( !desktops.isEmpty() )
+ requestFocus( findDesktop( true, currentDesktop() ));
+ else
+ focusToNull();
+
+ updateCurrentTopMenu();
+
+ // Update focus chain:
+ // If input: chain = { 1, 2, 3, 4 } and currentDesktop() = 3,
+ // Output: chain = { 3, 1, 2, 4 }.
+ //kDebug(1212) << QString("Switching to desktop #%1, at focus_chain index %2\n")
+ // .arg(currentDesktop()).arg(desktop_focus_chain.find( currentDesktop() ));
+ for( int i = desktop_focus_chain.indexOf( currentDesktop() ); i > 0; i-- )
+ desktop_focus_chain[i] = desktop_focus_chain[i-1];
+ desktop_focus_chain[0] = currentDesktop();
+
+ //QString s = "desktop_focus_chain[] = { ";
+ //for( uint i = 0; i < desktop_focus_chain.size(); i++ )
+ // s += QString::number( desktop_focus_chain[i] ) + ", ";
+ //kDebug( 1212 ) << s << "}\n";
+
+ // Not for the very first time, only if something changed and there are more than 1 desktops
+
+ //if( effects != NULL && old_desktop != 0 && old_desktop != new_desktop )
+ // static_cast( effects )->desktopChanged( old_desktop );
+ if( compositing())
+ addRepaintFull();
+
+ }
+
/**
* Called only from D-Bus
*/
@@ -1631,6 +1763,46 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate )
updateClientArea();
}
+/**
+ * Adds/removes client \a c to/from \a desk.
+ *
+ * Takes care of transients as well.
+ */
+void Workspace::toggleClientOnActivity( Client* c, const QString &activity, bool dont_activate )
+ {
+ //int old_desktop = c->desktop();
+ bool was_on_activity = c->isOnActivity(activity);
+ bool was_on_all = c->isOnAllActivities();
+ //note: all activities === no activities
+ bool enable = was_on_all || !was_on_activity;
+ c->setOnActivity( activity, enable );
+ if( c->isOnActivity(activity) == was_on_activity && c->isOnAllActivities() == was_on_all ) // No change
+ return;
+
+ if( c->isOnActivity( activityController_.currentActivity() ))
+ {
+ if( c->wantsTabFocus() && options->focusPolicyIsReasonable() &&
+ !was_on_activity && // for stickyness changes
+ //FIXME not sure if the line above refers to the correct activity
+ !dont_activate )
+ requestFocus( c );
+ else
+ restackClientUnderActive( c );
+ }
+ else
+ raiseClient( c );
+
+ //notifyWindowDesktopChanged( c, old_desktop );
+ //FIXME does tiling break?
+
+ ClientList transients_stacking_order = ensureStackingOrder( c->transients() );
+ for( ClientList::ConstIterator it = transients_stacking_order.constBegin();
+ it != transients_stacking_order.constEnd();
+ ++it )
+ toggleClientOnActivity( *it, activity, dont_activate );
+ updateClientArea();
+ }
+
int Workspace::numScreens() const
{
if( !options->xineramaEnabled )
diff --git a/workspace.h b/workspace.h
index 65e6516286..095e24eb6f 100644
--- a/workspace.h
+++ b/workspace.h
@@ -32,6 +32,8 @@ along with this program. If not, see .
#include
#include
+#include "kactivitycontroller.h"
+
#include "plugins.h"
#include "utils.h"
#include "kdecoration.h"
@@ -312,8 +314,11 @@ class Workspace : public QObject, public KDecorationDefines
QSize desktopGridSize_;
int* desktopGrid_;
int currentDesktop_;
+ QString activity_;
bool desktopLayoutDynamicity_;
+ KActivityController activityController_;
+
bool tilingEnabled_;
// Each tilingLayout is for one virtual desktop.
// The length is always one more than the number of
@@ -373,6 +378,7 @@ class Workspace : public QObject, public KDecorationDefines
bool only_normal = true ) const;
Client* findDesktop( bool topmost, int desktop ) const;
void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
+ void toggleClientOnActivity( Client* c, const QString &activity, bool dont_activate );
void windowToPreviousDesktop( Client* c );
void windowToNextDesktop( Client* c );
void sendClientToScreen( Client* c, int screen );
@@ -722,8 +728,10 @@ class Workspace : public QObject, public KDecorationDefines
void slotAddToTabGroup( QAction* ); // Add client to a group
void slotSwitchToTab( QAction* ); // Change the tab
void desktopPopupAboutToShow();
+ void activityPopupAboutToShow();
void clientPopupAboutToShow();
void slotSendToDesktop( QAction* );
+ void slotToggleOnActivity( QAction* );
void clientPopupActivated( QAction* );
void configureWM();
void desktopResized();
@@ -747,6 +755,8 @@ class Workspace : public QObject, public KDecorationDefines
void resetCursorPosTime();
void delayedCheckUnredirect();
+ void updateCurrentActivity(const QString &activity);
+
protected:
bool keyPressMouseEmulation( XKeyEvent& ev );
@@ -758,6 +768,7 @@ class Workspace : public QObject, public KDecorationDefines
void initShortcuts();
void readShortcuts();
void initDesktopPopup();
+ void initActivityPopup();
void discardPopup();
void setupWindowShortcut( Client* c );
void checkCursorPos();
@@ -930,6 +941,7 @@ class Workspace : public QObject, public KDecorationDefines
QMenu* trans_popup;
QActionGroup* trans_popup_group;
QMenu* desk_popup;
+ QMenu* activity_popup;
QMenu* add_tabs_popup; // Menu to add the group to other group
QMenu* switch_to_tab_popup; // Menu to change tab