Git commit 3dc6a7fd527344de4fba777480c4431f77281fb8 by Ivan =C4=8Cuki=C4=87. Committed on 30/06/2012 at 23:04. Pushed by ivan into branch 'ivan/plugin-refactor'. Share Like Connect online again M +69 -7 service/Application.cpp M +2 -6 service/Application.h M +3 -1 service/CMakeLists.txt M +38 -4 service/Event.cpp M +13 -2 service/Event.h C +15 -4 service/Plugin.cpp [from: service/common.h - 074% similarity] C +32 -15 service/Plugin.h [from: service/Event.cpp - 053% similarity] M +194 -64 service/Resources.cpp A +69 -0 service/Resources_p.h [License: GPL (v2)] M +11 -0 service/common.h M +14 -14 service/plugins/CMakeLists.txt M +0 -1 service/plugins/slc/CMakeLists.txt M +50 -77 service/plugins/slc/slc.cpp M +19 -9 service/plugins/slc/slc.h C +27 -4 service/utils/remove_if.h [from: service/common.h - 051% sim= ilarity] [License: UNKNOWN] * The files marked with a * at the end have a non valid license. Please read:= http://techbase.kde.org/Policies/Licensing_Policy and use the headers whic= h are listed at that page. http://commits.kde.org/kactivities/3dc6a7fd527344de4fba777480c4431f77281fb8 diff --git a/service/Application.cpp b/service/Application.cpp index 7604228..8efdd79 100644 --- a/service/Application.cpp +++ b/service/Application.cpp @@ -26,10 +26,12 @@ #include #include #include +#include = #include #include #include +#include = #include #include @@ -38,6 +40,7 @@ = #include #include +#include = static QList < QThread * > s_moduleThreads; = @@ -77,11 +80,25 @@ T * runInQThread() return object; } = +class Application::Private { +public: + Private() + : resources (runInQThread ()), + activities (runInQThread ()), + features (runInQThread ()) + { + } + + Resources * resources; + Activities * activities; + Features * features; + + QList < Plugin * > backends; + +}; + Application::Application() - : KUniqueApplication(), - m_resources (runInQThread ()), - m_activities (runInQThread ()), - m_features (runInQThread ()) + : KUniqueApplication(), d() { // TODO: We should move away from any GUI code setQuitOnLastWindowClosed(false); @@ -98,6 +115,52 @@ Application::Application() // NOTE: We have a custom crash handler KCrash::setFlags(KCrash::AutoRestart); = + // Loading the plugins + + KService::List offers =3D KServiceTypeTrader::self()->query("ActivityM= anager/Plugin"); + + QStringList disabledPlugins; // TODO: =3D shared->pluginConfig("Global= ").readEntry("disabledPlugins", QStringList()); + + foreach (const KService::Ptr & service, offers) { + if (!disabledPlugins.contains(service->library())) { + disabledPlugins.append( + service->property("X-ActivityManager-PluginOverrides",= QVariant::StringList).toStringList() + ); + } + } + + foreach (const KService::Ptr & service, offers) { + if (disabledPlugins.contains(service->library())) { + continue; + } + + // kDebug() << "Loading plugin:" + // << service->name() << service->storageId() << service->libr= ary() + // << service->property("X-ActivityManager-PluginType", QVaria= nt::String); + + KPluginFactory * factory =3D KPluginLoader(service->library()).fac= tory(); + + if (!factory) { + continue; + } + + Plugin * plugin =3D factory->create < Plugin > (this); + + if (plugin) { + plugin->init( + d->activities, + d->resources, + d->features + ); + + d->backends << plugin; + + } else { + // kDebug() << "Failed to load plugin:" << service->name(); + } + + } + } = Application::~Application() @@ -112,12 +175,12 @@ Application::~Application() = Activities & Application::activities() const { - return *m_activities; + return *d->activities; } = Resources & Application::resources() const { - return *m_resources; + return *d->resources; } = = @@ -142,7 +205,6 @@ int main(int argc, char ** argv) "http://www.kde.org/"); = KCmdLineArgs::init(argc, argv, &about); - initSignalCatching(); = return Application::self().exec(); diff --git a/service/Application.h b/service/Application.h index e7077d2..568ad0f 100644 --- a/service/Application.h +++ b/service/Application.h @@ -22,6 +22,7 @@ = #include #include +#include = class Resources; class Activities; @@ -42,12 +43,7 @@ public: Features & features() const; = private: - Resources * m_resources; - Activities * m_activities; - Features * m_features; - // const std::unique_ptr < Resources > m_resources; - // const std::unique_ptr < Activities > m_activities; - // const std::unique_ptr < Features > m_features; + D_PTR; }; = #endif // APPLICATION_H diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt index e934c31..6adea4a 100644 --- a/service/CMakeLists.txt +++ b/service/CMakeLists.txt @@ -72,7 +72,7 @@ include_directories ( ${KDE4_INCLUDES} ) = -# add_subdirectory (plugins) +add_subdirectory (plugins) # add_subdirectory (ui/plugins) = set (activity_manager_SRCS @@ -82,6 +82,8 @@ set (activity_manager_SRCS Resources.cpp Features.cpp = + Plugin.cpp + NepomukActivityManager.cpp = Event.cpp diff --git a/service/Event.cpp b/service/Event.cpp index 8435cf5..540fbb5 100644 --- a/service/Event.cpp +++ b/service/Event.cpp @@ -19,18 +19,52 @@ = #include "Event.h" = +#include +#include + = Event::Event(const QString & vApplication, WId vWid, const QString & vUri,= int vType, int vReason) : application(vApplication), wid(vWid), uri(vUri), type(vType), reason= (vReason), timestamp(QDateTime::currentDateTime()) { } = +Event Event::deriveWithType(Type type) const +{ + Event result(*this); + result.type =3D type; + qDebug() << "deriveWithType" << result; + return result; +} + bool Event::operator =3D=3D (const Event & other) const { return application =3D=3D other.application && - wid =3D=3D other.wid && - uri =3D=3D other.uri && - type =3D=3D other.type && - reason =3D=3D other.reason; + wid =3D=3D other.wid && + uri =3D=3D other.uri && + type =3D=3D other.type && + reason =3D=3D other.reason && + timestamp =3D=3D other.timestamp; } + +QString Event::typeName() const +{ + switch (type) { + case Accessed: return "Accessed"; + case Opened: return "Opened"; + case Modified: return "Modified"; + case Closed: return "Closed"; + case FocussedIn: return "FocussedIn"; + case FocussedOut: return "FocussedOut"; + + } + + return "Other"; +} + +QDebug operator << (QDebug dbg, const Event & e) +{ + dbg << "Event(" << e.application << e.wid << e.typeName() << e.uri << = ":" << e.timestamp << ")"; + return dbg.space(); +} + diff --git a/service/Event.h b/service/Event.h index 494366d..5cf65c7 100644 --- a/service/Event.h +++ b/service/Event.h @@ -22,13 +22,15 @@ = #include #include -#include +#include +#include = /** * */ class Event { public: + enum Type { Accessed =3D 0, ///< resource was accessed, but we don't know f= or how long it will be open/used = @@ -63,9 +65,11 @@ public: UserEventReason =3D 32 }; = - Event(const QString & application, WId wid, const QString & uri, + Event(const QString & application =3D QString(), WId wid =3D 0, const = QString & uri =3D QString(), int type =3D Accessed, int reason =3D User); = + Event deriveWithType(Type type) const; + bool operator =3D=3D (const Event & other) const; = public: @@ -75,9 +79,16 @@ public: int type; int reason; QDateTime timestamp; + + QString typeName() const; }; = +QDebug operator << (QDebug dbg, const Event & e); + typedef QList EventList; = +Q_DECLARE_METATYPE(Event) +Q_DECLARE_METATYPE(EventList) + #endif // EVENT_H = diff --git a/service/common.h b/service/Plugin.cpp similarity index 74% copy from service/common.h copy to service/Plugin.cpp index 73f1da6..7c4d87c 100644 --- a/service/common.h +++ b/service/Plugin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Ivan Cukic + * Copyright (C) 2011 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -17,7 +17,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ = -#define ACTIVITY_MANAGER_SERVICE "org.kde.ActivityManager" -#define ACTIVITY_MANAGER_OBJECT_TYPE(A) ACTIVITY_MANAGER_SERVICE #A -#define ACTIVITY_MANAGER_OBJECT_PATH(A) "/ActivityManager/" #A +#include "Plugin.h" = +Plugin::Plugin(QObject * parent) + : QObject(parent) +{ +} + +Plugin::~Plugin() +{ +} + +bool Plugin::init(QObject *, QObject *, QObject *) +{ + return true; +} diff --git a/service/Event.cpp b/service/Plugin.h similarity index 53% copy from service/Event.cpp copy to service/Plugin.h index 8435cf5..d82e1e8 100644 --- a/service/Event.cpp +++ b/service/Plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Ivan Cukic + * Copyright (C) 2011, 2012 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -17,20 +17,37 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ = +#ifndef PLUGIN_H +#define PLUGIN_H + +#include +#include +#include + #include "Event.h" = +#define KAMD_EXPORT_PLUGIN(ClassName, AboutData) \ + K_PLUGIN_FACTORY(ClassName##Factory, registerPlugin();) \ + K_EXPORT_PLUGIN(ClassName##Factory("AboutData")) + + +/** + * + */ +class KDE_EXPORT Plugin: public QObject { + Q_OBJECT + +public: + Plugin(QObject * parent); + virtual ~Plugin(); + + virtual bool init( + QObject * activities, + QObject * resources, + QObject * features + ); + +}; + +#endif // PLUGIN_H = -Event::Event(const QString & vApplication, WId vWid, const QString & vUri,= int vType, int vReason) - : application(vApplication), wid(vWid), uri(vUri), type(vType), reason= (vReason), timestamp(QDateTime::currentDateTime()) -{ -} - -bool Event::operator =3D=3D (const Event & other) const -{ - return - application =3D=3D other.application && - wid =3D=3D other.wid && - uri =3D=3D other.uri && - type =3D=3D other.type && - reason =3D=3D other.reason; -} diff --git a/service/Resources.cpp b/service/Resources.cpp index 0401857..5284b2c 100644 --- a/service/Resources.cpp +++ b/service/Resources.cpp @@ -18,6 +18,7 @@ */ = #include "Resources.h" +#include "Resources_p.h" #include "resourcesadaptor.h" = #include @@ -29,6 +30,7 @@ = #include #include +#include = #include #include @@ -40,6 +42,7 @@ #include "common.h" = #include +#include = // TODO static QString CurrentActivity() @@ -78,99 +81,227 @@ static void doWithNepomukForActivity(const QString & _= activity, Function doWhat) #endif } = -class Resources::Private: public QThread { -public: - Private(Resources * parent) - : QThread(parent), q(parent) - { - } - - EventList events; - QMutex events_mutex; +Resources::Private::Private(Resources * parent) + : QThread(parent), focussedWindow(0), q(parent) +{ +} = - void run() - { - forever { - // initial delay before processing the events - sleep(5); +EventList events; +QMutex events_mutex; = - EventList currentEvents; +void Resources::Private::run() +{ + forever { + // initial delay before processing the events + sleep(5); = - { - QMutexLocker locker(& events_mutex); + EventList currentEvents; = - if (events.count() =3D=3D 0) { - // kDebug() << "No more events to process, exiting."; - return; - } + { + QMutexLocker locker(& events_mutex); = - currentEvents =3D events; - events.clear(); + if (events.count() =3D=3D 0) { + // kDebug() << "No more events to process, exiting."; + return; } = - emit q->ProcessedResourceEvents(currentEvents); + currentEvents =3D events; + events.clear(); } - } = - void addEvent(const QString & application, WId wid, const QString & ur= i, - int type, int reason) - { - Event newEvent(application, wid, uri, type, reason); - addEvent(newEvent); + emit q->ProcessedResourceEvents(currentEvents); } +} + +void Resources::Private::insertEvent(const Event & newEvent) +{ + if (lastEvent =3D=3D newEvent) return; + lastEvent =3D newEvent; + + events << newEvent; + emit q->RegisteredResourceEvent(newEvent); +} = - void addEvent(const Event & newEvent) +void Resources::Private::addEvent(const QString & application, WId wid, co= nst QString & uri, + int type, int reason) +{ + Event newEvent(application, wid, uri, type, reason); + addEvent(newEvent); +} + +void Resources::Private::addEvent(const Event & newEvent) +{ + // And now, for something completely delayed { - // Passing the events to the plugins that want them immediately - emit q->RegisteredResourceEvent(newEvent); + QMutexLocker locker(& events_mutex); + + // Deleting previously registered Accessed events if + // the current one has the same application and uri + if (newEvent.type !=3D Event::Accessed) { + kamd::utils::remove_if(events, [&newEvent] (const Event & even= t) -> bool { + return + event.reason =3D=3D Event::Accessed && + event.application =3D=3D newEvent.application && + event.uri =3D=3D newEvent.uri + ; + }); + } = - // And now, for something completely delayed - { - QMutexLocker locker(& events_mutex); + // Process the windowing + // Essentially, this is the brain of SLC. We need to track the + // window focus changes to be able to generate the potential + // missing events like FocussedOut before Closed and similar. + // So, there is no point in having the same logic in SLC plugin + // as well. + + if (newEvent.wid !=3D 0) { + WindowData & data =3D windows[newEvent.wid]; + const KUrl & kuri(newEvent.uri); + + qDebug() << kuri << data.focussedResource; + + data.application =3D newEvent.application; = - // Deleting the accessed events if we have other types of even= ts - // with the same parameters - // TODO: Filter out a bit more - if (newEvent.type !=3D Event::Accessed) { - foreach (const Event & event, events) { - if (event.type =3D=3D Event::Accessed && event.uri =3D= =3D newEvent.uri - && event.application =3D=3D newEvent.applicati= on) { - // Accessed events are of a lower priority - // then the other ones - if (newEvent.type =3D=3D Event::Accessed) { - events.removeAll(newEvent); - } + switch (newEvent.type) { + case Event::Opened: + insertEvent(newEvent); + + if (data.focussedResource.isEmpty()) { + // This window haven't had anything focussed, + // assuming the new document is focussed + + data.focussedResource =3D newEvent.uri; + insertEvent(newEvent.deriveWithType(Event::Focusse= dIn)); + } + + break; + + case Event::FocussedIn: + + if (!data.resources.contains(kuri)) { + // This window did not contain this resource befor= e, + // sending Opened event + + insertEvent(newEvent.deriveWithType(Event::Opened)= ); + } + + data.focussedResource =3D newEvent.uri; + insertEvent(newEvent); + + break; + + case Event::Closed: + + qDebug() << data.focussedResource << kuri; + + if (data.focussedResource =3D=3D kuri) { + // If we are closing a document that is in focus, + // release focus first + + insertEvent(newEvent.deriveWithType(Event::Focusse= dOut)); + data.focussedResource.clear(); } - } - } = - events.append(newEvent); + insertEvent(newEvent); + + break; + + case Event::FocussedOut: + + if (data.focussedResource =3D=3D kuri) { + data.focussedResource.clear(); + } + + insertEvent(newEvent); + + break; + + default: + insertEvent(newEvent); + break; + + } } + } + + start(); +} + +QList Resources::Private::resourcesLinkedToActivity(const QString &= activity) const +{ + return doWithNepomukForActivity(activity, [] (const QString & activity) + { + return EXEC_NEPOMUK(resourcesLinkedToActivity(activity)); + }, + QList() + ); +} + +void Resources::Private::windowClosed(WId windowId) +{ + kDebug() << "Window closed..." << windowId + << "one of ours?" << windows.contains(windowId); = - start(); + if (!windows.contains(windowId)) { + return; } = - QList resourcesLinkedToActivity(const QString & activity) const - { - return doWithNepomukForActivity(activity, [] (const QString & acti= vity) - { - return EXEC_NEPOMUK(resourcesLinkedToActivity(activity)); - }, - QList() - ); + if (focussedWindow =3D=3D windowId) { + focussedWindow =3D 0; + } + + foreach (const KUrl & uri, windows[windowId].resources) { + q->RegisterResourceEvent(windows[windowId].application, + toInt(windowId), uri.url(), Event::Closed, 0); + } + + windows.remove(windowId); +} + +void Resources::Private::activeWindowChanged(WId windowId) +{ + Q_UNUSED(windowId) + kDebug() << "Window focussed..." << windowId + << "one of ours?" << windows.contains(windowId); + + if (windowId =3D=3D focussedWindow) return; + + if (windows.contains(focussedWindow)) { + const WindowData & data =3D windows[focussedWindow]; + + if (!data.focussedResource.isEmpty()) { + insertEvent(Event(data.application, focussedWindow, data.focus= sedResource.url(), Event::FocussedOut)); + } } = -private: - Resources * const q; -}; + focussedWindow =3D windowId; + + if (windows.contains(focussedWindow)) { + const WindowData & data =3D windows[focussedWindow]; + + if (!data.focussedResource.isEmpty()) { + insertEvent(Event(data.application, windowId, data.focussedRes= ource.url(), Event::FocussedIn)); + } + } +} = = Resources::Resources(QObject * parent) : QObject(parent), d(this) { + qRegisterMetaType < Event > ("Event"); + qRegisterMetaType < EventList > ("EventList"); + qRegisterMetaType < WId > ("WId"); + new ResourcesAdaptor(this); QDBusConnection::sessionBus().registerObject( ACTIVITY_MANAGER_OBJECT_PATH(Resources), this); + + connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), + d.get(), SLOT(windowClosed(WId))); + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), + d.get(), SLOT(activeWindowChanged(WId))); + } = Resources::~Resources() @@ -280,7 +411,6 @@ bool Resources::IsResourceLinkedToActivity(const QStrin= g & uri, const QString & = QStringList Resources::ResourcesLinkedToActivity(const QString & activity)= const { - qDebug() << "This is the current thread id for Resources" << QThread::= currentThreadId() << QThread::currentThread(); QStringList result; = foreach (const KUrl & uri, d->resourcesLinkedToActivity(activity)) { diff --git a/service/Resources_p.h b/service/Resources_p.h new file mode 100644 index 0000000..a28d45c --- /dev/null +++ b/service/Resources_p.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010, 2011, 2012 Ivan Cukic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * or (at your option) any later version, as published by the Free + * Software Foundation + * + * 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, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef RESOURCES_P_H +#define RESOURCES_P_H + +#include "Resources.h" +#include "resourcesadaptor.h" + +#include +#include +#include + +class Resources::Private: public QThread { + Q_OBJECT + +public: + Private(Resources * parent); + + void run(); + + void insertEvent(const Event & newEvent); + + void addEvent(const QString & application, WId wid, const QString & ur= i, + int type, int reason); + + void addEvent(const Event & newEvent); + + QList resourcesLinkedToActivity(const QString & activity) const; + +private Q_SLOTS: + void windowClosed(WId windowId); + + void activeWindowChanged(WId windowId); + +private: + struct WindowData { + QSet < KUrl > resources; + KUrl focussedResource; + QString application; + }; + + Event lastEvent; + EventList events; + QMutex events_mutex; + + QHash < WId, WindowData > windows; + WId focussedWindow; + + Resources * const q; +}; + +#endif // RESOURCES_P_H diff --git a/service/common.h b/service/common.h index 73f1da6..d1bb06a 100644 --- a/service/common.h +++ b/service/common.h @@ -21,3 +21,14 @@ #define ACTIVITY_MANAGER_OBJECT_TYPE(A) ACTIVITY_MANAGER_SERVICE #A #define ACTIVITY_MANAGER_OBJECT_PATH(A) "/ActivityManager/" #A = +#include + +__inline int toInt(WId wid) +{ +#ifdef Q_OS_WIN64 // krazy:skip + return (int)((__int64)wid); +#else + return (int)wid; +#endif +} + diff --git a/service/plugins/CMakeLists.txt b/service/plugins/CMakeLists.txt index 2276d6b..df0ab61 100644 --- a/service/plugins/CMakeLists.txt +++ b/service/plugins/CMakeLists.txt @@ -1,15 +1,15 @@ macro_optional_add_subdirectory(slc) -macro_optional_add_subdirectory(activityranking) -macro_optional_add_subdirectory(sqlite) -macro_optional_add_subdirectory(globalshortcuts) - -get_property(KACTIVITIES_BUILD_NEPOMUK_PLUGIN GLOBAL PROPERTY KACTIVITIES_= BUILD_NEPOMUK_PLUGIN) -get_property(KACTIVITIES_BUILD_DUMMY_PLUGIN GLOBAL PROPERTY KACTIVITIES_BU= ILD_DUMMY_PLUGIN) - -if(KACTIVITIES_BUILD_NEPOMUK_PLUGIN AND Nepomuk_FOUND) - macro_optional_add_subdirectory(nepomuk) -endif() - -if (KACTIVITIES_BUILD_DUMMY_PLUGIN) - macro_optional_add_subdirectory(dummy) -endif() +# macro_optional_add_subdirectory(activityranking) +# macro_optional_add_subdirectory(sqlite) +# macro_optional_add_subdirectory(globalshortcuts) +# +# get_property(KACTIVITIES_BUILD_NEPOMUK_PLUGIN GLOBAL PROPERTY KACTIVITIE= S_BUILD_NEPOMUK_PLUGIN) +# get_property(KACTIVITIES_BUILD_DUMMY_PLUGIN GLOBAL PROPERTY KACTIVITIES_= BUILD_DUMMY_PLUGIN) +# +# if(KACTIVITIES_BUILD_NEPOMUK_PLUGIN AND Nepomuk_FOUND) +# macro_optional_add_subdirectory(nepomuk) +# endif() +# +# if (KACTIVITIES_BUILD_DUMMY_PLUGIN) +# macro_optional_add_subdirectory(dummy) +# endif() diff --git a/service/plugins/slc/CMakeLists.txt b/service/plugins/slc/CMake= Lists.txt index fd81b75..2515b26 100644 --- a/service/plugins/slc/CMakeLists.txt +++ b/service/plugins/slc/CMakeLists.txt @@ -13,7 +13,6 @@ set( slc_SRCS slc.cpp ../../Plugin.cpp - ../../SharedInfo.cpp ) = qt4_add_dbus_adaptor( diff --git a/service/plugins/slc/slc.cpp b/service/plugins/slc/slc.cpp index 0cd483b..b8f9993 100644 --- a/service/plugins/slc/slc.cpp +++ b/service/plugins/slc/slc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Ivan Cukic ivan.cukic(at)kde.org + * Copyright (C) 2011, 2012 Ivan Cukic ivan.cukic(at)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 @@ -24,116 +24,89 @@ #include = SlcPlugin::SlcPlugin(QObject * parent, const QVariantList & args) - : Plugin(parent), focussedWindow(0) + : Plugin(parent) { Q_UNUSED(args) - // kDebug() << "We are in the SlcPlugin"; = QDBusConnection dbus =3D QDBusConnection::sessionBus(); new SLCAdaptor(this); dbus.registerObject("/SLC", this); - - connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), - this, SLOT(activeWindowChanged(WId))); } = SlcPlugin::~SlcPlugin() { } = -void SlcPlugin::addEvents(const EventList & events) +QString SlcPlugin::focussedResourceURI() const { - foreach (const Event & event, events) { - switch (event.type) { - case Event::FocussedIn: - case Event::Opened: - // kDebug() << "Event::FocussedIn" << focussedWindow << ev= ent.wid << event.uri; - - lastFocussedResource[event.wid] =3D event.uri; - - if (event.wid =3D=3D focussedWindow) { - updateFocus(focussedWindow); - } + return m_focussedResource; +} = - break; +QString SlcPlugin::focussedResourceMimetype() const +{ + return m_resources[m_focussedResource].mimetype; +} = - case Event::FocussedOut: - case Event::Closed: - // kDebug() << "Event::FocussedOut" << focussedWindow << e= vent.wid << event.uri; +QString SlcPlugin::focussedResourceTitle() const +{ + return m_resources[m_focussedResource].title; +} = - if (lastFocussedResource[event.wid] =3D=3D event.uri) { - lastFocussedResource[event.wid] =3D KUrl(); - } +void SlcPlugin::registeredResourceEvent(const Event & event) +{ + switch (event.type) { + case Event::FocussedIn: = - if (event.wid =3D=3D focussedWindow) { - updateFocus(); - } + if (m_focussedResource !=3D event.uri) { + m_focussedResource =3D event.uri; + const ResourceInfo & info =3D m_resources[m_focussedResour= ce]; + emit focusChanged(event.uri, info.mimetype, info.title); + } = - break; + break; = - default: - // nothing - break; - } - } -} + case Event::FocussedOut: = -KUrl SlcPlugin::_focussedResourceURI() -{ - KUrl kuri; + if (m_focussedResource =3D=3D event.uri) { + m_focussedResource.clear(); + emit focusChanged(QString(), QString(), QString()); + } = - if (lastFocussedResource.contains(focussedWindow)) { - kuri =3D lastFocussedResource[focussedWindow]; - } else { - foreach (const KUrl & uri, sharedInfo()->windows()[focussedWindow]= .resources) { - kuri =3D uri; break; - } - } = - return kuri; -} + case Event::Closed: + m_resources.remove(event.uri); = -QString SlcPlugin::focussedResourceURI() -{ - return _focussedResourceURI().url(); -} + break; = -QString SlcPlugin::focussedResourceMimetype() -{ - return sharedInfo()->resources().contains(_focussedResourceURI()) ? - sharedInfo()->resources()[_focussedResourceURI()].mimetype : QStri= ng(); + default: + break; + } } = -QString SlcPlugin::focussedResourceTitle() +void SlcPlugin::registeredResourceMimeType(const QString & uri, const QStr= ing & mimetype) { - return sharedInfo()->resources().contains(_focussedResourceURI()) ? - sharedInfo()->resources()[_focussedResourceURI()].title : QString(= ); + m_resources[uri].mimetype =3D mimetype; } = -void SlcPlugin::activeWindowChanged(WId wid) +void SlcPlugin::registeredResourceTitle(const QString & uri, const QString= & title) { - if (wid =3D=3D focussedWindow) return; - - focussedWindow =3D wid; - - updateFocus(wid); + m_resources[uri].title =3D title; } = -void SlcPlugin::updateFocus(WId wid) +bool SlcPlugin::init(QObject * activities, QObject * resources, QObject * = features) { - // kDebug() << "SHARED INFO" << (void*) sharedInfo(); - - if (wid =3D=3D 0 || !sharedInfo()->windows().contains(wid)) { - // kDebug() << "Clearing focus" << wid; - emit focusChanged(QString(), QString(), QString()); - - } else if (wid =3D=3D focussedWindow) { - // kDebug() << "It is the currently focused window" << wid; - SharedInfo::ResourceData resourceData =3D sharedInfo()->resources(= )[_focussedResourceURI()]; - emit focusChanged(focussedResourceURI(), resourceData.mimetype, re= sourceData.title); - - } + connect(resources, SIGNAL(RegisteredResourceEvent(Event)), + this, SLOT(registeredResourceEvent(Event)), + Qt::QueuedConnection); + connect(resources, SIGNAL(RegisteredResourceMimeType(QString, QString)= ), + this, SLOT(registeredResourceMimeType(QString, QString)), + Qt::QueuedConnection); + connect(resources, SIGNAL(RegisteredResourceTitle(QString, QString)), + this, SLOT(registeredResourceTitle(QString, QString)), + Qt::QueuedConnection); + + return true; } = KAMD_EXPORT_PLUGIN(SlcPlugin, "activitymanger_plugin_slc") diff --git a/service/plugins/slc/slc.h b/service/plugins/slc/slc.h index 9ea2c4c..109f305 100644 --- a/service/plugins/slc/slc.h +++ b/service/plugins/slc/slc.h @@ -23,6 +23,8 @@ = #include "../../Plugin.h" = +#include + class SlcPlugin: public Plugin { Q_OBJECT @@ -32,25 +34,33 @@ public: explicit SlcPlugin(QObject *parent =3D nullptr, const QVariantList & a= rgs =3D QVariantList()); ~SlcPlugin(); = - virtual void addEvents(const EventList & events) _override; + virtual bool init( + QObject * activities, + QObject * resources, + QObject * features + ) _override; = private Q_SLOTS: - void activeWindowChanged(WId windowId); + void registeredResourceEvent(const Event & event); + void registeredResourceMimeType(const QString & uri, const QString & m= imetype); + void registeredResourceTitle(const QString & uri, const QString & titl= e); = public Q_SLOTS: - QString focussedResourceURI(); - QString focussedResourceMimetype(); - QString focussedResourceTitle(); + QString focussedResourceURI() const; + QString focussedResourceMimetype() const; + QString focussedResourceTitle() const; = Q_SIGNALS: void focusChanged(const QString & uri, const QString & mimetype, const= QString & title); = private: - void updateFocus(WId wid =3D 0); + struct ResourceInfo { + QString title; + QString mimetype; + }; = - WId focussedWindow; - KUrl _focussedResourceURI(); - QHash < WId, KUrl > lastFocussedResource; + QHash < QString, ResourceInfo > m_resources; + QString m_focussedResource; }; = #endif // PLUGINS_SLC_SLC_H diff --git a/service/common.h b/service/utils/remove_if.h similarity index 51% copy from service/common.h copy to service/utils/remove_if.h index 73f1da6..9e2913b 100644 --- a/service/common.h +++ b/service/utils/remove_if.h @@ -13,11 +13,34 @@ * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the - * Free Software Foundation, Inc., + * Free Software Foundation,3 Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ = -#define ACTIVITY_MANAGER_SERVICE "org.kde.ActivityManager" -#define ACTIVITY_MANAGER_OBJECT_TYPE(A) ACTIVITY_MANAGER_SERVICE #A -#define ACTIVITY_MANAGER_OBJECT_PATH(A) "/ActivityManager/" #A +#ifndef UTILS_REMOVE_IF_H +#define UTILS_REMOVE_IF_H = +#include +#include + +/******************************************************************** + * Syntactic sugar for the erase-remove idiom * + ********************************************************************/ + +namespace kamd { +namespace utils { + +template +__inline void remove_if(Collection & collection, Filter filter) +{ + collection.erase( + std::remove_if( + collection.begin(), collection.end(), filter + ), collection.end() + ); +} + +} // namespace utils +} // namespace kamd + +#endif // UTILS_REMOVE_IF_H