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:
parent
34d0df3e0a
commit
da85b5fdc7
17 changed files with 602 additions and 371 deletions
|
@ -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()
|
||||
|
|
|
@ -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
292
activities.cpp
Normal 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
129
activities.h
Normal 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 ¤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
|
24
client.cpp
24
client.cpp
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
18
effects.cpp
18
effects.cpp
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
99
sm.cpp
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
12
toplevel.cpp
12
toplevel.cpp
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
//****************************************
|
||||
|
|
239
workspace.cpp
239
workspace.cpp
|
@ -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();
|
||||
|
|
47
workspace.h
47
workspace.h
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue