Split out Activities related code from Workspace

All activities related code moves into new singleton class Activities.
This class gets only included into the build if the build option is
enabled which means there are less ifdefs all over the code and it also
handles better the moc doesn't like ifdef case.

The class holds the list of open and all activites, the current and the
previous activity and the KActivities::Controller. It also emits the
signals for any activities related changes.

Workspace still contains some activities related code. That is the
adjustment on change of current activity. Nevertheless the code looks
much cleaner now and does not contain the confusing naming conflict with
takeActivity() which existed before.

In all the places where Activities got used the code got adjusted and
quite often the ifdef got added with a fallback for the disabled case.
This commit is contained in:
Martin Gräßlin 2013-04-04 16:14:12 +02:00
parent 34d0df3e0a
commit da85b5fdc7
17 changed files with 602 additions and 371 deletions

View file

@ -180,6 +180,13 @@ if(KWIN_BUILD_KAPPMENU)
)
endif()
if(KWIN_BUILD_ACTIVITIES)
set(
kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS}
activities.cpp
)
endif()
if(KWIN_HAVE_EGL)
set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} eglonxbackend.cpp)
endif()

View file

@ -30,6 +30,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "cursor.h"
#include "focuschain.h"
#include "workspace.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include <fixx11h.h>
#include <kxerrorhandler.h>
@ -294,7 +297,7 @@ void Workspace::activateClient(Client* c, bool force)
if (!c->isOnCurrentActivity()) {
++block_focus;
//DBUS!
activityController_.setCurrentActivity(c->activities().first()); //first isn't necessarily best, but it's easiest
Activities::self()->setCurrent(c->activities().first()); //first isn't necessarily best, but it's easiest
--block_focus;
}
#endif

292
activities.cpp Normal file
View file

@ -0,0 +1,292 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "activities.h"
// KWin
#include "client.h"
#include "workspace.h"
// KDE
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
#include <KDE/KGlobal>
#include <KActivities/Controller>
// Qt
#include <QtConcurrentRun>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QFutureWatcher>
namespace KWin
{
Activities *Activities::s_self = NULL;
Activities *Activities::create(QObject *parent)
{
Q_ASSERT(!s_self);
s_self = new Activities(parent);
return s_self;
}
Activities::Activities(QObject *parent)
: QObject(parent)
, m_controller(new KActivities::Controller(this))
{
connect(m_controller, SIGNAL(activityRemoved(QString)), SLOT(slotRemoved(QString)));
connect(m_controller, SIGNAL(activityRemoved(QString)), SIGNAL(removed(QString)));
connect(m_controller, SIGNAL(activityAdded(QString)), SLOT(slotAdded(QString)));
connect(m_controller, SIGNAL(activityAdded(QString)), SIGNAL(added(QString)));
connect(m_controller, SIGNAL(currentActivityChanged(QString)), SLOT(slotCurrentChanged(QString)));
}
Activities::~Activities()
{
s_self = NULL;
}
void Activities::setCurrent(const QString &activity)
{
m_controller->setCurrentActivity(activity);
}
void Activities::slotCurrentChanged(const QString &newActivity)
{
if (m_current == newActivity) {
return;
}
m_previous = m_current;
m_current = newActivity;
emit currentChanged(newActivity);
}
void Activities::slotAdded(const QString &activity)
{
m_all << activity;
}
void Activities::slotRemoved(const QString &activity)
{
m_all.removeOne(activity);
foreach (Client * client, Workspace::self()->clientList()) {
client->setOnActivity(activity, false);
}
//toss out any session data for it
KConfigGroup cg(KGlobal::config(), QString("SubSession: ") + activity);
cg.deleteGroup();
}
void Activities::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;
Workspace *ws = Workspace::self();
if (c->isOnCurrentActivity()) {
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)
ws->requestFocus(c);
else
ws->restackClientUnderActive(c);
} else
ws->raiseClient(c);
//notifyWindowDesktopChanged( c, old_desktop );
ClientList transients_stacking_order = ws->ensureStackingOrder(c->transients());
for (ClientList::ConstIterator it = transients_stacking_order.constBegin();
it != transients_stacking_order.constEnd();
++it)
toggleClientOnActivity(*it, activity, dont_activate);
ws->updateClientArea();
}
bool Activities::start(const QString &id)
{
Workspace *ws = Workspace::self();
if (ws->sessionSaving()) {
return false; //ksmserver doesn't queue requests (yet)
}
if (!m_all.contains(id)) {
return false; //bogus id
}
ws->loadSubSessionInfo(id);
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
ksmserver.asyncCall("restoreSubSession", id);
} else {
kDebug(1212) << "couldn't get ksmserver interface";
return false;
}
return true;
}
bool Activities::stop(const QString &id)
{
if (Workspace::self()->sessionSaving()) {
return false; //ksmserver doesn't queue requests (yet)
//FIXME what about session *loading*?
}
//ugly hack to avoid dbus deadlocks
update(true, false);
QMetaObject::invokeMethod(this, "reallyStop", Qt::QueuedConnection, Q_ARG(QString, id));
//then lie and assume it worked.
return true;
}
void Activities::reallyStop(const QString &id)
{
Workspace *ws = Workspace::self();
if (ws->sessionSaving())
return; //ksmserver doesn't queue requests (yet)
kDebug(1212) << id;
QSet<QByteArray> saveSessionIds;
QSet<QByteArray> dontCloseSessionIds;
const ClientList &clients = ws->clientList();
for (ClientList::const_iterator it = clients.constBegin(); it != clients.constEnd(); ++it) {
const Client* c = (*it);
const QByteArray sessionId = c->sessionId();
if (sessionId.isEmpty()) {
continue; //TODO support old wm_command apps too?
}
//kDebug() << sessionId;
//if it's on the activity that's closing, it needs saving
//but if a process is on some other open activity, I don't wanna close it yet
//this is, of course, complicated by a process having many windows.
if (c->isOnAllActivities()) {
dontCloseSessionIds << sessionId;
continue;
}
const QStringList activities = c->activities();
foreach (const QString & activityId, activities) {
if (activityId == id) {
saveSessionIds << sessionId;
} else if (m_running.contains(activityId)) {
dontCloseSessionIds << sessionId;
}
}
}
ws->storeSubSession(id, saveSessionIds);
QStringList saveAndClose;
QStringList saveOnly;
foreach (const QByteArray & sessionId, saveSessionIds) {
if (dontCloseSessionIds.contains(sessionId)) {
saveOnly << sessionId;
} else {
saveAndClose << sessionId;
}
}
kDebug(1212) << "saveActivity" << id << saveAndClose << saveOnly;
//pass off to ksmserver
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
ksmserver.asyncCall("saveSubSession", id, saveAndClose, saveOnly);
} else {
kDebug(1212) << "couldn't get ksmserver interface";
}
}
//BEGIN threaded activity list fetching
typedef QPair<QStringList*, QStringList> AssignedList;
typedef QPair<QString, QStringList> CurrentAndList;
static AssignedList
fetchActivityList(KActivities::Controller *controller, QStringList *target, bool running) // could be member function, but actually it's much simpler this way
{
return AssignedList(target, running ? controller->listActivities(KActivities::Info::Running) :
controller->listActivities());
}
static CurrentAndList
fetchActivityListAndCurrent(KActivities::Controller *controller)
{
QStringList l = controller->listActivities();
QString c = controller->currentActivity();
return CurrentAndList(c, l);
}
void Activities::update(bool running, bool updateCurrent, QObject *target, QString slot)
{
if (updateCurrent) {
QFutureWatcher<CurrentAndList>* watcher = new QFutureWatcher<CurrentAndList>;
connect( watcher, SIGNAL(finished()), SLOT(handleReply()) );
if (!slot.isEmpty()) {
watcher->setProperty("activityControllerCallback", slot); // "activity reply trigger"
watcher->setProperty("activityControllerCallbackTarget", qVariantFromValue((void*)target));
}
watcher->setFuture(QtConcurrent::run(fetchActivityListAndCurrent, m_controller));
} else {
QFutureWatcher<AssignedList>* watcher = new QFutureWatcher<AssignedList>;
connect(watcher, SIGNAL(finished()), SLOT(handleReply()));
if (!slot.isEmpty()) {
watcher->setProperty("activityControllerCallback", slot); // "activity reply trigger"
watcher->setProperty("activityControllerCallbackTarget", qVariantFromValue((void*)target));
}
QStringList *target = running ? &m_running : &m_all;
watcher->setFuture(QtConcurrent::run(fetchActivityList, m_controller, target, running));
}
}
void Activities::handleReply()
{
QObject *watcherObject = 0;
if (QFutureWatcher<AssignedList>* watcher = dynamic_cast< QFutureWatcher<AssignedList>* >(sender())) {
// we carry over the to-be-updated StringList member as pointer in the threaded return
*(watcher->result().first) = watcher->result().second;
watcherObject = watcher;
}
if (!watcherObject) {
if (QFutureWatcher<CurrentAndList>* watcher = dynamic_cast< QFutureWatcher<CurrentAndList>* >(sender())) {
m_all = watcher->result().second;
slotCurrentChanged(watcher->result().first);
watcherObject = watcher;
}
}
if (watcherObject) {
QString slot = watcherObject->property("activityControllerCallback").toString();
QObject *target = static_cast<QObject*>(watcherObject->property("activityControllerCallbackTarget").value<void*>());
watcherObject->deleteLater(); // has done it's job
if (!slot.isEmpty())
QMetaObject::invokeMethod(target, slot.toAscii().data(), Qt::DirectConnection);
}
}
//END threaded activity list fetching
} // namespace

129
activities.h Normal file
View file

@ -0,0 +1,129 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_ACTIVITIES_H
#define KWIN_ACTIVITIES_H
#include <QObject>
#include <QStringList>
namespace KActivities {
class Controller;
}
namespace KWin
{
class Client;
class Activities : public QObject
{
Q_OBJECT
public:
~Activities();
bool stop(const QString &id);
bool start(const QString &id);
void update(bool running, bool updateCurrent, QObject *target = NULL, QString slot = QString());
void setCurrent(const QString &activity);
/**
* Adds/removes client \a c to/from \a activity.
*
* Takes care of transients as well.
*/
void toggleClientOnActivity(Client* c, const QString &activity, bool dont_activate);
const QStringList &running() const;
const QStringList &all() const;
const QString &current() const;
const QString &previous() const;
static Activities *self();
static Activities *create(QObject *parent);
Q_SIGNALS:
/**
* This signal is emitted when the global
* activity is changed
* @param id id of the new current activity
*/
void currentChanged(const QString &id);
/**
* This signal is emitted when a new activity is added
* @param id id of the new activity
*/
void added(const QString &id);
/**
* This signal is emitted when the activity
* is removed
* @param id id of the removed activity
*/
void removed(const QString &id);
private Q_SLOTS:
void slotRemoved(const QString &activity);
void slotAdded(const QString &activity);
void slotCurrentChanged(const QString &newActivity);
void reallyStop(const QString &id); //dbus deadlocks suck
void handleReply();
private:
explicit Activities(QObject *parent);
QStringList m_running;
QStringList m_all;
QString m_current;
QString m_previous;
KActivities::Controller *m_controller;
static Activities *s_self;
};
inline
Activities *Activities::self()
{
return s_self;
}
inline
const QStringList &Activities::all() const
{
return m_all;
}
inline
const QString &Activities::current() const
{
return m_current;
}
inline
const QString &Activities::previous() const
{
return m_previous;
}
inline
const QStringList &Activities::running() const
{
return m_running;
}
}
#endif // KWIN_ACTIVITIES_H

View file

@ -40,6 +40,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <signal.h>
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include "bridge.h"
#include "client_machine.h"
#include "composite.h"
@ -1511,17 +1514,22 @@ void Client::setDesktop(int desktop)
*/
void Client::setOnActivity(const QString &activity, bool enable)
{
#ifdef KWIN_BUILD_ACTIVITIES
QStringList newActivitiesList = activities();
if (newActivitiesList.contains(activity) == enable) //nothing to do
return;
if (enable) {
QStringList allActivities = workspace()->activityList();
QStringList allActivities = Activities::self()->all();
if (!allActivities.contains(activity)) //bogus ID
return;
newActivitiesList.append(activity);
} else
newActivitiesList.removeOne(activity);
setOnActivities(newActivitiesList);
#else
Q_UNUSED(activity)
Q_UNUSED(enable)
#endif
}
/**
@ -1531,11 +1539,12 @@ void Client::setOnActivity(const QString &activity, bool enable)
#define NULL_UUID "00000000-0000-0000-0000-000000000000"
void Client::setOnActivities(QStringList newActivitiesList)
{
#ifdef KWIN_BUILD_ACTIVITIES
QString joinedActivitiesList = newActivitiesList.join(",");
joinedActivitiesList = rules()->checkActivity(joinedActivitiesList, false);
newActivitiesList = joinedActivitiesList.split(',', QString::SkipEmptyParts);
QStringList allActivities = workspace()->activityList();
QStringList allActivities = Activities::self()->all();
if ( newActivitiesList.isEmpty() ||
(newActivitiesList.count() > 1 && newActivitiesList.count() == allActivities.count()) ||
(newActivitiesList.count() == 1 && newActivitiesList.at(0) == NULL_UUID)) {
@ -1553,6 +1562,9 @@ void Client::setOnActivities(QStringList newActivitiesList)
}
updateActivities(false);
#else
Q_UNUSED(newActivitiesList)
#endif
}
void Client::blockActivityUpdates(bool b)
@ -1635,14 +1647,16 @@ void Client::setOnAllDesktops(bool b)
*/
void Client::setOnAllActivities(bool on)
{
#ifdef KWIN_BUILD_ACTIVITIES
if (on == isOnAllActivities())
return;
if (on) {
setOnActivities(QStringList());
} else {
setOnActivity(Workspace::self()->currentActivity(), true);
setOnActivity(Activities::self()->current(), true);
}
#endif
}
/**
@ -2382,6 +2396,7 @@ QPixmap* kwin_get_menu_pix_hack()
void Client::checkActivities()
{
#ifdef KWIN_BUILD_ACTIVITIES
QStringList newActivitiesList;
QByteArray prop = getStringProperty(window(), atoms->activities);
activitiesDefined = !prop.isEmpty();
@ -2408,7 +2423,7 @@ void Client::checkActivities()
return; //expected change, it's ok.
//otherwise, somebody else changed it. we need to validate before reacting
QStringList allActivities = workspace()->activityList();
QStringList allActivities = Activities::self()->all();
if (allActivities.isEmpty()) {
kDebug() << "no activities!?!?";
//don't touch anything, there's probably something bad going on and we don't wanna make it worse
@ -2421,6 +2436,7 @@ void Client::checkActivities()
}
}
setOnActivities(newActivitiesList);
#endif
}
#undef NULL_UUID

View file

@ -29,6 +29,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinadaptor.h"
#include "workspace.h"
#include "virtualdesktops.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
// Qt
#include <QDBusServiceWatcher>
@ -122,17 +125,23 @@ WRAP(bool, waitForCompositingSetup)
#undef WRAP
// wrap returning methods with one argument to Workspace
#define WRAP( rettype, name, argtype ) \
rettype DBusInterface::name( argtype arg ) \
{\
return Workspace::self()->name(arg); \
bool DBusInterface::startActivity(const QString &in0)
{
#ifdef KWIN_BUILD_ACTIVITIES
return Activities::self()->start(in0);
#else
return false;
#endif
}
WRAP(bool, startActivity, const QString &)
WRAP(bool, stopActivity, const QString &)
#undef WRAP
bool DBusInterface::stopActivity(const QString &in0)
{
#ifdef KWIN_BUILD_ACTIVITIES
return Activities::self()->stop(in0);
#else
return false;
#endif
}
void DBusInterface::doNotManage(const QString &name)
{

View file

@ -22,6 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "effects.h"
#include "effectsadaptor.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include "deleted.h"
#include "client.h"
#include "cursor.h"
@ -229,9 +232,12 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
connect(Cursor::self(), SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)),
SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)));
connect(ws, SIGNAL(propertyNotify(long)), this, SLOT(slotPropertyNotify(long)));
connect(ws, SIGNAL(activityAdded(QString)), SIGNAL(activityAdded(QString)));
connect(ws, SIGNAL(activityRemoved(QString)), SIGNAL(activityRemoved(QString)));
connect(ws, SIGNAL(currentActivityChanged(QString)), SIGNAL(currentActivityChanged(QString)));
#ifdef KWIN_BUILD_ACTIVITIES
Activities *activities = Activities::self();
connect(activities, SIGNAL(added(QString)), SIGNAL(activityAdded(QString)));
connect(activities, SIGNAL(removed(QString)), SIGNAL(activityRemoved(QString)));
connect(activities, SIGNAL(currentChanged(QString)), SIGNAL(currentActivityChanged(QString)));
#endif
connect(ws, SIGNAL(stackingOrderChanged()), SIGNAL(stackingOrderChanged()));
#ifdef KWIN_BUILD_TABBOX
connect(ws->tabBox(), SIGNAL(tabBoxAdded(int)), SIGNAL(tabBoxAdded(int)));
@ -824,7 +830,11 @@ void EffectsHandlerImpl::setShowingDesktop(bool showing)
QString EffectsHandlerImpl::currentActivity() const
{
return Workspace::self()->currentActivity();
#ifdef KWIN_BUILD_ACTIVITIES
return Activities::self()->current();
#else
return QString();
#endif
}
int EffectsHandlerImpl::currentDesktop() const

View file

@ -27,6 +27,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kglobal.h>
#include <X11/extensions/shape.h>
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include "cursor.h"
#include "notifications.h"
#include <QX11Info>
@ -196,6 +199,7 @@ bool Client::manage(Window w, bool isMapped)
desk = info->desktop(); // Window had the initial desktop property, force it
if (desktop() == 0 && asn_valid && asn_data.desktop() != 0)
desk = asn_data.desktop();
#ifdef KWIN_BUILD_ACTIVITIES
if (!isMapped && !noborder && isNormalWindow() && !activitiesDefined) {
//a new, regular window, when we're not recovering from a crash,
//and it hasn't got an activity. let's try giving it the current one.
@ -204,8 +208,9 @@ bool Client::manage(Window w, bool isMapped)
//with a public API for setting windows to be on all activities.
//something like KWindowSystem::setOnAllActivities or
//KActivityConsumer::setOnAllActivities
setOnActivity(Workspace::self()->currentActivity(), true);
setOnActivity(Activities::self()->current(), true);
}
#endif
}
if (desk == 0) // Assume window wants to be visible on the current desktop

View file

@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "scripting_model.h"
#include "activities.h"
#include "client.h"
// Qt
#include <QDesktopWidget>
@ -311,7 +312,7 @@ AbstractLevel *AbstractLevel::create(const QList< ClientModel::LevelRestriction
switch (restriction) {
case ClientModel::ActivityRestriction: {
#ifdef KWIN_BUILD_ACTIVITIES
const QStringList &activities = Workspace::self()->activityList();
const QStringList &activities = Activities::self()->all();
for (QStringList::const_iterator it = activities.begin(); it != activities.end(); ++it) {
AbstractLevel *childLevel = create(childRestrictions, childrenRestrictions, model, currentLevel);
if (!childLevel) {
@ -402,8 +403,9 @@ ForkLevel::ForkLevel(const QList<ClientModel::LevelRestriction> &childRestrictio
connect(VirtualDesktopManager::self(), SIGNAL(countChanged(uint,uint)), SLOT(desktopCountChanged(uint,uint)));
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SLOT(screenCountChanged(int)));
#ifdef KWIN_BUILD_ACTIVITIES
connect(Workspace::self(), SIGNAL(activityAdded(QString)), SLOT(activityAdded(QString)));
connect(Workspace::self(), SIGNAL(activityRemoved(QString)), SLOT(activityRemoved(QString)));
Activities *activities = Activities::self();
connect(activities, SIGNAL(added(QString)), SLOT(activityAdded(QString)));
connect(activities, SIGNAL(removed(QString)), SLOT(activityRemoved(QString)));
#endif
}

View file

@ -23,6 +23,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../client.h"
#include "../outline.h"
#include "../virtualdesktops.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "../activities.h"
#endif
#include <QDesktopWidget>
@ -41,11 +44,14 @@ WorkspaceWrapper::WorkspaceWrapper(QObject* parent) : QObject(parent)
connect(vds, SIGNAL(countChanged(uint,uint)), SIGNAL(numberDesktopsChanged(uint)));
connect(vds, SIGNAL(layoutChanged(int,int)), SIGNAL(desktopLayoutChanged()));
connect(ws, SIGNAL(clientDemandsAttentionChanged(KWin::Client*,bool)), SIGNAL(clientDemandsAttentionChanged(KWin::Client*,bool)));
connect(ws, SIGNAL(currentActivityChanged(QString)), SIGNAL(currentActivityChanged(QString)));
connect(ws, SIGNAL(activityAdded(QString)), SIGNAL(activitiesChanged(QString)));
connect(ws, SIGNAL(activityAdded(QString)), SIGNAL(activityAdded(QString)));
connect(ws, SIGNAL(activityRemoved(QString)), SIGNAL(activitiesChanged(QString)));
connect(ws, SIGNAL(activityRemoved(QString)), SIGNAL(activityRemoved(QString)));
#ifdef KWIN_BUILD_ACTIVITIES
KWin::Activities *activities = KWin::Activities::self();
connect(activities, SIGNAL(currentChanged(QString)), SIGNAL(currentActivityChanged(QString)));
connect(activities, SIGNAL(added(QString)), SIGNAL(activitiesChanged(QString)));
connect(activities, SIGNAL(added(QString)), SIGNAL(activityAdded(QString)));
connect(activities, SIGNAL(removed(QString)), SIGNAL(activitiesChanged(QString)));
connect(activities, SIGNAL(removed(QString)), SIGNAL(activityRemoved(QString)));
#endif
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SIGNAL(numberScreensChanged(int)));
connect(QApplication::desktop(), SIGNAL(resized(int)), SIGNAL(screenResized(int)));
foreach (KWin::Client *client, ws->clientList()) {
@ -81,11 +87,27 @@ GETTER(KWin::Client*, activeClient)
GETTER(QList< KWin::Client* >, clientList)
GETTER(int, activeScreen)
GETTER(int, numScreens)
GETTER(QString, currentActivity)
GETTER(QStringList, activityList)
#undef GETTER
QString WorkspaceWrapper::currentActivity() const
{
#ifdef KWIN_BUILD_ACTIVITIES
return Activities::self()->current();
#else
return QString();
#endif
}
QStringList WorkspaceWrapper::activityList() const
{
#ifdef KWIN_BUILD_ACTIVITIES
return Activities::self()->all();
#else
return QStringList();
#endif
}
#define SLOTWRAPPER( name ) \
void WorkspaceWrapper::name( ) { \
Workspace::self()->name(); \

99
sm.cpp
View file

@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "workspace.h"
#include "client.h"
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QSocketNotifier>
#include <QSessionManager>
#include <kdebug.h>
@ -184,81 +182,6 @@ void Workspace::storeSubSession(const QString &name, QSet<QByteArray> sessionIds
//cg.writeEntry( "desktop", currentDesktop());
}
bool Workspace::stopActivity(const QString &id)
{
if (sessionSaving()) {
return false; //ksmserver doesn't queue requests (yet)
//FIXME what about session *loading*?
}
//ugly hack to avoid dbus deadlocks
#ifdef KWIN_BUILD_ACTIVITIES
updateActivityList(true, false);
#endif
QMetaObject::invokeMethod(this, "reallyStopActivity", Qt::QueuedConnection, Q_ARG(QString, id));
//then lie and assume it worked.
return true;
}
void Workspace::reallyStopActivity(const QString &id)
{
if (sessionSaving())
return; //ksmserver doesn't queue requests (yet)
kDebug() << id;
QSet<QByteArray> saveSessionIds;
QSet<QByteArray> dontCloseSessionIds;
for (ClientList::const_iterator it = clients.constBegin(); it != clients.constEnd(); ++it) {
const Client* c = (*it);
const QByteArray sessionId = c->sessionId();
if (sessionId.isEmpty()) {
continue; //TODO support old wm_command apps too?
}
//kDebug() << sessionId;
//if it's on the activity that's closing, it needs saving
//but if a process is on some other open activity, I don't wanna close it yet
//this is, of course, complicated by a process having many windows.
if (c->isOnAllActivities()) {
dontCloseSessionIds << sessionId;
continue;
}
const QStringList activities = c->activities();
foreach (const QString & activityId, activities) {
if (activityId == id) {
saveSessionIds << sessionId;
} else if (openActivities_.contains(activityId)) {
dontCloseSessionIds << sessionId;
}
}
}
storeSubSession(id, saveSessionIds);
QStringList saveAndClose;
QStringList saveOnly;
foreach (const QByteArray & sessionId, saveSessionIds) {
if (dontCloseSessionIds.contains(sessionId)) {
saveOnly << sessionId;
} else {
saveAndClose << sessionId;
}
}
kDebug() << "saveActivity" << id << saveAndClose << saveOnly;
//pass off to ksmserver
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
ksmserver.asyncCall("saveSubSession", id, saveAndClose, saveOnly);
} else {
kDebug() << "couldn't get ksmserver interface";
}
}
/*!
Loads the session information from the config file.
@ -318,28 +241,6 @@ void Workspace::loadSubSessionInfo(const QString &name)
addSessionInfo(cg);
}
bool Workspace::startActivity(const QString &id)
{
if (sessionSaving()) {
return false; //ksmserver doesn't queue requests (yet)
}
if (!allActivities_.contains(id)) {
return false; //bogus id
}
loadSubSessionInfo(id);
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
ksmserver.asyncCall("restoreSubSession", id);
} else {
kDebug() << "couldn't get ksmserver interface";
return false;
}
return true;
}
/*!
Returns a SessionInfo for client \a c. The returned session
info is removed from the storage. It's up to the caller to delete it.

View file

@ -29,6 +29,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "tabbox/tabboxconfig.h"
#include "tabbox/desktopchain.h"
// kwin
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include "client.h"
#include "effects.h"
#include "focuschain.h"
@ -73,7 +76,9 @@ TabBoxHandlerImpl::TabBoxHandlerImpl(TabBox* tabBox)
VirtualDesktopManager *vds = VirtualDesktopManager::self();
connect(vds, SIGNAL(countChanged(uint,uint)), m_desktopFocusChain, SLOT(resize(uint,uint)));
connect(vds, SIGNAL(currentChanged(uint,uint)), m_desktopFocusChain, SLOT(addDesktop(uint,uint)));
connect(Workspace::self(), SIGNAL(currentActivityChanged(QString)), m_desktopFocusChain, SLOT(useChain(QString)));
#ifdef KWIN_BUILD_ACTIVITIES
connect(Activities::self(), SIGNAL(currentChanged(QString)), m_desktopFocusChain, SLOT(useChain(QString)));
#endif
}
TabBoxHandlerImpl::~TabBoxHandlerImpl()

View file

@ -22,6 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kxerrorhandler.h>
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#include "atoms.h"
#include "client.h"
#include "client_machine.h"
@ -464,6 +467,15 @@ bool Toplevel::isDeleted() const
return false;
}
bool Toplevel::isOnCurrentActivity() const
{
#ifdef KWIN_BUILD_ACTIVITIES
return isOnActivity(Activities::self()->current());
#else
return true;
#endif
}
} // namespace
#include "toplevel.moc"

View file

@ -635,11 +635,6 @@ inline bool Toplevel::isOnCurrentDesktop() const
return isOnDesktop(VirtualDesktopManager::self()->current());
}
inline bool Toplevel::isOnCurrentActivity() const
{
return isOnActivity(Workspace::self()->currentActivity());
}
inline QByteArray Toplevel::resourceName() const
{
return resource_name; // it is always lowercase

View file

@ -43,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#include <KActivities/Info>
#endif
@ -421,7 +422,7 @@ void UserActionsMenu::menuAboutToShow()
initScreenPopup();
}
#ifdef KWIN_BUILD_ACTIVITIES
ws->updateActivityList(true, false, this, "showHideActivityMenu");
Activities::self()->update(true, false, this, "showHideActivityMenu");
#endif
m_resizeOperation->setEnabled(m_client.data()->isResizable());
@ -471,7 +472,7 @@ void UserActionsMenu::menuAboutToShow()
void UserActionsMenu::showHideActivityMenu()
{
#ifdef KWIN_BUILD_ACTIVITIES
const QStringList &openActivities_ = Workspace::self()->openActivities();
const QStringList &openActivities_ = Activities::self()->running();
kDebug() << "activities:" << openActivities_.size();
if (openActivities_.size() < 2) {
delete m_activityMenu;
@ -715,7 +716,7 @@ void UserActionsMenu::activityPopupAboutToShow()
action->setChecked(true);
m_activityMenu->addSeparator();
foreach (const QString &id, Workspace::self()->openActivities()) {
foreach (const QString &id, Activities::self()->running()) {
KActivities::Info activity(id);
QString name = activity.name();
name.replace('&', "&&");
@ -804,6 +805,7 @@ void UserActionsMenu::slotSendToScreen(QAction *action)
void UserActionsMenu::slotToggleOnActivity(QAction *action)
{
#ifdef KWIN_BUILD_ACTIVITIES
QString activity = action->data().toString();
if (m_client.isNull())
return;
@ -813,10 +815,11 @@ void UserActionsMenu::slotToggleOnActivity(QAction *action)
return;
}
Workspace::self()->toggleClientOnActivity(m_client.data(), activity, false);
Activities::self()->toggleClientOnActivity(m_client.data(), activity, false);
if (m_activityMenu && m_activityMenu->isVisible() && m_activityMenu->actions().count()) {
m_activityMenu->actions().at(0)->setChecked(m_client.data()->isOnAllActivities());
}
#endif
}
//****************************************

View file

@ -74,6 +74,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef KWIN_BUILD_SCRIPTING
#include "scripting/scripting.h"
#endif
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
#ifdef KWIN_BUILD_KAPPMENU
#include "appmenu.h"
#endif
@ -151,6 +154,11 @@ Workspace::Workspace(bool restore)
// start the cursor support
Cursor::create(this);
#ifdef KWIN_BUILD_ACTIVITIES
Activities *activities = Activities::create(this);
connect(activities, SIGNAL(currentChanged(QString)), SLOT(updateCurrentActivity(QString)));
#endif
// PluginMgr needs access to the config file, so we need to wait for it for finishing
reparseConfigFuture.waitForFinished();
options->loadConfig();
@ -231,15 +239,6 @@ Workspace::Workspace(bool restore)
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), &screenChangedTimer, SLOT(start()));
connect(QApplication::desktop(), SIGNAL(resized(int)), &screenChangedTimer, SLOT(start()));
#ifdef KWIN_BUILD_ACTIVITIES
connect(&activityController_, SIGNAL(currentActivityChanged(QString)), SLOT(updateCurrentActivity(QString)));
connect(&activityController_, SIGNAL(activityRemoved(QString)), SLOT(slotActivityRemoved(QString)));
connect(&activityController_, SIGNAL(activityRemoved(QString)), SIGNAL(activityRemoved(QString)));
connect(&activityController_, SIGNAL(activityAdded(QString)), SLOT(slotActivityAdded(QString)));
connect(&activityController_, SIGNAL(activityAdded(QString)), SIGNAL(activityAdded(QString)));
connect(&activityController_, SIGNAL(currentActivityChanged(QString)), SIGNAL(currentActivityChanged(QString)));
#endif
connect(&screenChangedTimer, SIGNAL(timeout()), SLOT(screenChangeTimeout()));
screenChangedTimer.setSingleShot(true);
screenChangedTimer.setInterval(100);
@ -393,7 +392,7 @@ void Workspace::init()
if (!VirtualDesktopManager::self()->setCurrent(initial_desktop))
VirtualDesktopManager::self()->setCurrent(1);
#ifdef KWIN_BUILD_ACTIVITIES
updateActivityList(false, true);
Activities::self()->update(false, true);
#endif
reconfigureTimer.setSingleShot(true);
@ -1139,80 +1138,6 @@ Client *Workspace::findClientToActivateOnDesktop(uint desktop)
return FocusChain::self()->getForActivation(desktop);
}
#ifdef KWIN_BUILD_ACTIVITIES
//BEGIN threaded activity list fetching
typedef QPair<QStringList*, QStringList> AssignedList;
typedef QPair<QString, QStringList> CurrentAndList;
static AssignedList
fetchActivityList(KActivities::Controller *controller, QStringList *target, bool running) // could be member function, but actually it's much simpler this way
{
return AssignedList(target, running ? controller->listActivities(KActivities::Info::Running) :
controller->listActivities());
}
static CurrentAndList
fetchActivityListAndCurrent(KActivities::Controller *controller)
{
QStringList l = controller->listActivities();
QString c = controller->currentActivity();
return CurrentAndList(c, l);
}
void Workspace::updateActivityList(bool running, bool updateCurrent, QObject *target, QString slot)
{
if (updateCurrent) {
QFutureWatcher<CurrentAndList>* watcher = new QFutureWatcher<CurrentAndList>;
connect( watcher, SIGNAL(finished()), SLOT(handleActivityReply()) );
if (!slot.isEmpty()) {
watcher->setProperty("activityControllerCallback", slot); // "activity reply trigger"
watcher->setProperty("activityControllerCallbackTarget", qVariantFromValue((void*)target));
}
watcher->setFuture(QtConcurrent::run(fetchActivityListAndCurrent, &activityController_ ));
} else {
QFutureWatcher<AssignedList>* watcher = new QFutureWatcher<AssignedList>;
connect(watcher, SIGNAL(finished()), SLOT(handleActivityReply()));
if (!slot.isEmpty()) {
watcher->setProperty("activityControllerCallback", slot); // "activity reply trigger"
watcher->setProperty("activityControllerCallbackTarget", qVariantFromValue((void*)target));
}
QStringList *target = running ? &openActivities_ : &allActivities_;
watcher->setFuture(QtConcurrent::run(fetchActivityList, &activityController_, target, running));
}
}
void Workspace::handleActivityReply()
{
QObject *watcherObject = 0;
if (QFutureWatcher<AssignedList>* watcher = dynamic_cast< QFutureWatcher<AssignedList>* >(sender())) {
*(watcher->result().first) = watcher->result().second; // cool trick, ehh? :-)
watcherObject = watcher;
}
if (!watcherObject) {
if (QFutureWatcher<CurrentAndList>* watcher = dynamic_cast< QFutureWatcher<CurrentAndList>* >(sender())) {
allActivities_ = watcher->result().second;
updateCurrentActivity(watcher->result().first);
emit currentActivityChanged(currentActivity());
watcherObject = watcher;
}
}
if (watcherObject) {
QString slot = watcherObject->property("activityControllerCallback").toString();
QObject *target = static_cast<QObject*>(watcherObject->property("activityControllerCallbackTarget").value<void*>());
watcherObject->deleteLater(); // has done it's job
if (!slot.isEmpty())
QMetaObject::invokeMethod(target, slot.toAscii().data(), Qt::DirectConnection);
}
}
//END threaded activity list fetching
#else // make gcc happy - stupd moc cannot handle preproc defs so we MUST define
void Workspace::handleActivityReply() {}
#endif // KWIN_BUILD_ACTIVITIES
/**
* Updates the current activity when it changes
* do *not* call this directly; it does not set the activity.
@ -1222,61 +1147,58 @@ void Workspace::handleActivityReply() {}
void Workspace::updateCurrentActivity(const QString &new_activity)
{
#ifdef KWIN_BUILD_ACTIVITIES
//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));
++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;
ObscuringWindows obs_wins;
QString old_activity = activity_;
activity_ = new_activity;
const QString &old_activity = Activities::self()->previous();
for (ToplevelList::ConstIterator it = stacking_order.constBegin();
it != stacking_order.constEnd();
++it) {
Client *c = qobject_cast<Client*>(*it);
if (!c) {
continue;
}
if (!c->isOnActivity(new_activity) && c != movingClient && c->isOnCurrentDesktop()) {
if (c->isShown(true) && c->isOnActivity(old_activity) && !compositing())
obs_wins.create(c);
c->updateVisibility();
}
for (ToplevelList::ConstIterator it = stacking_order.constBegin();
it != stacking_order.constEnd();
++it) {
Client *c = qobject_cast<Client*>(*it);
if (!c) {
continue;
}
// 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 ))
{
movingClient->setDesktop( new_desktop );
*/
for (int i = stacking_order.size() - 1; i >= 0 ; --i) {
Client *c = qobject_cast<Client*>(stacking_order.at(i));
if (!c) {
continue;
}
if (c->isOnActivity(new_activity))
c->updateVisibility();
if (!c->isOnActivity(new_activity) && c != movingClient && c->isOnCurrentDesktop()) {
if (c->isShown(true) && c->isOnActivity(old_activity) && !compositing())
obs_wins.create(c);
c->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);
}
// 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 ))
{
movingClient->setDesktop( new_desktop );
*/
for (int i = stacking_order.size() - 1; i >= 0 ; --i) {
Client *c = qobject_cast<Client*>(stacking_order.at(i));
if (!c) {
continue;
}
if (c->isOnActivity(new_activity))
c->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;
@ -1311,29 +1233,9 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
// static_cast<EffectsHandlerImpl*>( effects )->desktopChanged( old_desktop );
if (compositing() && m_compositor)
m_compositor->addRepaintFull();
}
/**
* updates clients when an activity is destroyed.
* this ensures that a client does not get 'lost' if the only activity it's on is removed.
*/
void Workspace::slotActivityRemoved(const QString &activity)
{
allActivities_.removeOne(activity);
foreach (Toplevel * toplevel, stacking_order) {
if (Client *client = qobject_cast<Client*>(toplevel)) {
client->setOnActivity(activity, false);
}
}
//toss out any session data for it
KConfigGroup cg(KGlobal::config(), QString("SubSession: ") + activity);
cg.deleteGroup();
}
void Workspace::slotActivityAdded(const QString &activity)
{
allActivities_ << activity;
#else
Q_UNUSED(new_activity)
#endif
}
void Workspace::moveClientsFromRemovedDesktops()
@ -1402,43 +1304,6 @@ void Workspace::sendClientToDesktop(Client* c, int desk, bool dont_activate)
updateClientArea();
}
/**
* Adds/removes client \a c to/from \a activity.
*
* 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->isOnCurrentActivity()) {
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 );
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
{
return QApplication::desktop()->screenCount();

View file

@ -34,9 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// need to include utils.h before we use the ifdefs
#include "utils.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include <KActivities/Controller>
#endif
#include "plugins.h"
#include "kdecoration.h"
@ -208,12 +205,6 @@ public:
QPoint cascadeOffset(const Client *c) const;
private:
QString activity_;
QStringList allActivities_, openActivities_;
#ifdef KWIN_BUILD_ACTIVITIES
KActivities::Controller activityController_;
#endif
Outline* m_outline;
Compositor *m_compositor;
@ -228,18 +219,6 @@ public:
void setActiveScreenMouse(const QPoint& mousepos);
QRect screenGeometry(int screen) const;
int screenNumber(const QPoint& pos) const;
QString currentActivity() const {
return activity_;
}
QStringList activityList() const {
return allActivities_;
}
const QStringList &openActivities() const {
return openActivities_;
}
#ifdef KWIN_BUILD_ACTIVITIES
void updateActivityList(bool running, bool updateCurrent, QObject *target = NULL, QString slot = QString());
#endif
// True when performing Workspace::updateClientArea().
// The calls below are valid only in that case.
bool inUpdateClientArea() const;
@ -282,7 +261,6 @@ public:
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);
@ -314,6 +292,7 @@ public:
void storeSession(KConfig* config, SMSavePhase phase);
void storeClient(KConfigGroup &cg, int num, Client *c);
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
void loadSubSessionInfo(const QString &name);
SessionInfo* takeSessionInfo(Client*);
WindowRules findWindowRules(const Client*, bool);
@ -337,8 +316,6 @@ public:
**/
QList<int> decorationSupportedColors() const;
bool waitForCompositingSetup();
bool stopActivity(const QString &id);
bool startActivity(const QString &id);
QString supportInformation() const;
void setCurrentScreen(int new_screen);
@ -490,10 +467,6 @@ private slots:
void slotBlockShortcuts(int data);
void slotReloadConfig();
void updateCurrentActivity(const QString &new_activity);
void slotActivityRemoved(const QString &activity);
void slotActivityAdded(const QString &activity);
void reallyStopActivity(const QString &id); //dbus deadlocks suck
void handleActivityReply();
// virtual desktop handling
void moveClientsFromRemovedDesktops();
void slotDesktopCountChanged(uint previousCount, uint newCount);
@ -520,23 +493,6 @@ signals:
void propertyNotify(long a);
void configChanged();
void reinitializeCompositing();
/**
* This signal is emitted when the global
* activity is changed
* @param id id of the new current activity
*/
void currentActivityChanged(const QString &id);
/**
* This signal is emitted when a new activity is added
* @param id id of the new activity
*/
void activityAdded(const QString &id);
/**
* This signal is emitted when the activity
* is removed
* @param id id of the removed activity
*/
void activityRemoved(const QString &id);
/**
* This signels is emitted when ever the stacking order is change, ie. a window is risen
* or lowered
@ -588,7 +544,6 @@ private:
void loadSessionInfo();
void addSessionInfo(KConfigGroup &cg);
void loadSubSessionInfo(const QString &name);
void loadWindowRules();
void editWindowRules(Client* c, bool whole_app);