diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a6f8ce317..b3b4324eaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/activation.cpp b/activation.cpp index eb99915c3b..786bbad6be 100644 --- a/activation.cpp +++ b/activation.cpp @@ -30,6 +30,9 @@ along with this program. If not, see . #include "cursor.h" #include "focuschain.h" #include "workspace.h" +#ifdef KWIN_BUILD_ACTIVITIES +#include "activities.h" +#endif #include #include @@ -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 diff --git a/activities.cpp b/activities.cpp new file mode 100644 index 0000000000..e48dc33dd3 --- /dev/null +++ b/activities.cpp @@ -0,0 +1,292 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2013 Martin Gräßlin + +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 . +*********************************************************************/ +#include "activities.h" +// KWin +#include "client.h" +#include "workspace.h" +// KDE +#include +#include +#include +#include +// Qt +#include +#include +#include +#include + +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 saveSessionIds; + QSet 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 AssignedList; +typedef QPair 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* watcher = new QFutureWatcher; + 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* watcher = new QFutureWatcher; + 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* watcher = dynamic_cast< QFutureWatcher* >(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* watcher = dynamic_cast< QFutureWatcher* >(sender())) { + m_all = watcher->result().second; + slotCurrentChanged(watcher->result().first); + watcherObject = watcher; + } + } + + if (watcherObject) { + QString slot = watcherObject->property("activityControllerCallback").toString(); + QObject *target = static_cast(watcherObject->property("activityControllerCallbackTarget").value()); + watcherObject->deleteLater(); // has done it's job + if (!slot.isEmpty()) + QMetaObject::invokeMethod(target, slot.toAscii().data(), Qt::DirectConnection); + } +} +//END threaded activity list fetching + +} // namespace diff --git a/activities.h b/activities.h new file mode 100644 index 0000000000..d662b98cfd --- /dev/null +++ b/activities.h @@ -0,0 +1,129 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2013 Martin Gräßlin + +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 . +*********************************************************************/ +#ifndef KWIN_ACTIVITIES_H +#define KWIN_ACTIVITIES_H + +#include +#include + +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 ¤t() 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 diff --git a/client.cpp b/client.cpp index 5f5f703ff8..af06acec00 100644 --- a/client.cpp +++ b/client.cpp @@ -40,6 +40,9 @@ along with this program. If not, see . #include #include +#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 diff --git a/dbusinterface.cpp b/dbusinterface.cpp index 624b698622..8cebebf3c4 100644 --- a/dbusinterface.cpp +++ b/dbusinterface.cpp @@ -29,6 +29,9 @@ along with this program. If not, see . #include "kwinadaptor.h" #include "workspace.h" #include "virtualdesktops.h" +#ifdef KWIN_BUILD_ACTIVITIES +#include "activities.h" +#endif // Qt #include @@ -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) { diff --git a/effects.cpp b/effects.cpp index bb382e95a0..7d9dea17c7 100644 --- a/effects.cpp +++ b/effects.cpp @@ -22,6 +22,9 @@ along with this program. If not, see . #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 diff --git a/manage.cpp b/manage.cpp index 0a55feeb3c..7a8473a155 100644 --- a/manage.cpp +++ b/manage.cpp @@ -27,6 +27,9 @@ along with this program. If not, see . #include #include +#ifdef KWIN_BUILD_ACTIVITIES +#include "activities.h" +#endif #include "cursor.h" #include "notifications.h" #include @@ -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 diff --git a/scripting/scripting_model.cpp b/scripting/scripting_model.cpp index b2d05756dd..67dcde6add 100644 --- a/scripting/scripting_model.cpp +++ b/scripting/scripting_model.cpp @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "scripting_model.h" +#include "activities.h" #include "client.h" // Qt #include @@ -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 &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 } diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp index 17c1d97495..9b913cf787 100644 --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -23,6 +23,9 @@ along with this program. If not, see . #include "../client.h" #include "../outline.h" #include "../virtualdesktops.h" +#ifdef KWIN_BUILD_ACTIVITIES +#include "../activities.h" +#endif #include @@ -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(); \ diff --git a/sm.cpp b/sm.cpp index ad19881108..1d6b89aaf6 100644 --- a/sm.cpp +++ b/sm.cpp @@ -30,8 +30,6 @@ along with this program. If not, see . #include "workspace.h" #include "client.h" -#include -#include #include #include #include @@ -184,81 +182,6 @@ void Workspace::storeSubSession(const QString &name, QSet 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 saveSessionIds; - QSet 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. diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index b1ee625ad8..27ebbadc9d 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -29,6 +29,9 @@ along with this program. If not, see . #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() diff --git a/toplevel.cpp b/toplevel.cpp index 9bb9802bd3..f8d81968a5 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -22,6 +22,9 @@ along with this program. If not, see . #include +#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" diff --git a/toplevel.h b/toplevel.h index dfc48f141b..aa7ac3e322 100644 --- a/toplevel.h +++ b/toplevel.h @@ -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 diff --git a/useractions.cpp b/useractions.cpp index 5d6e937cad..033ed6d51f 100755 --- a/useractions.cpp +++ b/useractions.cpp @@ -43,6 +43,7 @@ along with this program. If not, see . #endif #ifdef KWIN_BUILD_ACTIVITIES +#include "activities.h" #include #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 } //**************************************** diff --git a/workspace.cpp b/workspace.cpp index f24486a7be..9d9e1e86be 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -74,6 +74,9 @@ along with this program. If not, see . #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 AssignedList; -typedef QPair 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* watcher = new QFutureWatcher; - 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* watcher = new QFutureWatcher; - 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* watcher = dynamic_cast< QFutureWatcher* >(sender())) { - *(watcher->result().first) = watcher->result().second; // cool trick, ehh? :-) - watcherObject = watcher; - } - - if (!watcherObject) { - if (QFutureWatcher* watcher = dynamic_cast< QFutureWatcher* >(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(watcherObject->property("activityControllerCallbackTarget").value()); - 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(*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(*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(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(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( 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(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(); diff --git a/workspace.h b/workspace.h index 8d75b9297e..b751521d6d 100644 --- a/workspace.h +++ b/workspace.h @@ -34,9 +34,6 @@ along with this program. If not, see . // need to include utils.h before we use the ifdefs #include "utils.h" -#ifdef KWIN_BUILD_ACTIVITIES -#include -#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 sessionIds); + void loadSubSessionInfo(const QString &name); SessionInfo* takeSessionInfo(Client*); WindowRules findWindowRules(const Client*, bool); @@ -337,8 +316,6 @@ public: **/ QList 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);