diff --git a/CMakeLists.txt b/CMakeLists.txt index 396803007..8e5f3c98d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,178 +1,178 @@ project(plasma-workspace) set(PROJECT_VERSION "5.6.90") set(PROJECT_VERSION_MAJOR 5) cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(QT_MIN_VERSION "5.6.0") set(KF5_MIN_VERSION "5.18.0") set(INSTALL_SDDM_THEME TRUE) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Widgets Quick QuickWidgets Concurrent Test Script Network) find_package(ECM 1.8.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Plasma DocTools Runner JsEmbed NotifyConfig Su NewStuff Wallet KCMUtils IdleTime Declarative TextWidgets KDELibs4Support Crash GlobalAccel DBusAddons) find_package(KF5NetworkManagerQt ${KF5_MIN_VERSION}) set_package_properties(KF5NetworkManagerQt PROPERTIES DESCRIPTION "Qt wrapper for NetworkManager API" TYPE OPTIONAL PURPOSE "Needed by geolocation data engine." ) find_package(KF5XmlRpcClient REQUIRED) # WARNING PlasmaQuick provides unversioned CMake config find_package(KF5 REQUIRED COMPONENTS PlasmaQuick) find_package(KF5 REQUIRED COMPONENTS SysGuard) find_package(KF5 REQUIRED COMPONENTS Package) # Baloo has a different version scheme than KF5 for now find_package(KF5 5.1 REQUIRED COMPONENTS Baloo) find_package(KF5TextEditor) find_package(KWinDBusInterface CONFIG REQUIRED) find_package(KScreenLocker REQUIRED) find_package(ScreenSaverDBusInterface CONFIG REQUIRED) find_package(KF5Holidays) set_package_properties(KF5Holidays PROPERTIES DESCRIPTION "Holidays provider for Plasma calendar" TYPE OPTIONAL PURPOSE "Needed to for holidays plugin for Plasma Calendar." ) find_package(Phonon4Qt5 4.6.60 REQUIRED NO_MODULE) set_package_properties(Phonon4Qt5 PROPERTIES DESCRIPTION "Qt-based audio library" TYPE REQUIRED) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMPackageConfigHelpers) include(ECMMarkNonGuiExecutable) include(CMakePackageConfigHelpers) include(WriteBasicConfigVersionFile) include(CheckIncludeFiles) include(FeatureSummary) include(ECMOptionalAddSubdirectory) include(ECMQtDeclareLoggingCategory) include(KDEPackageAppTemplates) find_package(KF5Activities ${KF5_MIN_VERSION}) set_package_properties(KF5Activities PROPERTIES DESCRIPTION "management of Plasma activities" TYPE OPTIONAL PURPOSE "Needed by activity related plasmoids." ) find_package(ZLIB) set_package_properties(ZLIB PROPERTIES DESCRIPTION "Support for gzip compressed files and data streams" URL "http://www.zlib.net" TYPE REQUIRED ) find_package(dbusmenu-qt5 CONFIG) set_package_properties(dbusmenu-qt5 PROPERTIES DESCRIPTION "Support for notification area menus via the DBusMenu protocol" URL "https://launchpad.net/libdbusmenu-qt" TYPE OPTIONAL ) find_package(X11) set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" URL "http://www.x.org" TYPE OPTIONAL PURPOSE "Required for building the X11 based workspace") if(X11_FOUND) find_package(XCB MODULE REQUIRED COMPONENTS XCB) set_package_properties(XCB PROPERTIES TYPE REQUIRED) if(NOT X11_SM_FOUND) message(FATAL_ERROR "\nThe X11 Session Management (SM) development package could not be found.\nPlease install libSM.\n") endif(NOT X11_SM_FOUND) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS X11Extras) endif() if(X11_FOUND AND XCB_XCB_FOUND) set(HAVE_X11 1) endif() find_package(KF5Wayland CONFIG) set_package_properties(KF5Wayland PROPERTIES TYPE REQUIRED PURPOSE "Required for Wayland integration of plasmashell") include(ConfigureChecks.cmake) include_directories("${CMAKE_CURRENT_BINARY_DIR}") configure_file(config-workspace.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-workspace.h) configure_file(config-unix.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-unix.h ) configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h) configure_file(plasma.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/plasma.desktop) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma.desktop DESTINATION ${KDE_INSTALL_DATADIR}/xsessions ) configure_file(plasmawayland.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/plasmawayland.desktop) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasmawayland.desktop DESTINATION ${KDE_INSTALL_DATADIR}/wayland-sessions ) plasma_install_package(lookandfeel org.kde.breeze.desktop look-and-feel lookandfeel) if (INSTALL_SDDM_THEME) # Install the login theme into the SDDM directory # Longer term we need to look at making SDDM load from look and feel somehow.. and allow copying at runtime #NOTE this trailing slash is important to rename the directory install(DIRECTORY lookandfeel/contents/loginmanager/ DESTINATION ${KDE_INSTALL_FULL_DATADIR}/sddm/themes/breeze PATTERN "README.txt" EXCLUDE) install(DIRECTORY lookandfeel/contents/components DESTINATION ${KDE_INSTALL_FULL_DATADIR}/sddm/themes/breeze PATTERN "README.txt" EXCLUDE) endif() add_subdirectory(doc) add_subdirectory(libkworkspace) -add_subdirectory(libtaskmanager) +add_subdirectory(liblegacytaskmanager) add_subdirectory(components) if(dbusmenu-qt5_FOUND) add_subdirectory(appmenu) endif() add_subdirectory(plasma-windowed) add_subdirectory(shell) add_subdirectory(freespacenotifier) add_subdirectory(klipper) add_subdirectory(krunner) add_subdirectory(ksmserver) add_subdirectory(ksplash) add_subdirectory(systemmonitor) add_subdirectory(statusnotifierwatcher) add_subdirectory(startkde) add_subdirectory(themes) add_subdirectory(containmentactions) add_subdirectory(runners) add_subdirectory(applets) add_subdirectory(dataengines) add_subdirectory(wallpapers) add_subdirectory(kioslave) add_subdirectory(ktimezoned) add_subdirectory(kuiserver) add_subdirectory(menu) add_subdirectory(phonon) add_subdirectory(solidautoeject) add_subdirectory(drkonqi) ecm_optional_add_subdirectory(xembed-sni-proxy) add_subdirectory(soliduiserver) if(KF5Holidays_FOUND) add_subdirectory(plasmacalendarintegration) endif() add_subdirectory(templates) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/containmentactions/switchwindow/CMakeLists.txt b/containmentactions/switchwindow/CMakeLists.txt index 900f21538..f13c65dd5 100644 --- a/containmentactions/switchwindow/CMakeLists.txt +++ b/containmentactions/switchwindow/CMakeLists.txt @@ -1,20 +1,20 @@ add_definitions(-DTRANSLATION_DOMAIN=\"plasma_containmentactions_switchwindow\") set(switchwindow_SRCS switch.cpp ) ki18n_wrap_ui(switchwindow_SRCS config.ui) add_library(plasma_containmentactions_switchwindow MODULE ${switchwindow_SRCS}) kcoreaddons_desktop_to_json(plasma_containmentactions_switchwindow plasma-containmentactions-switchwindow.desktop) target_link_libraries(plasma_containmentactions_switchwindow KF5::Plasma KF5::KIOCore KF5::I18n KF5::WindowSystem - taskmanager) + legacytaskmanager) install(TARGETS plasma_containmentactions_switchwindow DESTINATION ${KDE_INSTALL_PLUGINDIR}) install(FILES plasma-containmentactions-switchwindow.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) diff --git a/containmentactions/switchwindow/switch.cpp b/containmentactions/switchwindow/switch.cpp index dcef82fde..4107c144e 100644 --- a/containmentactions/switchwindow/switch.cpp +++ b/containmentactions/switchwindow/switch.cpp @@ -1,264 +1,264 @@ /* * Copyright 2009 by Chani Armitage * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, 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 Library 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. */ #include "switch.h" #include #include #include #include #include #include #include #include #include SwitchWindow::SwitchWindow(QObject *parent, const QVariantList &args) : Plasma::ContainmentActions(parent, args), - m_groupManager(new TaskManager::GroupManager(this)), - m_tasksModel(new TaskManager::TasksModel(m_groupManager, this)), + m_groupManager(new LegacyTaskManager::GroupManager(this)), + m_tasksModel(new LegacyTaskManager::TasksModel(m_groupManager, this)), m_mode(AllFlat), m_clearOrderTimer(0) { - m_groupManager->setGroupingStrategy(static_cast(0)); + m_groupManager->setGroupingStrategy(static_cast(0)); m_groupManager->reconnect(); } SwitchWindow::~SwitchWindow() { } void SwitchWindow::restore(const KConfigGroup &config) { m_mode = (MenuMode)config.readEntry("mode", (int)AllFlat); } QWidget* SwitchWindow::createConfigurationInterface(QWidget* parent) { QWidget *widget = new QWidget(parent); m_ui.setupUi(widget); widget->setWindowTitle(i18nc("plasma_containmentactions_switchwindow", "Configure Switch Window Plugin")); switch (m_mode) { case AllFlat: m_ui.flatButton->setChecked(true); break; case DesktopSubmenus: m_ui.subButton->setChecked(true); break; case CurrentDesktop: m_ui.curButton->setChecked(true); break; } return widget; } void SwitchWindow::configurationAccepted() { if (m_ui.flatButton->isChecked()) { m_mode = AllFlat; } else if (m_ui.subButton->isChecked()) { m_mode = DesktopSubmenus; } else { m_mode = CurrentDesktop; } } void SwitchWindow::save(KConfigGroup &config) { config.writeEntry("mode", (int)m_mode); } void SwitchWindow::makeMenu() { qDeleteAll(m_actions); m_actions.clear(); if (m_tasksModel->rowCount() == 0) { return; } QMultiHash desktops; //make all the window actions for (int i = 0; i < m_tasksModel->rowCount(); ++i) { - if (m_tasksModel->data(m_tasksModel->index(i, 0), TaskManager::TasksModel::IsStartup).toBool()) { + if (m_tasksModel->data(m_tasksModel->index(i, 0), LegacyTaskManager::TasksModel::IsStartup).toBool()) { qDebug() << "skipped fake task"; continue; } QString name = m_tasksModel->data(m_tasksModel->index(i, 0), Qt::DisplayRole).toString(); if (name.isEmpty()) { continue; } QAction *action = new QAction(name, this); action->setIcon(m_tasksModel->data(m_tasksModel->index(i, 0), Qt::DecorationRole).value()); - action->setData(m_tasksModel->data(m_tasksModel->index(i, 0), TaskManager::TasksModel::Id).toString()); - desktops.insert(m_tasksModel->data(m_tasksModel->index(i, 0), TaskManager::TasksModel::Desktop).toInt(), action); + action->setData(m_tasksModel->data(m_tasksModel->index(i, 0), LegacyTaskManager::TasksModel::Id).toString()); + desktops.insert(m_tasksModel->data(m_tasksModel->index(i, 0), LegacyTaskManager::TasksModel::Desktop).toInt(), action); connect(action, &QAction::triggered, [=]() { switchTo(action); }); } //sort into menu if (m_mode == CurrentDesktop) { int currentDesktop = KWindowSystem::currentDesktop(); QAction *a = new QAction(i18nc("plasma_containmentactions_switchwindow", "Windows"), this); a->setSeparator(true); m_actions << a; m_actions << desktops.values(currentDesktop); m_actions << desktops.values(-1); } else { int numDesktops = KWindowSystem::numberOfDesktops(); if (m_mode == AllFlat) { for (int i = 1; i <= numDesktops; ++i) { if (desktops.contains(i)) { QString name = KWindowSystem::desktopName(i); name = QStringLiteral("%1: %2").arg(i).arg(name); QAction *a = new QAction(name, this); a->setSeparator(true); m_actions << a; m_actions << desktops.values(i); } } if (desktops.contains(-1)) { QAction *a = new QAction(i18nc("plasma_containmentactions_switchwindow", "All Desktops"), this); a->setSeparator(true); m_actions << a; m_actions << desktops.values(-1); } } else { //submenus for (int i = 1; i <= numDesktops; ++i) { if (desktops.contains(i)) { QString name = KWindowSystem::desktopName(i); name = QStringLiteral("%1: %2").arg(i).arg(name); QMenu *subMenu = new QMenu(name); subMenu->addActions(desktops.values(i)); QAction *a = new QAction(name, this); a->setMenu(subMenu); m_actions << a; } } if (desktops.contains(-1)) { QMenu *subMenu = new QMenu(i18nc("plasma_containmentactions_switchwindow", "All Desktops")); subMenu->addActions(desktops.values(-1)); QAction *a = new QAction(i18nc("plasma_containmentactions_switchwindow", "All Desktops"), this); a->setMenu(subMenu); m_actions << a; } } } } QList SwitchWindow::contextualActions() { makeMenu(); return m_actions; } void SwitchWindow::switchTo(QAction *action) { int id = action->data().toInt(); qDebug() << id; - TaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(id); + LegacyTaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(id); if (!item) { return; } - TaskManager::TaskItem* taskItem = static_cast(item); + LegacyTaskManager::TaskItem* taskItem = static_cast(item); taskItem->task()->activateRaiseOrIconify(); } void SwitchWindow::clearWindowsOrder() { qDebug() << "CLEARING>......................."; m_windowsOrder.clear(); } void SwitchWindow::performNextAction() { doSwitch(true); } void SwitchWindow::performPreviousAction() { doSwitch(false); } void SwitchWindow::doSwitch(bool up) { //TODO somehow find the "next" or "previous" window //without changing hte window order (don't want to always go between two windows) if (m_windowsOrder.isEmpty()) { m_windowsOrder = KWindowSystem::stackingOrder(); } else { if (!m_clearOrderTimer) { m_clearOrderTimer = new QTimer(this); connect(m_clearOrderTimer, &QTimer::timeout, this, &SwitchWindow::clearWindowsOrder); m_clearOrderTimer->setSingleShot(true); m_clearOrderTimer->setInterval(1000); } m_clearOrderTimer->start(); } const WId activeWindow = KWindowSystem::activeWindow(); bool next = false; WId first = 0; WId last = 0; for (int i = 0; i < m_windowsOrder.count(); ++i) { const WId id = m_windowsOrder.at(i); const KWindowInfo info(id, NET::WMDesktop | NET::WMVisibleName | NET::WMWindowType); if (info.windowType(NET::NormalMask | NET::DialogMask | NET::UtilityMask) != -1 && info.isOnCurrentDesktop()) { if (next) { KWindowSystem::forceActiveWindow(id); return; } if (first == 0) { first = id; } if (id == activeWindow) { if (up) { next = true; } else if (last) { KWindowSystem::forceActiveWindow(last); return; } } last = id; } } KWindowSystem::forceActiveWindow(up ? first : last); } K_EXPORT_PLASMA_CONTAINMENTACTIONS_WITH_JSON(switchwindow, SwitchWindow, "plasma-containmentactions-switchwindow.json") #include "switch.moc" diff --git a/containmentactions/switchwindow/switch.h b/containmentactions/switchwindow/switch.h index 3c749017c..7db3ea434 100644 --- a/containmentactions/switchwindow/switch.h +++ b/containmentactions/switchwindow/switch.h @@ -1,79 +1,79 @@ /* * Copyright 2009 by Chani Armitage * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, 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 Library 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 SWITCHWINDOW_HEADER #define SWITCHWINDOW_HEADER #include "ui_config.h" #include -// libtaskmanager -#include +// liblegacytaskmanager +#include #include #include class QAction; class QTimer; -namespace TaskManager +namespace LegacyTaskManager { class Task; -} // namespace TaskManager +} // namespace LegacyTaskManager class SwitchWindow : public Plasma::ContainmentActions { Q_OBJECT public: SwitchWindow(QObject* parent, const QVariantList& args); ~SwitchWindow() override; void restore(const KConfigGroup &config) override; QWidget* createConfigurationInterface(QWidget* parent) override; void configurationAccepted() override; void save(KConfigGroup &config) override; void performNextAction() override; void performPreviousAction() override; void doSwitch(bool up); QList contextualActions() override; private: void makeMenu(); private Q_SLOTS: void clearWindowsOrder(); void switchTo(QAction *action); private: enum MenuMode { AllFlat = 0, DesktopSubmenus, CurrentDesktop }; QList m_actions; - TaskManager::GroupManager *m_groupManager; - TaskManager::TasksModel *m_tasksModel; + LegacyTaskManager::GroupManager *m_groupManager; + LegacyTaskManager::TasksModel *m_tasksModel; Ui::Config m_ui; MenuMode m_mode; QTimer *m_clearOrderTimer; QList m_windowsOrder; }; #endif diff --git a/dataengines/tasks/CMakeLists.txt b/dataengines/tasks/CMakeLists.txt index f81b59723..46b19de7a 100644 --- a/dataengines/tasks/CMakeLists.txt +++ b/dataengines/tasks/CMakeLists.txt @@ -1,23 +1,23 @@ set(tasks_engine_SRCS tasksengine.cpp taskservice.cpp taskjob.cpp virtualdesktopssource.cpp taskwindowservice.cpp taskwindowjob.cpp ) add_library(plasma_engine_tasks MODULE ${tasks_engine_SRCS}) target_link_libraries(plasma_engine_tasks KF5::CoreAddons KF5::Service KF5::WindowSystem KF5::Plasma Qt5::DBus - taskmanager) + legacytaskmanager) kcoreaddons_desktop_to_json(plasma_engine_tasks plasma-dataengine-tasks.desktop) install(TARGETS plasma_engine_tasks DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/dataengine) install(FILES plasma-dataengine-tasks.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) install(FILES tasks.operations DESTINATION ${PLASMA_DATA_INSTALL_DIR}/services) install(FILES windowtasks.operations DESTINATION ${PLASMA_DATA_INSTALL_DIR}/services) diff --git a/dataengines/tasks/taskjob.cpp b/dataengines/tasks/taskjob.cpp index 3c8246fbd..595ebdf7d 100644 --- a/dataengines/tasks/taskjob.cpp +++ b/dataengines/tasks/taskjob.cpp @@ -1,140 +1,140 @@ /* * Copyright 2008 Alain Boyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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. */ #include "taskjob.h" -TaskJob::TaskJob(const TaskManager::TasksModel *model, const TaskManager::GroupManager *groupManager, const QString &operation, QMap ¶meters, QObject *parent) : +TaskJob::TaskJob(const LegacyTaskManager::TasksModel *model, const LegacyTaskManager::GroupManager *groupManager, const QString &operation, QMap ¶meters, QObject *parent) : ServiceJob(model->objectName(), operation, parameters, parent), m_model(model), m_groupManager(groupManager) { } TaskJob::~TaskJob() { } void TaskJob::start() { - TaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(parameters().value(QStringLiteral("Id")).toInt()); + LegacyTaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(parameters().value(QStringLiteral("Id")).toInt()); if (!item) { return; } - TaskManager::TaskItem* taskItem = static_cast(item); + LegacyTaskManager::TaskItem* taskItem = static_cast(item); // only a subset of task operations are exported const QString operation = operationName(); if (operation == QLatin1String("setMaximized")) { taskItem->task()->setMaximized(parameters().value(QStringLiteral("maximized")).toBool()); setResult(true); return; } else if (operation == QLatin1String("setMinimized")) { taskItem->task()->setIconified(parameters().value(QStringLiteral("minimized")).toBool()); setResult(true); return; } else if (operation == QLatin1String("setShaded")) { taskItem->task()->setShaded(parameters().value(QStringLiteral("shaded")).toBool()); setResult(true); return; } else if (operation == QLatin1String("setFullScreen")) { taskItem->task()->setFullScreen(parameters().value(QStringLiteral("fullScreen")).toBool()); setResult(true); return; } else if (operation == QLatin1String("setAlwaysOnTop")) { taskItem->task()->setAlwaysOnTop(parameters().value(QStringLiteral("alwaysOnTop")).toBool()); setResult(true); return; } else if (operation == QLatin1String("setKeptBelowOthers")) { taskItem->task()->setKeptBelowOthers(parameters().value(QStringLiteral("keptBelowOthers")).toBool()); setResult(true); return; } else if (operation == QLatin1String("toggleMaximized")) { taskItem->task()->toggleMaximized(); setResult(true); return; } else if (operation == QLatin1String("toggleMinimized")) { taskItem->task()->toggleIconified(); setResult(true); return; } else if (operation == QLatin1String("toggleShaded")) { taskItem->task()->toggleShaded(); setResult(true); return; } else if (operation == QLatin1String("toggleFullScreen")) { taskItem->task()->toggleFullScreen(); setResult(true); return; } else if (operation == QLatin1String("toggleAlwaysOnTop")) { taskItem->task()->toggleAlwaysOnTop(); setResult(true); return; } else if (operation == QLatin1String("toggleKeptBelowOthers")) { taskItem->task()->toggleKeptBelowOthers(); setResult(true); return; } else if (operation == QLatin1String("restore")) { taskItem->task()->restore(); setResult(true); return; } else if (operation == QLatin1String("resize")) { taskItem->task()->resize(); setResult(true); return; } else if (operation == QLatin1String("move")) { taskItem->task()->move(); setResult(true); return; } else if (operation == QLatin1String("raise")) { taskItem->task()->raise(); setResult(true); return; } else if (operation == QLatin1String("lower")) { taskItem->task()->lower(); setResult(true); return; } else if (operation == QLatin1String("activate")) { taskItem->task()->activate(); setResult(true); return; } else if (operation == QLatin1String("activateRaiseOrIconify")) { taskItem->task()->activateRaiseOrIconify(); setResult(true); return; } else if (operation == QLatin1String("close")) { taskItem->task()->close(); setResult(true); return; } else if (operation == QLatin1String("toDesktop")) { taskItem->task()->toDesktop(parameters().value(QStringLiteral("desktop")).toInt()); setResult(true); return; } else if (operation == QLatin1String("toCurrentDesktop")) { taskItem->task()->toCurrentDesktop(); setResult(true); return; } else if (operation == QLatin1String("publishIconGeometry")) { taskItem->task()->publishIconGeometry(parameters().value(QStringLiteral("geometry")).toRect()); setResult(true); return; } setResult(false); } diff --git a/dataengines/tasks/taskjob.h b/dataengines/tasks/taskjob.h index d1592b847..7de030189 100644 --- a/dataengines/tasks/taskjob.h +++ b/dataengines/tasks/taskjob.h @@ -1,52 +1,52 @@ /* * Copyright 2008 Alain Boyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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 TASKJOB_H #define TASKJOB_H // plasma #include -//taskmanager +//legacytaskmanager #include #include #include #include /** * Task Job */ class TaskJob : public Plasma::ServiceJob { Q_OBJECT public: - TaskJob(const TaskManager::TasksModel *model, const TaskManager::GroupManager *groupManager, const QString &operation, QMap ¶meters, QObject *parent = NULL); + TaskJob(const LegacyTaskManager::TasksModel *model, const LegacyTaskManager::GroupManager *groupManager, const QString &operation, QMap ¶meters, QObject *parent = NULL); ~TaskJob() override; protected: void start() override; private: - const TaskManager::TasksModel *m_model; - const TaskManager::GroupManager *m_groupManager; + const LegacyTaskManager::TasksModel *m_model; + const LegacyTaskManager::GroupManager *m_groupManager; }; #endif // TASKJOB_H diff --git a/dataengines/tasks/tasksengine.cpp b/dataengines/tasks/tasksengine.cpp index 449a95677..6ad103f36 100644 --- a/dataengines/tasks/tasksengine.cpp +++ b/dataengines/tasks/tasksengine.cpp @@ -1,71 +1,71 @@ /* * Copyright 2007 Robert Knight * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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. */ #include #include "tasksengine.h" #include "virtualdesktopssource.h" // own #include "taskservice.h" #include "taskwindowservice.h" TasksEngine::TasksEngine(QObject *parent, const QVariantList &args) : Plasma::DataEngine(parent, args), - m_groupManager(new TaskManager::GroupManager(this)), - m_tasksModel(new TaskManager::TasksModel(m_groupManager, this)) + m_groupManager(new LegacyTaskManager::GroupManager(this)), + m_tasksModel(new LegacyTaskManager::TasksModel(m_groupManager, this)) { Q_UNUSED(args); //TODO HACK Remove //TasksModel does not initialize itself, So we need to set grouping strategy. - m_groupManager->setGroupingStrategy(TaskManager::GroupManager::NoGrouping); - m_groupManager->setSortingStrategy(TaskManager::GroupManager::DesktopSorting); + m_groupManager->setGroupingStrategy(LegacyTaskManager::GroupManager::NoGrouping); + m_groupManager->setSortingStrategy(LegacyTaskManager::GroupManager::DesktopSorting); setModel(QStringLiteral("tasks"), m_tasksModel); m_groupManager->reconnect(); } TasksEngine::~TasksEngine() { } Plasma::Service *TasksEngine::serviceForSource(const QString &name) { Plasma::Service *service; if (name.isEmpty()) { service = new TaskWindowService(); } else if (name == QLatin1String("tasks")) { service = new TaskService(m_tasksModel, m_groupManager); } else { service = Plasma::DataEngine::serviceForSource(name); } service->setParent(this); return service; } bool TasksEngine::sourceRequestEvent(const QString &source) { if (source == QLatin1String("virtualDesktops")) { addSource(new VirtualDesktopsSource); return true; } return false; } K_EXPORT_PLASMA_DATAENGINE_WITH_JSON(tasks, TasksEngine, "plasma-dataengine-tasks.json") #include "tasksengine.moc" diff --git a/dataengines/tasks/tasksengine.h b/dataengines/tasks/tasksengine.h index 7cb794cae..38a8744e2 100644 --- a/dataengines/tasks/tasksengine.h +++ b/dataengines/tasks/tasksengine.h @@ -1,70 +1,70 @@ /* * Copyright 2007 Robert Knight * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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 TASKSENGINE_H #define TASKSENGINE_H // plasma #include #include -// libtaskmanager -#include +// liblegacytaskmanager +#include #include #include -namespace TaskManager +namespace LegacyTaskManager { class Task; -} // namespace TaskManager +} // namespace LegacyTaskManager /** * Tasks Data Engine * * This engine provides information regarding tasks (windows that are currently open) * as well as startup tasks (windows that are about to open). * Each task and startup is represented by a unique source. Sources are added and removed * as windows are opened and closed. You cannot request a customized source. * * A service is also provided for each task. It exposes some operations that can be * performed on the windows (ex: maximize, minimize, activate). * - * The data and operations are provided and handled by the taskmanager library. + * The data and operations are provided and handled by the legacytaskmanager library. * It should be noted that only a subset of data and operations are exposed. */ class TasksEngine : public Plasma::DataEngine { Q_OBJECT public: TasksEngine(QObject *parent, const QVariantList &args); ~TasksEngine() override; Plasma::Service *serviceForSource(const QString &name) override; protected: bool sourceRequestEvent(const QString &source) override; private: friend class TaskSource; friend class TaskWindowService; - TaskManager::GroupManager *m_groupManager; - TaskManager::TasksModel *m_tasksModel; + LegacyTaskManager::GroupManager *m_groupManager; + LegacyTaskManager::TasksModel *m_tasksModel; }; #endif // TASKSENGINE_H diff --git a/dataengines/tasks/taskservice.cpp b/dataengines/tasks/taskservice.cpp index ea5670912..66aeb3e5b 100644 --- a/dataengines/tasks/taskservice.cpp +++ b/dataengines/tasks/taskservice.cpp @@ -1,44 +1,44 @@ /* * Copyright 2008 Alain Boyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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. */ #include #include #include "taskservice.h" // own #include "taskjob.h" -TaskService::TaskService(TaskManager::TasksModel *model, TaskManager::GroupManager *groupManager) : +TaskService::TaskService(LegacyTaskManager::TasksModel *model, LegacyTaskManager::GroupManager *groupManager) : Plasma::Service(), m_model(model), m_groupManager(groupManager) { setName(QStringLiteral("tasks")); } TaskService::~TaskService() { } Plasma::ServiceJob *TaskService::createJob(const QString &operation, QMap ¶meters) { return new TaskJob(m_model, m_groupManager, operation, parameters, this); } #include "taskservice.moc" diff --git a/dataengines/tasks/taskservice.h b/dataengines/tasks/taskservice.h index 089b8fc9b..f669a129e 100644 --- a/dataengines/tasks/taskservice.h +++ b/dataengines/tasks/taskservice.h @@ -1,49 +1,49 @@ /* * Copyright 2008 Alain Boyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 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 Library 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 TASKSERVICE_H #define TASKSERVICE_H // plasma #include #include #include #include /** * Task Service */ class TaskService : public Plasma::Service { Q_OBJECT public: - TaskService(TaskManager::TasksModel *model, TaskManager::GroupManager *groupManager); + TaskService(LegacyTaskManager::TasksModel *model, LegacyTaskManager::GroupManager *groupManager); ~TaskService() override; protected: Plasma::ServiceJob *createJob(const QString &operation, QMap ¶meters) override; private: - TaskManager::TasksModel *m_model; - TaskManager::GroupManager *m_groupManager; + LegacyTaskManager::TasksModel *m_model; + LegacyTaskManager::GroupManager *m_groupManager; }; #endif // TASKSERVICE_H diff --git a/libtaskmanager/CMakeLists.txt b/liblegacytaskmanager/CMakeLists.txt similarity index 50% rename from libtaskmanager/CMakeLists.txt rename to liblegacytaskmanager/CMakeLists.txt index 4f813304b..dab11b3bf 100644 --- a/libtaskmanager/CMakeLists.txt +++ b/liblegacytaskmanager/CMakeLists.txt @@ -1,124 +1,124 @@ find_package(KF5Activities REQUIRED) add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1204) add_definitions(-DTRANSLATION_DOMAIN=\"libtaskmanager\") remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_FROM_BYTEARRAY) ########### next target ############### -set(taskmanager_LIB_SRCS +set(legacytaskmanager_LIB_SRCS abstractgroupableitem.cpp abstractgroupingstrategy.cpp abstractsortingstrategy.cpp groupmanager.cpp launcheritem.cpp startup.cpp strategies/activitysortingstrategy.cpp strategies/alphasortingstrategy.cpp strategies/desktopsortingstrategy.cpp strategies/programgroupingstrategy.cpp strategies/manualgroupingstrategy.cpp strategies/manualsortingstrategy.cpp task.cpp taskactions.cpp taskgroup.cpp taskitem.cpp - taskmanager.cpp + legacytaskmanager.cpp tasksmodel.cpp launcherconfig.cpp launcherproperties.cpp ) -ki18n_wrap_ui(taskmanager_LIB_SRCS launcherconfig.ui launcherproperties.ui) +ki18n_wrap_ui(legacytaskmanager_LIB_SRCS launcherconfig.ui launcherproperties.ui) if(WIN32) - set(taskmanager_LIB_SRCS ${taskmanager_LIB_SRCS} task_win.cpp) + set(legacytaskmanager_LIB_SRCS ${legacytaskmanager_LIB_SRCS} task_win.cpp) else() - set(taskmanager_LIB_SRCS ${taskmanager_LIB_SRCS} task_x11.cpp) + set(legacytaskmanager_LIB_SRCS ${legacytaskmanager_LIB_SRCS} task_x11.cpp) endif() -add_library(taskmanager ${taskmanager_LIB_SRCS}) -add_library(PW::LibTaskManager ALIAS taskmanager) -generate_export_header(taskmanager) -target_include_directories(taskmanager PUBLIC "$" "$") -target_link_libraries(taskmanager +add_library(legacytaskmanager ${legacytaskmanager_LIB_SRCS}) +add_library(PW::LibLegacyTaskManager ALIAS legacytaskmanager) +generate_export_header(legacytaskmanager) +target_include_directories(legacytaskmanager PUBLIC "$" "$") +target_link_libraries(legacytaskmanager PUBLIC Qt5::Core Qt5::Gui KF5::WindowSystem # KStartupInfo PRIVATE KF5::Activities KF5::ProcessCore KF5::ConfigCore KF5::ConfigWidgets KF5::IconThemes KF5::I18n KF5::KIOCore KF5::KIOWidgets # KRun KF5::Service ) if (X11_FOUND) - target_link_libraries(taskmanager PRIVATE ${Qt5X11Extras_LIBRARIES} ${X11_LIBRARIES}) + target_link_libraries(legacytaskmanager PRIVATE ${Qt5X11Extras_LIBRARIES} ${X11_LIBRARIES}) if (X11_Xfixes_FOUND) - target_link_libraries(taskmanager PRIVATE ${X11_Xfixes_LIB}) + target_link_libraries(legacytaskmanager PRIVATE ${X11_Xfixes_LIB}) endif () if (X11_Xrender_FOUND) - target_link_libraries(taskmanager PRIVATE ${X11_Xrender_LIB}) + target_link_libraries(legacytaskmanager PRIVATE ${X11_Xrender_LIB}) endif () if (X11_Xcomposite_FOUND) - target_link_libraries(taskmanager PRIVATE ${X11_Xcomposite_LIB}) + target_link_libraries(legacytaskmanager PRIVATE ${X11_Xcomposite_LIB}) endif () endif() -set_target_properties(taskmanager PROPERTIES +set_target_properties(legacytaskmanager PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} - EXPORT_NAME LibTaskManager) -install(TARGETS taskmanager EXPORT libtaskmanagerLibraryTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) + EXPORT_NAME LibLegacyTaskManager) +install(TARGETS legacytaskmanager EXPORT liblegacytaskmanagerLibraryTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) install(FILES abstractgroupableitem.h abstractgroupingstrategy.h abstractsortingstrategy.h groupmanager.h launcheritem.h startup.h task.h taskactions.h taskgroup.h taskitem.h - taskmanager.h + legacytaskmanager.h tasksmodel.h - ${CMAKE_CURRENT_BINARY_DIR}/taskmanager_export.h - DESTINATION ${KDE_INSTALL_INCLUDEDIR}/taskmanager COMPONENT Devel + ${CMAKE_CURRENT_BINARY_DIR}/legacytaskmanager_export.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR}/legacytaskmanager COMPONENT Devel ) -write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/LibTaskManagerConfigVersion.cmake VERSION "${PROJECT_VERSION}" COMPATIBILITY AnyNewerVersion) +write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/LibLegacyTaskManagerConfigVersion.cmake VERSION "${PROJECT_VERSION}" COMPATIBILITY AnyNewerVersion) -set(CMAKECONFIG_INSTALL_DIR ${KDE_INSTALL_LIBDIR}/cmake/LibTaskManager) -ecm_configure_package_config_file(LibTaskManagerConfig.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/LibTaskManagerConfig.cmake" +set(CMAKECONFIG_INSTALL_DIR ${KDE_INSTALL_LIBDIR}/cmake/LibLegacyTaskManager) +ecm_configure_package_config_file(LibLegacyTaskManagerConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/LibLegacyTaskManagerConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LibTaskManagerConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/LibTaskManagerConfigVersion.cmake +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LibLegacyTaskManagerConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LibLegacyTaskManagerConfigVersion.cmake DESTINATION ${CMAKECONFIG_INSTALL_DIR}) -install(EXPORT libtaskmanagerLibraryTargets +install(EXPORT liblegacytaskmanagerLibraryTargets NAMESPACE PW:: DESTINATION ${CMAKECONFIG_INSTALL_DIR} - FILE LibTaskManagerLibraryTargets.cmake ) + FILE LibLegacyTaskManagerLibraryTargets.cmake ) -install(FILES taskmanagerrulesrc +install(FILES legacytaskmanagerrulesrc DESTINATION ${KDE_INSTALL_CONFDIR}) #set(tasksmodel_SRCS # modeltest/dynamictreemodel.cpp # modeltest/modeltest.cpp # modeltest/main.cpp # ) #add_executable(tasksmodeltest ${tasksmodel_SRCS}) #target_link_libraries(tasksmodeltest KF5::KIOCore KF5::KIOWidgets ${X11_LIBRARIES} taskmanager kephal) diff --git a/liblegacytaskmanager/LibLegacyTaskManagerConfig.cmake.in b/liblegacytaskmanager/LibLegacyTaskManagerConfig.cmake.in new file mode 100644 index 000000000..6479dab45 --- /dev/null +++ b/liblegacytaskmanager/LibLegacyTaskManagerConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +find_dependency(KF5SysGuard) +include("${CMAKE_CURRENT_LIST_DIR}/LibLegacyTaskManagerLibraryTargets.cmake") diff --git a/libtaskmanager/Mainpage.dox b/liblegacytaskmanager/Mainpage.dox similarity index 73% rename from libtaskmanager/Mainpage.dox rename to liblegacytaskmanager/Mainpage.dox index 11dbb7f2e..ae6bc86f3 100644 --- a/libtaskmanager/Mainpage.dox +++ b/liblegacytaskmanager/Mainpage.dox @@ -1,21 +1,21 @@ /** @mainpage Task management library -This directory contains the classes making up libtaskmanager, which +This directory contains the classes making up liblegacytaskmanager, which provides task management facilities such as might be useful for a taskbar implementation. @authors Matthias Elter \ Richard Moore \ John Firebaugh \ @maintainers Aaron Seigo \ @licenses @lgpl */ -// DOXYGEN_SET_PROJECT_NAME = libtaskmanager +// DOXYGEN_SET_PROJECT_NAME = liblegacytaskmanager // vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/libtaskmanager/Messages.sh b/liblegacytaskmanager/Messages.sh similarity index 100% rename from libtaskmanager/Messages.sh rename to liblegacytaskmanager/Messages.sh diff --git a/libtaskmanager/abstractgroupableitem.cpp b/liblegacytaskmanager/abstractgroupableitem.cpp similarity index 97% rename from libtaskmanager/abstractgroupableitem.cpp rename to liblegacytaskmanager/abstractgroupableitem.cpp index 289e23cfc..398c60611 100644 --- a/libtaskmanager/abstractgroupableitem.cpp +++ b/liblegacytaskmanager/abstractgroupableitem.cpp @@ -1,152 +1,152 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "abstractgroupableitem.h" #include #include #include #include "taskgroup.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" -namespace TaskManager +namespace LegacyTaskManager { class AbstractGroupableItem::Private { public: Private() : m_id(m_nextId++) { } QPointer m_parentGroup; int m_id; private: static int m_nextId; }; int AbstractGroupableItem::Private::m_nextId = 1; AbstractGroupableItem::AbstractGroupableItem(QObject *parent) : QObject(parent), d(new Private) { } AbstractGroupableItem::~AbstractGroupableItem() { //qDebug(); /*if (parentGroup()) { qDebug() << "Error: item gets destroyed but still has a parent group"; }*/ delete d; } bool AbstractGroupableItem::isGrouped() const { return d->m_parentGroup && d->m_parentGroup.data()->parentGroup(); } QIcon AbstractGroupableItem::icon() const { return QIcon(); } QString AbstractGroupableItem::name() const { return QString(); } QString AbstractGroupableItem::genericName() const { return QString(); } int AbstractGroupableItem::id() const { return d->m_id; } WindowList AbstractGroupableItem::winIds() const { return WindowList(); } GroupPtr AbstractGroupableItem::parentGroup() const { //qDebug(); return d->m_parentGroup.data(); } void AbstractGroupableItem::setParentGroup(const GroupPtr group) { d->m_parentGroup = group; } //Item is member of group bool AbstractGroupableItem::isGroupMember(const GroupPtr group) const { //qDebug(); if (!group) { //qDebug() << "Null Group Pointer"; return false; } if (!parentGroup()) { return false; } return group->members().contains(const_cast(this)); } bool AbstractGroupableItem::isStartupItem() const { return false; } void AbstractGroupableItem::launchNewInstance() const { const QUrl &url = launcherUrl(); if (url.isValid()) { new KRun(url, 0); } } -} // TaskManager namespace +} // LegacyTaskManager namespace diff --git a/libtaskmanager/abstractgroupableitem.h b/liblegacytaskmanager/abstractgroupableitem.h similarity index 92% rename from libtaskmanager/abstractgroupableitem.h rename to liblegacytaskmanager/abstractgroupableitem.h index 8ec883648..b2ce2f9e5 100644 --- a/libtaskmanager/abstractgroupableitem.h +++ b/liblegacytaskmanager/abstractgroupableitem.h @@ -1,147 +1,147 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef ABSTRACTGROUPABLEITEM_H #define ABSTRACTGROUPABLEITEM_H #include #include #include -#include "taskmanager.h" -#include "taskmanager_export.h" +#include "legacytaskmanager.h" +#include "legacytaskmanager_export.h" -namespace TaskManager +namespace LegacyTaskManager { class TaskGroup; class AbstractGroupableItem; enum ItemType { GroupItemType, LauncherItemType, TaskItemType }; typedef TaskGroup* GroupPtr; typedef QList ItemList; typedef QList GroupList; /** * Abstract Class for an Item that is groupable * So groups can handle tasks and subgroups the same way */ -class TASKMANAGER_EXPORT AbstractGroupableItem : public QObject +class LEGACYTASKMANAGER_EXPORT AbstractGroupableItem : public QObject { Q_OBJECT public: AbstractGroupableItem(QObject *parent); ~AbstractGroupableItem() override; virtual QIcon icon() const; virtual QString name() const; virtual QString genericName() const; virtual WindowList winIds() const; /** * @return unique identifier of this item */ int id() const; /** * Returns the parent group of this item */ GroupPtr parentGroup() const; /** * Not only member of rootGroup */ bool isGrouped() const; bool isGroupMember(const GroupPtr group) const; virtual ItemType itemType() const = 0; /** * @deprecated: use itemType() instead **/ - TASKMANAGER_DEPRECATED virtual bool isGroupItem() const = 0; + LEGACYTASKMANAGER_DEPRECATED virtual bool isGroupItem() const = 0; virtual bool isStartupItem() const; virtual bool isOnCurrentDesktop() const = 0; virtual bool isOnAllDesktops() const = 0; virtual int desktop() const = 0; virtual bool isShaded() const = 0; virtual bool isMaximized() const = 0; virtual bool isMinimized() const = 0; virtual bool isFullScreen() const = 0; virtual bool isKeptBelowOthers() const = 0; virtual bool isAlwaysOnTop() const = 0; virtual bool isActionSupported(NET::Action) const = 0; virtual bool isActive() const = 0; virtual bool demandsAttention() const = 0; virtual void addMimeData(QMimeData *) const = 0; virtual QUrl launcherUrl() const = 0; virtual void launchNewInstance() const; public Q_SLOTS: /** Functions that both, Tasks and Groups have */ virtual void toDesktop(int) = 0; virtual void setShaded(bool) = 0; virtual void toggleShaded() = 0; virtual void setMaximized(bool) = 0; virtual void toggleMaximized() = 0; virtual void setMinimized(bool) = 0; virtual void toggleMinimized() = 0; virtual void setFullScreen(bool) = 0; virtual void toggleFullScreen() = 0; virtual void setKeptBelowOthers(bool) = 0; virtual void toggleKeptBelowOthers() = 0; virtual void setAlwaysOnTop(bool) = 0; virtual void toggleAlwaysOnTop() = 0; virtual void close() = 0; void setParentGroup(const GroupPtr group); /*void removedFromGroup(); void addedToGroup(const GroupPtr group);*/ Q_SIGNALS: - void changed(::TaskManager::TaskChanges changes); + void changed(::LegacyTaskManager::TaskChanges changes); void destroyed(AbstractGroupableItem *); private: class Private; Private * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/abstractgroupingstrategy.cpp b/liblegacytaskmanager/abstractgroupingstrategy.cpp similarity index 99% rename from libtaskmanager/abstractgroupingstrategy.cpp rename to liblegacytaskmanager/abstractgroupingstrategy.cpp index cdaa74254..274e01bae 100644 --- a/libtaskmanager/abstractgroupingstrategy.cpp +++ b/liblegacytaskmanager/abstractgroupingstrategy.cpp @@ -1,280 +1,280 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "abstractgroupingstrategy.h" #include #include "task.h" -namespace TaskManager +namespace LegacyTaskManager { class AbstractGroupingStrategy::Private { public: Private() : type(GroupManager::NoGrouping) , destroyGroupsOnDestruction(true) { } GroupManager *groupManager; QStringList usedNames; QList createdGroups; GroupManager::TaskGroupingStrategy type; bool destroyGroupsOnDestruction : 1; }; AbstractGroupingStrategy::AbstractGroupingStrategy(GroupManager *groupManager) : QObject(groupManager), d(new Private) { d->groupManager = groupManager; } AbstractGroupingStrategy::~AbstractGroupingStrategy() { if (d->destroyGroupsOnDestruction) { destroyGroups(); qDeleteAll(d->createdGroups); } delete d; } bool AbstractGroupingStrategy::destroyGroupsOnDestruction() const { return d->destroyGroupsOnDestruction; } void AbstractGroupingStrategy::setDestroyGroupsOnDestruction(bool destroy) { d->destroyGroupsOnDestruction = destroy; } void AbstractGroupingStrategy::destroyGroups() { // cleanup all created groups foreach (TaskGroup * group, d->createdGroups) { disconnect(group, 0, this, 0); TaskGroup *parentGroup = group->parentGroup(); if (!parentGroup) { parentGroup = d->groupManager->rootGroup(); } foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() != GroupItemType) { parentGroup->add(item); } } parentGroup->remove(group); } foreach (TaskGroup * group, d->createdGroups) { emit groupRemoved(group); } } GroupManager::TaskGroupingStrategy AbstractGroupingStrategy::type() const { return d->type; } void AbstractGroupingStrategy::setType(GroupManager::TaskGroupingStrategy type) { d->type = type; } void AbstractGroupingStrategy::desktopChanged(int newDesktop) { Q_UNUSED(newDesktop) } QList AbstractGroupingStrategy::strategyActions(QObject *parent, AbstractGroupableItem *item) { Q_UNUSED(parent) Q_UNUSED(item) return QList(); } GroupPtr AbstractGroupingStrategy::rootGroup() const { if (d->groupManager) { return d->groupManager->rootGroup(); } return 0; } TaskGroup* AbstractGroupingStrategy::createGroup(ItemList items) { GroupPtr oldGroup; if (!items.isEmpty() && items.first()->isGrouped()) { oldGroup = items.first()->parentGroup(); } else { oldGroup = rootGroup(); } TaskGroup *newGroup = new TaskGroup(d->groupManager); ItemList oldGroupMembers = oldGroup->members(); int index = oldGroupMembers.count(); d->createdGroups.append(newGroup); //qDebug() << "added group" << d->createdGroups.count(); // NOTE: Queued is vital to make sure groups only get removed after their children, for // correct QAbstractItemModel (TasksModel) transaction semantics. connect(newGroup, &TaskGroup::itemRemoved, this, &AbstractGroupingStrategy::checkGroup, Qt::QueuedConnection); foreach (AbstractGroupableItem * item, items) { int idx = oldGroupMembers.indexOf(item); if (idx >= 0 && idx < index) { index = idx; } newGroup->add(item); } Q_ASSERT(oldGroup); // Place new group where first of the moved items was... oldGroup->add(newGroup, index); return newGroup; } void AbstractGroupingStrategy::closeGroup(TaskGroup *group) { Q_ASSERT(group); disconnect(group, 0, this, 0); d->createdGroups.removeAll(group); //qDebug() << "closig group" << group->name() << d->createdGroups.count(); d->usedNames.removeAll(group->name()); //d->usedIcons.removeAll(group->icon());//TODO TaskGroup *parentGroup = group->parentGroup(); if (!parentGroup) { parentGroup = rootGroup(); } if (parentGroup && d->groupManager) { int index = parentGroup->members().indexOf(group); foreach (AbstractGroupableItem * item, group->members()) { parentGroup->add(item, index); //move item to the location where its group was if (!d->groupManager) { // this means that the above add() caused a change in grouping strategy break; } } parentGroup->remove(group); } emit groupRemoved(group); // FIXME: due to a bug in Qt 4.x, the event loop reference count is incorrect // when going through x11EventFilter .. :/ so we have to singleShot the deleteLater QTimer::singleShot(0, group, &QObject::deleteLater); } void AbstractGroupingStrategy::checkGroup() { TaskGroup *group = qobject_cast(sender()); if (!group) { return; } if (group->members().size() <= 0) { closeGroup(group); } } bool AbstractGroupingStrategy::manualGroupingRequest(AbstractGroupableItem* taskItem, TaskGroup* groupItem) { if (editableGroupProperties() & Members) { groupItem->add(taskItem); return true; } return false; } //TODO move to manual strategy? bool AbstractGroupingStrategy::manualGroupingRequest(ItemList items) { if (editableGroupProperties() & Members) { TaskGroup *group = createGroup(items); setName(nameSuggestions(group).first(), group); setIcon(iconSuggestions(group).first(), group); return true; } return false; } bool AbstractGroupingStrategy::setName(const QString &name, TaskGroup *group) { d->usedNames.removeAll(group->name()); if ((editableGroupProperties() & Name) && (!d->usedNames.contains(name))) { d->usedNames.append(name); group->setName(name); return true; } return false; } //Returns 6 free names QList AbstractGroupingStrategy::nameSuggestions(TaskGroup *) { QList nameList; int i = 1; while (nameList.count() < 6) { if (!d->usedNames.contains("Group" + QString::number(i))) { nameList.append("Group" + QString::number(i)); } i++; } if (nameList.isEmpty()) { nameList.append(QStringLiteral("default")); } return nameList; } bool AbstractGroupingStrategy::setIcon(const QIcon &icon, TaskGroup *group) { if (editableGroupProperties() & Icon) { group->setIcon(icon); return true; } return false; } QList AbstractGroupingStrategy::iconSuggestions(TaskGroup *) { QList iconList; iconList.append(QIcon::fromTheme(QStringLiteral("xorg"))); return iconList; } }//namespace diff --git a/libtaskmanager/abstractgroupingstrategy.h b/liblegacytaskmanager/abstractgroupingstrategy.h similarity index 96% rename from libtaskmanager/abstractgroupingstrategy.h rename to liblegacytaskmanager/abstractgroupingstrategy.h index 475dd39f4..a0f755cbe 100644 --- a/libtaskmanager/abstractgroupingstrategy.h +++ b/liblegacytaskmanager/abstractgroupingstrategy.h @@ -1,143 +1,143 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef ABSTRACTGROUPINGSTRATEGY_H #define ABSTRACTGROUPINGSTRATEGY_H #include #include "abstractgroupableitem.h" #include "groupmanager.h" #include "taskgroup.h" -#include "taskmanager_export.h" +#include "legacytaskmanager_export.h" class QAction; -namespace TaskManager +namespace LegacyTaskManager { /** * Base class for strategies which can be used to * automatically group tasks. */ -class TASKMANAGER_EXPORT AbstractGroupingStrategy : public QObject +class LEGACYTASKMANAGER_EXPORT AbstractGroupingStrategy : public QObject { Q_OBJECT public: AbstractGroupingStrategy(GroupManager *groupManager); ~AbstractGroupingStrategy() override; /** * Whether the grouping strategy will undo the current group topology * when it is destroyed. * * See also destroyGroups(). */ bool destroyGroupsOnDestruction() const; /** * Setting this to false prevents the grouping strategy from undoing * the current group toplogy when it is destroyed. This is mostly * useful to avoid unnecessary work during shutdown. * * See also destroyGroups(). */ void setDestroyGroupsOnDestruction(bool destroy); /** Handles a new item */ virtual void handleItem(AbstractGroupableItem *) = 0; /** Returns the strategy type */ GroupManager::TaskGroupingStrategy type() const; /** DesktopChanges time to backup any needed data */ virtual void desktopChanged(int newDesktop); /** * Returns list of actions that a task can do in this groupingStrategy * If the visualization supports grouping it has to show these actions. */ virtual QList strategyActions(QObject *parent, AbstractGroupableItem *item); /** Returns the root group to use in grouping */ GroupPtr rootGroup() const; enum EditableGroupProperties { None = 0, Name = 1, Icon = 4, Members = 8, All = 15 }; /** * Returns which group properties are editable by the user and which are handled solely by the strategy. * The visualization should create a configuration interface based on this. */ virtual EditableGroupProperties editableGroupProperties() = 0; /* The following functions check if a property is editable and sets it on group*/ virtual bool setName(const QString &, TaskGroup*); /** Returns a List of unused Names*/ virtual QList nameSuggestions(TaskGroup *); virtual bool setIcon(const QIcon &, TaskGroup*); /** Returns a list of icons*/ virtual QList iconSuggestions(TaskGroup *); /** Adds an item to group if EditableGroupProperties::Members is set */ bool manualGroupingRequest(AbstractGroupableItem* taskItem, TaskGroup* groupItem); /** * Creates a new group if EditableGroupProperties::Members is set * Should be called if the user wants to group items manually */ bool manualGroupingRequest(ItemList items); protected: /** Create a group with items and returns the newly created group */ TaskGroup* createGroup(ItemList items); Q_SIGNALS: void groupRemoved(TaskGroup*); protected Q_SLOTS: /** Uncollapse all groups into the root group. */ void destroyGroups(); /** Adds all group members to the parentgroup of group and removes the group */ virtual void closeGroup(TaskGroup *group); /** Checks if the group is still necessary, removes group if empty*/ virtual void checkGroup(); /** Returns the strategy type */ void setType(GroupManager::TaskGroupingStrategy type); private: class Private; Private * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/abstractsortingstrategy.cpp b/liblegacytaskmanager/abstractsortingstrategy.cpp similarity index 98% rename from libtaskmanager/abstractsortingstrategy.cpp rename to liblegacytaskmanager/abstractsortingstrategy.cpp index 568321035..cc6143a98 100644 --- a/libtaskmanager/abstractsortingstrategy.cpp +++ b/liblegacytaskmanager/abstractsortingstrategy.cpp @@ -1,190 +1,190 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "abstractsortingstrategy.h" #include "taskitem.h" #include "taskgroup.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" #include "abstractgroupableitem.h" #include #include #include -namespace TaskManager +namespace LegacyTaskManager { class AbstractSortingStrategy::Private { public: Private() : type(GroupManager::NoSorting) { } QList managedGroups; GroupManager::TaskSortingStrategy type; }; AbstractSortingStrategy::AbstractSortingStrategy(QObject *parent) : QObject(parent), d(new Private) { } AbstractSortingStrategy::~AbstractSortingStrategy() { delete d; } GroupManager::TaskSortingStrategy AbstractSortingStrategy::type() const { return d->type; } void AbstractSortingStrategy::setType(GroupManager::TaskSortingStrategy type) { d->type = type; } void AbstractSortingStrategy::handleGroup(TaskGroup *group) { //qDebug(); if (d->managedGroups.contains(group) || !group) { return; } d->managedGroups.append(group); disconnect(group, 0, this, 0); //To avoid duplicate connections connect(group, SIGNAL(destroyed()), this, SLOT(removeGroup())); //FIXME necessary? ItemList sortedList = group->members(); sortItems(sortedList); //the sorting doesn't work with totally unsorted lists, therefore we sort it in the correct order the first time foreach (AbstractGroupableItem * item, sortedList) { handleItem(item); } } void AbstractSortingStrategy::removeGroup() { TaskGroup *group = dynamic_cast(sender()); if (!group) { return; } d->managedGroups.removeAll(group); } void AbstractSortingStrategy::handleItem(AbstractGroupableItem *item) { //qDebug() << item->name(); if (item->itemType() == GroupItemType) { handleGroup(qobject_cast(item)); } else if (item->itemType() == TaskItemType && !(qobject_cast(item))->task()) { //ignore startup tasks connect(item, SIGNAL(gotTaskPointer()), this, SLOT(check())); //sort the task as soon as it is a real one return; } check(item); } void AbstractSortingStrategy::check(AbstractGroupableItem *itemToCheck) { AbstractGroupableItem *item; if (!itemToCheck) { item = dynamic_cast(sender()); } else { item = itemToCheck; } if (!item) { qWarning() << "invalid item" << itemToCheck; return; } //qDebug() << item->name(); if (item->itemType() == TaskItemType) { if (!(qobject_cast(item))->task()) { //ignore startup tasks return; } } if (!item->parentGroup()) { //qDebug() << "No parent group"; return; } ItemList sortedList = item->parentGroup()->members(); sortItems(sortedList); int oldIndex = item->parentGroup()->members().indexOf(item); int newIndex = sortedList.indexOf(item); if (oldIndex != newIndex) { item->parentGroup()->moveItem(oldIndex, newIndex); } } void AbstractSortingStrategy::sortItems(ItemList &items) { Q_UNUSED(items) } bool AbstractSortingStrategy::manualSortingRequest(AbstractGroupableItem *item, int newIndex) { Q_UNUSED(item); Q_UNUSED(newIndex); return false; } bool AbstractSortingStrategy::moveItem(AbstractGroupableItem *item, int newIndex) { //qDebug() << "move to " << newIndex; if (!item->parentGroup()) { qWarning() << "error: no parentgroup but the item was asked to move"; return false; } const ItemList list = item->parentGroup()->members(); if ((newIndex < 0) || (newIndex >= list.size())) { newIndex = list.size(); } int oldIndex = list.indexOf(item); if (newIndex > oldIndex) { newIndex--; //the index has to be adjusted if we move the item from right to left because the item on the left is removed first } if (oldIndex != newIndex) { return item->parentGroup()->moveItem(oldIndex, newIndex); } return false; } } //namespace diff --git a/libtaskmanager/abstractsortingstrategy.h b/liblegacytaskmanager/abstractsortingstrategy.h similarity index 94% rename from libtaskmanager/abstractsortingstrategy.h rename to liblegacytaskmanager/abstractsortingstrategy.h index dfbad7481..0cf6780d6 100644 --- a/libtaskmanager/abstractsortingstrategy.h +++ b/liblegacytaskmanager/abstractsortingstrategy.h @@ -1,89 +1,89 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef ABSTRACTSORTINGSTRATEGY_H #define ABSTRACTSORTINGSTRATEGY_H #include #include #include -#include +#include -namespace TaskManager +namespace LegacyTaskManager { /** * Base class for strategies which can be used to * automatically sort tasks. */ -class TASKMANAGER_EXPORT AbstractSortingStrategy : public QObject +class LEGACYTASKMANAGER_EXPORT AbstractSortingStrategy : public QObject { Q_OBJECT public: AbstractSortingStrategy(QObject *parent); ~AbstractSortingStrategy() override; /** Returns the strategy type */ GroupManager::TaskSortingStrategy type() const; /** Adds group under control of sorting strategy. all added subgroups are automatically added to this sortingStrategy*/ void handleGroup(TaskGroup *); /** Moves Item to new index*/ bool moveItem(AbstractGroupableItem *, int); /**Reimplement this to support manual sorting*/ virtual bool manualSortingRequest(AbstractGroupableItem *item, int newIndex); public Q_SLOTS: /** Handles a new item, is typically called after an item was added to a handled group*/ virtual void handleItem(AbstractGroupableItem *); /** Checks if the order has to be updated. Must be connected to a AbstractGroupableItem* */ void check(AbstractGroupableItem *item = 0); protected Q_SLOTS: void removeGroup(); //FIXME necessary? protected: void setType(GroupManager::TaskSortingStrategy strategy); private: /** * Sorts list of items according to startegy. * Has to be reimplemented by every SortingStrategy. * * @param items the items that are to be sorted; the list is passed * in by value and should be in the proprer sorting order when * the method returns. */ virtual void sortItems(ItemList &ites); class Private; Private * const d; }; typedef QHash itemHashTable; typedef QHash desktopHashTable; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/groupmanager.cpp b/liblegacytaskmanager/groupmanager.cpp similarity index 91% rename from libtaskmanager/groupmanager.cpp rename to liblegacytaskmanager/groupmanager.cpp index fb7cdc9a4..e092c5723 100644 --- a/libtaskmanager/groupmanager.cpp +++ b/liblegacytaskmanager/groupmanager.cpp @@ -1,1403 +1,1403 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "groupmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "abstractsortingstrategy.h" #include "startup.h" #include "task.h" #include "taskitem.h" #include "taskgroup.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" #include "strategies/activitysortingstrategy.h" #include "strategies/alphasortingstrategy.h" #include "strategies/desktopsortingstrategy.h" #include "strategies/programgroupingstrategy.h" #include "strategies/manualgroupingstrategy.h" #include "strategies/manualsortingstrategy.h" #include "launcheritem.h" #include "launcherconfig.h" -namespace TaskManager +namespace LegacyTaskManager { class GroupManagerPrivate { public: GroupManagerPrivate(GroupManager *manager) : q(manager), sortingStrategy(GroupManager::NoSorting), groupingStrategy(GroupManager::NoGrouping), lastGroupingStrategy(GroupManager::NoGrouping), abstractGroupingStrategy(0), abstractSortingStrategy(0), groupIsFullLimit(0), showOnlyCurrentDesktop(false), showOnlyCurrentActivity(true), showOnlyCurrentScreen(false), showOnlyMinimized(false), onlyGroupWhenFull(false), cachedOnlyGroupWhenFull(false), changingGroupingStrategy(false), readingLauncherConfig(false), separateLaunchers(true), forceGrouping(false), launchersLocked(false) { } - /** reload all tasks from TaskManager */ + /** reload all tasks from LegacyTaskManager */ void reloadTasks(); void actuallyReloadTasks(); /** - * Keep track of changes in Taskmanager + * Keep track of changes in LegacyTaskmanager */ void currentDesktopChanged(int); void currentActivityChanged(QString); - void taskChanged(::TaskManager::Task *, ::TaskManager::TaskChanges); + void taskChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges); void checkScreenChange(); void taskDestroyed(QObject *item); void startupItemDestroyed(AbstractGroupableItem *); void startupDestroyed(QObject *); void checkIfFull(); void actuallyCheckIfFull(); - bool addTask(::TaskManager::Task *); - void removeTask(::TaskManager::Task *); - void addStartup(::TaskManager::Startup *); - void removeStartup(::TaskManager::Startup *); + bool addTask(::LegacyTaskManager::Task *); + void removeTask(::LegacyTaskManager::Task *); + void addStartup(::LegacyTaskManager::Startup *); + void removeStartup(::LegacyTaskManager::Startup *); void actuallyRemoveStartup(); void sycocaChanged(const QStringList &types); void launcherVisibilityChange(); void checkLauncherVisibility(LauncherItem *launcher); int launcherIndex(const QUrl &url); KConfigGroup launcherConfig(const KConfigGroup &config = KConfigGroup()); TaskGroup *currentRootGroup(); GroupManager *q; QHash startupList; GroupManager::TaskSortingStrategy sortingStrategy; GroupManager::TaskGroupingStrategy groupingStrategy; GroupManager::TaskGroupingStrategy lastGroupingStrategy; AbstractGroupingStrategy *abstractGroupingStrategy; AbstractSortingStrategy *abstractSortingStrategy; QRect currentScreenGeometry; QTimer screenTimer; QTimer reloadTimer; QTimer checkIfFullTimer; QSet geometryTasks; int groupIsFullLimit; QUuid configToken; QHash > rootGroups; //container for groups QList launchers; - QList< ::TaskManager::Startup *> startupRemoveList; + QList< ::LegacyTaskManager::Startup *> startupRemoveList; int currentDesktop; QString currentActivity; bool showOnlyCurrentDesktop : 1; bool showOnlyCurrentActivity : 1; bool showOnlyCurrentScreen : 1; bool showOnlyMinimized : 1; bool onlyGroupWhenFull : 1; bool cachedOnlyGroupWhenFull : 1; bool changingGroupingStrategy : 1; bool readingLauncherConfig : 1; bool separateLaunchers : 1; bool forceGrouping : 1; bool launchersLocked : 1; }; GroupManager::GroupManager(QObject *parent) : QObject(parent), d(new GroupManagerPrivate(this)) { - connect(TaskManager::self(), SIGNAL(taskAdded(::TaskManager::Task *)), this, SLOT(addTask(::TaskManager::Task *))); - connect(TaskManager::self(), SIGNAL(taskRemoved(::TaskManager::Task *)), this, SLOT(removeTask(::TaskManager::Task *))); - connect(TaskManager::self(), SIGNAL(startupAdded(::TaskManager::Startup *)), this, SLOT(addStartup(::TaskManager::Startup *))); - connect(TaskManager::self(), SIGNAL(startupRemoved(::TaskManager::Startup *)), this, SLOT(removeStartup(::TaskManager::Startup *))); + connect(LegacyTaskManager::self(), SIGNAL(taskAdded(::LegacyTaskManager::Task *)), this, SLOT(addTask(::LegacyTaskManager::Task *))); + connect(LegacyTaskManager::self(), SIGNAL(taskRemoved(::LegacyTaskManager::Task *)), this, SLOT(removeTask(::LegacyTaskManager::Task *))); + connect(LegacyTaskManager::self(), SIGNAL(startupAdded(::LegacyTaskManager::Startup *)), this, SLOT(addStartup(::LegacyTaskManager::Startup *))); + connect(LegacyTaskManager::self(), SIGNAL(startupRemoved(::LegacyTaskManager::Startup *)), this, SLOT(removeStartup(::LegacyTaskManager::Startup *))); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(const QStringList &))); - d->currentDesktop = TaskManager::self()->currentDesktop(); - d->currentActivity = TaskManager::self()->currentActivity(); + d->currentDesktop = LegacyTaskManager::self()->currentDesktop(); + d->currentActivity = LegacyTaskManager::self()->currentActivity(); d->rootGroups[d->currentActivity][d->currentDesktop] = new TaskGroup(this, QStringLiteral("RootGroup")); d->reloadTimer.setSingleShot(true); d->reloadTimer.setInterval(0); connect(&d->reloadTimer, SIGNAL(timeout()), this, SLOT(actuallyReloadTasks())); d->screenTimer.setSingleShot(true); d->screenTimer.setInterval(100); connect(&d->screenTimer, SIGNAL(timeout()), this, SLOT(checkScreenChange())); d->checkIfFullTimer.setSingleShot(true); d->checkIfFullTimer.setInterval(0); connect(&d->checkIfFullTimer, SIGNAL(timeout()), this, SLOT(actuallyCheckIfFull())); } GroupManager::~GroupManager() { - TaskManager::self()->setTrackGeometry(false, d->configToken); + LegacyTaskManager::self()->setTrackGeometry(false, d->configToken); delete d->abstractSortingStrategy; if (d->abstractGroupingStrategy) { d->abstractGroupingStrategy->setDestroyGroupsOnDestruction(false); delete d->abstractGroupingStrategy; } delete d; } TaskGroup *GroupManagerPrivate::currentRootGroup() { return rootGroups[currentActivity][currentDesktop]; } void GroupManagerPrivate::reloadTasks() { reloadTimer.start(); } void GroupManagerPrivate::actuallyReloadTasks() { - //qDebug() << "number of tasks available " << TaskManager::self()->tasks().size(); - QHash taskList = TaskManager::self()->tasks(); + //qDebug() << "number of tasks available " << LegacyTaskManager::self()->tasks().size(); + QHash taskList = LegacyTaskManager::self()->tasks(); QMutableHashIterator it(taskList); while (it.hasNext()) { it.next(); if (addTask(it.value())) { //qDebug() << "task added " << it.value()->visibleName(); it.remove(); } } // Remove what remains it.toFront(); while (it.hasNext()) { it.next(); removeTask(it.value()); } emit q->reload(); } -void GroupManagerPrivate::addStartup(::TaskManager::Startup *startup) +void GroupManagerPrivate::addStartup(::LegacyTaskManager::Startup *startup) { if (startupList.contains(startup)) { return; } QHash::iterator it = startupList.begin(); QHash::iterator itEnd = startupList.end(); while (it != itEnd) { if (it.key()->desktopId() == startup->desktopId() && it.key()->bin() == startup->bin()) { return; } ++it; } foreach(const AbstractGroupableItem *item, currentRootGroup()->members()) { if (item->itemType() == TaskItemType) { const TaskItem *task = static_cast(item); if (task->launcherUrl().toLocalFile() == startup->desktopId() || task->taskName().toLower() == startup->bin()) { return; } } } TaskItem *item = new TaskItem(q, startup); foreach (LauncherItem * launcher, launchers) { if (launcher->associateItemIfMatches(item)) { // Task demands attention, so is to be shown, therefore hide the launcher... currentRootGroup()->remove(launcher); } } startupList.insert(startup, item); currentRootGroup()->add(item); QObject::connect(startup, SIGNAL(destroyed(QObject*)), q, SLOT(startupDestroyed(QObject*))); QObject::connect(item, SIGNAL(destroyed(AbstractGroupableItem*)), q, SLOT(startupItemDestroyed(AbstractGroupableItem*))); } -void GroupManagerPrivate::removeStartup(::TaskManager::Startup *startup) +void GroupManagerPrivate::removeStartup(::LegacyTaskManager::Startup *startup) { startupRemoveList.append(startup); QTimer::singleShot(2000, q, SLOT(actuallyRemoveStartup())); } void GroupManagerPrivate::actuallyRemoveStartup() { if (startupRemoveList.isEmpty()) { return; } - ::TaskManager::Startup *startup = startupRemoveList.takeFirst(); + ::LegacyTaskManager::Startup *startup = startupRemoveList.takeFirst(); if (!startupList.contains(startup)) { return; } TaskItem *item = startupList.take(startup); if (item->parentGroup()) { item->parentGroup()->remove(item); } item->setTaskPointer(0); foreach (LauncherItem * launcher, launchers) { launcher->removeItemIfAssociated(item); } delete startup; } -bool GroupManagerPrivate::addTask(::TaskManager::Task *task) +bool GroupManagerPrivate::addTask(::LegacyTaskManager::Task *task) { if (!task) { return false; } //qDebug(); /* qDebug() << task->visibleName() << task->visibleNameWithState() << task->name() << task->className() << task->classClass(); */ bool skip = false; if (!task->showInTaskbar()) { //qDebug() << "Do not show in taskbar"; skip = true; } if (showOnlyCurrentScreen && !task->isOnScreen(currentScreenGeometry)) { //qDebug() << "Not on this screen and showOnlyCurrentScreen"; skip = true; } // Should the Task be displayed ? We always display if attention is demaded if (!task->demandsAttention()) { // As the Task doesn't demand attention // go through all filters whether the task should be displayed or not if (showOnlyCurrentDesktop && !task->isOnCurrentDesktop()) { /* qDebug() << "Not on this desktop and showOnlyCurrentDesktop" << KWindowSystem::currentDesktop() << task->desktop(); */ skip = true; } if (showOnlyCurrentActivity && !task->isOnCurrentActivity()) { /* qDebug() << "Not on this desktop and showOnlyCurrentActivity" << KWindowSystem::currentActivity() << task->desktop(); */ skip = true; } if (showOnlyMinimized && !task->isMinimized()) { //qDebug() << "Not minimized and only showing minimized"; skip = true; } NET::WindowType type = task->info().windowType(NET::NormalMask | NET::DialogMask | NET::OverrideMask | NET::UtilityMask); if (type == NET::Utility) { //qDebug() << "skipping utility window" << task->name(); skip = true; } //TODO: should we check for transiency? if so the following code can detect it. /* QHash ::iterator it = d->itemList.begin(); while (it != d->itemList.end()) { TaskItem *item = it.value(); if (item->task()->hasTransient(task->window())) { qDebug() << "TRANSIENT TRANSIENT TRANSIENT!"; return flase; } ++it; } */ } //Ok the Task should be displayed TaskItem *item = qobject_cast(currentRootGroup()->getMemberByWId(task->window())); if (!item || skip) { TaskItem *startupItem = 0; QHash::iterator it = startupList.begin(); QHash::iterator itEnd = startupList.end(); const QString desktopId = TaskItem::launcherUrlFromTask(q, task).toLocalFile(); while (it != itEnd) { if (it.key()->matchesWindow(task->window()) || it.key()->desktopId() == desktopId || it.key()->bin() == task->className()) { //qDebug() << "startup task found"; item = startupItem = it.value(); - ::TaskManager::Startup *startup = it.key(); + ::LegacyTaskManager::Startup *startup = it.key(); startupRemoveList.removeAll(startup); startupList.erase(it); QObject::disconnect(item, 0, q, 0); if (!skip) { item->setTaskPointer(task); } delete startup; break; } ++it; } // if we are to skip because we don't display, we simply delete the startup related to it if (skip) { delete startupItem; return false; } if (!item) { item = new TaskItem(q, task); } QObject::connect(task, SIGNAL(destroyed(QObject*)), q, SLOT(taskDestroyed(QObject*))); foreach (LauncherItem * launcher, launchers) { if (launcher->associateItemIfMatches(item)) { // Task demands attention, so is to be shown, therefore hide the launcher... currentRootGroup()->remove(launcher); } } } //Find a fitting group for the task with GroupingStrategies if (abstractGroupingStrategy && (forceGrouping || !task->demandsAttention())) { //do not group attention tasks abstractGroupingStrategy->handleItem(item); } else { currentRootGroup()->add(item); if (abstractSortingStrategy) { abstractSortingStrategy->handleItem(item); abstractSortingStrategy->check(item); } } if (showOnlyCurrentScreen) { geometryTasks.insert(task); } return true; } -void GroupManagerPrivate::removeTask(::TaskManager::Task *task) +void GroupManagerPrivate::removeTask(::LegacyTaskManager::Task *task) { if (!task) { return; } //qDebug() << "remove: " << task->visibleName(); geometryTasks.remove(task); AbstractGroupableItem *item = currentRootGroup()->getMemberByWId(task->window()); if (!item) { // this can happen if the window hasn't been caught previously, // of it it is an ignored type such as a NET::Utility type window //qDebug() << "invalid item"; return; } foreach (LauncherItem * launcher, launchers) { launcher->removeItemIfAssociated(item); } if (item->parentGroup()) { item->parentGroup()->remove(item); } //the item must exist as long as the Task does because of activate calls so don't delete the item here, it will delete itself. } void GroupManagerPrivate::taskDestroyed(QObject *item) { Task *task = static_cast(item); if (showOnlyCurrentScreen) { geometryTasks.remove(task); } } void GroupManagerPrivate::startupDestroyed(QObject *obj) { - ::TaskManager::Startup *startup = static_cast< ::TaskManager::Startup *>(obj); + ::LegacyTaskManager::Startup *startup = static_cast< ::LegacyTaskManager::Startup *>(obj); if (!startupList.contains(startup)) { return; } TaskItem *item = startupList.take(startup); startupRemoveList.removeAll(startup); if (item->parentGroup()) { item->parentGroup()->remove(item); } item->setTaskPointer(0); foreach (LauncherItem * launcher, launchers) { launcher->removeItemIfAssociated(item); } } void GroupManagerPrivate::startupItemDestroyed(AbstractGroupableItem *item) { TaskItem *taskItem = static_cast(item); startupList.remove(startupList.key(taskItem)); geometryTasks.remove(taskItem->task()); } bool GroupManager::manualGroupingRequest(AbstractGroupableItem* item, TaskGroup* groupItem) { if (d->abstractGroupingStrategy) { return d->abstractGroupingStrategy->manualGroupingRequest(item, groupItem); } return false; } bool GroupManager::manualGroupingRequest(ItemList items) { if (d->abstractGroupingStrategy) { return d->abstractGroupingStrategy->manualGroupingRequest(items); } return false; } bool GroupManager::manualSortingRequest(AbstractGroupableItem* taskItem, int newIndex) { if (d->abstractSortingStrategy && !launchersLocked()) { return d->abstractSortingStrategy->manualSortingRequest(taskItem, newIndex); } return false; } GroupPtr GroupManager::rootGroup() const { return d->currentRootGroup(); } void GroupManagerPrivate::currentActivityChanged(QString newActivity) { if (!showOnlyCurrentActivity || currentActivity == newActivity) { return; } if (!rootGroups.contains(newActivity) || !rootGroups.value(newActivity).contains(currentDesktop)) { qDebug() << "created new desk group"; rootGroups[newActivity][currentDesktop] = new TaskGroup(q, QStringLiteral("RootGroup")); if (abstractSortingStrategy) { abstractSortingStrategy->handleGroup(rootGroups[newActivity][currentDesktop]); } } if (onlyGroupWhenFull) { QObject::disconnect(currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), q, SLOT(checkIfFull())); QObject::disconnect(currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), q, SLOT(checkIfFull())); } currentActivity = newActivity; foreach (LauncherItem * item, launchers) { if (item->shouldShow(q)) { rootGroups[currentActivity][currentDesktop]->add(item); } else { rootGroups[currentActivity][currentDesktop]->remove(item); } } if (onlyGroupWhenFull) { QObject::connect(currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), q, SLOT(checkIfFull())); QObject::connect(currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), q, SLOT(checkIfFull())); } actuallyReloadTasks(); } void GroupManagerPrivate::currentDesktopChanged(int newDesktop) { //qDebug(); if (!showOnlyCurrentDesktop) { return; } if (currentDesktop == newDesktop) { return; } if (!rootGroups[currentActivity].contains(newDesktop)) { qDebug() << "created new desk group"; rootGroups[currentActivity][newDesktop] = new TaskGroup(q, QStringLiteral("RootGroup")); if (abstractSortingStrategy) { abstractSortingStrategy->handleGroup(rootGroups[currentActivity][newDesktop]); } } if (onlyGroupWhenFull) { QObject::disconnect(currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), q, SLOT(checkIfFull())); QObject::disconnect(currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), q, SLOT(checkIfFull())); } currentDesktop = newDesktop; foreach (LauncherItem * item, launchers) { if (item->shouldShow(q)) { rootGroups[currentActivity][currentDesktop]->add(item); } else { rootGroups[currentActivity][currentDesktop]->remove(item); } } if (onlyGroupWhenFull) { QObject::connect(currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), q, SLOT(checkIfFull())); QObject::connect(currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), q, SLOT(checkIfFull())); } actuallyReloadTasks(); } -void GroupManagerPrivate::taskChanged(::TaskManager::Task *task, ::TaskManager::TaskChanges changes) +void GroupManagerPrivate::taskChanged(::LegacyTaskManager::Task *task, ::LegacyTaskManager::TaskChanges changes) { //qDebug(); if (!task) { return; } bool takeAction = false; bool show = true; - if (showOnlyCurrentDesktop && changes & ::TaskManager::DesktopChanged) { + if (showOnlyCurrentDesktop && changes & ::LegacyTaskManager::DesktopChanged) { takeAction = true; show = task->isOnCurrentDesktop(); - //qDebug() << task->visibleName() << "on" << TaskManager::self()->currentDesktop(); + //qDebug() << task->visibleName() << "on" << LegacyTaskManager::self()->currentDesktop(); } - if (showOnlyCurrentActivity && changes & ::TaskManager::ActivitiesChanged) { + if (showOnlyCurrentActivity && changes & ::LegacyTaskManager::ActivitiesChanged) { takeAction = true; show = task->isOnCurrentActivity(); - //qDebug() << task->visibleName() << "on" << TaskManager::self()->currentDesktop(); + //qDebug() << task->visibleName() << "on" << LegacyTaskManager::self()->currentDesktop(); } - if (showOnlyMinimized && changes & ::TaskManager::StateChanged) { + if (showOnlyMinimized && changes & ::LegacyTaskManager::StateChanged) { //TODO: wouldn't it be nice to get notification of JUST minimization? takeAction = true; show = task->isMinimized(); } - if (showOnlyCurrentScreen && changes & ::TaskManager::GeometryChanged) { + if (showOnlyCurrentScreen && changes & ::LegacyTaskManager::GeometryChanged) { geometryTasks.insert(task); if (!screenTimer.isActive()) { screenTimer.start(); } } - if (changes & ::TaskManager::AttentionChanged) { + if (changes & ::LegacyTaskManager::AttentionChanged) { if (task->demandsAttention()) { takeAction = true; show = true; } else if (task->info().windowType(NET::UtilityMask) == NET::Utility) { removeTask(task); } else if (abstractGroupingStrategy) { // Group tasks again when they no longer demands attention. TaskItem *item = qobject_cast(currentRootGroup()->getMemberByWId(task->window())); if (item) { abstractGroupingStrategy->handleItem(item); } } } // Some apps, eg. LibreOffice, change classClass/className after start-up... - if (changes & ::TaskManager::ClassChanged) { + if (changes & ::LegacyTaskManager::ClassChanged) { // Instead of just moving item (as what happend in the #if below), just remove and re-add the task. // This way the grouping happens properly. AbstractGroupableItem *item = currentRootGroup()->getMemberByWId(task->window()); if (item && TaskItemType == item->itemType()) { static_cast(item)->resetLauncherCheck(); } removeTask(task); addTask(task); } if (!takeAction) { return; } show = show && (!showOnlyCurrentScreen || task->isOnScreen(currentScreenGeometry)); if (show) { //qDebug() << "add(task);"; addTask(task); } else { //qDebug() << "remove(task);"; removeTask(task); } } QRect GroupManager::screenGeometry() const { return d->currentScreenGeometry; } void GroupManager::setScreenGeometry(const QRect& geometry) { if (geometry != d->currentScreenGeometry) { d->currentScreenGeometry = geometry; d->reloadTasks(); emit screenGeometryChanged(geometry); } } void GroupManagerPrivate::checkScreenChange() { //qDebug(); if (showOnlyCurrentScreen) { foreach (Task *task, geometryTasks) { if (task->isOnScreen(currentScreenGeometry)) { addTask(task); } else { removeTask(task); } } } geometryTasks.clear(); } void GroupManager::reconnect() { //qDebug(); - disconnect(TaskManager::self(), SIGNAL(desktopChanged(int)), this, SLOT(currentDesktopChanged(int))); - disconnect(TaskManager::self(), SIGNAL(activityChanged(QString)), this, SLOT(currentActivityChanged(QString))); - disconnect(TaskManager::self(), SIGNAL(windowChanged(::TaskManager::Task *, ::TaskManager::TaskChanges)), - this, SLOT(taskChanged(::TaskManager::Task *, ::TaskManager::TaskChanges))); + disconnect(LegacyTaskManager::self(), SIGNAL(desktopChanged(int)), this, SLOT(currentDesktopChanged(int))); + disconnect(LegacyTaskManager::self(), SIGNAL(activityChanged(QString)), this, SLOT(currentActivityChanged(QString))); + disconnect(LegacyTaskManager::self(), SIGNAL(windowChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges)), + this, SLOT(taskChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges))); if (d->showOnlyCurrentDesktop || d->showOnlyMinimized || d->showOnlyCurrentScreen || d->showOnlyCurrentActivity) { // listen to the relevant task manager signals if (d->showOnlyCurrentDesktop) { - connect(TaskManager::self(), SIGNAL(desktopChanged(int)), + connect(LegacyTaskManager::self(), SIGNAL(desktopChanged(int)), this, SLOT(currentDesktopChanged(int))); } if (d->showOnlyCurrentActivity) { - connect(TaskManager::self(), SIGNAL(activityChanged(QString)), + connect(LegacyTaskManager::self(), SIGNAL(activityChanged(QString)), this, SLOT(currentActivityChanged(QString))); } } - connect(TaskManager::self(), SIGNAL(windowChanged(::TaskManager::Task *, ::TaskManager::TaskChanges)), - this, SLOT(taskChanged(::TaskManager::Task *, ::TaskManager::TaskChanges))); + connect(LegacyTaskManager::self(), SIGNAL(windowChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges)), + this, SLOT(taskChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges))); - TaskManager::self()->setTrackGeometry(d->showOnlyCurrentScreen, d->configToken); + LegacyTaskManager::self()->setTrackGeometry(d->showOnlyCurrentScreen, d->configToken); if (!d->showOnlyCurrentScreen) { d->geometryTasks.clear(); } d->reloadTasks(); } bool GroupManager::addLauncher(const QUrl &url, const QIcon &icon, const QString &name, const QString &genericName, const QString &wmClass, int insertPos) { if (url.isEmpty() || launchersLocked()) { return false; } int index = launcherIndex(url); LauncherItem *launcher = -1 != index ? d->launchers.at(index) : 0L; // Do not insert launchers twice if (!launcher) { launcher = new LauncherItem(d->currentRootGroup(), url); if (!launcher->isValid()) { delete launcher; return false; } if (!icon.isNull()) { launcher->setIcon(icon); } if (!name.isEmpty()) { launcher->setName(name); } if (!genericName.isEmpty()) { launcher->setGenericName(genericName); } if (!wmClass.isEmpty()) { launcher->setWmClass(wmClass); } QStack groups; groups.push(d->currentRootGroup()); while (!groups.isEmpty()) { TaskGroup *group = groups.pop(); foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() == GroupItemType) { groups.push(static_cast(item)); } else { launcher->associateItemIfMatches(item); } } } if (insertPos >= 0 && insertPos < d->launchers.count()) { d->launchers.insert(insertPos, launcher); } else { d->launchers.append(launcher); } connect(launcher, SIGNAL(associationChanged()), this, SLOT(launcherVisibilityChange())); d->checkLauncherVisibility(launcher); if (!d->separateLaunchers && d->abstractSortingStrategy && ManualSorting == d->abstractSortingStrategy->type()) { // Ensure item is placed where launcher would be... foreach (AbstractGroupableItem * item, d->rootGroups[d->currentActivity][d->currentDesktop]->members()) { if (LauncherItemType != item->itemType() && item->launcherUrl() == url) { manualSortingRequest(item, launcherIndex(url)); break; } } } if (d->abstractSortingStrategy) { d->abstractSortingStrategy->check(launcher); } if (!d->readingLauncherConfig) { emit launcherListChanged(); } } return launcher; } void GroupManager::removeLauncher(const QUrl &url) { if (launchersLocked()) { return; } int index = launcherIndex(url); if (index == -1 || index >= d->launchers.count()) { return; } LauncherItem *launcher = d->launchers.at(index); if (!launcher) { return; } d->launchers.removeAt(index); typedef QHash Metagroup; foreach (Metagroup metagroup, d->rootGroups) { foreach (TaskGroup * rootGroup, metagroup) { rootGroup->remove(launcher); } } launcher->deleteLater(); if (!d->separateLaunchers && d->abstractSortingStrategy && ManualSorting == d->abstractSortingStrategy->type()) { // Ensure item is placed at end of launchers... foreach (AbstractGroupableItem * item, d->rootGroups[d->currentActivity][d->currentDesktop]->members()) { if (LauncherItemType != item->itemType() && item->launcherUrl() == url) { manualSortingRequest(item, d->launchers.count()); break; } } } if (!d->readingLauncherConfig) { emit launcherListChanged(); } } void GroupManagerPrivate::sycocaChanged(const QStringList &types) { if (types.contains(QStringLiteral("apps"))) { QList removals; foreach (LauncherItem *launcher, launchers) { if (launcher->launcherUrl().scheme() != QLatin1String("preferred") && !QFile::exists(launcher->launcherUrl().toLocalFile())) { removals << launcher->launcherUrl(); } } foreach (const QUrl & url, removals) { q->removeLauncher(url); } } } void GroupManagerPrivate::launcherVisibilityChange() { checkLauncherVisibility(qobject_cast(q->sender())); } void GroupManagerPrivate::checkLauncherVisibility(LauncherItem *launcher) { if (!launcher) { return; } if (launcher->shouldShow(q)) { rootGroups[currentActivity][currentDesktop]->add(launcher); } else { rootGroups[currentActivity][currentDesktop]->remove(launcher); } } bool GroupManager::launcherExists(const QUrl &url) const { return d->launcherIndex(url) != -1; } int GroupManager::launcherIndex(const QUrl &url) const { return d->launcherIndex(url); } int GroupManager::launcherCount() const { return d->launchers.count(); } bool GroupManager::launchersLocked() const { return d->launchersLocked; } void GroupManager::setLaunchersLocked(bool l) { d->launchersLocked = l; } QUrl GroupManager::launcherForWmClass(const QString &wmClass) const { foreach (LauncherItem * l, d->launchers) { if (l->wmClass() == wmClass) { return l->launcherUrl(); } } return QUrl(); } QString GroupManager::launcherWmClass(const QUrl &url) const { int index = launcherIndex(url); LauncherItem *l = -1 != index ? d->launchers.at(index) : 0L; return l ? l->wmClass() : QString(); } bool GroupManager::isItemAssociatedWithLauncher(AbstractGroupableItem *item) const { if (item) { switch (item->itemType()) { case LauncherItemType: return true; case GroupItemType: { foreach (AbstractGroupableItem * i, static_cast(item)->members()) { if (isItemAssociatedWithLauncher(i)) { return true; } } break; } case TaskItemType: { foreach (LauncherItem * launcher, d->launchers) { if (launcher->isAssociated(item)) { return true; } } } } } return false; } void GroupManager::moveLauncher(const QUrl &url, int newIndex) { if (!url.isValid()) { return; } int oldIndex = launcherIndex(url); if (oldIndex >= 0 && newIndex != oldIndex) { d->launchers.insert(newIndex, d->launchers.takeAt(oldIndex)); emit launcherListChanged(); } } bool GroupManager::separateLaunchers() const { return d->separateLaunchers; } void GroupManager::setSeparateLaunchers(bool s) { if (d->separateLaunchers != s) { d->separateLaunchers = s; emit separateLaunchersChanged(s); } } bool GroupManager::forceGrouping() const { return d->forceGrouping; } void GroupManager::setForceGrouping(bool s) { if (d->forceGrouping != s) { d->forceGrouping = s; emit forceGroupingChanged(s); } } void GroupManager::createConfigurationInterface(KConfigDialog *parent) { new LauncherConfig(parent); } QList GroupManager::launcherList() const { QList launchers; foreach (LauncherItem *l, d->launchers) { QUrl u(l->launcherUrl()); QUrlQuery uQuery(u); if (!l->wmClass().isEmpty()) { uQuery.addQueryItem(QStringLiteral("wmClass"), l->wmClass()); } if (!l->launcherUrl().isValid() || !KDesktopFile::isDesktopFile(l->launcherUrl().toLocalFile())) { if (!l->name().isEmpty()) { uQuery.addQueryItem(QStringLiteral("name"), l->name()); } if (!l->genericName().isEmpty()) { uQuery.addQueryItem(QStringLiteral("genericName"), l->genericName()); } if (!l->icon().name().isEmpty()) { uQuery.addQueryItem(QStringLiteral("icon"), l->icon().name()); } else if (!l->icon().isNull()) { QPixmap pixmap = l->icon().pixmap(QSize(64, 64)); QByteArray bytes; QBuffer buffer(&bytes); buffer.open(QIODevice::WriteOnly); pixmap.save(&buffer, "PNG"); uQuery.addQueryItem(QStringLiteral("iconData"), bytes.toBase64(QByteArray::Base64UrlEncoding)); } } u.setQuery(uQuery); launchers << u; } return launchers; } void GroupManager::setLauncherList(QList launcherList) { d->readingLauncherConfig = true; QSet urls; foreach (QUrl l, launcherList) { QUrlQuery query(l); QString name(query.queryItemValue(QStringLiteral("name"))); QString genericName(query.queryItemValue(QStringLiteral("genericName"))); QString wmClass(query.queryItemValue(QStringLiteral("wmClass"))); QString iconData(query.queryItemValue(QStringLiteral("iconData"))); QIcon icon; if (!iconData.isEmpty()) { QPixmap pixmap; QByteArray bytes = QByteArray::fromBase64(iconData.toLocal8Bit(), QByteArray::Base64UrlEncoding); pixmap.loadFromData(bytes); icon.addPixmap(pixmap); } else { QString iconName = query.queryItemValue(QStringLiteral("icon")); if (!iconName.isEmpty()) { icon = QIcon::fromTheme(iconName); } } l.setQuery(QUrlQuery()); if (addLauncher(l, icon, name, genericName, wmClass)) { urls << l; } } QList removals; foreach (LauncherItem *launcher, d->launchers) { if (!urls.contains(launcher->launcherUrl())) { removals << launcher->launcherUrl(); } } foreach (const QUrl & url, removals) { removeLauncher(url); } d->readingLauncherConfig = false; emit launcherListChanged(); } int GroupManagerPrivate::launcherIndex(const QUrl &url) { // we check first for exact matches ... int index = 0; foreach (const LauncherItem * item, launchers) { if (item->launcherUrl() == url) { return index; } ++index; } // .. and if that fails for preferred launcher matches index = 0; foreach (const LauncherItem * item, launchers) { if (item->launcherUrl().scheme() == QLatin1String("preferred")) { KService::Ptr service = KService::serviceByStorageId(item->defaultApplication(item->launcherUrl())); if (service) { QUrl prefUrl(service->entryPath()); if (prefUrl.scheme().isEmpty()) { prefUrl.setScheme(QStringLiteral("file")); } if (prefUrl == url) { return index; } } } ++index; } return -1; } bool GroupManager::onlyGroupWhenFull() const { return d->onlyGroupWhenFull; } void GroupManager::setOnlyGroupWhenFull(bool onlyGroupWhenFull) { //qDebug() << onlyGroupWhenFull; if (d->onlyGroupWhenFull == onlyGroupWhenFull) { return; } d->onlyGroupWhenFull = onlyGroupWhenFull; disconnect(d->currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), this, SLOT(checkIfFull())); disconnect(d->currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), this, SLOT(checkIfFull())); if (onlyGroupWhenFull) { connect(d->currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), this, SLOT(checkIfFull())); connect(d->currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), this, SLOT(checkIfFull())); d->checkIfFull(); } else { setGroupingStrategy(d->groupingStrategy); } emit onlyGroupWhenFullChanged(onlyGroupWhenFull); } int GroupManager::fullLimit() const { return d->groupIsFullLimit; } void GroupManager::setFullLimit(int limit) { //qDebug() << limit; if (d->groupIsFullLimit != limit) { d->groupIsFullLimit = limit; if (d->onlyGroupWhenFull) { d->checkIfFull(); } emit fullLimitChanged(limit); } } void GroupManagerPrivate::checkIfFull() { // Start a timer so that if we have been triggered by a layouting // we give time for it to finish up instead of starting a new one // right away. checkIfFullTimer.start(); } void GroupManagerPrivate::actuallyCheckIfFull() { //qDebug(); if (!onlyGroupWhenFull || groupingStrategy != GroupManager::ProgramGrouping || changingGroupingStrategy) { return; } if (currentRootGroup()->totalSize() >= groupIsFullLimit) { if (!abstractGroupingStrategy) { geometryTasks.clear(); q->setGroupingStrategy(GroupManager::ProgramGrouping); } } else if (abstractGroupingStrategy) { geometryTasks.clear(); q->setGroupingStrategy(GroupManager::NoGrouping); //let the visualization think we still use the programGrouping groupingStrategy = GroupManager::ProgramGrouping; } } bool GroupManager::showOnlyCurrentScreen() const { return d->showOnlyCurrentScreen; } void GroupManager::setShowOnlyCurrentScreen(bool showOnlyCurrentScreen) { if (showOnlyCurrentScreen != d->showOnlyCurrentScreen) { d->showOnlyCurrentScreen = showOnlyCurrentScreen; reconnect(); emit showOnlyCurrentScreenChanged(showOnlyCurrentScreen); } } bool GroupManager::showOnlyCurrentDesktop() const { return d->showOnlyCurrentDesktop; } void GroupManager::setShowOnlyCurrentDesktop(bool showOnlyCurrentDesktop) { if (showOnlyCurrentDesktop != d->showOnlyCurrentDesktop) { d->showOnlyCurrentDesktop = showOnlyCurrentDesktop; reconnect(); emit showOnlyCurrentDesktopChanged(showOnlyCurrentDesktop); } } bool GroupManager::showOnlyCurrentActivity() const { return d->showOnlyCurrentActivity; } void GroupManager::setShowOnlyCurrentActivity(bool showOnlyCurrentActivity) { if (showOnlyCurrentActivity != d->showOnlyCurrentActivity) { d->showOnlyCurrentActivity = showOnlyCurrentActivity; reconnect(); emit showOnlyCurrentActivityChanged(showOnlyCurrentActivity); } } bool GroupManager::showOnlyMinimized() const { return d->showOnlyMinimized; } void GroupManager::setShowOnlyMinimized(bool showOnlyMinimized) { if (showOnlyMinimized != d->showOnlyMinimized) { d->showOnlyMinimized = showOnlyMinimized; reconnect(); emit showOnlyMinimizedChanged(showOnlyMinimized); } } GroupManager::TaskSortingStrategy GroupManager::sortingStrategy() const { return d->sortingStrategy; } AbstractSortingStrategy* GroupManager::taskSorter() const { return d->abstractSortingStrategy; } void GroupManager::setSortingStrategy(TaskSortingStrategy sortOrder) { if (d->abstractSortingStrategy) { if (d->abstractSortingStrategy->type() == sortOrder) { return; } d->abstractSortingStrategy->deleteLater(); d->abstractSortingStrategy = 0; } switch (sortOrder) { case ManualSorting: d->abstractSortingStrategy = new ManualSortingStrategy(this); break; case AlphaSorting: d->abstractSortingStrategy = new AlphaSortingStrategy(this); break; case DesktopSorting: d->abstractSortingStrategy = new DesktopSortingStrategy(this); break; case ActivitySorting: d->abstractSortingStrategy = new ActivitySortingStrategy(this); break; case NoSorting: //manual and no grouping result both in non automatic grouping break; default: qDebug() << "Invalid Strategy"; } if (d->abstractSortingStrategy) { typedef QHash Metagroup; foreach (Metagroup metagroup, d->rootGroups) { foreach (TaskGroup * group, metagroup) { d->abstractSortingStrategy->handleGroup(group); } } } d->sortingStrategy = sortOrder; reconnect(); emit sortingStrategyChanged(sortOrder); } GroupManager::TaskGroupingStrategy GroupManager::groupingStrategy() const { return d->groupingStrategy; } AbstractGroupingStrategy* GroupManager::taskGrouper() const { return d->abstractGroupingStrategy; } void GroupManager::setGroupingStrategy(TaskGroupingStrategy strategy) { if (d->changingGroupingStrategy || (d->cachedOnlyGroupWhenFull == d->onlyGroupWhenFull && d->groupingStrategy == strategy)) { return; } d->changingGroupingStrategy = true; d->cachedOnlyGroupWhenFull = d->onlyGroupWhenFull; //qDebug() << strategy << kBacktrace(); if (d->onlyGroupWhenFull) { disconnect(d->currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), this, SLOT(checkIfFull())); disconnect(d->currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), this, SLOT(checkIfFull())); } if (d->abstractGroupingStrategy) { disconnect(d->abstractGroupingStrategy, 0, this, 0); delete d->abstractGroupingStrategy; d->abstractGroupingStrategy = 0; } switch (strategy) { case ManualGrouping: d->abstractGroupingStrategy = new ManualGroupingStrategy(this); break; case ProgramGrouping: d->abstractGroupingStrategy = new ProgramGroupingStrategy(this); break; case NoGrouping: break; default: qDebug() << "Strategy not implemented"; } d->groupingStrategy = strategy; d->actuallyReloadTasks(); if (d->onlyGroupWhenFull) { connect(d->currentRootGroup(), SIGNAL(itemAdded(AbstractGroupableItem*)), this, SLOT(checkIfFull())); connect(d->currentRootGroup(), SIGNAL(itemRemoved(AbstractGroupableItem*)), this, SLOT(checkIfFull())); } d->changingGroupingStrategy = false; emit groupingStrategyChanged(strategy); } -} // TaskManager namespace +} // LegacyTaskManager namespace #include "moc_groupmanager.cpp" diff --git a/libtaskmanager/groupmanager.h b/liblegacytaskmanager/groupmanager.h similarity index 94% rename from libtaskmanager/groupmanager.h rename to liblegacytaskmanager/groupmanager.h index 7cd1263ee..0f988f680 100644 --- a/libtaskmanager/groupmanager.h +++ b/liblegacytaskmanager/groupmanager.h @@ -1,253 +1,253 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef GROUPMANAGER_H #define GROUPMANAGER_H #include #include #include #include -#include +#include #include "launcheritem.h" class KConfigDialog; -namespace TaskManager +namespace LegacyTaskManager { class AbstractSortingStrategy; class AbstractGroupingStrategy; class GroupManagerPrivate; /** * Manages the grouping stuff. It doesn't know anything about grouping and sorting itself, this is done in the grouping and sorting strategies. */ -class TASKMANAGER_EXPORT GroupManager: public QObject +class LEGACYTASKMANAGER_EXPORT GroupManager: public QObject { Q_OBJECT Q_PROPERTY(QRect screenGeometry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) Q_PROPERTY(TaskGroupingStrategy groupingStrategy READ groupingStrategy WRITE setGroupingStrategy NOTIFY groupingStrategyChanged) Q_PROPERTY(bool onlyGroupWhenFull READ onlyGroupWhenFull WRITE setOnlyGroupWhenFull NOTIFY onlyGroupWhenFullChanged) Q_PROPERTY(bool forceGrouping READ forceGrouping WRITE setForceGrouping NOTIFY forceGroupingChanged) Q_PROPERTY(int fullLimit READ fullLimit WRITE setFullLimit NOTIFY fullLimitChanged) Q_PROPERTY(TaskSortingStrategy sortingStrategy READ sortingStrategy WRITE setSortingStrategy NOTIFY sortingStrategyChanged) Q_PROPERTY(bool showOnlyCurrentScreen READ showOnlyCurrentScreen WRITE setShowOnlyCurrentScreen NOTIFY showOnlyCurrentScreenChanged) Q_PROPERTY(bool showOnlyCurrentDesktop READ showOnlyCurrentDesktop WRITE setShowOnlyCurrentDesktop NOTIFY showOnlyCurrentDesktopChanged) Q_PROPERTY(bool showOnlyCurrentActivity READ showOnlyCurrentActivity WRITE setShowOnlyCurrentActivity NOTIFY showOnlyCurrentActivityChanged) Q_PROPERTY(bool showOnlyMinimized READ showOnlyMinimized WRITE setShowOnlyMinimized NOTIFY showOnlyMinimizedChanged) Q_PROPERTY(bool separateLaunchers READ separateLaunchers WRITE setSeparateLaunchers NOTIFY separateLaunchersChanged) Q_PROPERTY(QList launcherList READ launcherList WRITE setLauncherList NOTIFY launcherListChanged) public: GroupManager(QObject *parent); ~GroupManager() override; /** * Returns a group which contains all items and subgroups. * Visualizations should be based on this. */ GroupPtr rootGroup() const; /** * Strategy used to Group new items */ enum TaskGroupingStrategy { NoGrouping = 0, ProgramGrouping = 1, ManualGrouping = 2 }; TaskGroupingStrategy groupingStrategy() const; void setGroupingStrategy(TaskGroupingStrategy); AbstractGroupingStrategy* taskGrouper() const; /** * How the task are ordered */ enum TaskSortingStrategy { NoSorting = 0, ManualSorting = 1, AlphaSorting = 2, DesktopSorting = 3, ActivitySorting = 4 }; TaskSortingStrategy sortingStrategy() const; void setSortingStrategy(TaskSortingStrategy); AbstractSortingStrategy* taskSorter() const; bool showOnlyCurrentScreen() const; void setShowOnlyCurrentScreen(bool); bool showOnlyCurrentDesktop() const; void setShowOnlyCurrentDesktop(bool); bool showOnlyCurrentActivity() const; void setShowOnlyCurrentActivity(bool); bool showOnlyMinimized() const; void setShowOnlyMinimized(bool); bool onlyGroupWhenFull() const; /** * Only apply the grouping startegy when the taskbar is full according to * setFullLimit(int). This is currently limited to ProgramGrouping. */ void setOnlyGroupWhenFull(bool state); /** * @return the currently set limit when the taskbar is considered as full */ int fullLimit() const; /** * Set the limit when the taskbar is considered as full */ void setFullLimit(int limit); /** * Functions to call if the user wants to do something manually, the strategy allows or refuses the request */ bool manualGroupingRequest(AbstractGroupableItem* taskItem, TaskGroup* groupItem); bool manualGroupingRequest(ItemList items); bool manualSortingRequest(AbstractGroupableItem* taskItem, int newIndex); /** * @returns the geometry of the currently set screen */ QRect screenGeometry() const; /** * Sets the current screen @p geometry */ void setScreenGeometry(const QRect& geometry); /** * Reconnect all neccessary signals to the taskmanager, and clear the per desktop stored rootGroups */ void reconnect(); /** Adds a Launcher for the executable/.desktop-file at url and returns a reference to the launcher*/ Q_INVOKABLE bool addLauncher(const QUrl &url, const QIcon &icon = QIcon(), const QString &name = QString(), const QString &genericName = QString(), const QString &wmClass = QString(), int insertPos = -1); /** Removes the given launcher*/ void removeLauncher(const QUrl &url); /** Get the current list of launchers */ QList launcherList() const; /** Set a new list of launchers */ void setLauncherList(const QList launchers); /** @return true if there is a matching launcher */ Q_INVOKABLE bool launcherExists(const QUrl &url) const; bool launcherExistsForUrl(const QUrl &url) const; /** @return position of launcher */ int launcherIndex(const QUrl &url) const; /** @return number of launchers */ int launcherCount() const; /** @return true if launchers should not be movable */ bool launchersLocked() const; /** lock launchers, so that they cannot be moved */ void setLaunchersLocked(bool l); /** move a launcher */ void moveLauncher(const QUrl &url, int newIndex); /** should launchers be show separate from tasks? */ bool separateLaunchers() const; /** set if launchers should been show separate from tasks */ void setSeparateLaunchers(bool s); /** Should grouping *always* happen? */ bool forceGrouping() const; /** set if grouping should *always* happen */ void setForceGrouping(bool s); /** create launcher mapping rules config page */ void createConfigurationInterface(KConfigDialog *parent); /** @return the launcher associated with a window class */ QUrl launcherForWmClass(const QString &wmClass) const; /** @return the window class associated with launcher */ QString launcherWmClass(const QUrl &url) const; /** @return true if item is associated with a launcher */ bool isItemAssociatedWithLauncher(AbstractGroupableItem *item) const; Q_SIGNALS: /** Signal that the rootGroup has to be reloaded in the visualization */ void reload(); /** Signal that the launcher list has changed */ void launcherListChanged(); void screenGeometryChanged(const QRect& geometry); void groupingStrategyChanged(TaskGroupingStrategy); void onlyGroupWhenFullChanged(bool); void forceGroupingChanged(bool); void fullLimitChanged(int); void sortingStrategyChanged(TaskSortingStrategy); void showOnlyCurrentScreenChanged(bool); void showOnlyCurrentDesktopChanged(bool); void showOnlyCurrentActivityChanged(bool); void showOnlyMinimizedChanged(bool); void separateLaunchersChanged(bool); private: Q_PRIVATE_SLOT(d, void currentDesktopChanged(int)) Q_PRIVATE_SLOT(d, void currentActivityChanged(QString)) - Q_PRIVATE_SLOT(d, void taskChanged(::TaskManager::Task *, ::TaskManager::TaskChanges)) + Q_PRIVATE_SLOT(d, void taskChanged(::LegacyTaskManager::Task *, ::LegacyTaskManager::TaskChanges)) Q_PRIVATE_SLOT(d, void checkScreenChange()) Q_PRIVATE_SLOT(d, void startupItemDestroyed(AbstractGroupableItem *)) Q_PRIVATE_SLOT(d, void startupDestroyed(QObject *)) Q_PRIVATE_SLOT(d, void checkIfFull()) Q_PRIVATE_SLOT(d, void actuallyCheckIfFull()) - Q_PRIVATE_SLOT(d, bool addTask(::TaskManager::Task *)) - Q_PRIVATE_SLOT(d, void removeTask(::TaskManager::Task *)) - Q_PRIVATE_SLOT(d, void addStartup(::TaskManager::Startup *)) - Q_PRIVATE_SLOT(d, void removeStartup(::TaskManager::Startup *)) + Q_PRIVATE_SLOT(d, bool addTask(::LegacyTaskManager::Task *)) + Q_PRIVATE_SLOT(d, void removeTask(::LegacyTaskManager::Task *)) + Q_PRIVATE_SLOT(d, void addStartup(::LegacyTaskManager::Startup *)) + Q_PRIVATE_SLOT(d, void removeStartup(::LegacyTaskManager::Startup *)) Q_PRIVATE_SLOT(d, void actuallyRemoveStartup()) Q_PRIVATE_SLOT(d, void actuallyReloadTasks()) Q_PRIVATE_SLOT(d, void taskDestroyed(QObject *)) Q_PRIVATE_SLOT(d, void sycocaChanged(const QStringList &)) Q_PRIVATE_SLOT(d, void launcherVisibilityChange()) friend class GroupManagerPrivate; GroupManagerPrivate * const d; }; } #endif diff --git a/libtaskmanager/launcherconfig.cpp b/liblegacytaskmanager/launcherconfig.cpp similarity index 97% rename from libtaskmanager/launcherconfig.cpp rename to liblegacytaskmanager/launcherconfig.cpp index 79d14febd..bb34f304d 100644 --- a/libtaskmanager/launcherconfig.cpp +++ b/liblegacytaskmanager/launcherconfig.cpp @@ -1,212 +1,212 @@ /***************************************************************** Copyright (C) 2011 Craig Drummond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "launcherconfig.h" #include "launcherproperties.h" #include #include #include #include #include #include #include -namespace TaskManager +namespace LegacyTaskManager { #define SEP "::" LauncherConfig::LauncherConfig(KConfigDialog *parent) : QWidget(parent) { connect(parent, SIGNAL(applyClicked()), SLOT(save())); connect(parent, SIGNAL(okClicked()), SLOT(save())); parent->addPage(this, i18n("Launcher Matching Rules"), QStringLiteral("fork")); ui.setupUi(this); ui.add->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); ui.edit->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); ui.remove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); ui.edit->setEnabled(false); ui.remove->setEnabled(false); connect(ui.add, &QPushButton::clicked, this, &LauncherConfig::add); connect(ui.edit, &QPushButton::clicked, this, &LauncherConfig::edit); connect(ui.remove, &QPushButton::clicked, this, &LauncherConfig::remove); connect(ui.view, &QTreeWidget::itemSelectionChanged, this, &LauncherConfig::selectionChanged); connect(this, SIGNAL(modified()), parent, SLOT(settingsModified())); connect(ui.label, SIGNAL(leftClickedUrl(QString)), SLOT(showMoreInfo())); load(); } LauncherConfig::~LauncherConfig() { } void LauncherConfig::load() { - KConfig cfg(QStringLiteral("taskmanagerrulesrc")); + KConfig cfg(QStringLiteral("legacytaskmanagerrulesrc")); KConfigGroup grp(&cfg, "Mapping"); foreach (const QString & key, grp.keyList()) { QString launcher = grp.readEntry(key, QString()); if (launcher.isEmpty()) { continue; } if (launcher.endsWith(QLatin1String(".desktop"))) { launcher = QUrl(launcher).toDisplayString(QUrl::PrettyDecoded); } int sepPos = key.indexOf(SEP); QString classClass, className; if (key.contains(SEP)) { classClass = key.left(sepPos); className = key.mid(sepPos + 2); } else { classClass = key; } new QTreeWidgetItem(ui.view, QStringList() << classClass << className << launcher); } if (ui.view->topLevelItemCount()) { ui.view->header()->resizeSections(QHeaderView::ResizeToContents); } } void LauncherConfig::save() { QMap entries; - KConfig cfg(QStringLiteral("taskmanagerrulesrc")); + KConfig cfg(QStringLiteral("legacytaskmanagerrulesrc")); KConfigGroup grp(&cfg, "Mapping"); // Go over view and create entries... for (int i = 0; i < ui.view->topLevelItemCount(); ++i) { QTreeWidgetItem *item = ui.view->topLevelItem(i); entries.insertMulti(item->text(0) + (item->text(1).isEmpty() ? QString() : (SEP + item->text(1))), item->text(2)); } // Remove old values... QSet newKeys = entries.keys().toSet(), oldKeys = grp.keyList().toSet(), removedKeys = oldKeys.subtract(newKeys); foreach (const QString & key, removedKeys) { grp.deleteEntry(key); } // Store new values... QMapIterator i(entries); while (i.hasNext()) { i.next(); grp.writeEntry(i.key(), i.value()); } } void LauncherConfig::add() { LauncherProperties *prop = new LauncherProperties(this); connect(prop, &LauncherProperties::properties, this, &LauncherConfig::addWithProperties); prop->run(); } void LauncherConfig::addWithProperties(const QString &classClass, const QString &className, const QString &launcher) { for (int i = 0; i < ui.view->topLevelItemCount(); ++i) { QTreeWidgetItem *item = ui.view->topLevelItem(i); if (item->text(0) == classClass && item->text(1) == className) { KMessageBox::error(this, i18n("A launcher is already defined for %1", classClass + (className.isEmpty() ? QString() : (QChar(' ') + className)))); return; } } new QTreeWidgetItem(ui.view, QStringList() << classClass << className << launcher); } void LauncherConfig::edit() { QList items = ui.view->selectedItems(); if (1 == items.count()) { QTreeWidgetItem *item = items.at(0); LauncherProperties *prop = new LauncherProperties(this); connect(prop, &LauncherProperties::properties, this, &LauncherConfig::setProperties); prop->run(item->text(0), item->text(1), item->text(2)); } } void LauncherConfig::setProperties(const QString &classClass, const QString &className, const QString &launcher) { QList items = ui.view->selectedItems(); if (1 == items.count()) { QTreeWidgetItem *item = items.at(0); if (item->text(0) != classClass || item->text(1) != className || item->text(2) != launcher) { item->setText(0, classClass); item->setText(1, className); item->setText(2, launcher); emit modified(); } } } void LauncherConfig::remove() { QList items = ui.view->selectedItems(); if (1 == items.count()) { delete items.at(0); emit modified(); } } void LauncherConfig::selectionChanged() { bool enable = 1 == ui.view->selectedItems().count(); ui.edit->setEnabled(enable); ui.remove->setEnabled(enable); } void LauncherConfig::showMoreInfo() { QWhatsThis::showText(ui.label->mapToGlobal(QPoint(0, 0)), i18n("To associate an application with a launcher, the task manager " "reads the application's window class and name. These are then " "used to look up the launcher details of an installed application. " "This attempts to match these against the application's \'Name\'. " "This can sometimes fail. The list above allows you to manually " "set the class+name to launcher/name mapping."), ui.label); } } diff --git a/libtaskmanager/launcherconfig.h b/liblegacytaskmanager/launcherconfig.h similarity index 98% rename from libtaskmanager/launcherconfig.h rename to liblegacytaskmanager/launcherconfig.h index 1ee9ed797..56d3f5df6 100644 --- a/libtaskmanager/launcherconfig.h +++ b/liblegacytaskmanager/launcherconfig.h @@ -1,65 +1,65 @@ /***************************************************************** Copyright (C) 2011 Craig Drummond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef LAUNCHER_CONFIG_H #define LAUNCHER_CONFIG_H #include #include "ui_launcherconfig.h" class KConfigDialog; -namespace TaskManager +namespace LegacyTaskManager { class LauncherConfig : public QWidget { Q_OBJECT public: LauncherConfig(KConfigDialog *parent = 0L); ~LauncherConfig() override; Q_SIGNALS: void modified(); public Q_SLOTS: void load(); void save(); private Q_SLOTS: void add(); void addWithProperties(const QString &classClass, const QString &className, const QString &launcher); void edit(); void setProperties(const QString &classClass, const QString &className, const QString &launcher); void remove(); void selectionChanged(); void showMoreInfo(); private: Ui::LauncherConfig ui; }; } #endif diff --git a/libtaskmanager/launcherconfig.ui b/liblegacytaskmanager/launcherconfig.ui similarity index 100% rename from libtaskmanager/launcherconfig.ui rename to liblegacytaskmanager/launcherconfig.ui diff --git a/libtaskmanager/launcheritem.cpp b/liblegacytaskmanager/launcheritem.cpp similarity index 99% rename from libtaskmanager/launcheritem.cpp rename to liblegacytaskmanager/launcheritem.cpp index d4ad31a29..30ef149e7 100644 --- a/libtaskmanager/launcheritem.cpp +++ b/liblegacytaskmanager/launcheritem.cpp @@ -1,525 +1,525 @@ /***************************************************************** Copyright 2010 Anton Kreuzkamp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "launcheritem.h" #include #if HAVE_X11 #include #endif #include #include #include #include #include #include #include #include #include #include #include // KIO #include // no camelcase include #include "groupmanager.h" #include "taskitem.h" #include "taskgroup.h" -namespace TaskManager +namespace LegacyTaskManager { class LauncherItemPrivate { public: LauncherItemPrivate(LauncherItem *launcher) : q(launcher) { } void associateDestroyed(QObject *obj); LauncherItem *q; QUrl url; QUrl resolvedUrl; QIcon icon; QString name; QString genericName; QString wmClass; QSet associates; }; LauncherItem::LauncherItem(QObject *parent, const QUrl &url) : AbstractGroupableItem(parent), d(new LauncherItemPrivate(this)) { if (url.isEmpty()) { d->icon = QIcon::fromTheme(QStringLiteral("unknown")); } else { setLauncherUrl(url); } } LauncherItem::~LauncherItem() { emit destroyed(this); delete d; } bool LauncherItem::associateItemIfMatches(AbstractGroupableItem *item) { if (d->associates.contains(item)) { return false; } QUrl itemUrl = item->launcherUrl(); if (!itemUrl.isEmpty()) { if (d->url == itemUrl || d->resolvedUrl == itemUrl) { d->associates.insert(item); connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(associateDestroyed(QObject*))); emit associationChanged(); return true; } else if (!launcherUrl().isEmpty()) { return false; } } QString name; if (item->itemType() == TaskItemType && !item->isStartupItem()) { name = static_cast(item)->taskName().toLower(); } else { name = item->name().toLower(); } if (!name.isEmpty() && name.compare(d->name, Qt::CaseInsensitive) == 0) { d->associates.insert(item); connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(associateDestroyed(QObject*))); emit associationChanged(); // Store this mapping! if (TaskItemType == item->itemType()) { static_cast(item)->setLauncherUrl(this); } return true; } return false; } bool LauncherItem::isAssociated(AbstractGroupableItem *item) const { return d->associates.contains(item); } void LauncherItem::removeItemIfAssociated(AbstractGroupableItem *item) { disconnect(item, SIGNAL(destroyed(QObject*)), this, SLOT(associateDestroyed(QObject*))); // now let's just pretend it was destroyed d->associateDestroyed(item); } bool LauncherItem::shouldShow(const GroupManager *manager) const { if (!manager) { return d->associates.isEmpty(); } const bool screen = manager->showOnlyCurrentScreen(); const bool desk = manager->showOnlyCurrentDesktop(); const bool activity = manager->showOnlyCurrentActivity(); foreach (QObject *obj, d->associates) { TaskItem *item = qobject_cast(obj); if (!item || !item->task()) { continue; } if ((!screen || item->task()->isOnScreen(manager->screenGeometry())) && (!desk || item->isOnCurrentDesktop()) && (!activity || item->task()->isOnCurrentActivity())) { return false; } } return true; } void LauncherItemPrivate::associateDestroyed(QObject *obj) { if (associates.remove(obj)) { emit q->associationChanged(); } } QIcon LauncherItem::icon() const { return d->icon; } QString LauncherItem::name() const { return d->name; } QString LauncherItem::genericName() const { return d->genericName; } QString LauncherItem::wmClass() const { return d->wmClass; } void LauncherItem::setName(const QString& name) { //NOTE: preferred is NOT a protocol, it's just a magic string if (d->url.scheme() != QLatin1String("preferred")) { d->name = name; } } void LauncherItem::setGenericName(const QString& genericName) { //NOTE: preferred is NOT a protocol, it's just a magic string if (d->url.scheme() != QLatin1String("preferred")) { d->genericName = genericName; } } void LauncherItem::setWmClass(const QString &wmClass) { d->wmClass = wmClass; } ItemType LauncherItem::itemType() const { return LauncherItemType; } bool LauncherItem::isGroupItem() const { return false; } void LauncherItem::launch() { quint32 timeStamp = 0; #if HAVE_X11 if (QX11Info::isPlatformX11()) { timeStamp = QX11Info::appUserTime(); } #endif //NOTE: preferred is NOT a protocol, it's just a magic string if (d->url.scheme() == QLatin1String("preferred")) { KService::Ptr service = KService::serviceByStorageId(defaultApplication(d->url)); if (!service) { return; } QString desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath()); new KRun(QUrl::fromLocalFile(desktopFile), 0, false, KStartupInfo::createNewStartupIdForTimestamp(timeStamp)); } else { new KRun(d->url, 0, false, KStartupInfo::createNewStartupIdForTimestamp(timeStamp)); } } void LauncherItem::addMimeData(QMimeData* mimeData) const { mimeData->setUrls({d->url}); } QUrl LauncherItem::launcherUrl() const { return d->url; } //Ugly hack written by Aaron Seigo from plasmagenericshell/scripting/scriptengine.cpp QString LauncherItem::defaultApplication(const QUrl &url) { const QString application = url.host(); if (application.isEmpty()) { return QString(); } // FIXME: there are some pretty horrible hacks below, in the sense that they assume a very // specific implementation system. there is much room for improvement here. see // kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;) if (application.compare(QLatin1String("mailer"), Qt::CaseInsensitive) == 0) { KEMailSettings settings; // in KToolInvocation, the default is kmail; but let's be friendlier :) QString command = settings.getSetting(KEMailSettings::ClientProgram); if (command.isEmpty()) { if (KService::Ptr kontact = KService::serviceByStorageId(QStringLiteral("kontact"))) { return kontact->storageId(); } else if (KService::Ptr kmail = KService::serviceByStorageId(QStringLiteral("kmail"))) { return kmail->storageId(); } } if (!command.isEmpty()) { if (settings.getSetting(KEMailSettings::ClientTerminal) == QLatin1String("true")) { KConfigGroup confGroup(KSharedConfig::openConfig(), "General"); const QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", QStringLiteral("konsole")); command = preferredTerminal + QLatin1String(" -e ") + command; } return command; } } else if (application.compare(QLatin1String("browser"), Qt::CaseInsensitive) == 0) { KConfigGroup config(KSharedConfig::openConfig(), "General"); QString browserApp = config.readPathEntry("BrowserApplication", QString()); if (browserApp.isEmpty()) { const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QStringLiteral("text/html")); if (htmlApp) { browserApp = htmlApp->storageId(); } } else if (browserApp.startsWith('!')) { browserApp = browserApp.mid(1); } return browserApp; } else if (application.compare(QLatin1String("terminal"), Qt::CaseInsensitive) == 0) { KConfigGroup confGroup(KSharedConfig::openConfig(), "General"); return confGroup.readPathEntry("TerminalApplication", QStringLiteral("konsole")); } else if (application.compare(QLatin1String("filemanager"), Qt::CaseInsensitive) == 0) { KService::Ptr service = KMimeTypeTrader::self()->preferredService(QStringLiteral("inode/directory")); if (service) { return service->storageId(); } } else if (application.compare(QLatin1String("windowmanager"), Qt::CaseInsensitive) == 0) { KConfig cfg(QStringLiteral("ksmserverrc"), KConfig::NoGlobals); KConfigGroup confGroup(&cfg, "General"); return confGroup.readEntry("windowManager", QStringLiteral("kwin")); } else if (KService::Ptr service = KMimeTypeTrader::self()->preferredService(application)) { return service->storageId(); } else { // try the files in share/apps/kcm_componentchooser/*.desktop QStringList directories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kcm_componentchooser"), QStandardPaths::LocateDirectory); QStringList services; foreach(const QString& directory, directories) { QDir d(directory); foreach(const QString& f, d.entryList(QStringList("*.desktop"))) services += d.absoluteFilePath(f); } //qDebug() << "ok, trying in" << services.count(); foreach (const QString & service, services) { KConfig config(service, KConfig::SimpleConfig); KConfigGroup cg = config.group(QByteArray()); const QString type = cg.readEntry("valueName", QString()); //qDebug() << " checking" << service << type << application; if (type.compare(application, Qt::CaseInsensitive) == 0) { KConfig store(cg.readPathEntry("storeInFile", QStringLiteral("null"))); KConfigGroup storeCg(&store, cg.readEntry("valueSection", QString())); const QString exec = storeCg.readPathEntry(cg.readEntry("valueName", "kcm_componenchooser_null"), cg.readEntry("defaultImplementation", QString())); if (!exec.isEmpty()) { return exec; } break; } } } return QLatin1String(""); } void LauncherItem::setLauncherUrl(const QUrl& url) { // Takes care of improperly escaped characters and resolves paths // into file:/// URLs QUrl newUrl(url.url()); if (d->url.scheme() != QLatin1String("preferred") && newUrl == d->url) { return; } d->url = newUrl; if (d->url.isLocalFile() && KDesktopFile::isDesktopFile(d->url.toLocalFile())) { KDesktopFile f(d->url.toLocalFile()); if (f.tryExec()) { d->icon = QIcon::fromTheme(f.readIcon()); d->name = f.readName(); d->genericName = f.readGenericName(); } else { d->url = QUrl(); return; } } else if (d->url.scheme() == QLatin1String("preferred")) { //NOTE: preferred is NOT a protocol, it's just a magic string const KService::Ptr service = KService::serviceByStorageId(defaultApplication(d->url)); if (service) { QString desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath()); KDesktopFile f(desktopFile); KConfigGroup cg(&f, "Desktop Entry"); d->icon = QIcon::fromTheme(f.readIcon()); const QString exec = cg.readEntry("Exec", QString()); d->name = cg.readEntry("Name", QString()); if (d->name.isEmpty() && !exec.isEmpty()) { d->name = exec.split(' ').at(0); } d->genericName = f.readGenericName(); d->resolvedUrl = QUrl::fromLocalFile(desktopFile); } else { d->url = QUrl(); } } else { const KFileItem fileItem(d->url); d->icon = QIcon::fromTheme(fileItem.iconName()); } if (d->name.isEmpty()) { d->name = d->url.fileName(); } if (d->icon.isNull()) { d->icon = QIcon::fromTheme(QStringLiteral("unknown")); } } bool LauncherItem::isValid() const { return d->url.isValid(); } void LauncherItem::setIcon(const QIcon& icon) { //NOTE: preferred is NOT a protocol, it's just a magic string if (d->url.scheme() != QLatin1String("preferred")) { d->icon = icon; } } bool LauncherItem::demandsAttention() const { return false; } bool LauncherItem::isActionSupported(NET::Action) const { return false; } bool LauncherItem::isActive() const { return false; } bool LauncherItem::isAlwaysOnTop() const { return false; } bool LauncherItem::isFullScreen() const { return false; } bool LauncherItem::isKeptBelowOthers() const { return false; } bool LauncherItem::isMaximized() const { return false; } bool LauncherItem::isMinimized() const { return false; } bool LauncherItem::isOnAllDesktops() const { return false; } bool LauncherItem::isOnCurrentDesktop() const { return false; } bool LauncherItem::isShaded() const { return false; } int LauncherItem::desktop() const { return 0; } void LauncherItem::setAlwaysOnTop(bool) { } void LauncherItem::setFullScreen(bool) { } void LauncherItem::setKeptBelowOthers(bool) { } void LauncherItem::setMaximized(bool) { } void LauncherItem::setMinimized(bool) { } void LauncherItem::setShaded(bool) { } void LauncherItem::toDesktop(int) { } void LauncherItem::toggleAlwaysOnTop() { } void LauncherItem::toggleFullScreen() { } void LauncherItem::toggleKeptBelowOthers() { } void LauncherItem::toggleMaximized() { } void LauncherItem::toggleMinimized() { } void LauncherItem::toggleShaded() { } void LauncherItem::close() { } //END -} // TaskManager namespace +} // LegacyTaskManager namespace #include "moc_launcheritem.cpp" diff --git a/libtaskmanager/launcheritem.h b/liblegacytaskmanager/launcheritem.h similarity index 94% rename from libtaskmanager/launcheritem.h rename to liblegacytaskmanager/launcheritem.h index 9d2e9b4ad..c62f35cf4 100644 --- a/libtaskmanager/launcheritem.h +++ b/liblegacytaskmanager/launcheritem.h @@ -1,131 +1,131 @@ /***************************************************************** Copyright 2010 Anton Kreuzkamp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef LAUNCHERITEM_H #define LAUNCHERITEM_H #include "abstractgroupableitem.h" -#include "taskmanager_export.h" +#include "legacytaskmanager_export.h" -namespace TaskManager +namespace LegacyTaskManager { class LauncherItemPrivate; class GroupManager; /** * An item shown in the taskmanager, in order to use it to launch the application (or file) the launcher is linked to. * If the Application is running the launcher gets hidden, in order to not waste space. */ -class TASKMANAGER_EXPORT LauncherItem : public AbstractGroupableItem +class LEGACYTASKMANAGER_EXPORT LauncherItem : public AbstractGroupableItem { Q_OBJECT public: /** * Creates a LauncherItem for a executable * @param url the URL to the application or file the launcher gets linked to */ LauncherItem(QObject *parent, const QUrl &url); ~LauncherItem() override; /** * @deprecated: use itemType() instead **/ - TASKMANAGER_DEPRECATED bool isGroupItem() const override; + LEGACYTASKMANAGER_DEPRECATED bool isGroupItem() const override; ItemType itemType() const override; bool isValid() const; QIcon icon() const override; QString name() const override; QString genericName() const override; QString wmClass() const; void setIcon(const QIcon &icon); void setName(const QString &name); void setGenericName(const QString &genericName); void setWmClass(const QString &wmClass); // bookkeeping methods for showing/not showing /** Return true if this is a *new* association */ bool associateItemIfMatches(AbstractGroupableItem *item); bool isAssociated(AbstractGroupableItem *item) const; void removeItemIfAssociated(AbstractGroupableItem *item); bool shouldShow(const GroupManager *manager) const; //reimplemented pure virtual methods from abstractgroupableitem bool isOnCurrentDesktop() const override; bool isOnAllDesktops() const override; int desktop() const override; bool isShaded() const override; bool isMaximized() const override; bool isMinimized() const override; bool isFullScreen() const override; bool isKeptBelowOthers() const override; bool isAlwaysOnTop() const override; bool isActionSupported(NET::Action) const override; bool isActive() const override; bool demandsAttention() const override; void addMimeData(QMimeData *mimeData) const override; QUrl launcherUrl() const override; void setLauncherUrl(const QUrl &url); //preferred applications hack static QString defaultApplication(const QUrl &url); public Q_SLOTS: void toDesktop(int) override; void setShaded(bool) override; void toggleShaded() override; void setMaximized(bool) override; void toggleMaximized() override; void setMinimized(bool) override; void toggleMinimized() override; void setFullScreen(bool) override; void toggleFullScreen() override; void setKeptBelowOthers(bool) override; void toggleKeptBelowOthers() override; void setAlwaysOnTop(bool) override; void toggleAlwaysOnTop() override; void close() override; void launch(); Q_SIGNALS: void associationChanged(); private: friend class LauncherItemPrivate; LauncherItemPrivate * const d; Q_PRIVATE_SLOT(d, void associateDestroyed(QObject *obj)) }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/launcherproperties.cpp b/liblegacytaskmanager/launcherproperties.cpp similarity index 99% rename from libtaskmanager/launcherproperties.cpp rename to liblegacytaskmanager/launcherproperties.cpp index 418d13891..b42c85e1f 100644 --- a/libtaskmanager/launcherproperties.cpp +++ b/liblegacytaskmanager/launcherproperties.cpp @@ -1,206 +1,206 @@ /***************************************************************** Copyright (C) 2011 Craig Drummond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "launcherproperties.h" #include #include #include #include #include #include #include #include #include #include #include #include -namespace TaskManager +namespace LegacyTaskManager { LauncherProperties::LauncherProperties(QWidget *parent) : QDialog(parent) , grabber(0L) { setWindowTitle(i18n("Launcher Properties")); QWidget *mainWidet = new QWidget(this); ui.setupUi(mainWidet); setLayout(new QVBoxLayout(this)); layout()->addWidget(mainWidet); buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); layout()->addWidget(buttons); setAttribute(Qt::WA_DeleteOnClose); setWindowModality(Qt::WindowModal); ui.browse->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); connect(ui.detect, &QPushButton::clicked, this, &LauncherProperties::detect); connect(ui.browse, &QPushButton::clicked, this, &LauncherProperties::browse); connect(ui.classClass, &KLineEdit::textChanged, this, &LauncherProperties::check); connect(ui.className, &KLineEdit::textChanged, this, &LauncherProperties::check); connect(ui.launcher, &KLineEdit::textChanged, this, &LauncherProperties::check); connect(buttons, &QDialogButtonBox::accepted, this, &LauncherProperties::okClicked); connect(buttons, &QDialogButtonBox::rejected, this, &LauncherProperties::reject); resize(400, 100); } LauncherProperties::~LauncherProperties() { delete grabber; } void LauncherProperties::run(const QString &cc, const QString &cn, const QString &l) { ui.classClass->setText(cc); ui.className->setText(cn); ui.launcher->setText(l); check(); show(); } void LauncherProperties::check() { buttons->button(QDialogButtonBox::Ok)->setEnabled(!ui.classClass->text().isEmpty() && !ui.launcher->text().isEmpty()); } void LauncherProperties::detect() { // Taken from oxygen... // use a dialog, so that all user input is blocked // use WX11BypassWM and moving away so that it's not actually visible // grab only mouse, so that keyboard can be used e.g. for switching windows grabber = new QDialog(0, Qt::X11BypassWindowManagerHint); grabber->move(-1000, -1000); grabber->setModal(true); grabber->show(); grabber->grabMouse(Qt::CrossCursor); grabber->installEventFilter(this); } void LauncherProperties::browse() { KOpenWithDialog *dlg = new KOpenWithDialog(QList(), i18n("Select launcher application:"), QString(), this); dlg->hideNoCloseOnExit(); dlg->hideRunInTerminal(); dlg->setAttribute(Qt::WA_DeleteOnClose); dlg->setWindowModality(Qt::WindowModal); connect(dlg, &KOpenWithDialog::accepted, this, &LauncherProperties::launcherSelected); dlg->show(); } void LauncherProperties::launcherSelected() { KOpenWithDialog *dlg = qobject_cast(sender()); if (dlg) { KService::Ptr srv = dlg->service(); if (srv && srv->isApplication() && !srv->entryPath().isEmpty()) { QUrl url = QUrl::fromLocalFile(srv->entryPath()); if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) { ui.launcher->setText(url.toDisplayString(QUrl::PrettyDecoded)); } } else { QString path = dlg->text(); if (!path.isEmpty()) { QUrl url = QUrl::fromLocalFile(path); if (url.isLocalFile()) { ui.launcher->setText(url.toDisplayString(QUrl::PrettyDecoded)); } } } } } void LauncherProperties::okClicked() { emit properties(ui.classClass->text(), ui.className->text(), ui.launcher->text()); accept(); } bool LauncherProperties::eventFilter(QObject *o, QEvent *e) { // check object and event type if (o != grabber || QEvent::MouseButtonRelease != e->type()) { return false; } // delete old grabber delete grabber; grabber = 0; // check button if (Qt::LeftButton != static_cast< QMouseEvent* >(e)->button()) { return true; } // read window information WId window = findWindow(); if (0 != window) { KWindowInfo info(window, 0, NET::WM2WindowClass); if (info.valid()) { ui.classClass->setText(info.windowClassClass()); ui.className->setText(info.windowClassName()); } } return true; } WId LauncherProperties::findWindow() { Window root; Window child; uint mask; int rootX, rootY, x, y; Window parent = QX11Info::appRootWindow(); Atom wm_state = XInternAtom(QX11Info::display(), "WM_STATE", False); // why is there a loop of only 10 here for (int i = 0; i < 10; ++i) { XQueryPointer(QX11Info::display(), parent, &root, &child, &rootX, &rootY, &x, &y, &mask); if (child == None) return 0; Atom type; int format; unsigned long nitems, after; unsigned char* prop; if (XGetWindowProperty( QX11Info::display(), child, wm_state, 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &prop) == Success) { if (prop != NULL) XFree(prop); if (type != None) return child; } parent = child; } return 0; } } diff --git a/libtaskmanager/launcherproperties.h b/liblegacytaskmanager/launcherproperties.h similarity index 98% rename from libtaskmanager/launcherproperties.h rename to liblegacytaskmanager/launcherproperties.h index c04445217..881e278f0 100644 --- a/libtaskmanager/launcherproperties.h +++ b/liblegacytaskmanager/launcherproperties.h @@ -1,66 +1,66 @@ /***************************************************************** Copyright (C) 2011 Craig Drummond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef LAUNCHER_PROPERTIES_H #define LAUNCHER_PROPERTIES_H #include #include "ui_launcherproperties.h" class QDialogButtonBox; -namespace TaskManager +namespace LegacyTaskManager { class LauncherProperties : public QDialog { Q_OBJECT public: LauncherProperties(QWidget *parent = 0L); ~LauncherProperties() override; void run(const QString &cc = QString(), const QString &cn = QString(), const QString &l = QString()); Q_SIGNALS: void properties(const QString &, const QString &, const QString &); private Q_SLOTS: void check(); void detect(); void browse(); void launcherSelected(); void okClicked(); private: bool eventFilter(QObject *o, QEvent *e) override; WId findWindow(); private: Ui::LauncherProperties ui; QDialog *grabber; QDialogButtonBox *buttons; }; } #endif diff --git a/libtaskmanager/launcherproperties.ui b/liblegacytaskmanager/launcherproperties.ui similarity index 100% rename from libtaskmanager/launcherproperties.ui rename to liblegacytaskmanager/launcherproperties.ui diff --git a/libtaskmanager/taskmanager.cpp b/liblegacytaskmanager/legacytaskmanager.cpp similarity index 82% rename from libtaskmanager/taskmanager.cpp rename to liblegacytaskmanager/legacytaskmanager.cpp index bbd496d77..94c1343d2 100644 --- a/libtaskmanager/taskmanager.cpp +++ b/liblegacytaskmanager/legacytaskmanager.cpp @@ -1,562 +1,562 @@ /***************************************************************** Copyright (c) 2000 Matthias Elter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own -#include "taskmanager.h" +#include "legacytaskmanager.h" // Qt #include #include #include #include // KDE #include #include #include #include #include #if HAVE_X11 #include #endif #ifdef Q_WS_WIN #include #endif #include -namespace TaskManager +namespace LegacyTaskManager { -class TaskManagerSingleton +class LegacyTaskManagerSingleton { public: - TaskManager self; + LegacyTaskManager self; }; -Q_GLOBAL_STATIC(TaskManagerSingleton, privateTaskManagerSelf) +Q_GLOBAL_STATIC(LegacyTaskManagerSingleton, privateTaskManagerSelf) static const int s_startupDefaultTimeout = 5; -TaskManager* TaskManager::self() +LegacyTaskManager* LegacyTaskManager::self() { return &privateTaskManagerSelf->self; } -class TaskManager::Private +class LegacyTaskManager::Private { public: - Private(TaskManager *manager) + Private(LegacyTaskManager *manager) : q(manager), active(0), startupInfo(0), watcher(0) { } void onAppExitCleanup() { q->disconnect(KWindowSystem::self(), 0, q, 0); delete watcher; watcher = 0; delete startupInfo; startupInfo = 0; foreach (Task *task, tasksByWId) { task->clearPixmapData(); } foreach (Startup *startup, startups) { startup->clearPixmapData(); } } - TaskManager *q; + LegacyTaskManager *q; Task *active; KStartupInfo* startupInfo; KDirWatch *watcher; QHash tasksByWId; QList startups; WindowList skiptaskbarWindows; QSet trackGeometryTokens; KActivities::Consumer activityConsumer; }; -TaskManager::TaskManager() +LegacyTaskManager::LegacyTaskManager() : QObject(), d(new Private(this)) { connect(KWindowSystem::self(), &KWindowSystem::windowAdded, - this, &TaskManager::windowAdded); + this, &LegacyTaskManager::windowAdded); connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, - this, &TaskManager::windowRemoved); + this, &LegacyTaskManager::windowRemoved); connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, - this, &TaskManager::activeWindowChanged); + this, &LegacyTaskManager::activeWindowChanged); connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged, - this, &TaskManager::currentDesktopChanged); + this, &LegacyTaskManager::currentDesktopChanged); connect(KWindowSystem::self(), SIGNAL(windowChanged(WId, const ulong*)), this, SLOT(windowChanged(WId, const ulong*))); connect(&d->activityConsumer, &KActivities::Consumer::currentActivityChanged, - this, &TaskManager::activityChanged); + this, &LegacyTaskManager::activityChanged); if (QCoreApplication::instance()) { connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(onAppExitCleanup())); } emit activityChanged(d->activityConsumer.currentActivity()); // register existing windows const QList windows = KWindowSystem::windows(); QList::ConstIterator end(windows.end()); for (QList::ConstIterator it = windows.begin(); it != end; ++it) { windowAdded(*it); } // set active window WId win = KWindowSystem::activeWindow(); activeWindowChanged(win); d->watcher = new KDirWatch(this); d->watcher->addFile(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)+"/klaunchrc"); - connect(d->watcher, &KDirWatch::dirty, this, &TaskManager::configureStartup); - connect(d->watcher, &KDirWatch::created, this, &TaskManager::configureStartup); - connect(d->watcher, &KDirWatch::deleted, this, &TaskManager::configureStartup); + connect(d->watcher, &KDirWatch::dirty, this, &LegacyTaskManager::configureStartup); + connect(d->watcher, &KDirWatch::created, this, &LegacyTaskManager::configureStartup); + connect(d->watcher, &KDirWatch::deleted, this, &LegacyTaskManager::configureStartup); configureStartup(); } -TaskManager::~TaskManager() +LegacyTaskManager::~LegacyTaskManager() { QHash tasksByWId = d->tasksByWId; d->tasksByWId.clear(); qDeleteAll(tasksByWId); QList startups = d->startups; d->startups.clear(); qDeleteAll(startups); delete d; } -void TaskManager::configureStartup() +void LegacyTaskManager::configureStartup() { KConfig _c(QStringLiteral("klaunchrc")); KConfigGroup c(&_c, "FeedbackStyle"); if (!c.readEntry("TaskbarButton", true)) { delete d->startupInfo; d->startupInfo = 0; return; } if (!d->startupInfo) { d->startupInfo = new KStartupInfo(KStartupInfo::CleanOnCantDetect, this); connect(d->startupInfo, &KStartupInfo::gotNewStartup, - this, &TaskManager::gotNewStartup); + this, &LegacyTaskManager::gotNewStartup); connect(d->startupInfo, &KStartupInfo::gotStartupChange, - this, &TaskManager::gotStartupChange); + this, &LegacyTaskManager::gotStartupChange); connect(d->startupInfo, &KStartupInfo::gotRemoveStartup, - this, &TaskManager::killStartup); + this, &LegacyTaskManager::killStartup); } c = KConfigGroup(&_c, "TaskbarButtonSettings"); d->startupInfo->setTimeout(c.readEntry("Timeout", s_startupDefaultTimeout)); } -Task *TaskManager::findTask(WId w) +Task *LegacyTaskManager::findTask(WId w) { QHashIterator it (d->tasksByWId); while (it.hasNext()) { it.next(); if (it.key() == w || it.value()->hasTransient(w)) { return it.value(); } } return 0; } -Task *TaskManager::findTask(int desktop, const QPoint& p) +Task *LegacyTaskManager::findTask(int desktop, const QPoint& p) { QList list = KWindowSystem::stackingOrder(); Task *task = 0; int currentIndex = -1; foreach (Task *t, d->tasksByWId) { if (!t->isOnAllDesktops() && t->desktop() != desktop) { continue; } //FIXME activities? if (t->isIconified() || t->isShaded()) { continue; } if (t->geometry().contains(p)) { int index = list.indexOf(t->window()); if (index > currentIndex) { currentIndex = index; task = t; } } } return task; } -void TaskManager::windowAdded(WId w) +void LegacyTaskManager::windowAdded(WId w) { #if HAVE_X11 KWindowInfo info(w, NET::WMWindowType | NET::WMPid | NET::WMState | NET::WMName, NET::WM2TransientFor); // ignore NET::Tool and other special window types NET::WindowType wType = info.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask); if (info.transientFor() > 0) { const WId transientFor = info.transientFor(); // check if it's transient for a skiptaskbar window if (d->skiptaskbarWindows.contains(transientFor)) { return; } // lets see if this is a transient for an existing task if (transientFor != QX11Info::appRootWindow()) { Task *t = findTask(transientFor); if (t) { if (t->window() != w) { t->addTransient(w, info); // qDebug() << "TM: Transient " << w << " added for Task: " << t->window(); } return; } } } if (wType != NET::Normal && wType != NET::Override && wType != NET::Unknown && wType != NET::Dialog && wType != NET::Utility) { return; } // ignore windows that want to be ignored by the taskbar if ((info.state() & NET::SkipTaskbar) != 0) { d->skiptaskbarWindows.insert(w); // remember them though return; } #endif Task *t = new Task(w, 0); d->tasksByWId.insert(w, t); - connect(t, SIGNAL(changed(::TaskManager::TaskChanges)), - this, SLOT(taskChanged(::TaskManager::TaskChanges))); + connect(t, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), + this, SLOT(taskChanged(::LegacyTaskManager::TaskChanges))); if (d->startupInfo) { KStartupInfoId startupInfoId; // checkStartup modifies startupInfoId d->startupInfo->checkStartup(w, startupInfoId); foreach (Startup *startup, d->startups) { if (startup->id() == startupInfoId) { startup->addWindowMatch(w); } } } // qDebug() << "TM: Task added for WId: " << w; emit taskAdded(t); } -void TaskManager::windowRemoved(WId w) +void LegacyTaskManager::windowRemoved(WId w) { d->skiptaskbarWindows.remove(w); // find task Task *t = findTask(w); if (!t) { return; } if (t->window() == w) { d->tasksByWId.remove(w); emit taskRemoved(t); if (t == d->active) { d->active = 0; } //qDebug() << "TM: Task for WId " << w << " removed."; // FIXME: due to a bug in Qt 4.x, the event loop reference count is incorrect // when going through x11EventFilter .. :/ so we have to singleShot the deleteLater QTimer::singleShot(0, t, &QObject::deleteLater); } else { t->removeTransient(w); //qDebug() << "TM: Transient " << w << " for Task " << t->window() << " removed."; } } -void TaskManager::windowChanged(WId w, const unsigned long *dirty) +void LegacyTaskManager::windowChanged(WId w, const unsigned long *dirty) { #if HAVE_X11 if (dirty[NETWinInfo::PROTOCOLS] & NET::WMState) { NETWinInfo info(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMState | NET::XAWMState); if (info.state() & NET::SkipTaskbar) { windowRemoved(w); d->skiptaskbarWindows.insert(w); return; } else { d->skiptaskbarWindows.remove(w); if (info.mappingState() != NET::Withdrawn && !findTask(w)) { // skipTaskBar state was removed and the window is still // mapped, so add this window windowAdded(w); } } } // check if any state we are interested in is marked dirty if (!(dirty[NETWinInfo::PROTOCOLS] & (NET::WMVisibleName | NET::WMName | NET::WMState | NET::WMIcon | NET::XAWMState | NET::WMDesktop) || (trackGeometry() && dirty[NETWinInfo::PROTOCOLS] & NET::WMGeometry) || (dirty[NETWinInfo::PROTOCOLS2] & NET::WM2Activities))) { return; } // find task Task *t = findTask(w); if (!t) { return; } - //qDebug() << "TaskManager::windowChanged " << w << " " << dirty[NETWinInfo::PROTOCOLS] << dirty[NETWinInfo::PROTOCOLS2]; + //qDebug() << "LegacyTaskManager::windowChanged " << w << " " << dirty[NETWinInfo::PROTOCOLS] << dirty[NETWinInfo::PROTOCOLS2]; unsigned long propagatedChanges = 0; if ((dirty[NETWinInfo::PROTOCOLS] & NET::WMState) && t->updateDemandsAttentionState(w)) { propagatedChanges = NET::WMState; } //qDebug() << "got changes, but will we refresh?" << dirty[NETWinInfo::PROTOCOLS] << dirty[NETWinInfo::PROTOCOLS2]; if (dirty[NETWinInfo::PROTOCOLS] || dirty[NETWinInfo::PROTOCOLS2]) { // only refresh this stuff if we have other changes besides icons t->refresh(Task::WindowProperties(dirty[NETWinInfo::PROTOCOLS] | propagatedChanges, dirty[NETWinInfo::PROTOCOLS2])); } #endif } -void TaskManager::taskChanged(::TaskManager::TaskChanges changes) +void LegacyTaskManager::taskChanged(::LegacyTaskManager::TaskChanges changes) { Task *t = qobject_cast(sender()); if (!t || changes == TaskUnchanged || !d->tasksByWId.contains(t->info().win())) { return; } emit windowChanged(d->tasksByWId[t->info().win()], changes); } -void TaskManager::activeWindowChanged(WId w) +void LegacyTaskManager::activeWindowChanged(WId w) { - //qDebug() << "TaskManager::activeWindowChanged" << w; + //qDebug() << "LegacyTaskManager::activeWindowChanged" << w; Task *t = findTask(w); if (!t) { if (d->active) { d->active->setActive(false); d->active = 0; } //qDebug() << "no active window"; } else { if (t->info().windowType(NET::UtilityMask) == NET::Utility && !t->demandsAttention()) { // we don't want to mark utility windows as active since task managers // actually care about the main window and skip utility windows; utility // windows are hidden when their associated window loses focus anyways // see http://bugs.kde.org/show_bug.cgi?id=178509 return; } if (d->active) { d->active->setActive(false); } d->active = t; d->active->setActive(true); //qDebug() << "active window is" << t->name(); } } -void TaskManager::currentDesktopChanged(int desktop) +void LegacyTaskManager::currentDesktopChanged(int desktop) { emit desktopChanged(desktop); } -void TaskManager::gotNewStartup(const KStartupInfoId& id, const KStartupInfoData& data) +void LegacyTaskManager::gotNewStartup(const KStartupInfoId& id, const KStartupInfoData& data) { Startup *s = new Startup(id, data, 0); - connect(s, &QObject::destroyed, this, &TaskManager::startupDestroyed); + connect(s, &QObject::destroyed, this, &LegacyTaskManager::startupDestroyed); d->startups.append(s); emit startupAdded(s); } -void TaskManager::gotStartupChange(const KStartupInfoId& id, const KStartupInfoData& data) +void LegacyTaskManager::gotStartupChange(const KStartupInfoId& id, const KStartupInfoData& data) { foreach (Startup *startup, d->startups) { if (startup->id() == id) { startup->update(data); return; } } } -void TaskManager::killStartup(const KStartupInfoId& id) +void LegacyTaskManager::killStartup(const KStartupInfoId& id) { foreach (Startup *startup, d->startups) { if (startup->id() == id) { d->startups.removeAll(startup); emit startupRemoved(startup); } } } -void TaskManager::startupDestroyed(QObject* obj) +void LegacyTaskManager::startupDestroyed(QObject* obj) { d->startups.removeAll(static_cast(obj)); } -QString TaskManager::desktopName(int desk) const +QString LegacyTaskManager::desktopName(int desk) const { return KWindowSystem::desktopName(desk); } -QHash TaskManager::tasks() const +QHash LegacyTaskManager::tasks() const { return d->tasksByWId; } -QList TaskManager::startups() const +QList LegacyTaskManager::startups() const { return d->startups; } -int TaskManager::numberOfDesktops() const +int LegacyTaskManager::numberOfDesktops() const { return KWindowSystem::numberOfDesktops(); } -bool TaskManager::isOnTop(const Task *task) const +bool LegacyTaskManager::isOnTop(const Task *task) const { if (!task) { return false; } QList list = KWindowSystem::stackingOrder(); QListIterator it(list); it.toBack(); const bool multiscreen = QGuiApplication::screens().count() > 1; // we only use taskScreen when there are multiple screens, so we // only fetch the value in that case; still, do it outside the loop const QRect taskScreen = multiscreen ? task->screen() : QRect(); while (it.hasPrevious()) { const WId top = it.previous(); Task *t = d->tasksByWId.value(top); if (!t) { foreach (const WId transient, task->transients()) { if (transient == top) { return true; } } continue; } if (t == task) { return true; } foreach (const WId transient, task->transients()) { if (transient == top) { return true; } } if (t->isFullScreen() && t->screen() != taskScreen) { // it seems window managers always claim that fullscreen // windows are stacked above everything else .. even when // a window on a different physical screen has input focus // so we work around this decision here by only paying attention // to fullscreen windows that are on the same screen as us continue; } #ifndef Q_WS_WIN if (!t->isIconified() && (t->isAlwaysOnTop() == task->isAlwaysOnTop())) { return false; } #endif } return false; } -void TaskManager::setTrackGeometry(bool track, const QUuid &token) +void LegacyTaskManager::setTrackGeometry(bool track, const QUuid &token) { if (track) { if (!d->trackGeometryTokens.contains(token)) { d->trackGeometryTokens.insert(token); } } else { d->trackGeometryTokens.remove(token); } } -bool TaskManager::trackGeometry() const +bool LegacyTaskManager::trackGeometry() const { return !d->trackGeometryTokens.isEmpty(); } -int TaskManager::currentDesktop() const +int LegacyTaskManager::currentDesktop() const { return KWindowSystem::currentDesktop(); } -QString TaskManager::currentActivity() const +QString LegacyTaskManager::currentActivity() const { return d->activityConsumer.currentActivity(); } -} // TaskManager namespace +} // LegacyTaskManager namespace -#include "moc_taskmanager.cpp" +#include "moc_legacytaskmanager.cpp" diff --git a/libtaskmanager/taskmanager.h b/liblegacytaskmanager/legacytaskmanager.h similarity index 86% rename from libtaskmanager/taskmanager.h rename to liblegacytaskmanager/legacytaskmanager.h index 2367272fc..f49b568e3 100644 --- a/libtaskmanager/taskmanager.h +++ b/liblegacytaskmanager/legacytaskmanager.h @@ -1,224 +1,224 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ -#ifndef TASKMANAGER_H -#define TASKMANAGER_H +#ifndef LEGACYTASKMANAGER_H +#define LEGACYTASKMANAGER_H #include #include #include #include class QUuid; -namespace TaskManager +namespace LegacyTaskManager { typedef QSet WindowList; class Task; class Startup; enum TaskChange { TaskUnchanged = 0, NameChanged = 1, StateChanged = 2, DesktopChanged = 32, GeometryChanged = 64, WindowTypeChanged = 128, ActionsChanged = 256, TransientsChanged = 512, IconChanged = 1024, ActivitiesChanged = 4096, AttentionChanged = 8192, ClassChanged = 0x4000, EverythingChanged = 0xffff }; Q_DECLARE_FLAGS(TaskChanges, TaskChange) -} // namespace TaskManager +} // namespace LegacyTaskManager // Own #include #include -#include +#include -namespace TaskManager +namespace LegacyTaskManager { /** * A generic API for task managers. This class provides an easy way to * build NET compliant task managers. It provides support for startup * notification, virtual desktops and the full range of WM properties. * * @see Task * @see Startup */ -class TASKMANAGER_EXPORT TaskManager : public QObject +class LEGACYTASKMANAGER_EXPORT LegacyTaskManager : public QObject { Q_OBJECT Q_PROPERTY(int currentDesktop READ currentDesktop) Q_PROPERTY(int numberOfDesktops READ numberOfDesktops) Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY activityChanged) public: - static TaskManager* self(); + static LegacyTaskManager* self(); - TaskManager(); - ~TaskManager() override; + LegacyTaskManager(); + ~LegacyTaskManager() override; /** * Returns the task for a given WId, or 0 if there is no such task. */ Task *findTask(WId w); /** * Returns the task for a given location, or 0 if there is no such task. */ Task *findTask(int desktop, const QPoint& p); /** * Returns a list of all current tasks. */ QHash tasks() const; /** * Returns a list of all current startups. */ QList startups() const; /** * Returns the name of the nth desktop. */ QString desktopName(int n) const; /** * Returns the number of virtual desktops. */ int numberOfDesktops() const; /** * Returns the number of the current desktop. */ int currentDesktop() const; /** * Returns the number of the current desktop. */ QString currentActivity() const; /** * Returns true if the specified task is on top. */ bool isOnTop(const Task*) const; /** * Tells the task manager whether or not we care about geometry * updates. This generates a lot of activity so should only be used * when necessary. */ void setTrackGeometry(bool track, const QUuid &token); /** * @return true if geometry tracking is on */ bool trackGeometry() const; Q_SIGNALS: /** * Emitted when a new task has started. */ - void taskAdded(::TaskManager::Task *task); + void taskAdded(::LegacyTaskManager::Task *task); /** * Emitted when a task has terminated. */ - void taskRemoved(::TaskManager::Task *task); + void taskRemoved(::LegacyTaskManager::Task *task); /** * Emitted when a new task is expected. */ - void startupAdded(::TaskManager::Startup *startup); + void startupAdded(::LegacyTaskManager::Startup *startup); /** * Emitted when a startup item should be removed. This could be because * the task has started, because it is known to have died, or simply * as a result of a timeout. */ - void startupRemoved(::TaskManager::Startup *startup); + void startupRemoved(::LegacyTaskManager::Startup *startup); /** * Emitted when the current desktop changes. */ void desktopChanged(int desktop); /** * Emitted when the current activity changes. */ void activityChanged(const QString &activity); /** * Emitted when a window changes desktop. */ - void windowChanged(::TaskManager::Task *task, ::TaskManager::TaskChanges change); + void windowChanged(::LegacyTaskManager::Task *task, ::LegacyTaskManager::TaskChanges change); protected Q_SLOTS: //* @internal void windowAdded(WId); //* @internal void windowRemoved(WId); //* @internal void windowChanged(WId, const unsigned long*); //* @internal void activeWindowChanged(WId); //* @internal void currentDesktopChanged(int); //* @internal void killStartup(const KStartupInfoId&); //* @internal void gotNewStartup(const KStartupInfoId&, const KStartupInfoData&); //* @internal void gotStartupChange(const KStartupInfoId&, const KStartupInfoData&); //* @internal void startupDestroyed(QObject*); //* @internal - void taskChanged(::TaskManager::TaskChanges changes); + void taskChanged(::LegacyTaskManager::TaskChanges changes); protected Q_SLOTS: void configureStartup(); private: class Private; Private * const d; Q_PRIVATE_SLOT(d, void onAppExitCleanup()) }; -} // TaskManager namespace +} // LegacyTaskManager namespace -Q_DECLARE_OPERATORS_FOR_FLAGS(TaskManager::TaskChanges) +Q_DECLARE_OPERATORS_FOR_FLAGS(LegacyTaskManager::TaskChanges) #endif diff --git a/libtaskmanager/taskmanagerrulesrc b/liblegacytaskmanager/legacytaskmanagerrulesrc similarity index 100% rename from libtaskmanager/taskmanagerrulesrc rename to liblegacytaskmanager/legacytaskmanagerrulesrc diff --git a/libtaskmanager/startup.cpp b/liblegacytaskmanager/startup.cpp similarity index 93% rename from libtaskmanager/startup.cpp rename to liblegacytaskmanager/startup.cpp index 8e506dd91..fcffe897a 100644 --- a/libtaskmanager/startup.cpp +++ b/liblegacytaskmanager/startup.cpp @@ -1,122 +1,122 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "startup.h" // Qt #include -// libtaskmanager -#include "taskmanager.h" +// liblegacytaskmanager +#include "legacytaskmanager.h" -namespace TaskManager +namespace LegacyTaskManager { class Startup::Private { public: Private(const KStartupInfoId& id, const KStartupInfoData& data) : id(id), data(data) { } QIcon icon; KStartupInfoId id; KStartupInfoData data; QSet windowMatches; }; Startup::Startup(const KStartupInfoId& id, const KStartupInfoData& data, QObject * parent, const char *name) : QObject(parent), d(new Private(id, data)) { setObjectName(name); } Startup::~Startup() { delete d; } QString Startup::text() const { return d->data.findName(); } QString Startup::desktopId() const { return d->data.applicationId(); } QString Startup::wmClass() const { return d->data.WMClass(); } QString Startup::bin() const { return d->data.bin(); } QIcon Startup::icon() const { if (d->icon.isNull()) { d->icon = QIcon::fromTheme(d->data.findIcon()); } return d->icon; } void Startup::update(const KStartupInfoData& data) { d->data.update(data); - emit changed(::TaskManager::TaskUnchanged); + emit changed(::LegacyTaskManager::TaskUnchanged); } KStartupInfoId Startup::id() const { return d->id; } void Startup::addWindowMatch(WId window) { d->windowMatches.insert(window); } bool Startup::matchesWindow(WId window) const { return d->windowMatches.contains(window); } void Startup::clearPixmapData() { d->icon = QIcon(); } -} // TaskManager namespace +} // LegacyTaskManager namespace diff --git a/libtaskmanager/startup.h b/liblegacytaskmanager/startup.h similarity index 90% rename from libtaskmanager/startup.h rename to liblegacytaskmanager/startup.h index d8250e76e..996038fc9 100644 --- a/libtaskmanager/startup.h +++ b/liblegacytaskmanager/startup.h @@ -1,99 +1,99 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef STARTUP_H #define STARTUP_H // Qt #include #include // KDE #include -#include -#include +#include +#include -namespace TaskManager +namespace LegacyTaskManager { /** * Represents a task which is in the process of starting. * - * @see TaskManager + * @see LegacyTaskManager */ -class TASKMANAGER_EXPORT Startup: public QObject +class LEGACYTASKMANAGER_EXPORT Startup: public QObject { Q_OBJECT Q_PROPERTY(QString text READ text) Q_PROPERTY(QString bin READ bin) Q_PROPERTY(QIcon icon READ icon) public: Startup(const KStartupInfoId& id, const KStartupInfoData& data, QObject * parent, const char *name = 0); ~Startup() override; /** * The name of the starting task (if known). */ QString text() const; QString desktopId() const; QString wmClass() const; /** * The name of the executable of the starting task. */ QString bin() const; /** * The name of the icon to be used for the starting task. */ QIcon icon() const; void update(const KStartupInfoData& data); KStartupInfoId id() const; void addWindowMatch(WId window); bool matchesWindow(WId window) const; /** * Releases pixmap objects; useful to clear out pixmap usage prior to application stoppage */ void clearPixmapData(); Q_SIGNALS: /** * Indicates that this startup has changed in some way. */ - void changed(::TaskManager::TaskChanges); + void changed(::LegacyTaskManager::TaskChanges); private: class Private; Private * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/strategies/activitysortingstrategy.cpp b/liblegacytaskmanager/strategies/activitysortingstrategy.cpp similarity index 98% rename from libtaskmanager/strategies/activitysortingstrategy.cpp rename to liblegacytaskmanager/strategies/activitysortingstrategy.cpp index cfe916c76..8561288b6 100644 --- a/libtaskmanager/strategies/activitysortingstrategy.cpp +++ b/liblegacytaskmanager/strategies/activitysortingstrategy.cpp @@ -1,248 +1,248 @@ /*************************************************************************** * Copyright (C) 2013 OPENTIA Group http://opentia.com * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include #include #include -namespace TaskManager +namespace LegacyTaskManager { ActivitySortingStrategy::ActivitySortingStrategy(QObject *parent) :AbstractSortingStrategy(parent) { setType(GroupManager::ActivitySorting); } class ActivitySortingStrategy::Comparator { public: Comparator(QStringList *activitiesOrder, GroupManager *groupManager) { m_activitiesOrder = activitiesOrder; m_groupManager = groupManager; } bool operator()(const AbstractGroupableItem *i1, const AbstractGroupableItem *i2) { if (m_groupManager && m_groupManager->separateLaunchers()) { if (i1->isStartupItem()) { if (i2->isStartupItem()) { return i1->name().toLower() < i2->name().toLower(); } return false; } if (i2->isStartupItem()) { return true; } if (i1->itemType() == LauncherItemType) { if (i2->itemType() == LauncherItemType) { return i1->name().toLower() < i2->name().toLower(); } return true; } if (i2->itemType() == LauncherItemType) { return false; } } if (!m_priorityCache.contains(i1->id())) { addToCache(i1); } if (!m_priorityCache.contains(i2->id())) { addToCache(i2); } QList::const_iterator it1 = m_priorityCache[i1->id()].constBegin(); QList::const_iterator it2 = m_priorityCache[i2->id()].constBegin(); QList::const_iterator i1end = m_priorityCache[i1->id()].constEnd(); QList::const_iterator i2end = m_priorityCache[i2->id()].constEnd(); while (it1 != i1end) { if (it2 == i2end) { return true; } else if (*it1 == *it2) { it1++; it2++; } else { return *it1 < *it2; } } return false; } private: QList getActivitiesIndexes(const AbstractGroupableItem *item) { QList cacheEntry; const TaskItem *taskItem = qobject_cast(item); if (taskItem) { Q_FOREACH(QString activity, taskItem->activities()) { cacheEntry << m_activitiesOrder->indexOf(activity); } } const TaskGroup *taskGroup = qobject_cast(item); if (taskGroup) { Q_FOREACH(AbstractGroupableItem *member, taskGroup->members()) { QList memberIndexes = getActivitiesIndexes(member); Q_FOREACH(int i, memberIndexes) { if (!cacheEntry.contains(i)) { cacheEntry << i; } } } } return cacheEntry; } void addToCache(const AbstractGroupableItem *item) { QList cacheEntry = getActivitiesIndexes(item); qSort(cacheEntry.begin(), cacheEntry.end()); m_priorityCache[item->id()] = cacheEntry; } GroupManager *m_groupManager; const QStringList *m_activitiesOrder; QHash > m_priorityCache; }; ActivitySortingStrategy::~ActivitySortingStrategy() { } void ActivitySortingStrategy::sortItems(ItemList& items) { if (m_activitiesOrder.isEmpty()) { checkActivitiesOrder(items); } Comparator comparator(&m_activitiesOrder, qobject_cast(parent())); qStableSort(items.begin(), items.end(), comparator); } void ActivitySortingStrategy::handleItem(AbstractGroupableItem* item) { - connect(item, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(checkChanges(::TaskManager::TaskChanges))); + connect(item, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), this, SLOT(checkChanges(::LegacyTaskManager::TaskChanges))); AbstractSortingStrategy::handleItem(item); checkChanges(ActivitiesChanged, item); } bool ActivitySortingStrategy::lessThanActivityData(QPair< QString, int >& d1, QPair< QString, int >& d2) { if (d1.second == d2.second) { return d1.first < d2.first; } return d1.second > d2.second; } void ActivitySortingStrategy::addActivitiesToActivityCount(ItemList& items, QHash& activityCount) { Q_FOREACH(AbstractGroupableItem *item, items) { const TaskItem *taskItem = qobject_cast< const TaskItem* >(item); if (taskItem){ Q_FOREACH(QString activity, taskItem->activities()) { if (activityCount.contains(activity)) { activityCount[activity]++; } else { activityCount[activity] = 1; } } } const TaskGroup *taskGroup = qobject_cast< const TaskGroup* >(item); if (taskGroup) { ItemList subItems = taskGroup->members(); addActivitiesToActivityCount(subItems, activityCount); } } } bool ActivitySortingStrategy::checkActivitiesOrder(ItemList& items) { //Number of tasks by activity QHash activityCount; addActivitiesToActivityCount(items, activityCount); QList > activityData; Q_FOREACH(QString activity, activityCount.keys()) { activityData << QPair(activity, activityCount[activity]); } qSort(activityData.begin(), activityData.end(), lessThanActivityData); QStringList newActivitiesOrder; QList >::const_iterator it; for (it = activityData.constBegin(); it != activityData.constEnd(); it++) { newActivitiesOrder << it->first; } if (newActivitiesOrder != m_activitiesOrder) { m_activitiesOrder = newActivitiesOrder; return true; } return false; } void ActivitySortingStrategy::checkChanges(TaskChanges changes, AbstractGroupableItem *item) { if (!item) { item = qobject_cast< AbstractGroupableItem* >(sender()); } if (!item) { return; } if (changes & ActivitiesChanged) { if (!item->parentGroup()) { check(item); } else { TaskGroup* base = item->parentGroup(); while (base->parentGroup()) { base = base->parentGroup(); } ItemList items = base->members(); if (checkActivitiesOrder(items)) { //If the order of the activities has changed, all elements //should be put in order again sortItems(items); int i = 0; Q_FOREACH(AbstractGroupableItem *element, items) { moveItem(element, i); i++; } } else { check(item); } } } } } diff --git a/libtaskmanager/strategies/activitysortingstrategy.h b/liblegacytaskmanager/strategies/activitysortingstrategy.h similarity index 94% rename from libtaskmanager/strategies/activitysortingstrategy.h rename to liblegacytaskmanager/strategies/activitysortingstrategy.h index a22667f67..a28cb25e2 100644 --- a/libtaskmanager/strategies/activitysortingstrategy.h +++ b/liblegacytaskmanager/strategies/activitysortingstrategy.h @@ -1,61 +1,61 @@ /*************************************************************************** * Copyright (C) 2013 OPENTIA Group http://opentia.com * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #ifndef ACTIVITYSORTINGSTRATEGY_H #define ACTIVITYSORTINGSTRATEGY_H #include #include -namespace TaskManager { +namespace LegacyTaskManager { /** * Sorts the tasks by activity. * The activities with more tasks will be before than the ones with less tasks. * If one task is in various activities, the one with more tasks will be taken into account. */ class ActivitySortingStrategy: public AbstractSortingStrategy { Q_OBJECT public: ActivitySortingStrategy(QObject *parent); ~ActivitySortingStrategy() override; void sortItems(ItemList& items) override; protected Q_SLOTS: void handleItem(AbstractGroupableItem *item) override; - void checkChanges(::TaskManager::TaskChanges changes, ::TaskManager::AbstractGroupableItem *item = 0); + void checkChanges(::LegacyTaskManager::TaskChanges changes, ::LegacyTaskManager::AbstractGroupableItem *item = 0); private: /** * Checks if the order of the activities stored in the instance is still valid and if not, it stores the * correct order. */ bool checkActivitiesOrder(ItemList& items); void addActivitiesToActivityCount(ItemList& items, QHash& activityCount); static bool lessThanActivityData(QPair &d1, QPair &d2); class Comparator; QStringList m_activitiesOrder; }; } #endif diff --git a/libtaskmanager/strategies/alphasortingstrategy.cpp b/liblegacytaskmanager/strategies/alphasortingstrategy.cpp similarity index 98% rename from libtaskmanager/strategies/alphasortingstrategy.cpp rename to liblegacytaskmanager/strategies/alphasortingstrategy.cpp index 1dfba26b0..a907845a6 100644 --- a/libtaskmanager/strategies/alphasortingstrategy.cpp +++ b/liblegacytaskmanager/strategies/alphasortingstrategy.cpp @@ -1,98 +1,98 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "alphasortingstrategy.h" #include #include #include #include #include "taskitem.h" #include "taskgroup.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" -namespace TaskManager +namespace LegacyTaskManager { AlphaSortingStrategy::AlphaSortingStrategy(QObject *parent) : AbstractSortingStrategy(parent) { setType(GroupManager::AlphaSorting); } void AlphaSortingStrategy::sortItems(ItemList &items) { GroupManager *gm = qobject_cast(parent()); bool separateLaunchers = !gm || gm->separateLaunchers(); //qDebug(); QMap map; QMap launcherMap; foreach (AbstractGroupableItem * groupable, items) { if (!groupable) { continue; } if (groupable->itemType() == GroupItemType) { map.insertMulti(groupable->name().toLower(), groupable); continue; } else if (groupable->itemType() == LauncherItemType) { if (separateLaunchers) { launcherMap.insertMulti(groupable->name().toLower(), groupable); } else { map.insertMulti(groupable->name().toLower(), groupable); } continue; } TaskItem *item = qobject_cast(groupable); if (!item) { // qDebug() << "Wrong object type"; continue; } if (!item->task()) { // qDebug() << "Null Task Pointer"; continue; } //sort by programname not windowname //qDebug() << "inserting multi item" << item->task()->classClass(); map.insertMulti(item->taskName().toLower(), groupable); } items.clear(); if (separateLaunchers) { items << launcherMap.values(); } items << map.values(); } } //namespace diff --git a/libtaskmanager/strategies/alphasortingstrategy.h b/liblegacytaskmanager/strategies/alphasortingstrategy.h similarity index 96% rename from libtaskmanager/strategies/alphasortingstrategy.h rename to liblegacytaskmanager/strategies/alphasortingstrategy.h index 5a6ed116d..0428df39a 100644 --- a/libtaskmanager/strategies/alphasortingstrategy.h +++ b/liblegacytaskmanager/strategies/alphasortingstrategy.h @@ -1,47 +1,47 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef ALPHASORTINGSTRATEGY_H #define ALPHASORTINGSTRATEGY_H #include #include -namespace TaskManager +namespace LegacyTaskManager { /** Sorts the tasks alphabetically by programname found in Task::classClass()*/ class AlphaSortingStrategy : public AbstractSortingStrategy { Q_OBJECT public: AlphaSortingStrategy(QObject *parent); private: /** Sorts list of items according to strategy*/ void sortItems(ItemList&) override; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/strategies/desktopsortingstrategy.cpp b/liblegacytaskmanager/strategies/desktopsortingstrategy.cpp similarity index 96% rename from libtaskmanager/strategies/desktopsortingstrategy.cpp rename to liblegacytaskmanager/strategies/desktopsortingstrategy.cpp index 58a88636f..8fdd09028 100644 --- a/libtaskmanager/strategies/desktopsortingstrategy.cpp +++ b/liblegacytaskmanager/strategies/desktopsortingstrategy.cpp @@ -1,115 +1,115 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "desktopsortingstrategy.h" #include #include #include #include #include "abstractgroupableitem.h" #include "groupmanager.h" -namespace TaskManager +namespace LegacyTaskManager { static QString agiName(const AbstractGroupableItem *i) { if (i->itemType() == TaskItemType && !i->isStartupItem()) { return static_cast(i)->taskName().toLower(); } else { return i->name().toLower(); } } DesktopSortingStrategy::DesktopSortingStrategy(QObject *parent) : AbstractSortingStrategy(parent) { setType(GroupManager::DesktopSorting); } void DesktopSortingStrategy::sortItems(ItemList &items) { GroupManager *gm = qobject_cast(parent()); qStableSort(items.begin(), items.end(), (gm && gm->separateLaunchers()) ? DesktopSortingStrategy::lessThanSeperateLaunchers : DesktopSortingStrategy::lessThan); } /* * Sorting strategy is as follows: * For two items being compared * - Startup items will be sorted out to the end of the list and sorted by name there * - If both are not startup tasks first compare items by desktop number, * and then for items which belong to the same desktop sort by their NAME. */ bool DesktopSortingStrategy::lessThan(const AbstractGroupableItem *left, const AbstractGroupableItem *right) { const int leftDesktop = left->desktop(); const int rightDesktop = right->desktop(); if (leftDesktop == rightDesktop) { return agiName(left) < agiName(right); } return leftDesktop < rightDesktop; } bool DesktopSortingStrategy::lessThanSeperateLaunchers(const AbstractGroupableItem *left, const AbstractGroupableItem *right) { if (left->isStartupItem()) { if (right->isStartupItem()) { return left->name().toLower() < right->name().toLower(); } return false; } if (right->isStartupItem()) { return true; } if (left->itemType() == LauncherItemType) { if (right->itemType() == LauncherItemType) { return left->name().toLower() < right->name().toLower(); } return true; } if (right->itemType() == LauncherItemType) { return false; } return lessThan(left, right); } void DesktopSortingStrategy::handleItem(AbstractGroupableItem *item) { disconnect(item, 0, this, 0); //To avoid duplicate connections - connect(item, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(check())); + connect(item, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), this, SLOT(check())); AbstractSortingStrategy::handleItem(item); } } //namespace diff --git a/libtaskmanager/strategies/desktopsortingstrategy.h b/liblegacytaskmanager/strategies/desktopsortingstrategy.h similarity index 96% rename from libtaskmanager/strategies/desktopsortingstrategy.h rename to liblegacytaskmanager/strategies/desktopsortingstrategy.h index ab5a71393..650abe029 100644 --- a/libtaskmanager/strategies/desktopsortingstrategy.h +++ b/liblegacytaskmanager/strategies/desktopsortingstrategy.h @@ -1,52 +1,52 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef DESKTOPSORTINGSTRATEGY_H #define DESKTOPSORTINGSTRATEGY_H #include #include -namespace TaskManager +namespace LegacyTaskManager { /** Sorts the tasks by desktop*/ class DesktopSortingStrategy : public AbstractSortingStrategy { Q_OBJECT public: DesktopSortingStrategy(QObject *parent); protected Q_SLOTS: /** Handles a new item*/ void handleItem(AbstractGroupableItem *) override; private: /** Sorts list of items according to strategy*/ void sortItems(ItemList&) override; static bool lessThan(const AbstractGroupableItem *left, const AbstractGroupableItem *right); static bool lessThanSeperateLaunchers(const AbstractGroupableItem *left, const AbstractGroupableItem *right); }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/strategies/manualgroupingstrategy.cpp b/liblegacytaskmanager/strategies/manualgroupingstrategy.cpp similarity index 98% rename from libtaskmanager/strategies/manualgroupingstrategy.cpp rename to liblegacytaskmanager/strategies/manualgroupingstrategy.cpp index 681646cb7..96b04d87e 100644 --- a/libtaskmanager/strategies/manualgroupingstrategy.cpp +++ b/liblegacytaskmanager/strategies/manualgroupingstrategy.cpp @@ -1,132 +1,132 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "manualgroupingstrategy.h" #include #include #include #include "abstractgroupingstrategy.h" #include "groupmanager.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" -namespace TaskManager +namespace LegacyTaskManager { class ManualGroupingStrategy::Private { public: Private() : editableGroupProperties(AbstractGroupingStrategy::All), tempItem(0) { } AbstractGroupingStrategy::EditableGroupProperties editableGroupProperties; AbstractGroupableItem *tempItem; QPointer tempGroup; }; ManualGroupingStrategy::ManualGroupingStrategy(GroupManager *groupManager) : AbstractGroupingStrategy(groupManager), d(new Private) { setType(GroupManager::ManualGrouping); } ManualGroupingStrategy::~ManualGroupingStrategy() { delete d; } AbstractGroupingStrategy::EditableGroupProperties ManualGroupingStrategy::editableGroupProperties() { return d->editableGroupProperties; } QList ManualGroupingStrategy::strategyActions(QObject *parent, AbstractGroupableItem *item) { QList actionList; if (item->isGrouped()) { QAction *a = new QAction(i18n("Leave Group"), parent); connect(a, &QAction::triggered, this, &ManualGroupingStrategy::leaveGroup); actionList.append(a); d->tempItem = item; } if (item->itemType() == GroupItemType) { QAction *a = new QAction(i18n("Remove Group"), parent); connect(a, &QAction::triggered, this, &ManualGroupingStrategy::removeGroup); actionList.append(a); d->tempGroup = dynamic_cast(item); } return actionList; } void ManualGroupingStrategy::leaveGroup() { Q_ASSERT(d->tempItem); if (d->tempItem->isGrouped()) { d->tempItem->parentGroup()->parentGroup()->add(d->tempItem); } d->tempItem = 0; } void ManualGroupingStrategy::removeGroup() { TaskGroup *tempGroup = d->tempGroup.data(); if (!tempGroup) { return; } TaskGroup *parentGroup = tempGroup->parentGroup(); //tempGroup is invalid before last item has been moved to the parentGroup if (parentGroup) { foreach (AbstractGroupableItem * item, tempGroup->members()) { parentGroup->add(item); } //Group gets automatically closed on empty signal } d->tempGroup.clear(); } void ManualGroupingStrategy::handleItem(AbstractGroupableItem *item) { if (!rootGroup()) { return; } rootGroup()->add(item); } }//namespace diff --git a/libtaskmanager/strategies/manualgroupingstrategy.h b/liblegacytaskmanager/strategies/manualgroupingstrategy.h similarity index 97% rename from libtaskmanager/strategies/manualgroupingstrategy.h rename to liblegacytaskmanager/strategies/manualgroupingstrategy.h index 1ae7e253e..c52e87f56 100644 --- a/libtaskmanager/strategies/manualgroupingstrategy.h +++ b/liblegacytaskmanager/strategies/manualgroupingstrategy.h @@ -1,89 +1,89 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef MANUALGROUPINGSTRATEGY_H #define MANUALGROUPINGSTRATEGY_H #include "abstractgroupingstrategy.h" #include "taskgroup.h" -//#include "taskmanager.h" +//#include "legacytaskmanager.h" #include -namespace TaskManager +namespace LegacyTaskManager { class ManualGroupingStrategy; class GroupManager; /** * Allows to manually group tasks */ class ManualGroupingStrategy: public AbstractGroupingStrategy { Q_OBJECT public: ManualGroupingStrategy(GroupManager *groupManager); ~ManualGroupingStrategy() override; /** looks up if this item has been grouped before and groups it accordingly. *otherwise the item goes to the rootGroup */ void handleItem(AbstractGroupableItem *) override; /** Should be called if the user wants to manually add an item to a group */ //bool addItemToGroup(AbstractGroupableItem*, TaskGroup*); /** Should be called if the user wants to group items manually */ bool groupItems(ItemList items); /** Returns list of actions that a task can do in this groupingStrategy * fore example: remove this Task from this group */ QList strategyActions(QObject *parent, AbstractGroupableItem *item) override; EditableGroupProperties editableGroupProperties() override; protected Q_SLOTS: /** Checks if the group is still necessary, removes group if empty*/ //void checkGroup(); private: bool manualGrouping(TaskItem* taskItem, TaskGroup* groupItem); private Q_SLOTS: /** Actions which the strategy offers*/ /** sender item leaves group*/ void leaveGroup(); /** Removes all items from the sender group and adds to the parent Group*/ void removeGroup(); private: class Private; Private * const d; }; } #endif diff --git a/libtaskmanager/strategies/manualsortingstrategy.cpp b/liblegacytaskmanager/strategies/manualsortingstrategy.cpp similarity index 99% rename from libtaskmanager/strategies/manualsortingstrategy.cpp rename to liblegacytaskmanager/strategies/manualsortingstrategy.cpp index 47dcb46a0..4e6c73089 100644 --- a/libtaskmanager/strategies/manualsortingstrategy.cpp +++ b/liblegacytaskmanager/strategies/manualsortingstrategy.cpp @@ -1,105 +1,105 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "manualsortingstrategy.h" #include -namespace TaskManager +namespace LegacyTaskManager { ManualSortingStrategy::ManualSortingStrategy(GroupManager *parent) : AbstractSortingStrategy(parent) { setType(GroupManager::ManualSorting); } ManualSortingStrategy::~ManualSortingStrategy() { } bool ManualSortingStrategy::manualSortingRequest(AbstractGroupableItem *item, int newIndex) { GroupManager *gm = qobject_cast(parent()); if (!gm) { return false; } int oldIndex = gm->launcherIndex(item->launcherUrl()); if (LauncherItemType == item->itemType() || -1 != oldIndex) { bool moveRight = oldIndex > -1 && newIndex > oldIndex; if (newIndex >= 0 && newIndex - (moveRight ? 1 : 0) < gm->launcherCount()) { if (moveItem(item, newIndex)) { gm->moveLauncher(item->launcherUrl(), (newIndex > oldIndex ? --newIndex : newIndex)); return true; } } } else if (newIndex >= gm->launcherCount()) { return moveItem(item, newIndex); } return false; } void ManualSortingStrategy::sortItems(ItemList &items) { GroupManager *gm = qobject_cast(parent()); if (!gm) { return; } //qDebug(); QMap launcherMap; QList order; QMap map; foreach (AbstractGroupableItem * groupable, items) { if (!groupable) { continue; } int index = gm && (gm->separateLaunchers() && groupable->itemType() == LauncherItemType) ? gm->launcherIndex(groupable->launcherUrl()) : -1; if (index < 0) { QString name(groupable->name().toLower()); map.insertMulti(name, groupable); if (!order.contains(name)) { order.append(name); } } else { launcherMap.insertMulti(index, groupable); } } items.clear(); items << launcherMap.values(); foreach (QString n, order) { items << map.values(n); } } } //namespace diff --git a/libtaskmanager/strategies/manualsortingstrategy.h b/liblegacytaskmanager/strategies/manualsortingstrategy.h similarity index 96% rename from libtaskmanager/strategies/manualsortingstrategy.h rename to liblegacytaskmanager/strategies/manualsortingstrategy.h index 5adb5ab21..6563ac9bb 100644 --- a/libtaskmanager/strategies/manualsortingstrategy.h +++ b/liblegacytaskmanager/strategies/manualsortingstrategy.h @@ -1,51 +1,51 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef MANUALSORTINGSTRATEGY_H #define MANUALSORTINGSTRATEGY_H #include "abstractsortingstrategy.h" -namespace TaskManager +namespace LegacyTaskManager { /** * Manual Sorting * If showAllDesktops is enabled the position of the tasks logically changes on all desktops * If showAllDesktops is disabled the position only changes per virtual desktop even * if the task is on all desktops */ class ManualSortingStrategy : public AbstractSortingStrategy { Q_OBJECT public: ManualSortingStrategy(GroupManager *parent); ~ManualSortingStrategy() override; bool manualSortingRequest(AbstractGroupableItem *item, int newIndex) override; void sortItems(ItemList &items) override; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/strategies/programgroupingstrategy.cpp b/liblegacytaskmanager/strategies/programgroupingstrategy.cpp similarity index 99% rename from libtaskmanager/strategies/programgroupingstrategy.cpp rename to liblegacytaskmanager/strategies/programgroupingstrategy.cpp index 2e531f804..eeab9bc7f 100644 --- a/libtaskmanager/strategies/programgroupingstrategy.cpp +++ b/liblegacytaskmanager/strategies/programgroupingstrategy.cpp @@ -1,272 +1,272 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "programgroupingstrategy.h" #include #include #include #include #include #include "abstractgroupingstrategy.h" #include "groupmanager.h" -namespace TaskManager +namespace LegacyTaskManager { class ProgramGroupingStrategy::Private { public: Private() : editableGroupProperties(AbstractGroupingStrategy::None) { } AbstractGroupingStrategy::EditableGroupProperties editableGroupProperties; QPointer tempItem; QStringList blackList; //Programs in this list should not be grouped }; ProgramGroupingStrategy::ProgramGroupingStrategy(GroupManager *groupManager) : AbstractGroupingStrategy(groupManager), d(new Private) { setType(GroupManager::ProgramGrouping); KConfig groupBlacklist(QStringLiteral("taskbargroupblacklistrc"), KConfig::NoGlobals); KConfigGroup blackGroup(&groupBlacklist, "Blacklist"); d->blackList = blackGroup.readEntry("Applications", QStringList()); } ProgramGroupingStrategy::~ProgramGroupingStrategy() { delete d; } QList ProgramGroupingStrategy::strategyActions(QObject *parent, AbstractGroupableItem *item) { QList actionList; GroupManager *gm = qobject_cast(AbstractGroupingStrategy::parent()); if (!gm || !gm->forceGrouping()) { QAction *a = new QAction(parent); QString name = className(item); if (d->blackList.contains(name)) { a->setText(i18n("Allow this program to be grouped")); } else { a->setText(i18n("Do not allow this program to be grouped")); } connect(a, &QAction::triggered, this, &ProgramGroupingStrategy::toggleGrouping, Qt::QueuedConnection); actionList.append(a); d->tempItem = item; } return actionList; } QString ProgramGroupingStrategy::className(AbstractGroupableItem *item) { QString name; if (item->itemType() == GroupItemType) { //maybe add the condition that the subgroup was created by programGrouping TaskGroup *group = qobject_cast(item); TaskItem *task = qobject_cast(group->members().first()); //There are only TaskItems in programGrouping groups return task->task()->classClass(); } return (qobject_cast(item))->task()->classClass(); } void ProgramGroupingStrategy::toggleGrouping() { AbstractGroupableItem *tempItem = d->tempItem.data(); if (!tempItem) { return; } QString name = className(tempItem); if (d->blackList.contains(name)) { d->blackList.removeAll(name); if (tempItem->itemType() == GroupItemType) { foreach (AbstractGroupableItem * item, (qobject_cast(tempItem))->members()) { handleItem(item); } } else { handleItem(tempItem); } } else { d->blackList.append(name); GroupPtr root = rootGroup(); if (tempItem->itemType() == GroupItemType) { closeGroup(qobject_cast(tempItem)); } else if (root) { root->add(tempItem); } if (root) { foreach (AbstractGroupableItem * item, root->members()) { if (item->itemType() == GroupItemType) { untoggleGroupingOn(static_cast(item), name); } } } } d->tempItem.clear(); // Save immediately. Much better than saving in the destructor, // since this class is deleted at every change of virtual desktop (!) // So when doing it from the destructor we were constantly sync'ing // (and triggering KDirWatch) even when the blacklist hadn't changed at all... KConfig groupBlacklist(QStringLiteral("taskbargroupblacklistrc"), KConfig::NoGlobals); KConfigGroup blackGroup(&groupBlacklist, "Blacklist"); blackGroup.writeEntry("Applications", d->blackList); blackGroup.config()->sync(); } void ProgramGroupingStrategy::untoggleGroupingOn(TaskGroup *group, const QString &name) { if (!group->parentGroup()) { return; } foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() == GroupItemType) { untoggleGroupingOn(static_cast(item), name); } } foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() != GroupItemType && name == static_cast(item)->task()->classClass()) { if (group->parentGroup()) { group->parentGroup()->add(item); } } } if (group->members().isEmpty()) { closeGroup(group); } } void ProgramGroupingStrategy::handleItem(AbstractGroupableItem *item) { GroupPtr root = rootGroup(); if (!root) { return; } GroupManager *gm = qobject_cast(AbstractGroupingStrategy::parent()); if (item->itemType() == GroupItemType) { //qDebug() << item->name() << "item is groupitem"; root->add(item); return; } else if ((!gm || !gm->forceGrouping()) && d->blackList.contains((static_cast(item))->task()->classClass())) { //qDebug() << item->name() << "item is in blacklist"; root->add(item); return; } TaskItem *task = dynamic_cast(item); if (task && !programGrouping(task, root)) { //qDebug() << item->name() << "joined rootGroup "; root->add(item); } } bool ProgramGroupingStrategy::programGrouping(TaskItem* taskItem, TaskGroup* groupItem) { //qDebug() << "===== Task:" << taskItem->name() << " <=> Group:" << groupItem->name() << "====="; QList list; QString name = taskItem->task()->classClass(); //search for an existing group foreach (AbstractGroupableItem * item, groupItem->members()) { if (item->itemType() == GroupItemType) { //TODO: maybe add the condition that the subgroup was created by programGrouping? if (programGrouping(taskItem, static_cast(item))) { //qDebug() << " joined subGroup"; return true; } } else if (item->itemType() == LauncherItemType) { continue; } else { TaskItem *task = static_cast(item); //qDebug() << " testing" << (task->task() ? task->task()->classClass() : "No task!") << "==" << name; if (task != taskItem && task->task() && task->task()->classClass() == name) { //omit startup tasks list.append(item); } } } if (!list.isEmpty()) { if (groupItem->isRootGroup()) { //qDebug() << " create Group root group"; QIcon icon = taskItem->icon(); list.append(taskItem); TaskGroup* group = createGroup(list); group->setName(name); group->setIcon(icon); connect(group, &TaskGroup::checkIcon, this, &ProgramGroupingStrategy::updateIcon); } else { //qDebug() << " joined this Group"; groupItem->add(taskItem); } return true; } //qDebug() << " failed"; return false; } void ProgramGroupingStrategy::checkGroup() { TaskGroup *group = qobject_cast(sender()); if (group) { if (group->members().size() < 2) { closeGroup(group); } else { updateIcon(group); } } } void ProgramGroupingStrategy::updateIcon(TaskGroup *group) { foreach (AbstractGroupableItem * taskItem, group->members()) { if (!taskItem->icon().isNull()) { QIcon icon = taskItem->icon(); group->setIcon(icon); break; } } } }//namespace diff --git a/libtaskmanager/strategies/programgroupingstrategy.h b/liblegacytaskmanager/strategies/programgroupingstrategy.h similarity index 98% rename from libtaskmanager/strategies/programgroupingstrategy.h rename to liblegacytaskmanager/strategies/programgroupingstrategy.h index 27e7da9d9..dee46819c 100644 --- a/libtaskmanager/strategies/programgroupingstrategy.h +++ b/liblegacytaskmanager/strategies/programgroupingstrategy.h @@ -1,81 +1,81 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef PROGRAMGROUPINGSTRATEGY_H #define PROGRAMGROUPINGSTRATEGY_H #include "abstractgroupingstrategy.h" #include "taskgroup.h" -namespace TaskManager +namespace LegacyTaskManager { class GroupManager; /** * Groups tasks of the same program */ class ProgramGroupingStrategy: public AbstractGroupingStrategy { Q_OBJECT public: ProgramGroupingStrategy(GroupManager *groupManager); ~ProgramGroupingStrategy() override; /** Tasks are passed to this function to be grouped by this strategy */ void handleItem(AbstractGroupableItem *) override; /** Returns list of actions that a task can do in this groupingStrategy * fore example: start/stop group tasks of this program */ QList strategyActions(QObject *parent, AbstractGroupableItem *item) override; EditableGroupProperties editableGroupProperties() override { return None; }; protected Q_SLOTS: /** Checks if the group is still necessary */ void checkGroup() override; private Q_SLOTS: /** The program of the sender() of this function is started or stopped being grouped * by this strategy. This is done by adding the program to d->blackList */ void toggleGrouping(); void updateIcon(TaskGroup *group); private: QString className(AbstractGroupableItem *item); bool programGrouping(TaskItem* taskItem, TaskGroup* groupItem); void untoggleGroupingOn(TaskGroup *group, const QString &name); class Private; Private * const d; }; } #endif diff --git a/libtaskmanager/task.cpp b/liblegacytaskmanager/task.cpp similarity index 98% rename from libtaskmanager/task.cpp rename to liblegacytaskmanager/task.cpp index 085339165..8154bf932 100644 --- a/libtaskmanager/task.cpp +++ b/liblegacytaskmanager/task.cpp @@ -1,726 +1,726 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "task.h" #include "task_p.h" // Qt #include #include #include #include // KDE #include #include -#include "taskmanager.h" +#include "legacytaskmanager.h" -namespace TaskManager +namespace LegacyTaskManager { Task::Task(WId w, QObject *parent, const char *name) : QObject(parent), d(new Private(w)) { setObjectName(name); // try to load icon via net_wm refreshIcon(); refreshActivities(); // initial demands attention d->demandedAttention = demandsAttention(); } Task::~Task() { delete d; } void Task::timerEvent(QTimerEvent *) { if (d->cachedChanges.netWindowInfoProperties || d->cachedChanges.netWindowInfoProperties2) { d->lastUpdate = QTime(); refresh(d->cachedChanges); d->cachedChanges.netWindowInfoProperties = 0; d->cachedChanges.netWindowInfoProperties2 = 0; } killTimer(d->cachedChangesTimerId); d->cachedChangesTimerId = 0; } void Task::refreshIcon() { // try to load icon via net_wm d->pixmap = KWindowSystem::icon(d->win, 16, 16, true); // try to guess the icon from the classhint if (d->pixmap.isNull()) { d->pixmap = KIconLoader::global()->loadIcon(className().toLower(), KIconLoader::Small, KIconLoader::Small, KIconLoader::DefaultState, QStringList(), 0, true); // load the icon for X applications if (d->pixmap.isNull()) { d->pixmap = SmallIcon(QStringLiteral("xorg")); } } d->lastIcon = QPixmap(); d->icon = QIcon(); emit changed(IconChanged); } -::TaskManager::TaskChanges Task::refresh(WindowProperties dirty) +::LegacyTaskManager::TaskChanges Task::refresh(WindowProperties dirty) { if (!d->lastUpdate.isNull() && d->lastUpdate.elapsed() < 200) { d->cachedChanges.netWindowInfoProperties |= dirty.netWindowInfoProperties; d->cachedChanges.netWindowInfoProperties2 |= dirty.netWindowInfoProperties2; if (!d->cachedChangesTimerId) { d->cachedChangesTimerId = startTimer(200 - d->lastUpdate.elapsed()); } return TaskUnchanged; } d->lastUpdate.restart(); KWindowInfo info(d->win, windowInfoFlags, windowInfoFlags2); TaskChanges changes = TaskUnchanged; if (d->info.windowClassClass() != info.windowClassClass() || d->info.windowClassName() != info.windowClassName()) { changes |= ClassChanged; } if (d->info.visibleName() != info.visibleName() || d->info.visibleNameWithState() != info.visibleNameWithState() || d->info.name() != info.name()) { changes |= NameChanged; } d->info = info; if (dirty.netWindowInfoProperties & NET::WMState || dirty.netWindowInfoProperties & NET::XAWMState) { changes |= StateChanged; if (demandsAttention() != d->demandedAttention) { d->demandedAttention = !d->demandedAttention; changes |= AttentionChanged; } } if (dirty.netWindowInfoProperties & NET::WMDesktop) { changes |= DesktopChanged; } if (dirty.netWindowInfoProperties & NET::WMGeometry) { changes |= GeometryChanged; } if (dirty.netWindowInfoProperties & NET::WMWindowType) { changes |= WindowTypeChanged; } if (dirty.netWindowInfoProperties2 & NET::WM2AllowedActions) { changes |= ActionsChanged; } if (dirty.netWindowInfoProperties & NET::WMIcon) { refreshIcon(); } if (dirty.netWindowInfoProperties2 & NET::WM2Activities) { refreshActivities(); changes |= ActivitiesChanged; } if (changes != TaskUnchanged) { emit changed(changes); } return changes; } void Task::setActive(bool a) { d->active = a; TaskChanges changes = StateChanged; if (demandsAttention() != d->demandedAttention) { d->demandedAttention = !d->demandedAttention; changes |= AttentionChanged; } emit changed(changes); if (a) { emit activated(); } else { emit deactivated(); } } bool Task::isMaximized() const { return d->info.valid(true) && (d->info.state() & NET::MaxHoriz) && (d->info.state() & NET::MaxVert); } bool Task::isMinimized() const { return d->info.valid(true) && d->info.isMinimized(); } bool Task::isIconified() const { return d->info.valid(true) && d->info.isMinimized(); } bool Task::isAlwaysOnTop() const { return d->info.valid(true) && (d->info.state() & NET::StaysOnTop); } bool Task::isKeptBelowOthers() const { return d->info.valid(true) && (d->info.state() & NET::KeepBelow); } bool Task::isFullScreen() const { return d->info.valid(true) && (d->info.state() & NET::FullScreen); } bool Task::isShaded() const { return d->info.valid(true) && (d->info.state() & NET::Shaded); } bool Task::isOnCurrentDesktop() const { return d->info.valid(true) && d->info.isOnCurrentDesktop(); } bool Task::isOnAllDesktops() const { return d->info.valid(true) && d->info.onAllDesktops(); } bool Task::isActive() const { if (d->active) { return true; } const WId activeWindow = KWindowSystem::activeWindow(); foreach (WId window, d->transients) { if (activeWindow == window) { return true; } } return false; } bool Task::isOnTop() const { - return TaskManager::self()->isOnTop(this); + return LegacyTaskManager::self()->isOnTop(this); } bool Task::isModified() const { static QString modStr = QLatin1String("[") + i18nc("marks that a task has been modified", "modified") + QLatin1String("]"); int modStrPos = d->info.visibleName().indexOf(modStr); return (modStrPos != -1); } int Task::desktop() const { if (KWindowSystem::numberOfDesktops() < 2) { return 0; } return d->info.desktop(); } bool Task::demandsAttention() const { return (d->info.valid(true) && (d->info.state() & NET::DemandsAttention)) || !d->transientsDemandingAttention.isEmpty(); } bool Task::isOnScreen(const QRect& screen) const { return (d->info.valid(true) && d->info.geometry().intersects(screen)); } QRect Task::screen() const { QRect rv; if (!d->info.valid(true)) { return rv; } int area = 0; foreach (QScreen* screen, QGuiApplication::screens()) { const QRect desktopGeometry = screen->geometry(); const QRect onScreen = desktopGeometry.intersected(d->info.geometry()); if (onScreen.height() * onScreen.width() > area) { area = onScreen.height() * onScreen.width(); rv = screen->geometry(); } } return rv; } bool Task::showInTaskbar() const { return d->info.state() ^ NET::SkipTaskbar; } bool Task::showInPager() const { return d->info.state() ^ NET::SkipPager; } QRect Task::geometry() const { return d->info.geometry(); } void Task::removeTransient(WId w) { d->transients.remove(w); d->transientsDemandingAttention.remove(w); if (demandsAttention() != d->demandedAttention) { d->demandedAttention = !d->demandedAttention; emit changed(AttentionChanged); } } bool Task::hasTransient(WId w) const { return d->transients.contains(w); } WId Task::window() const { return d->win; } KWindowInfo Task::info() const { return d->info; } QString Task::visibleName() const { return d->info.visibleName(); } QString Task::visibleNameWithState() const { return d->info.visibleNameWithState(); } QString Task::name() const { return d->info.name(); } QPixmap Task::icon(int width, int height, bool allowResize) { if (width == d->lastWidth && height == d->lastHeight && allowResize == d->lastResize && !d->lastIcon.isNull()) { return d->lastIcon; } QPixmap newIcon = KWindowSystem::icon(d->win, width, height, allowResize); if (!newIcon.isNull()) { d->lastIcon = newIcon; d->lastWidth = width; d->lastHeight = height; d->lastResize = allowResize; } return newIcon; } QIcon Task::icon() { if (d->icon.isNull()) { d->icon.addPixmap(KWindowSystem::icon(d->win, KIconLoader::SizeSmall, KIconLoader::SizeSmall, false)); d->icon.addPixmap(KWindowSystem::icon(d->win, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium, false)); d->icon.addPixmap(KWindowSystem::icon(d->win, KIconLoader::SizeMedium, KIconLoader::SizeMedium, false)); d->icon.addPixmap(KWindowSystem::icon(d->win, KIconLoader::SizeLarge, KIconLoader::SizeLarge, false)); } return d->icon; } WindowList Task::transients() const { return d->transients; } QPixmap Task::pixmap() const { return d->pixmap; } QPixmap Task::bestIcon(int size, bool &isStaticIcon) { QPixmap pixmap; isStaticIcon = false; switch (size) { case KIconLoader::SizeSmall: { pixmap = icon(16, 16, true); // Icon of last resort if (pixmap.isNull()) { pixmap = KIconLoader::global()->loadIcon(QStringLiteral("xorg"), KIconLoader::NoGroup, KIconLoader::SizeSmall); isStaticIcon = true; } } break; case KIconLoader::SizeMedium: { // // Try 34x34 first for KDE 2.1 icons with shadows, if we don't // get one then try 32x32. // pixmap = icon(34, 34, false); if (((pixmap.width() != 34) || (pixmap.height() != 34)) && ((pixmap.width() != 32) || (pixmap.height() != 32))) { pixmap = icon(32, 32, true); } // Icon of last resort if (pixmap.isNull()) { pixmap = KIconLoader::global()->loadIcon(QStringLiteral("xorg"), KIconLoader::NoGroup, KIconLoader::SizeMedium); isStaticIcon = true; } } break; case KIconLoader::SizeLarge: { // If there's a 48x48 icon in the hints then use it pixmap = icon(size, size, false); // If not, try to get one from the classname if (pixmap.isNull() || pixmap.width() != size || pixmap.height() != size) { pixmap = KIconLoader::global()->loadIcon(className(), KIconLoader::NoGroup, size, KIconLoader::DefaultState, QStringList(), 0L, true); isStaticIcon = true; } // If we still don't have an icon then scale the one in the hints if (pixmap.isNull() || (pixmap.width() != size) || (pixmap.height() != size)) { pixmap = icon(size, size, true); isStaticIcon = false; } // Icon of last resort if (pixmap.isNull()) { pixmap = KIconLoader::global()->loadIcon(QStringLiteral("xorg"), KIconLoader::NoGroup, size); isStaticIcon = true; } } } return pixmap; } bool Task::idMatch(const QString& id1, const QString& id2) { if (id1.isEmpty() || id2.isEmpty()) return false; if (id1.contains(id2) > 0) return true; if (id2.contains(id1) > 0) return true; return false; } void Task::toggleMaximized() { setMaximized(!isMaximized()); } void Task::setIconified(bool iconify) { // qDebug() <<" going to iconify" << d->win; if (iconify) { KWindowSystem::minimizeWindow(d->win); } else { KWindowInfo info(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop); bool on_current = info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(info.desktop()); } KWindowSystem::unminimizeWindow(d->win); if (!on_current) { KWindowSystem::forceActiveWindow(d->win); } } } void Task::toggleIconified() { setIconified(!isIconified()); } void Task::raise() { // kDebug(1210) << "Task::raise(): " << name(); KWindowSystem::raiseWindow(d->win); } void Task::lower() { // kDebug(1210) << "Task::lower(): " << name(); KWindowSystem::lowerWindow(d->win); } void Task::activate() { WId w = d->win; if (!d->transientsDemandingAttention.isEmpty()) { WindowList::const_iterator it = d->transientsDemandingAttention.end(); --it; w = *it; } else if (!d->transients.isEmpty()) { WindowList::const_iterator it = d->transients.end(); --it; KWindowInfo info(*it, NET::WMState | NET::XAWMState | NET::WMDesktop); //this is a work around for (at least?) kwin where a shaded transient will prevent the main //window from being brought forward unless the transient is actually pulled forward, most //easily reproduced by opening a modal file open/save dialog on an app then shading the file //dialog and trying to bring the window forward by clicking on it in a tasks widget //TODO: do we need to check all the transients for shaded? if (info.valid(true) && (info.state() & NET::Shaded)) { w = *it; } } //kDebug(1210) << "Task::activate():" << name() << d->win << w; KWindowSystem::forceActiveWindow(w); } void Task::activateRaiseOrIconify() { //qDebug() << isActive() << isIconified() << isOnTop(); if (!isActive() || isIconified()) { activate(); } else if (!isOnTop()) { raise(); } else { setIconified(true); } } void Task::toCurrentDesktop() { toDesktop(KWindowSystem::currentDesktop()); } void Task::toggleAlwaysOnTop() { setAlwaysOnTop(!isAlwaysOnTop()); } void Task::toggleKeptBelowOthers() { setKeptBelowOthers(!isKeptBelowOthers()); } void Task::toggleFullScreen() { setFullScreen(!isFullScreen()); } void Task::toggleShaded() { setShaded(!isShaded()); } void Task::clearPixmapData() { d->lastIcon = QPixmap(); d->pixmap = QPixmap(); d->icon = QIcon(); } void Task::addMimeData(QMimeData *mimeData) const { Q_ASSERT(mimeData); QByteArray data; data.resize(sizeof(WId)); memcpy(data.data(), &d->win, sizeof(WId)); mimeData->setData(mimetype(), data); } QString Task::mimetype() { return QStringLiteral("windowsystem/winid"); } QString Task::groupMimetype() { return QStringLiteral("windowsystem/multiple-winids"); } QList Task::idsFromMimeData(const QMimeData *mimeData, bool *ok) { Q_ASSERT(mimeData); QList ids; if (ok) { *ok = false; } if (!mimeData->hasFormat(groupMimetype())) { // try to grab a singular id if it exists //qDebug() << "not group type"; bool singularOk; WId id = idFromMimeData(mimeData, &singularOk); if (ok) { *ok = singularOk; } if (singularOk) { //qDebug() << "and singular failed, too"; ids << id; } return ids; } QByteArray data(mimeData->data(groupMimetype())); if ((unsigned int)data.size() < sizeof(int) + sizeof(WId)) { //qDebug() << "wrong size" << data.size() << sizeof(int) + sizeof(WId); return ids; } int count = 0; memcpy(&count, data.data(), sizeof(int)); if (count < 1 || (unsigned int)data.size() < sizeof(int) + sizeof(WId) * count) { //qDebug() << "wrong size, 2" << data.size() << count << sizeof(int) + sizeof(WId) * count; return ids; } WId id; for (int i = 0; i < count; ++i) { memcpy(&id, data.data() + sizeof(int) + sizeof(WId) * i, sizeof(WId)); ids << id; } if (ok) { *ok = true; } return ids; } WId Task::idFromMimeData(const QMimeData *mimeData, bool *ok) { Q_ASSERT(mimeData); if (ok) { *ok = false; } if (!mimeData->hasFormat(mimetype())) { return 0; } QByteArray data(mimeData->data(mimetype())); if (data.size() != sizeof(WId)) { return 0; } WId id; memcpy(&id, data.data(), sizeof(WId)); if (ok) { *ok = true; } return id; } bool Task::isOnCurrentActivity() const { - return d->activities.isEmpty() || d->activities.contains(TaskManager::self()->currentActivity()); + return d->activities.isEmpty() || d->activities.contains(LegacyTaskManager::self()->currentActivity()); } bool Task::isOnAllActivities() const { return d->activities.isEmpty(); } QStringList Task::activities() const { return d->activities; } Task::WindowProperties::WindowProperties(unsigned int netWinInfoProperties, unsigned int netWinInfoProperties2) : netWindowInfoProperties(netWinInfoProperties), netWindowInfoProperties2(netWinInfoProperties2) { } -} // TaskManager namespace +} // LegacyTaskManager namespace diff --git a/libtaskmanager/task.h b/liblegacytaskmanager/task.h similarity index 97% rename from libtaskmanager/task.h rename to liblegacytaskmanager/task.h index 83bf52ddd..e9c9a9eab 100644 --- a/libtaskmanager/task.h +++ b/liblegacytaskmanager/task.h @@ -1,452 +1,452 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef TASK_H #define TASK_H // Qt #include #include #include #include // KDE #include -#include -#include +#include +#include #include class NETWinInfo; -namespace TaskManager +namespace LegacyTaskManager { /** * A dynamic interface to a task (main window). * - * @see TaskManager + * @see LegacyTaskManager */ -class TASKMANAGER_EXPORT Task : public QObject +class LEGACYTASKMANAGER_EXPORT Task : public QObject { Q_OBJECT Q_PROPERTY(QString visibleName READ visibleName) Q_PROPERTY(QString name READ name) Q_PROPERTY(QString className READ className) Q_PROPERTY(QString visibleNameWithState READ visibleNameWithState) Q_PROPERTY(QPixmap pixmap READ pixmap) Q_PROPERTY(bool maximized READ isMaximized) Q_PROPERTY(bool minimized READ isMinimized) // KDE4 deprecated Q_PROPERTY(bool iconified READ isIconified) Q_PROPERTY(bool shaded READ isShaded WRITE setShaded) Q_PROPERTY(bool active READ isActive) Q_PROPERTY(bool onCurrentDesktop READ isOnCurrentDesktop) Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops) Q_PROPERTY(bool alwaysOnTop READ isAlwaysOnTop WRITE setAlwaysOnTop) Q_PROPERTY(bool modified READ isModified) Q_PROPERTY(bool demandsAttention READ demandsAttention) Q_PROPERTY(int desktop READ desktop) Q_PROPERTY(bool onCurrentActivity READ isOnCurrentActivity) Q_PROPERTY(bool onAllActivities READ isOnAllActivities) Q_PROPERTY(QStringList activities READ activities) public: /** * Represents all the informations reported by KWindowSystem about the NET properties of the task */ struct WindowProperties { /** * This is corresponding to NET::Property enum reported properties. */ unsigned long netWindowInfoProperties; /** * This is corresponding to NET::Property2 enum reported properties. */ unsigned long netWindowInfoProperties2; WindowProperties(unsigned int netWinInfoProperties, unsigned int netWinInfoProperties2); }; Task(WId win, QObject *parent, const char *name = 0); ~Task() override; WId window() const; KWindowInfo info() const; QString visibleName() const; QString visibleNameWithState() const; QString name() const; QString className() const; QString classClass() const; int pid() const; /** * A list of the window ids of all transient windows (dialogs) associated * with this task. */ WindowList transients() const; /** * Returns a 16x16 (KIconLoader::Small) icon for the task. This method will * only fall back to a static icon if there is no icon of any size in * the WM hints. */ QPixmap pixmap() const; /** * Returns the best icon for any of the KIconLoader::StdSizes. If there is no * icon of the specified size specified in the WM hints, it will try to * get one using KIconLoader. * *
      *   bool gotStaticIcon;
      *   QPixmap icon = myTask->icon( KIconLoader::SizeMedium, gotStaticIcon );
      * 
* * @param size Any of the constants in KIconLoader::StdSizes. * @param isStaticIcon Set to true if KIconLoader was used, false otherwise. */ QPixmap bestIcon(int size, bool &isStaticIcon); /** * Tries to find an icon for the task with the specified size. If there * is no icon that matches then it will either resize the closest available * icon or return a null pixmap depending on the value of allowResize. * * Note that the last icon is cached, so a sequence of calls with the same * parameters will only query the NET properties if the icon has changed or * none was found. */ QPixmap icon(int width, int height, bool allowResize = false); /** * \return a QIcon for the task */ QIcon icon(); /** * Returns true iff the windows with the specified ids should be grouped * together in the task list. */ static bool idMatch(const QString &, const QString &); // state /** * Returns true if the task's window is maximized. */ bool isMaximized() const; /** * Returns true if the task's window is minimized. */ bool isMinimized() const; /** * @deprecated * Returns true if the task's window is minimized(iconified). */ bool isIconified() const; /** * Returns true if the task's window is shaded. */ bool isShaded() const; /** * Returns true if the task's window is the active window. */ bool isActive() const; /** * Returns true if the task's window is the topmost non-iconified, * non-always-on-top window. */ bool isOnTop() const; /** * Returns true if the task's window is on the current virtual desktop. */ bool isOnCurrentDesktop() const; /** * Returns true if the task's window is on all virtual desktops. */ bool isOnAllDesktops() const; /** * Returns true if the task's window will remain at the top of the * stacking order. */ bool isAlwaysOnTop() const; /** * Returns true if the task's window will remain at the bottom of the * stacking order. */ bool isKeptBelowOthers() const; /** * Returns true if the task's window is in full screen mode */ bool isFullScreen() const; /** * Returns true if the document the task is editing has been modified. * This is currently handled heuristically by looking for the string * '[i18n_modified]' in the window title where i18n_modified is the * word 'modified' in the current language. */ bool isModified() const ; /** * Returns the desktop on which this task's window resides. */ int desktop() const; /** * Returns true if the task is not active but demands user's attention. */ bool demandsAttention() const; /** * @returns true if the window is on the specified screen of a multihead configuration */ bool isOnScreen(const QRect& screen) const; /** * @returns the screen the largest part of this window is on (or -1 if not on any) */ QRect screen() const; /** * Returns true if the task should be shown in taskbar-like apps */ bool showInTaskbar() const; /** * Returns true if the task should be shown in pager-like apps */ bool showInPager() const; /** * Returns the geometry for this window */ QRect geometry() const; /** * Returns true if the task's window is on the current activity. */ bool isOnCurrentActivity() const; /** * Returns true if the task's window is on all activities */ bool isOnAllActivities() const; /** * Returns the activities on which this task's window resides. */ QStringList activities() const; // internal //* @internal - ::TaskManager::TaskChanges refresh(WindowProperties dirty); + ::LegacyTaskManager::TaskChanges refresh(WindowProperties dirty); //* @internal #if HAVE_X11 void addTransient(WId w, const KWindowInfo &info); #endif //* @internal void removeTransient(WId w); //* @internal bool hasTransient(WId w) const; //* @internal bool updateDemandsAttentionState(WId w); //* @internal void setActive(bool a); /** * Adds the identifying information for this task to mime data for drags, copies, etc */ void addMimeData(QMimeData *mimeData) const; /** * Returns the mimetype used for a Task */ static QString mimetype(); /** * Returns the mimetype used for multiple Tasks */ static QString groupMimetype(); /** * Given mime data, will return a WId if it can decode one from the data. Otherwise * returns 0. */ static WId idFromMimeData(const QMimeData *mimeData, bool *ok = 0); /** * Given mime data, will return a QList if it can decode WIds from the data. Otherwise * returns an empty list. */ static QList idsFromMimeData(const QMimeData *mimeData, bool *ok = 0); public Q_SLOTS: /** * Maximise the main window of this task. */ void setMaximized(bool); void toggleMaximized(); /** * Restore the main window of the task (if it was iconified). */ void restore(); /** * Move the window of this task. */ void move(); /** * Resize the window of this task. */ void resize(); /** * Iconify the task. */ void setIconified(bool); void toggleIconified(); /** * Close the task's window. */ void close(); /** * Raise the task's window. */ void raise(); /** * Lower the task's window. */ void lower(); /** * Activate the task's window. */ void activate(); /** * Perform the action that is most appropriate for this task. If it * is not active, activate it. Else if it is not the top window, raise * it. Otherwise, iconify it. */ void activateRaiseOrIconify(); /** * If true, the task's window will remain at the top of the stacking order. */ void setAlwaysOnTop(bool); void toggleAlwaysOnTop(); /** * If true, the task's window will remain at the bottom of the stacking order. */ void setKeptBelowOthers(bool); void toggleKeptBelowOthers(); /** * If true, the task's window will enter full screen mode. */ void setFullScreen(bool); void toggleFullScreen(); /** * If true then the task's window will be shaded. Most window managers * represent this state by displaying on the window's title bar. */ void setShaded(bool); void toggleShaded(); /** * Moves the task's window to the specified virtual desktop. */ void toDesktop(int); /** * Moves the task's window to the current virtual desktop. */ void toCurrentDesktop(); /** * This method informs the window manager of the location at which this * task will be displayed when iconised. It is used, for example by the * KWin inconify animation. */ void publishIconGeometry(QRect); /** * Releases pixmap objects; useful to clear out pixmap usage prior to application stoppage */ void clearPixmapData(); Q_SIGNALS: /** * Indicates that this task has changed in some way. */ - void changed(::TaskManager::TaskChanges change); + void changed(::LegacyTaskManager::TaskChanges change); /** * Indicates that this task is now the active task. */ void activated(); /** * Indicates that this task is no longer the active task. */ void deactivated(); protected: void findWindowFrameId(); void timerEvent(QTimerEvent *event) override; //* @internal */ void refreshIcon(); void refreshActivities(); private: class Private; Private * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/task_p.h b/liblegacytaskmanager/task_p.h similarity index 98% rename from libtaskmanager/task_p.h rename to liblegacytaskmanager/task_p.h index 28d3cd927..6e9d84cb2 100644 --- a/libtaskmanager/task_p.h +++ b/liblegacytaskmanager/task_p.h @@ -1,84 +1,84 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef TASKP_H #define TASKP_H #include "task.h" #include #include #include -namespace TaskManager +namespace LegacyTaskManager { static const NET::Properties windowInfoFlags = NET::WMState | NET::XAWMState | NET::WMDesktop | NET::WMVisibleName | NET::WMGeometry | NET::WMWindowType; static const NET::Properties2 windowInfoFlags2 = NET::WM2WindowClass | NET::WM2AllowedActions; class Task::Private { public: Private(WId w) : win(w), frameId(w), info(w, windowInfoFlags, windowInfoFlags2), lastWidth(0), lastHeight(0), cachedChanges(0, 0), cachedChangesTimerId(0), active(false), lastResize(false), demandedAttention(false), isX11(QX11Info::isPlatformX11()) { } WId win; WId frameId; KWindowInfo info; WindowList transients; WindowList transientsDemandingAttention; QStringList activities; int lastWidth; int lastHeight; QIcon icon; QRect iconGeometry; QTime lastUpdate; Task::WindowProperties cachedChanges; int cachedChangesTimerId; QPixmap pixmap; QPixmap lastIcon; bool active : 1; bool lastResize : 1; bool demandedAttention : 1; bool isX11; }; } #endif diff --git a/libtaskmanager/task_win.cpp b/liblegacytaskmanager/task_win.cpp similarity index 98% rename from libtaskmanager/task_win.cpp rename to liblegacytaskmanager/task_win.cpp index 92e77547b..5b1dc337c 100644 --- a/libtaskmanager/task_win.cpp +++ b/liblegacytaskmanager/task_win.cpp @@ -1,169 +1,169 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "task_p.h" #include -namespace TaskManager +namespace LegacyTaskManager { bool Task::updateDemandsAttentionState(WId w) { return false; } QString Task::className() const { return QString(); } QString Task::classClass() const { return QString(); } int Task::pid() const { return 0; // FIXME!!! } void Task::move() { bool on_current = d->info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(d->info.desktop()); KWindowSystem::forceActiveWindow(d->win); } if (d->info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } QRect geom = d->info.geometry(); QCursor::setPos(geom.center()); } void Task::resize() { bool on_current = d->info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(d->info.desktop()); KWindowSystem::forceActiveWindow(d->win); } if (d->info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } QRect geom = d->info.geometry(); QCursor::setPos(geom.bottomRight()); } void Task::setMaximized(bool maximize) { KWindowInfo info = KWindowSystem::windowInfo(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop); bool on_current = info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(info.desktop()); } if (info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } if (!on_current) { KWindowSystem::forceActiveWindow(d->win); } } void Task::restore() { KWindowInfo info = KWindowSystem::windowInfo(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop); bool on_current = info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(info.desktop()); } if (info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } if (!on_current) { KWindowSystem::forceActiveWindow(d->win); } } void Task::close() { PostMessage(d->win, WM_CLOSE, 0, 0); } void Task::toDesktop(int desk) { if (desk == KWindowSystem::currentDesktop()) { KWindowSystem::forceActiveWindow(d->win); } } void Task::setAlwaysOnTop(bool stay) { Q_UNUSED(stay); } void Task::setKeptBelowOthers(bool below) { Q_UNUSED(below); } void Task::setFullScreen(bool fullscreen) { Q_UNUSED(fullscreen); } void Task::setShaded(bool shade) { Q_UNUSED(shade); } void Task::publishIconGeometry(QRect rect) { if (rect == d->iconGeometry) { return; } d->iconGeometry = rect; } void Task::refreshActivities() { return; } -} // TaskManager namespace +} // LegacyTaskManager namespace diff --git a/libtaskmanager/task_x11.cpp b/liblegacytaskmanager/task_x11.cpp similarity index 99% rename from libtaskmanager/task_x11.cpp rename to liblegacytaskmanager/task_x11.cpp index c6f0159d8..2d49dfa26 100644 --- a/libtaskmanager/task_x11.cpp +++ b/liblegacytaskmanager/task_x11.cpp @@ -1,298 +1,298 @@ /***************************************************************** Copyright (c) 2000-2001 Matthias Elter Copyright (c) 2001 Richard Moore Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "task_p.h" #include #include #include #include -namespace TaskManager +namespace LegacyTaskManager { bool Task::updateDemandsAttentionState(WId w) { const bool empty = d->transientsDemandingAttention.isEmpty(); if (window() != w && d->isX11) { // 'w' is a transient for this task NETWinInfo i(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMState); if (i.state() & NET::DemandsAttention) { if (!d->transientsDemandingAttention.contains(w)) { d->transientsDemandingAttention.insert(w); } } else { d->transientsDemandingAttention.remove(w); } } return empty != d->transientsDemandingAttention.isEmpty(); } void Task::addTransient(WId w, const KWindowInfo &info) { d->transients.insert(w); if (info.hasState(NET::DemandsAttention)) { d->transientsDemandingAttention.insert(w); emit changed(TransientsChanged | StateChanged | AttentionChanged); } } QString Task::className() const { return d->info.windowClassName(); } QString Task::classClass() const { return d->info.windowClassClass(); } int Task::pid() const { if (!d->isX11) { return -1; } return NETWinInfo(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMPid).pid(); } void Task::move() { if (!d->isX11) { return; } bool on_current = d->info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(d->info.desktop()); KWindowSystem::forceActiveWindow(d->win); } if (d->info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } QRect geom = d->info.geometry(); QCursor::setPos(geom.center()); NETRootInfo ri(QX11Info::connection(), NET::WMMoveResize); ri.moveResizeRequest(d->win, geom.center().x(), geom.center().y(), NET::Move); } void Task::resize() { if (!d->isX11) { return; } bool on_current = d->info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(d->info.desktop()); KWindowSystem::forceActiveWindow(d->win); } if (d->info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } QRect geom = d->info.geometry(); QCursor::setPos(geom.bottomRight()); NETRootInfo ri(QX11Info::connection(), NET::WMMoveResize); ri.moveResizeRequest(d->win, geom.bottomRight().x(), geom.bottomRight().y(), NET::BottomRight); } void Task::setMaximized(bool maximize) { if (!d->isX11) { return; } KWindowInfo info(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop); bool on_current = info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(info.desktop()); } if (info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); if (maximize) { ni.setState(NET::Max, NET::Max); } else { ni.setState(0, NET::Max); } if (!on_current) { KWindowSystem::forceActiveWindow(d->win); } } void Task::restore() { if (!d->isX11) { return; } KWindowInfo info(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop); bool on_current = info.isOnCurrentDesktop(); if (!on_current) { KWindowSystem::setCurrentDesktop(info.desktop()); } if (info.isMinimized()) { KWindowSystem::unminimizeWindow(d->win); } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); ni.setState(0, NET::Max); if (!on_current) { KWindowSystem::forceActiveWindow(d->win); } } void Task::close() { if (!d->isX11) { return; } NETRootInfo ri(QX11Info::connection(), NET::CloseWindow); ri.closeWindowRequest(d->win); } void Task::toDesktop(int desk) { if (desk == 0) { if (isOnAllDesktops()) { KWindowSystem::setOnDesktop(d->win, KWindowSystem::currentDesktop()); KWindowSystem::forceActiveWindow(d->win); } else { KWindowSystem::setOnAllDesktops(d->win, true); } return; } KWindowSystem::setOnDesktop(d->win, desk); if (desk == KWindowSystem::currentDesktop()) { KWindowSystem::forceActiveWindow(d->win); } } void Task::setAlwaysOnTop(bool stay) { if (!d->isX11) { return; } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); if (stay) ni.setState(NET::StaysOnTop, NET::StaysOnTop); else ni.setState(0, NET::StaysOnTop); } void Task::setKeptBelowOthers(bool below) { if (!d->isX11) { return; } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); if (below) { ni.setState(NET::KeepBelow, NET::KeepBelow); } else { ni.setState(0, NET::KeepBelow); } } void Task::setFullScreen(bool fullscreen) { if (!d->isX11) { return; } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); if (fullscreen) { ni.setState(NET::FullScreen, NET::FullScreen); } else { ni.setState(0, NET::FullScreen); } } void Task::setShaded(bool shade) { if (!d->isX11) { return; } NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), NET::WMState); if (shade) ni.setState(NET::Shaded, NET::Shaded); else ni.setState(0, NET::Shaded); } void Task::publishIconGeometry(QRect rect) { if (!d->isX11) { return; } if (rect == d->iconGeometry) { return; } d->iconGeometry = rect; NETWinInfo ni(QX11Info::connection(), d->win, QX11Info::appRootWindow(), 0); NETRect r; if (rect.isValid()) { r.pos.x = rect.x(); r.pos.y = rect.y(); r.size.width = rect.width(); r.size.height = rect.height(); } ni.setIconGeometry(r); } void Task::refreshActivities() { if (!d->isX11) { return; } NETWinInfo info(QX11Info::connection(), d->win, QX11Info::appRootWindow(), 0, NET::WM2Activities); QString result(info.activities()); if (result.isEmpty() || result == QLatin1String("00000000-0000-0000-0000-000000000000")) { d->activities.clear(); } else { d->activities = result.split(','); } } } // namespace diff --git a/libtaskmanager/taskactions.cpp b/liblegacytaskmanager/taskactions.cpp similarity index 97% rename from libtaskmanager/taskactions.cpp rename to liblegacytaskmanager/taskactions.cpp index 0cd0c4300..7ff1f561f 100644 --- a/libtaskmanager/taskactions.cpp +++ b/liblegacytaskmanager/taskactions.cpp @@ -1,724 +1,724 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include "taskactions.h" #include "taskactions_p.h" // Own #include "taskgroup.h" #include "task.h" #include "taskitem.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" #include "abstractgroupingstrategy.h" // KDE #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// // NOTE: if you change the menu, keep kde-workspace/kwin/useractions.cpp in sync ////////////////////////////////////////////////////////////////////////////// -namespace TaskManager +namespace LegacyTaskManager { QAction *standardGroupableAction(GroupableAction action, AbstractGroupableItem *item, GroupManager *strategy, QObject *parent, int desktop) { Q_ASSERT(item); switch (action) { case MaximizeAction: return new MaximizeActionImpl(parent, item); break; case MinimizeAction: return new MinimizeActionImpl(parent, item); break; case ToCurrentDesktopAction: return new ToCurrentDesktopActionImpl(parent, item); break; case ToDesktopAction: return new ToDesktopActionImpl(parent, item, desktop); break; case ShadeAction: return new ShadeActionImpl(parent, item); break; case CloseAction: return new CloseActionImpl(parent, item); break; case ViewFullscreenAction: return new ViewFullscreenActionImpl(parent, item); break; case KeepBelowAction: return new KeepBelowActionImpl(parent, item); break; case ToggleLauncherAction: return new ToggleLauncherActionImpl(parent, item, strategy); break; case NewInstanceAction: return new NewInstanceActionImpl(parent, item); break; } return 0; } QAction* standardTaskAction(TaskAction action, TaskItem *item, QObject *parent) { Q_ASSERT(item); switch (action) { case ResizeAction: return new ResizeActionImpl(parent, item); break; case MoveAction: return new MoveActionImpl(parent, item); break; } return 0; } QAction* standardGroupingAction(GroupingAction action, AbstractGroupableItem *item, GroupManager *strategy, QObject *parent) { Q_ASSERT(item); Q_ASSERT(strategy); switch (action) { case LeaveGroupAction: return new LeaveGroupActionImpl(parent, item, strategy); break; } return 0; } static QString qt_strippedText(QString s) { s.remove(QStringLiteral("...")); int i = 0; while (i < s.size()) { ++i; if (s.at(i - 1) != QLatin1Char('&')) { continue; } if (i < s.size() && s.at(i) == QLatin1Char('&')) { ++i; } s.remove(i - 1, 1); } return s.trimmed(); } ToolTipMenu::ToolTipMenu(QWidget *parent, const QString &title) : QMenu(title, parent) { } bool ToolTipMenu::event(QEvent* e) { if (QEvent::ToolTip == e->type()) { //show action tooltip instead of widget tooltip QHelpEvent *he = dynamic_cast(e); QAction *act = he ? actionAt(he->pos()) : 0; if (act) { if (qt_strippedText(act->text()) != act->toolTip()) { QToolTip::showText(he->globalPos(), act->toolTip(), this); } else { QToolTip::hideText(); } return true; } } return QMenu::event(e); } MinimizeActionImpl::MinimizeActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleMinimized); setText(i18n("Mi&nimize")); setCheckable(true); setChecked(item->isMinimized()); setEnabled(item->isActionSupported(NET::ActionMinimize)); } MaximizeActionImpl::MaximizeActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleMaximized); setText(i18n("Ma&ximize")); setCheckable(true); setChecked(item->isMaximized()); setEnabled(item->isActionSupported(NET::ActionMax)); } ShadeActionImpl::ShadeActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleShaded); setText(i18n("&Shade")); setCheckable(true); setChecked(item->isShaded()); setEnabled(item->isActionSupported(NET::ActionShade)); } ResizeActionImpl::ResizeActionImpl(QObject *parent, TaskItem* item) : QAction(parent) { connect(this, &QAction::triggered, item->task(), &Task::resize); setText(i18n("Re&size")); setEnabled(item->isActionSupported(NET::ActionResize)); } MoveActionImpl::MoveActionImpl(QObject *parent, TaskItem* item) : QAction(parent) { connect(this, &QAction::triggered, item->task(), &Task::move); setText(i18n("&Move")); setIcon(QIcon::fromTheme(QStringLiteral("transform-move"))); setEnabled(item->isActionSupported(NET::ActionMove)); } CloseActionImpl::CloseActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::close); setText(i18n("&Close")); setIcon(QIcon::fromTheme(QStringLiteral("window-close"))); setEnabled(item->isActionSupported(NET::ActionClose)); } AbstractGroupableItemAction::AbstractGroupableItemAction(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { TaskGroup *group = qobject_cast(item); if (group) { addToTasks(group); } else if (TaskItem *taskItem = qobject_cast(item)) { m_tasks.append(taskItem->task()); } } void AbstractGroupableItemAction::addToTasks(TaskGroup *group) { foreach (AbstractGroupableItem * item, group->members()) { TaskGroup *subGroup = qobject_cast(item); if (subGroup) { addToTasks(subGroup); } else if (TaskItem *taskItem = qobject_cast(item)) { m_tasks.append(taskItem->task()); } } } ToCurrentDesktopActionImpl::ToCurrentDesktopActionImpl(QObject *parent, AbstractGroupableItem *item) : AbstractGroupableItemAction(parent, item) { connect(this, &QAction::triggered, this, &ToCurrentDesktopActionImpl::slotToCurrentDesktop); setText(i18n("Move &To Current Desktop")); setEnabled(!item->isOnCurrentDesktop() && item->isActionSupported(NET::ActionChangeDesktop)); } void ToCurrentDesktopActionImpl::slotToCurrentDesktop() { const int desktop = KWindowSystem::currentDesktop(); foreach (auto task, m_tasks) { if (task) { task.data()->toDesktop(desktop); } } } ToDesktopActionImpl::ToDesktopActionImpl(QObject *parent, AbstractGroupableItem *item, int desktop) : AbstractGroupableItemAction(parent, item), m_desktop(desktop) { connect(this, &QAction::triggered, this, &ToDesktopActionImpl::slotToDesktop); setCheckable(true); if (!desktop) { //to All Desktops setText(i18n("&All Desktops")); setChecked(item->isOnAllDesktops()); } else { - QString name = QStringLiteral("&%1 %2").arg(desktop).arg(TaskManager::self()->desktopName(desktop).replace('&', QLatin1String("&&"))); + QString name = QStringLiteral("&%1 %2").arg(desktop).arg(LegacyTaskManager::self()->desktopName(desktop).replace('&', QLatin1String("&&"))); setText(name); setChecked(!item->isOnAllDesktops() && item->desktop() == desktop); } } void ToDesktopActionImpl::slotToDesktop() { foreach (auto task, m_tasks) { if (task) { task.data()->toDesktop(m_desktop); } } } ToNewDesktopActionImpl::ToNewDesktopActionImpl(QObject *parent, AbstractGroupableItem *item) : AbstractGroupableItemAction(parent, item) { connect(this, &QAction::triggered, this, &ToNewDesktopActionImpl::slotToNewDesktop); setText(i18n("&New Desktop")); - m_newDesktop = TaskManager::self()->numberOfDesktops() + 1; + m_newDesktop = LegacyTaskManager::self()->numberOfDesktops() + 1; if (m_newDesktop > 20) { setEnabled(false); } } void ToNewDesktopActionImpl::slotToNewDesktop() { NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); info.setNumberOfDesktops(m_newDesktop); foreach (auto task, m_tasks) { if (task) { task.data()->toDesktop(m_newDesktop); } } } DesktopsMenu::DesktopsMenu(QWidget *parent, AbstractGroupableItem *item) : ToolTipMenu(parent) { QActionGroup *group = new QActionGroup(this); setTitle(i18n("Move To &Desktop")); addAction(new ToCurrentDesktopActionImpl(this, item)); QAction *action = new ToDesktopActionImpl(this, item, 0); //0 means all desktops addAction(action); group->addAction(action); addSeparator(); - for (int i = 1; i <= TaskManager::self()->numberOfDesktops(); i++) { + for (int i = 1; i <= LegacyTaskManager::self()->numberOfDesktops(); i++) { action = new ToDesktopActionImpl(this, item, i); addAction(action); group->addAction(action); } addSeparator(); addAction(new ToNewDesktopActionImpl(this, item)); setEnabled(item->isActionSupported(NET::ActionChangeDesktop)); } KeepAboveActionImpl::KeepAboveActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleAlwaysOnTop); setText(i18n("Keep &Above Others")); setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); setCheckable(true); setChecked(item->isAlwaysOnTop()); } KeepBelowActionImpl::KeepBelowActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleKeptBelowOthers); setText(i18n("Keep &Below Others")); setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); setCheckable(true); setChecked(item->isKeptBelowOthers()); } ViewFullscreenActionImpl::ViewFullscreenActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent) { connect(this, &QAction::triggered, item, &AbstractGroupableItem::toggleFullScreen); setText(i18n("&Fullscreen")); setIcon(QIcon::fromTheme(QStringLiteral("view-fullscreen"))); setCheckable(true); setChecked(item->isFullScreen()); setEnabled(item->isActionSupported(NET::ActionFullScreen)); } AdvancedMenu::AdvancedMenu(QWidget *parent, AbstractGroupableItem *item, GroupManager *strategy) : ToolTipMenu(parent) { setTitle(i18n("More Actions")); if (item->itemType() == TaskItemType) { addAction(new MoveActionImpl(this, static_cast(item))); addAction(new ResizeActionImpl(this, static_cast(item))); } addAction(new KeepAboveActionImpl(this, item)); addAction(new KeepBelowActionImpl(this, item)); addAction(new ViewFullscreenActionImpl(this, item)); addAction(new ShadeActionImpl(this, item)); if (strategy->taskGrouper()) { QList groupingStrategyActions = strategy->taskGrouper()->strategyActions(this, item); if (!groupingStrategyActions.isEmpty()) { addSeparator(); foreach (QAction * action, groupingStrategyActions) { addAction(action); } // delete groupingStrategyActions; } } } LeaveGroupActionImpl::LeaveGroupActionImpl(QObject *parent, AbstractGroupableItem *item, GroupManager *strategy) : QAction(parent), abstractItem(item), groupingStrategy(strategy) { Q_ASSERT(strategy); connect(this, &QAction::triggered, this, &LeaveGroupActionImpl::leaveGroup); setText(i18n("&Leave Group")); setIcon(QIcon::fromTheme(QStringLiteral("window-close"))); setEnabled(item->isGrouped()); } void LeaveGroupActionImpl::leaveGroup() { groupingStrategy->manualGroupingRequest(abstractItem, abstractItem->parentGroup()->parentGroup()); } ToggleLauncherActionImpl::ToggleLauncherActionImpl(QObject *parent, AbstractGroupableItem *item, GroupManager *strategy) : QAction(parent), m_abstractItem(item), m_groupingStrategy(strategy) { if (strategy->launchersLocked()) { setVisible(false); setChecked(false); } else { m_url = m_abstractItem->launcherUrl(); // FIXME TODO: This signal delivery is queued to allow QGraphicsView to perform an ungrab // on the launcher item after the popup menu closes before removing the launcher destroys // the item, avoiding a crash. The trade-of is that it requires more care when using the - // TaskManager::BasicMenu class, since the menu can no longer be deleted directly after + // LegacyTaskManager::BasicMenu class, since the menu can no longer be deleted directly after // exec() returns. The QML 2 scene graph may be smarter than trying to perform an ungrab // on a destroyed item, so reinvestigate whether this is chicanery is still needed. connect(this, &QAction::triggered, this, &ToggleLauncherActionImpl::toggleLauncher, Qt::QueuedConnection); switch (m_abstractItem->itemType()) { case LauncherItemType: setText(i18n("Remove This Launcher")); break; case GroupItemType: { TaskGroup *group = static_cast(m_abstractItem); foreach (AbstractGroupableItem * i, group->members()) { if (TaskItemType == i->itemType()) { m_abstractItem = i; break; } } if (TaskItemType != m_abstractItem->itemType()) { setVisible(false); setChecked(false); break; } } // fallthrough to TaskItemType below case TaskItemType: setText(i18n("&Show A Launcher When Not Running")); setCheckable(true); break; } setChecked(m_groupingStrategy->launcherExists(m_url)); } } void ToggleLauncherActionImpl::toggleLauncher() { if (!m_url.isValid()) { // No valid desktop file found, so prompt user... AppSelectorDialog *dlg = new AppSelectorDialog(m_abstractItem, m_groupingStrategy); dlg->show(); return; } else if (m_groupingStrategy->launcherExists(m_url)) { m_groupingStrategy->removeLauncher(m_url); } else if (m_url.isLocalFile()) { QIcon icon; // if we don't have a desktop file, it's because it is a bare executable if (static_cast(m_abstractItem)->task() && !KDesktopFile::isDesktopFile(m_url.toLocalFile())) { icon = static_cast(m_abstractItem)->task()->icon(); } m_groupingStrategy->addLauncher(m_url, icon, QString(), QString(), static_cast(m_abstractItem)->task() ? static_cast(m_abstractItem)->task()->classClass() : QString()); } } AppSelectorDialog::AppSelectorDialog(AbstractGroupableItem* item, GroupManager* strategy) : KOpenWithDialog(QList(), i18n("The application, to which this task is associated with, could not be determined. " "Please select the appropriate application from the list below:"), QString(), 0L), m_abstractItem(item), m_groupingStrategy(strategy) { hideNoCloseOnExit(); hideRunInTerminal(); setAttribute(Qt::WA_DeleteOnClose); setWindowModality(Qt::WindowModal); connect(this, &QDialog::accepted, this, &AppSelectorDialog::launcherSelected); } void AppSelectorDialog::launcherSelected() { if (m_abstractItem && m_groupingStrategy) { KService::Ptr srv = service(); TaskItem *taskItem = static_cast(m_abstractItem.data()); QString wmClass = taskItem->task() ? taskItem->task()->classClass() : QString(); if (srv && srv->isApplication() && !srv->entryPath().isEmpty()) { QUrl url = QUrl::fromLocalFile(srv->entryPath()); if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) { taskItem->setLauncherUrl(url); m_groupingStrategy->addLauncher(url, QIcon(), QString(), QString(), wmClass); } } else { QString path = text(); if (!path.isEmpty()) { QUrl url = QUrl::fromLocalFile(path); if (url.isLocalFile()) { taskItem->setLauncherUrl(url); m_groupingStrategy->addLauncher(url, taskItem->icon(), taskItem->name(), wmClass, wmClass); } } } } } NewInstanceActionImpl::NewInstanceActionImpl(QObject *parent, AbstractGroupableItem *item) : QAction(parent), m_abstractItem(item) { if (LauncherItemType == item->itemType()) { setVisible(false); } else { setIcon(QIcon::fromTheme(QStringLiteral("system-run"))); setText(i18n("Start New Instance")); connect(this, &QAction::triggered, this, &NewInstanceActionImpl::launchNewInstance); m_url = item->launcherUrl(); if (m_url.isEmpty()) { setVisible(false); } } } void NewInstanceActionImpl::launchNewInstance() { m_abstractItem->launchNewInstance(); } EditGroupActionImpl::EditGroupActionImpl(QObject *parent, TaskGroup *group, GroupManager *groupManager) : QAction(parent) { Q_ASSERT(groupManager); connect(this, &QAction::triggered, group, &TaskGroup::groupEditRequest); setText(i18n("&Edit Group")); //setIcon(QIcon::fromTheme("window-close")); bool applicable = true; if (groupManager->groupingStrategy()) { applicable = groupManager->taskGrouper()->editableGroupProperties(); } else { applicable = false; } setEnabled(applicable); setVisible(applicable); } GroupingStrategyMenu::GroupingStrategyMenu(QWidget *parent, AbstractGroupableItem* item, GroupManager *strategy) : ToolTipMenu(parent) { Q_ASSERT(item); Q_ASSERT(strategy); setTitle(QStringLiteral("Grouping strategy actions")); if (strategy->taskGrouper()) { QList groupingStrategyActions = strategy->taskGrouper()->strategyActions(this, item); if (!groupingStrategyActions.empty()) { addSeparator(); foreach (QAction * action, groupingStrategyActions) { addAction(action); } } } } BasicMenu::BasicMenu(QWidget *parent, TaskItem* item, GroupManager *strategy, QList visualizationActions, QList appActions, int maxWidth) : ToolTipMenu(parent) { Q_ASSERT(item); Q_ASSERT(strategy); if (maxWidth) { setTitle(fontMetrics().elidedText(item->name(), Qt::ElideRight, maxWidth)); } else { setTitle(item->name()); } setIcon(item->icon()); if (appActions.count()) { foreach (QAction * action, appActions) { if (action->isSeparator()) { addSeparator(); } else { addAction(action); } } addSeparator(); } - if (TaskManager::self()->numberOfDesktops() > 1) { + if (LegacyTaskManager::self()->numberOfDesktops() > 1) { addMenu(new DesktopsMenu(this, item)); } addAction(new MinimizeActionImpl(this, item)); addAction(new MaximizeActionImpl(this, item)); addAction(new NewInstanceActionImpl(this, item)); addAction(new ToggleLauncherActionImpl(this, item, strategy)); addMenu(new AdvancedMenu(this, item, strategy)); foreach (QAction * action, visualizationActions) { addAction(action); } addSeparator(); addAction(new CloseActionImpl(this, item)); } BasicMenu::BasicMenu(QWidget *parent, TaskGroup* group, GroupManager *strategy, QList visualizationActions, QList appActions, int maxWidth) : ToolTipMenu(parent) { Q_ASSERT(group); Q_ASSERT(strategy); setTitle(group->name()); setIcon(group->icon()); if (appActions.count()) { foreach (QAction * action, appActions) { if (action->isSeparator()) { addSeparator(); } else { addAction(action); } } addSeparator(); } foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() == GroupItemType) { addMenu(new BasicMenu(this, dynamic_cast(item), strategy)); } else { addMenu(new BasicMenu(this, dynamic_cast(item), strategy, QList (), QList (), maxWidth)); } } addSeparator(); - if (TaskManager::self()->numberOfDesktops() > 1) { + if (LegacyTaskManager::self()->numberOfDesktops() > 1) { addMenu(new DesktopsMenu(this, group)); } addAction(new MinimizeActionImpl(this, group)); addAction(new MaximizeActionImpl(this, group)); addAction(new NewInstanceActionImpl(this, group)); addAction(new ToggleLauncherActionImpl(this, group, strategy)); addMenu(new AdvancedMenu(this, group, strategy)); addAction(new EditGroupActionImpl(this, group, strategy)); foreach (QAction * action, visualizationActions) { addAction(action); } addSeparator(); addAction(new CloseActionImpl(this, group)); } BasicMenu::BasicMenu(QWidget *parent, LauncherItem* item, GroupManager *strategy, QList visualizationActions, QList appActions) : ToolTipMenu(parent) { Q_ASSERT(item); Q_ASSERT(strategy); setTitle(item->name()); setIcon(item->icon()); if (appActions.count()) { foreach (QAction * action, appActions) { if (action->isSeparator()) { addSeparator(); } else { addAction(action); } } addSeparator(); } addAction(new ToggleLauncherActionImpl(this, item, strategy)); if (!visualizationActions.isEmpty()) { addSeparator(); foreach (QAction * action, visualizationActions) { addAction(action); } } } GroupPopupMenu::GroupPopupMenu(QWidget *parent, TaskGroup *group, GroupManager *groupManager) : ToolTipMenu(parent) { setTitle(group->name()); setIcon(group->icon()); foreach (AbstractGroupableItem * item, group->members()) { if (!item) { // qDebug() << "invalid Item"; continue; } if (item->itemType() == GroupItemType) { ToolTipMenu* menu = new GroupPopupMenu(this, qobject_cast(item), groupManager); addMenu(menu); } else { TaskItem *taskItem = qobject_cast(item); if (taskItem && taskItem->task()) { QAction* action = new QAction(item->icon(), item->name(), this); connect(action, &QAction::triggered, taskItem->task(), &Task::activateRaiseOrIconify); addAction(action); } } } } -} // TaskManager namespace +} // LegacyTaskManager namespace #include "moc_taskactions_p.cpp" diff --git a/libtaskmanager/taskactions.h b/liblegacytaskmanager/taskactions.h similarity index 83% rename from libtaskmanager/taskactions.h rename to liblegacytaskmanager/taskactions.h index d54fc21dd..b01165da1 100644 --- a/libtaskmanager/taskactions.h +++ b/liblegacytaskmanager/taskactions.h @@ -1,146 +1,146 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef TASKACTIONS_H #define TASKACTIONS_H // Qt #include #include // Own #include #include #include #include -#include +#include -namespace TaskManager +namespace LegacyTaskManager { enum GroupableAction { MaximizeAction = 0, MinimizeAction, ToCurrentDesktopAction, ToDesktopAction, ShadeAction, CloseAction, ViewFullscreenAction, KeepBelowAction, ToggleLauncherAction, // adds/removes Launcher for the task NewInstanceAction // lauch a new instance of a launcher }; enum TaskAction { ResizeAction = 0, MoveAction }; enum GroupingAction { LeaveGroupAction = 0 }; /** * Factory method to create standard actions for groupable items. * * @param action the action to create * @param item the groupable item to associate it with * @param parent the parent for the action * @param desktop the desktop to associate the action with, only used for ToDesktopAction */ -TASKMANAGER_EXPORT QAction *standardGroupableAction(GroupableAction action, AbstractGroupableItem *item, QObject *parent = 0, int desktop = 0); +LEGACYTASKMANAGER_EXPORT QAction *standardGroupableAction(GroupableAction action, AbstractGroupableItem *item, QObject *parent = 0, int desktop = 0); /** * Factory method to create standard actions for groupable items. * * @param action the action to create * @param task the task to associate it with * @param parent the parent for the action */ -TASKMANAGER_EXPORT QAction *standardTaskAction(TaskAction action, TaskItem *task, QObject *parent = 0); +LEGACYTASKMANAGER_EXPORT QAction *standardTaskAction(TaskAction action, TaskItem *task, QObject *parent = 0); /** * Factory method to create standard actions for groupable items. * * @param action the action to create * @param item the groupable item to associate it with * @param strategy the GroupManager used to coorinate the grouping * @param parent the parent for the action */ -TASKMANAGER_EXPORT QAction* standardGroupingAction(GroupingAction action, AbstractGroupableItem *item, +LEGACYTASKMANAGER_EXPORT QAction* standardGroupingAction(GroupingAction action, AbstractGroupableItem *item, GroupManager *strategy, QObject *parent = 0); -class TASKMANAGER_EXPORT ToolTipMenu : public QMenu +class LEGACYTASKMANAGER_EXPORT ToolTipMenu : public QMenu { public: explicit ToolTipMenu(QWidget *parent = 0, const QString &title = QString()); bool event(QEvent* e) override; }; /** The ToDesktop menu */ -class TASKMANAGER_EXPORT DesktopsMenu : public ToolTipMenu +class LEGACYTASKMANAGER_EXPORT DesktopsMenu : public ToolTipMenu { Q_OBJECT public: DesktopsMenu(QWidget *parent, AbstractGroupableItem *task); }; /** Menu with the actions that the groupingStrategy provides*/ -class TASKMANAGER_EXPORT GroupingStrategyMenu : public ToolTipMenu +class LEGACYTASKMANAGER_EXPORT GroupingStrategyMenu : public ToolTipMenu { Q_OBJECT public: GroupingStrategyMenu(QWidget *parent, AbstractGroupableItem *task, GroupManager *strategy); }; /** The Advanced menu */ -class TASKMANAGER_EXPORT AdvancedMenu : public ToolTipMenu +class LEGACYTASKMANAGER_EXPORT AdvancedMenu : public ToolTipMenu { Q_OBJECT public: AdvancedMenu(QWidget *parent, AbstractGroupableItem *task, GroupManager *strategy); }; /** The standard menu*/ -class TASKMANAGER_EXPORT BasicMenu : public ToolTipMenu +class LEGACYTASKMANAGER_EXPORT BasicMenu : public ToolTipMenu { Q_OBJECT public: BasicMenu(QWidget *parent, GroupPtr task, GroupManager *strategy, QList visualizationActions = QList (), QList appActions = QList (), int maxWidth = 0); BasicMenu(QWidget *parent, TaskItem* task, GroupManager *strategy, QList visualizationActions = QList (), QList appActions = QList (), int maxWidth = 0); BasicMenu(QWidget *parent, LauncherItem* task, GroupManager *strategy, QList visualizationActions = QList (), QList appActions = QList ()); }; /** A Menu that shows a list of all tasks of the group, and shows a BasicMenu on right click on an item*/ -class TASKMANAGER_EXPORT GroupPopupMenu : public ToolTipMenu +class LEGACYTASKMANAGER_EXPORT GroupPopupMenu : public ToolTipMenu { Q_OBJECT public: GroupPopupMenu(QWidget *parent, GroupPtr task, GroupManager *strategy); }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/taskactions_p.h b/liblegacytaskmanager/taskactions_p.h similarity index 98% rename from libtaskmanager/taskactions_p.h rename to liblegacytaskmanager/taskactions_p.h index 055eb47cf..9491bbf5b 100644 --- a/libtaskmanager/taskactions_p.h +++ b/liblegacytaskmanager/taskactions_p.h @@ -1,235 +1,235 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef TASKACTIONS_P_H #define TASKACTIONS_P_H -#include "taskmanager.h" +#include "legacytaskmanager.h" #include #include -namespace TaskManager +namespace LegacyTaskManager { /** Maximize a window or all windows in a group*/ class MaximizeActionImpl : public QAction { Q_OBJECT public: MaximizeActionImpl(QObject *parent, AbstractGroupableItem *task); }; /** Minimize a window or all windows in a group*/ class MinimizeActionImpl : public QAction { Q_OBJECT public: MinimizeActionImpl(QObject *parent, AbstractGroupableItem *task); }; /** Shade a window or all windows in a group*/ class ShadeActionImpl : public QAction { Q_OBJECT public: ShadeActionImpl(QObject *parent, AbstractGroupableItem *task); }; class ToggleLauncherActionImpl : public QAction { Q_OBJECT public: ToggleLauncherActionImpl(QObject* parent, AbstractGroupableItem* item, GroupManager* strategy); private Q_SLOTS: void toggleLauncher(); private: AbstractGroupableItem *m_abstractItem; GroupManager *m_groupingStrategy; QUrl m_url; }; class AppSelectorDialog : public KOpenWithDialog { Q_OBJECT public: AppSelectorDialog(AbstractGroupableItem* item, GroupManager* strategy); private Q_SLOTS: void launcherSelected(); private: QPointer m_abstractItem; QPointer m_groupingStrategy; }; class NewInstanceActionImpl : public QAction { Q_OBJECT public: NewInstanceActionImpl(QObject* parent, AbstractGroupableItem* item); private Q_SLOTS: void launchNewInstance(); private: AbstractGroupableItem *m_abstractItem; QUrl m_url; }; /** Resize a window or all windows in a group*/ class ResizeActionImpl : public QAction { Q_OBJECT public: ResizeActionImpl(QObject *parent, TaskItem* task); }; /** Move a window or all windows in a group*/ class MoveActionImpl : public QAction { Q_OBJECT public: MoveActionImpl(QObject *parent, TaskItem* task); }; /** Shade a window or all windows in a group*/ class CloseActionImpl : public QAction { Q_OBJECT public: CloseActionImpl(QObject *parent, AbstractGroupableItem *task); }; class AbstractGroupableItemAction : public QAction { Q_OBJECT public: AbstractGroupableItemAction(QObject *parent, AbstractGroupableItem *item); protected: QList > m_tasks; private: void addToTasks(TaskGroup *group); }; /** Move window to current desktop*/ class ToCurrentDesktopActionImpl : public AbstractGroupableItemAction { Q_OBJECT public: ToCurrentDesktopActionImpl(QObject *parent, AbstractGroupableItem *task); private Q_SLOTS: void slotToCurrentDesktop(); }; /** Move window to a new desktop*/ class ToNewDesktopActionImpl : public AbstractGroupableItemAction { Q_OBJECT public: ToNewDesktopActionImpl(QObject *parent, AbstractGroupableItem *task); private Q_SLOTS: void slotToNewDesktop(); private: int m_newDesktop; }; /** Send a Task to a specific Desktop*/ class ToDesktopActionImpl : public AbstractGroupableItemAction { Q_OBJECT public: ToDesktopActionImpl(QObject *parent, AbstractGroupableItem *task, int desktop); private Q_SLOTS: void slotToDesktop(); private: int m_desktop; }; /** Set a window or all windows in a group to FullScreen*/ class ViewFullscreenActionImpl : public QAction { Q_OBJECT public: ViewFullscreenActionImpl(QObject *parent, AbstractGroupableItem *task); }; /** Keep a Window or all windows in a group above the rest */ class KeepAboveActionImpl : public QAction { Q_OBJECT public: KeepAboveActionImpl(QObject *parent, AbstractGroupableItem *task); }; /** Keep a Window or all windows in a group below the rest*/ class KeepBelowActionImpl : public QAction { Q_OBJECT public: KeepBelowActionImpl(QObject *parent, AbstractGroupableItem *task); }; /** Leave current Group*/ class LeaveGroupActionImpl : public QAction { Q_OBJECT public: LeaveGroupActionImpl(QObject *parent, AbstractGroupableItem *task, GroupManager*); private Q_SLOTS: void leaveGroup(); private: AbstractGroupableItem *abstractItem; GroupManager *groupingStrategy; }; /** Edit current Group*/ class EditGroupActionImpl : public QAction { Q_OBJECT public: EditGroupActionImpl(QObject *parent, TaskGroup *group, GroupManager*); }; /** Remove Group class RemoveGroupActionImpl : public QAction { Q_OBJECT public: RemoveGroupActionImpl(QObject *parent, AbstractGroupableItem *task); }; */ -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/taskgroup.cpp b/liblegacytaskmanager/taskgroup.cpp similarity index 96% rename from libtaskmanager/taskgroup.cpp rename to liblegacytaskmanager/taskgroup.cpp index ecedaf0c1..c98464589 100644 --- a/libtaskmanager/taskgroup.cpp +++ b/liblegacytaskmanager/taskgroup.cpp @@ -1,708 +1,708 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "taskgroup.h" -#include "taskmanager.h" +#include "legacytaskmanager.h" #include "taskitem.h" #include "groupmanager.h" // Qt #include #include // KDE -namespace TaskManager +namespace LegacyTaskManager { class TaskGroup::Private { public: Private(TaskGroup *group, GroupManager *manager) : q(group), groupIcon(QIcon::fromTheme(QStringLiteral("xorg"))), groupManager(manager) { } void itemDestroyed(AbstractGroupableItem *item); - void itemChanged(::TaskManager::TaskChanges changes); + void itemChanged(::LegacyTaskManager::TaskChanges changes); void signalRemovals(); TaskGroup *q; QList signalRemovalsFor; ItemList members; QString groupName; QIcon groupIcon; GroupManager *groupManager; }; TaskGroup::TaskGroup(GroupManager *parent, const QString &name) : AbstractGroupableItem(parent), d(new Private(this, parent)) { d->groupName = name; //qDebug() << "Group Created: Name: " << d->groupName; } TaskGroup::TaskGroup(GroupManager *parent) : AbstractGroupableItem(parent), d(new Private(this, parent)) { //qDebug() << "Group Created: Name: " << d->groupName; } TaskGroup::~TaskGroup() { emit destroyed(this); delete d; } WindowList TaskGroup::winIds() const { // qDebug() << name() << d->members.size(); if (d->members.isEmpty()) { // qDebug() << "empty group: " << name(); } WindowList ids; foreach (AbstractGroupableItem * groupable, d->members) { ids += groupable->winIds(); } // qDebug() << ids.size(); return ids; } //TODO unused WindowList TaskGroup::directMemberwinIds() const { WindowList ids; foreach (AbstractGroupableItem * groupable, d->members) { if (groupable->itemType() != GroupItemType) { ids += groupable->winIds(); } } return ids; } AbstractGroupableItem *TaskGroup::getMemberByWId(WId id) { foreach (AbstractGroupableItem * groupable, d->members) { if (groupable->itemType() == GroupItemType) { AbstractGroupableItem *item = static_cast(groupable)->getMemberByWId(id); if (item) { return item; } } else { if (groupable->winIds().isEmpty()) { continue; } if (groupable->winIds().values().first() == id) { return groupable; } } } //qDebug() << "item not found"; return 0; } AbstractGroupableItem *TaskGroup::getMemberById(int id) { foreach (AbstractGroupableItem * groupable, d->members) { if (groupable->id() == id) { return groupable; } else { if (groupable->itemType() == GroupItemType) { AbstractGroupableItem *item = static_cast(groupable)->getMemberById(id); if (item) { return item; } } } } //qDebug() << "item not found"; return 0; } //including subgroups int TaskGroup::totalSize() { int size = 0; foreach (AbstractGroupableItem * groupable, d->members) { if (groupable->itemType() == GroupItemType) { size += static_cast(groupable)->totalSize(); } else { size++; } } return size; } void TaskGroup::add(AbstractGroupableItem *item, int insertIndex) { /* if (!item->itemType() == GroupItemType) { if ((dynamic_cast(item))->task()) { qDebug() << "Add item" << (dynamic_cast(item))->task()->visibleName(); } qDebug() << " to Group " << name(); } */ if (!item) { // qDebug() << "invalid item"; return; } if (d->members.contains(item)) { //qDebug() << "already in this group"; return; } if (d->groupName.isEmpty()) { TaskItem *taskItem = qobject_cast(item); if (taskItem) { d->groupName = taskItem->taskName(); } } if (item->parentGroup()) { item->parentGroup()->remove(item); } else if (item->itemType() == GroupItemType) { TaskGroup *group = static_cast(item); if (group) { foreach (AbstractGroupableItem * subItem, group->members()) { - connect(subItem, SIGNAL(changed(::TaskManager::TaskChanges)), - item, SLOT(itemChanged(::TaskManager::TaskChanges)), Qt::UniqueConnection); + connect(subItem, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), + item, SLOT(itemChanged(::LegacyTaskManager::TaskChanges)), Qt::UniqueConnection); } } } int index = insertIndex; if (index < 0) { index = d->members.count(); if (d->groupManager->separateLaunchers()) { if (item->itemType() == LauncherItemType) { QUrl lUrl = item->launcherUrl(); int maxIndex = d->groupManager->launcherIndex(lUrl); if (maxIndex < 0 || maxIndex >= d->members.count()) { maxIndex = d->members.count() - 1; } for (index = 0; index < maxIndex; ++index) { if (d->members.at(index)->itemType() != LauncherItemType) { break; } } } } else { QUrl lUrl = item->launcherUrl(); int urlIdx = d->groupManager->launcherIndex(lUrl); if (urlIdx >= 0) { for (index = 0; index < d->members.count(); ++index) { int idx = d->groupManager->launcherIndex(d->members.at(index)->launcherUrl()); if (urlIdx < idx || idx < 0) { break; } } } } } item->setParentGroup(this); emit itemAboutToBeAdded(item, index); d->members.insert(index, item); connect(item, SIGNAL(destroyed(AbstractGroupableItem*)), this, SLOT(itemDestroyed(AbstractGroupableItem*))); //if the item will gain a parent those connections will be added by the if up there if (!isRootGroup()) { - connect(item, SIGNAL(changed(::TaskManager::TaskChanges)), - this, SLOT(itemChanged(::TaskManager::TaskChanges))); + connect(item, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), + this, SLOT(itemChanged(::LegacyTaskManager::TaskChanges))); } //For debug /* foreach (AbstractGroupableItem *item, d->members) { if (item->itemType() == GroupItemType) { qDebug() << (dynamic_cast(item))->name(); } else { qDebug() << (dynamic_cast(item))->task()->visibleName(); } }*/ emit itemAdded(item); } void TaskGroup::Private::itemDestroyed(AbstractGroupableItem *item) { emit q->itemAboutToBeRemoved(item); members.removeAll(item); signalRemovalsFor << item; QTimer::singleShot(0, q, SLOT(signalRemovals())); } void TaskGroup::Private::signalRemovals() { // signal removals for is full of dangling pointers. do not use them! foreach (AbstractGroupableItem * item, signalRemovalsFor) { emit q->itemRemoved(item); } signalRemovalsFor.clear(); } -void TaskGroup::Private::itemChanged(::TaskManager::TaskChanges changes) +void TaskGroup::Private::itemChanged(::LegacyTaskManager::TaskChanges changes) { if (q->manager()->forceGrouping()) { emit q->changed(changes); return; } - if (changes & ::TaskManager::IconChanged) { + if (changes & ::LegacyTaskManager::IconChanged) { emit q->checkIcon(q); } if (changes & StateChanged) { emit q->changed(StateChanged); } } void TaskGroup::remove(AbstractGroupableItem *item) { Q_ASSERT(item); /* if (item->itemType() == GroupItemType) { qDebug() << "Remove group" << (dynamic_cast(item))->name(); } else if ((dynamic_cast(item))->task()) { qDebug() << "Remove item" << (dynamic_cast(item))->task()->visibleName(); } qDebug() << "from Group: " << name(); */ /* qDebug() << "GroupMembers: "; foreach (AbstractGroupableItem *item, d->members) { if (item->itemType() == GroupItemType) { qDebug() << (dynamic_cast(item))->name(); } else { qDebug() << (dynamic_cast(item))->task()->visibleName(); } }*/ if (!d->members.contains(item)) { // qDebug() << "couldn't find item"; return; } emit itemAboutToBeRemoved(item); disconnect(item, 0, this, 0); d->members.removeAll(item); item->setParentGroup(0); /*if (d->members.isEmpty()) { qDebug() << "empty"; emit empty(this); }*/ emit itemRemoved(item); } void TaskGroup::clear() { ItemList copy = d->members; foreach (AbstractGroupableItem * ai, copy) { if (qobject_cast(ai)) { static_cast(ai)->clear(); } remove(ai); } } GroupManager *TaskGroup::manager() const { return d->groupManager; } ItemList TaskGroup::members() const { return d->members; } QString TaskGroup::name() const { return d->groupName; } void TaskGroup::setName(const QString &newName) { d->groupName = newName; emit changed(NameChanged); } QIcon TaskGroup::icon() const { return d->groupIcon; } void TaskGroup::setIcon(const QIcon &newIcon) { d->groupIcon = newIcon; emit changed(IconChanged); } ItemType TaskGroup::itemType() const { return GroupItemType; } bool TaskGroup::isGroupItem() const { return true; } bool TaskGroup::isRootGroup() const { return !parentGroup(); } /** only true if item is in this group */ bool TaskGroup::hasDirectMember(AbstractGroupableItem *item) const { return d->members.contains(item); } /** true if item is in this or any sub group */ bool TaskGroup::hasMember(AbstractGroupableItem *item) const { //qDebug(); TaskGroup *group = item->parentGroup(); while (group) { if (group == this) { return true; } group = group->parentGroup(); } return false; } /** Returns Direct Member group if the passed item is in a subgroup */ AbstractGroupableItem *TaskGroup::directMember(AbstractGroupableItem *item) const { AbstractGroupableItem *tempItem = item; while (tempItem) { if (d->members.contains(item)) { return item; } tempItem = tempItem->parentGroup(); } // qDebug() << "item not found"; return 0; } void TaskGroup::setShaded(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setShaded(state); } } void TaskGroup::toggleShaded() { setShaded(!isShaded()); } bool TaskGroup::isShaded() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isShaded()) { return false; } } return true; } void TaskGroup::toDesktop(int desk) { foreach (AbstractGroupableItem * item, d->members) { item->toDesktop(desk); } emit movedToDesktop(desk); } bool TaskGroup::isOnCurrentDesktop() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isOnCurrentDesktop()) { return false; } } return true; } void TaskGroup::addMimeData(QMimeData *mimeData) const { //qDebug() << d->members.count(); if (d->members.isEmpty()) { return; } QByteArray data; WindowList ids = winIds(); int count = ids.count(); data.resize(sizeof(int) + sizeof(WId) * count); memcpy(data.data(), &count, sizeof(int)); int i = 0; foreach (WId id, ids) { //qDebug() << "adding" << id; memcpy(data.data() + sizeof(int) + sizeof(WId) * i, &id, sizeof(WId)); ++i; } //qDebug() << "done:" << data.size() << count; mimeData->setData(Task::groupMimetype(), data); } QUrl TaskGroup::launcherUrl() const { // Strategy: try to return the first non-group item's launcherUrl, // failing that, try to return the launcherUrl of the first group // if any foreach (AbstractGroupableItem * item, d->members) { if (item->itemType() != GroupItemType) { return item->launcherUrl(); } } if (d->members.isEmpty()) { return QUrl(); } return d->members.first()->launcherUrl(); } bool TaskGroup::isOnAllDesktops() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isOnAllDesktops()) { return false; } } return true; } //return 0 if tasks are on different desktops or on all dektops int TaskGroup::desktop() const { if (d->members.isEmpty()) { return 0; } if (KWindowSystem::numberOfDesktops() < 2) { return 0; } int desk = d->members.first()->desktop(); foreach (AbstractGroupableItem * item, d->members) { if (item->desktop() != desk) { return 0; } } return desk; } void TaskGroup::setMaximized(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setMaximized(state); } } void TaskGroup::toggleMaximized() { setMaximized(!isMaximized()); } bool TaskGroup::isMaximized() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isMaximized()) { return false; } } return true; } void TaskGroup::setMinimized(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setMinimized(state); } } void TaskGroup::toggleMinimized() { setMinimized(!isMinimized()); } bool TaskGroup::isMinimized() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isMinimized()) { return false; } } return true; } void TaskGroup::setFullScreen(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setFullScreen(state); } } void TaskGroup::toggleFullScreen() { setFullScreen(!isFullScreen()); } bool TaskGroup::isFullScreen() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isFullScreen()) { return false; } } return true; } void TaskGroup::setKeptBelowOthers(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setKeptBelowOthers(state); } } void TaskGroup::toggleKeptBelowOthers() { setKeptBelowOthers(!isKeptBelowOthers()); } bool TaskGroup::isKeptBelowOthers() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isKeptBelowOthers()) { return false; } } return true; } void TaskGroup::setAlwaysOnTop(bool state) { foreach (AbstractGroupableItem * item, d->members) { item->setAlwaysOnTop(state); } } void TaskGroup::toggleAlwaysOnTop() { setAlwaysOnTop(!isAlwaysOnTop()); } bool TaskGroup::isAlwaysOnTop() const { foreach (AbstractGroupableItem * item, d->members) { if (!item->isAlwaysOnTop()) { return false; } } return true; } bool TaskGroup::isActionSupported(NET::Action action) const { if (KWindowSystem::allowedActionsSupported()) { foreach (AbstractGroupableItem * item, d->members) { if (!item->isActionSupported(action)) { return false; } } return true; } return false; } void TaskGroup::close() { foreach (AbstractGroupableItem * item, d->members) { item->close(); } } bool TaskGroup::isActive() const { foreach (AbstractGroupableItem * item, d->members) { if (item->isActive()) { return true; } } return false; } bool TaskGroup::demandsAttention() const { foreach (AbstractGroupableItem * item, d->members) { if (item->demandsAttention()) { return true; } } return false; } bool TaskGroup::moveItem(int oldIndex, int newIndex) { //qDebug() << oldIndex << newIndex; if ((d->members.count() <= newIndex) || (newIndex < 0) || (d->members.count() <= oldIndex || oldIndex < 0)) { // qDebug() << "index out of bounds"; return false; } AbstractGroupableItem *item = d->members.at(oldIndex); emit itemAboutToMove(item, oldIndex, newIndex); d->members.move(oldIndex, newIndex); emit itemPositionChanged(item); return true; } -} // TaskManager namespace +} // LegacyTaskManager namespace #include "moc_taskgroup.cpp" diff --git a/libtaskmanager/taskgroup.h b/liblegacytaskmanager/taskgroup.h similarity index 94% rename from libtaskmanager/taskgroup.h rename to liblegacytaskmanager/taskgroup.h index 432d20c16..54ccc2296 100644 --- a/libtaskmanager/taskgroup.h +++ b/liblegacytaskmanager/taskgroup.h @@ -1,162 +1,162 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***************************************************************************/ #ifndef TASKGROUP_H #define TASKGROUP_H #include #include "abstractgroupableitem.h" -#include "taskmanager_export.h" +#include "legacytaskmanager_export.h" #include "launcheritem.h" -namespace TaskManager +namespace LegacyTaskManager { class GroupManager; /** * TaskGroup, a container for tasks and subgroups */ -class TASKMANAGER_EXPORT TaskGroup : public AbstractGroupableItem +class LEGACYTASKMANAGER_EXPORT TaskGroup : public AbstractGroupableItem { Q_OBJECT public: TaskGroup(GroupManager *parent, const QString& name); TaskGroup(GroupManager *parent); ~TaskGroup() override; GroupManager *manager() const; ItemList members() const; WindowList winIds() const override; WindowList directMemberwinIds() const; AbstractGroupableItem *getMemberByWId(WId id); AbstractGroupableItem *getMemberById(int id); //including subgroups int totalSize(); QIcon icon() const override; void setIcon(const QIcon &icon); QString name() const override; void setName(const QString &newName); ItemType itemType() const override; /** * @deprecated: use itemType() instead **/ - TASKMANAGER_DEPRECATED bool isGroupItem() const override; + LEGACYTASKMANAGER_DEPRECATED bool isGroupItem() const override; bool isRootGroup() const; /** only true if item is in this group */ bool hasDirectMember(AbstractGroupableItem * item) const; /** only true if item is in this or any sub group */ bool hasMember(AbstractGroupableItem * item) const; /** Returns Direct Member group if the passed item is in a subgroup */ AbstractGroupableItem * directMember(AbstractGroupableItem *) const; int desktop() const override; bool isShaded() const override; bool isMaximized() const override; bool isMinimized() const override; bool isFullScreen() const override; bool isKeptBelowOthers() const override; bool isAlwaysOnTop() const override; bool isActionSupported(NET::Action) const override; /** returns true if at least one member is active */ bool isActive() const override; /** returns true if at least one member is demands attention */ bool demandsAttention() const override; bool isOnAllDesktops() const override; bool isOnCurrentDesktop() const override; void addMimeData(QMimeData *mimeData) const override; QUrl launcherUrl() const override; /** * Sorting strategies may use this to move items around * @param oldIndex the index the item to be moved is currently at * @param newIndex the index the item will be moved to */ bool moveItem(int oldIndex, int newIndex); public Q_SLOTS: /** the following are functions which perform the corresponding actions on all member tasks */ void toDesktop(int) override; void setShaded(bool) override; void toggleShaded() override; void setMaximized(bool) override; void toggleMaximized() override; void setMinimized(bool) override; void toggleMinimized() override; void setFullScreen(bool) override; void toggleFullScreen() override; void setKeptBelowOthers(bool) override; void toggleKeptBelowOthers() override; void setAlwaysOnTop(bool) override; void toggleAlwaysOnTop() override; /** close all members of this group */ void close() override; /** add item to group */ void add(AbstractGroupableItem *item, int insertIndex = -1); /** remove item from group */ void remove(AbstractGroupableItem *); /** remove all items from group */ void clear(); Q_SIGNALS: /** inform visualization about wat is added and removed */ void itemAboutToBeAdded(AbstractGroupableItem *item, int index); void itemAdded(AbstractGroupableItem *item); void itemAboutToBeRemoved(AbstractGroupableItem *item); void itemRemoved(AbstractGroupableItem *item); void groupEditRequest(); /** inform visualization about position change */ void itemAboutToMove(AbstractGroupableItem *item, int currentIndex, int newIndex); void itemPositionChanged(AbstractGroupableItem *item); /** The group changed the desktop, is emitted in the toDesktop function */ void movedToDesktop(int newDesk); void checkIcon(TaskGroup *group); private: Q_PRIVATE_SLOT(d, void itemDestroyed(AbstractGroupableItem *item)) - Q_PRIVATE_SLOT(d, void itemChanged(::TaskManager::TaskChanges changes)) + Q_PRIVATE_SLOT(d, void itemChanged(::LegacyTaskManager::TaskChanges changes)) Q_PRIVATE_SLOT(d, void signalRemovals()) class Private; Private * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/taskitem.cpp b/liblegacytaskmanager/taskitem.cpp similarity index 96% rename from libtaskmanager/taskitem.cpp rename to liblegacytaskmanager/taskitem.cpp index 434145475..43d9b250c 100644 --- a/libtaskmanager/taskitem.cpp +++ b/liblegacytaskmanager/taskitem.cpp @@ -1,856 +1,856 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Copyright (C) 2011 Craig Drummond Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ // Own #include "taskitem.h" #include "launcheritem.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "groupmanager.h" -namespace TaskManager +namespace LegacyTaskManager { class TaskItemPrivate { public: TaskItemPrivate(TaskItem *item) : q(item), launcherUrlLookupDone(false), isMenuBackedLauncher(false) { } - void filterChange(::TaskManager::TaskChanges change); + void filterChange(::LegacyTaskManager::TaskChanges change); TaskItem *q; QPointer task; QPointer startupTask; QUrl launcherUrl; QIcon launcherIcon; bool launcherUrlLookupDone; bool isMenuBackedLauncher; QString taskName; }; -void TaskItemPrivate::filterChange(::TaskManager::TaskChanges change) +void TaskItemPrivate::filterChange(::LegacyTaskManager::TaskChanges change) { - if (!isMenuBackedLauncher || change != ::TaskManager::TaskChange::IconChanged) { + if (!isMenuBackedLauncher || change != ::LegacyTaskManager::TaskChange::IconChanged) { emit q->changed(change); } } TaskItem::TaskItem(QObject *parent, Task *task) : AbstractGroupableItem(parent), d(new TaskItemPrivate(this)) { setTaskPointer(task); } TaskItem::TaskItem(QObject *parent, Startup *task) : AbstractGroupableItem(parent), d(new TaskItemPrivate(this)) { d->startupTask = task; - connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(filterChange(::TaskManager::TaskChanges))); + connect(task, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), this, SLOT(filterChange(::LegacyTaskManager::TaskChanges))); connect(task, &QObject::destroyed, this, &TaskItem::taskDestroyed); //this item isn't useful anymore if the Task was closed } TaskItem::~TaskItem() { emit destroyed(this); //qDebug(); /* if (parentGroup()) { parentGroup()->remove(this); }*/ delete d; } void TaskItem::taskDestroyed() { d->startupTask.clear(); d->task.clear(); // FIXME: due to a bug in Qt 4.x, the event loop reference count is incorrect // when going through x11EventFilter .. :/ so we have to singleShot the deleteLater QTimer::singleShot(0, this, &QObject::deleteLater); } void TaskItem::setTaskPointer(Task *task) { const bool differentTask = d->task != task; if (d->startupTask) { disconnect(d->startupTask.data(), 0, this, 0); d->startupTask.clear(); } else if (differentTask) { // if we aren't moving from startup -> task and the task pointer is changing on us // let's clear the launcher url d->launcherUrl.clear(); } resetLauncherCheck(); if (differentTask) { if (d->task) { disconnect(d->task.data(), 0, this, 0); } d->task = task; if (task) { - connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), this, SLOT(filterChange(::TaskManager::TaskChanges))); + connect(task, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), this, SLOT(filterChange(::LegacyTaskManager::TaskChanges))); connect(task, &QObject::destroyed, this, &TaskItem::taskDestroyed); emit gotTaskPointer(); } } if (!d->task) { // FIXME: due to a bug in Qt 4.x, the event loop reference count is incorrect // when going through x11EventFilter .. :/ so we have to singleShot the deleteLater QTimer::singleShot(0, this, &QObject::deleteLater); } } Task *TaskItem::task() const { return d->task.data(); } Startup *TaskItem::startup() const { /* if (d->startupTask.isNull()) { qDebug() << "pointer is Null"; } */ return d->startupTask.data(); } bool TaskItem::isStartupItem() const { return d->startupTask; } WindowList TaskItem::winIds() const { if (!d->task) { qDebug() << "no winId: probably startup task"; return WindowList(); } WindowList list; list << d->task.data()->window(); return list; } QIcon TaskItem::icon() const { if (d->task) { if (d->launcherIcon.isNull()) { d->launcherIcon = launcherIconFromUrl(launcherUrl()); } if (d->isMenuBackedLauncher && !d->launcherIcon.isNull()) { return d->launcherIcon; } else { return d->task.data()->icon(); } } if (d->startupTask) { return d->startupTask.data()->icon(); } return QIcon(); } QString TaskItem::name() const { if (d->task) { return d->task.data()->visibleName(); } if (d->startupTask) { return d->startupTask.data()->text(); } return QString(); } QString TaskItem::taskName() const { if (d->taskName.isEmpty()) { QUrl lUrl = launcherUrl(); if (!lUrl.isEmpty() && lUrl.isLocalFile() && KDesktopFile::isDesktopFile(lUrl.toLocalFile())) { KDesktopFile f(lUrl.toLocalFile()); if (f.tryExec()) { d->taskName = f.readName(); } } if (d->taskName.isEmpty() && d->task) { d->taskName = d->task.data()->classClass().toLower(); } } return d->taskName; } QStringList TaskItem::activities() const { if (!task()) { return QStringList(); } return task()->activities(); } QStringList TaskItem::activityNames(bool includeCurrent) const { if (!task()) { return QStringList(); } QStringList names; QStringList activities = task()->activities(); if (!includeCurrent) { - activities.removeOne(TaskManager::self()->currentActivity()); + activities.removeOne(LegacyTaskManager::self()->currentActivity()); } Q_FOREACH(QString activity, activities) { KActivities::Info info(activity); if (info.state() != KActivities::Info::Invalid) { names << info.name(); } } return names; } ItemType TaskItem::itemType() const { return TaskItemType; } bool TaskItem::isGroupItem() const { return false; } void TaskItem::setShaded(bool state) { if (!d->task) { return; } d->task.data()->setShaded(state); } void TaskItem::toggleShaded() { if (!d->task) { return; } d->task.data()->toggleShaded(); } bool TaskItem::isShaded() const { if (!d->task) { return false; } return d->task.data()->isShaded(); } void TaskItem::toDesktop(int desk) { if (!d->task) { return; } d->task.data()->toDesktop(desk); } bool TaskItem::isOnCurrentDesktop() const { return d->task && d->task.data()->isOnCurrentDesktop(); } bool TaskItem::isOnAllDesktops() const { return d->task && d->task.data()->isOnAllDesktops(); } int TaskItem::desktop() const { if (!d->task) { return 0; } return d->task.data()->desktop(); } void TaskItem::setMaximized(bool state) { if (!d->task) { return; } d->task.data()->setMaximized(state); } void TaskItem::toggleMaximized() { if (!d->task) { return; } d->task.data()->toggleMaximized(); } bool TaskItem::isMaximized() const { return d->task && d->task.data()->isMaximized(); } void TaskItem::setMinimized(bool state) { if (!d->task) { return; } d->task.data()->setIconified(state); } void TaskItem::toggleMinimized() { if (!d->task) { return; } d->task.data()->toggleIconified(); } bool TaskItem::isMinimized() const { if (!d->task) { return false; } return d->task.data()->isMinimized(); } void TaskItem::setFullScreen(bool state) { if (!d->task) { return; } d->task.data()->setFullScreen(state); } void TaskItem::toggleFullScreen() { if (!d->task) { return; } d->task.data()->toggleFullScreen(); } bool TaskItem::isFullScreen() const { if (!d->task) { return false; } return d->task.data()->isFullScreen(); } void TaskItem::setKeptBelowOthers(bool state) { if (!d->task) { return; } d->task.data()->setKeptBelowOthers(state); } void TaskItem::toggleKeptBelowOthers() { if (!d->task) { return; } d->task.data()->toggleKeptBelowOthers(); } bool TaskItem::isKeptBelowOthers() const { if (!d->task) { return false; } return d->task.data()->isKeptBelowOthers(); } void TaskItem::setAlwaysOnTop(bool state) { if (!d->task) { return; } d->task.data()->setAlwaysOnTop(state); } void TaskItem::toggleAlwaysOnTop() { if (!d->task) { return; } d->task.data()->toggleAlwaysOnTop(); } bool TaskItem::isAlwaysOnTop() const { if (!d->task) { return false; } return d->task.data()->isAlwaysOnTop(); } bool TaskItem::isActionSupported(NET::Action action) const { return d->task && d->task.data()->info().actionSupported(action); } void TaskItem::addMimeData(QMimeData *mimeData) const { if (!d->task) { return; } d->task.data()->addMimeData(mimeData); } void TaskItem::setLauncherUrl(const QUrl &url) { if (!d->launcherUrl.isEmpty()) { return; } d->launcherUrl = url; d->isMenuBackedLauncher = launcherUrlIsKnown(d->launcherUrl); if (!d->isMenuBackedLauncher) { d->launcherIcon = launcherIconFromUrl(url); } d->taskName = QString(); // Cause name to be re-generated... - KConfig cfg(QStringLiteral("taskmanagerrulesrc")); + KConfig cfg(QStringLiteral("legacytaskmanagerrulesrc")); KConfigGroup grp(&cfg, "Mapping"); grp.writeEntry(d->task.data()->classClass() + "::" + d->task.data()->className(), url.url()); cfg.sync(); } void TaskItem::setLauncherUrl(const AbstractGroupableItem *item) { if (!d->launcherUrl.isEmpty() || !item) { return; } d->launcherUrl = item->launcherUrl(); d->isMenuBackedLauncher = launcherUrlIsKnown(d->launcherUrl); if (!d->isMenuBackedLauncher) { d->launcherIcon = launcherIconFromUrl(d->launcherUrl); } d->taskName = QString(); // Cause name to be re-generated... } static KService::List getServicesViaPid(int pid) { // Attempt to find using commandline... KService::List services; if (pid == 0) { return services; } KSysGuard::Processes procs; procs.updateOrAddProcess(pid); KSysGuard::Process *proc = procs.getProcess(pid); QString cmdline = proc ? proc->command().simplified() : QString(); // proc->command has a trailing space??? if (cmdline.isEmpty()) { return services; } const int firstSpace = cmdline.indexOf(' '); services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline)); if (services.empty()) { // Could not find with complete commandline, so strip out path part... int slash = cmdline.lastIndexOf('/', firstSpace); if (slash > 0) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline.mid(slash + 1))); } } if (services.empty() && firstSpace > 0) { // Could not find with arguments, so try without... cmdline = cmdline.left(firstSpace); services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline)); int slash = cmdline.lastIndexOf('/'); if (slash > 0) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline.mid(slash + 1))); } } if (services.empty() && proc && !QStandardPaths::findExecutable(cmdline).isEmpty()) { // cmdline now exists without arguments if there were any services << QExplicitlySharedDataPointer(new KService(proc->name(), cmdline, QString())); } return services; } static QUrl getServiceLauncherUrl(int pid, const QString &type, const QStringList &cmdRemovals = QStringList()) { if (pid == 0) { return QUrl(); } KSysGuard::Processes procs; procs.updateOrAddProcess(pid); KSysGuard::Process *proc = procs.getProcess(pid); QString cmdline = proc ? proc->command().simplified() : QString(); // proc->command has a trailing space??? if (cmdline.isEmpty()) { return QUrl(); } foreach (const QString & r, cmdRemovals) { cmdline.replace(r, QLatin1String("")); } KService::List services = KServiceTypeTrader::self()->query(type, QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline)); if (services.empty()) { // Could not find with complete commandline, so strip out path part... int slash = cmdline.lastIndexOf('/', cmdline.indexOf(' ')); if (slash > 0) { services = KServiceTypeTrader::self()->query(type, QStringLiteral("exist Exec and ('%1' =~ Exec)").arg(cmdline.mid(slash + 1))); } if (services.empty()) { return QUrl(); } } QString path = services[0]->entryPath(); if (!QDir::isAbsolutePath(path)) { QString absolutePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/"+path); if (!absolutePath.isEmpty()) path = absolutePath; } if (QFile::exists(path)) { return QUrl::fromLocalFile(path); } return QUrl(); } QUrl TaskItem::launcherUrl() const { if (!d->task && !isStartupItem()) { return QUrl(); } if (!d->launcherUrl.isEmpty() || d->launcherUrlLookupDone) { return d->launcherUrl; } // Set a flag so that we remeber that we have already checked for a launcher. This is becasue if we fail, then // we will keep on failing so the isEmpty() check above is not enough. d->launcherUrlLookupDone = true; if (d->task || d->startupTask) { d->launcherUrl = launcherUrlFromTask(static_cast(parent()), d->task.data(), d->startupTask.data()); d->isMenuBackedLauncher = launcherUrlIsKnown(d->launcherUrl); } return d->launcherUrl; } QUrl TaskItem::launcherUrlFromTask(GroupManager *groupManager, Task *task, Startup *startup) { QUrl launcherUrl; // Search for applications which are executable and case-insensitively match the windowclass of the task and // See http://techbase.kde.org/Development/Tutorials/Services/Traders#The_KTrader_Query_Language KService::List services; bool triedPid = false; if (task && !(task->classClass().isEmpty() && task->className().isEmpty())) { // For KCModules, if we matched on window class, etc, we would end up matching to kcmshell4 - but we are more than likely // interested in the actual control module. Therefore we obtain this via the commandline. This commandline may contain // "kdeinit4:" or "[kdeinit]", so we remove these first. if ("Kcmshell4" == task->classClass()) { launcherUrl = getServiceLauncherUrl(task->pid(), QStringLiteral("KCModule"), QStringList() << QStringLiteral("kdeinit4:") << QStringLiteral("[kdeinit]")); if (!launcherUrl.isEmpty()) { return launcherUrl; } } // Check to see if this wmClass matched a saved one... - KConfig cfg(QStringLiteral("taskmanagerrulesrc")); + KConfig cfg(QStringLiteral("legacytaskmanagerrulesrc")); KConfigGroup grp(&cfg, "Mapping"); KConfigGroup set(&cfg, "Settings"); // Some apps have different launchers depending upon commandline... QStringList matchCommandLineFirst = set.readEntry("MatchCommandLineFirst", QStringList()); if (!task->classClass().isEmpty() && matchCommandLineFirst.contains(task->classClass())) { triedPid = true; services = getServicesViaPid(task->pid()); } // Try to match using className also if (!task->className().isEmpty() && matchCommandLineFirst.contains("::"+task->className())) { triedPid = true; services = getServicesViaPid(task->pid()); } // If the user has manualy set a mapping, respect this first... QString mapped(grp.readEntry(task->classClass() + "::" + task->className(), QString())); if (mapped.endsWith(QLatin1String(".desktop"))) { launcherUrl = mapped; return launcherUrl; } if (!task->classClass().isEmpty()) { if (mapped.isEmpty()) { mapped = grp.readEntry(task->classClass(), QString()); if (mapped.endsWith(QLatin1String(".desktop"))) { launcherUrl = mapped; return launcherUrl; } } // Some apps, such as Wine, cannot use className to map to launcher name - as Wine itself is not a GUI app // So, Settings/ManualOnly lists window classes where the user will always have to manualy set the launcher... QStringList manualOnly = set.readEntry("ManualOnly", QStringList()); if (!task->classClass().isEmpty() && manualOnly.contains(task->classClass())) { return launcherUrl; } if (!mapped.isEmpty()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ DesktopEntryName)").arg(mapped)); } if (!mapped.isEmpty() && services.empty()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Name)").arg(mapped)); } if (services.empty() && groupManager) { QUrl savedUrl = groupManager->launcherForWmClass(task->classClass()); if (savedUrl.isValid()) { launcherUrl = savedUrl; return launcherUrl; } } // To match other docks (docky, unity, etc.) attempt to match on DesktopEntryName first... if (services.empty()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ DesktopEntryName)").arg(task->classClass())); } // Try StartupWMClass if (services.empty()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ StartupWMClass)").arg(task->classClass())); } // Try 'Name' - unfortunately this can be translated, so has a good chance of failing! (As it does for KDE's own "System Settings" (even in English!!)) if (services.empty()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Name)").arg(task->classClass())); } } // Ok, absolute *last* chance, try matching via pid (but only if we have not already tried this!)... if (services.empty() && !triedPid) { services = getServicesViaPid(task->pid()); } // Try to improve on a possible from-binary fallback. // If no services were found or we got a fake-service back from getServicesViaPid() // we attempt to improve on this by adding a loosely matched reverse-domain-name // DesktopEntryName. Namely anything that is '*.classClass.desktop' would qualify here. // // Illustrative example of a case where the above heuristics would fail to produce // a reasonable result: // - org.kde.dragonplayer.desktop // - binary is 'dragon' // - qapp appname and thus classClass is 'dragonplayer' // - classClass cannot directly match the desktop file because of RDN // - classClass also cannot match the binary because of name mismatch // - in the following code *.classClass can match org.kde.dragonplayer though if (task && (services.empty() || services.at(0)->desktopEntryName().isEmpty())) { auto matchingServices = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' ~~ DesktopEntryName)").arg(task->classClass())); QMutableListIterator it(matchingServices); while (it.hasNext()) { auto service = it.next(); if (!service->desktopEntryName().endsWith("." + task->classClass())) { it.remove(); } } // Exactly one match is expected, otherwise we discard the results as to reduce // the likelihood of false-positive mappings. Since we essentially eliminate the // uniqueness that RDN is meant to bring to the table we could potentially end // up with more than one match here. if (matchingServices.length() == 1) { services = matchingServices; } } } if (services.empty() && startup) { // Try to match via desktop filename... if (!startup->desktopId().isNull() && startup->desktopId().endsWith(QLatin1String(".desktop"))) { if (startup->desktopId().startsWith(QLatin1String("/"))) { launcherUrl = QUrl::fromLocalFile(startup->desktopId()); return launcherUrl; } else { QString desktopName = startup->desktopId(); if (desktopName.endsWith(QLatin1String(".desktop"))) { desktopName = desktopName.mid(desktopName.length() - 8); } services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ DesktopEntryName)").arg(desktopName)); } } // Try StartupWMClass if (services.empty() && !startup->wmClass().isNull()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ StartupWMClass)").arg(startup->wmClass())); } // Try via name... if (services.empty() && !startup->text().isNull()) { services = KServiceTypeTrader::self()->query(QStringLiteral("Application"), QStringLiteral("exist Exec and ('%1' =~ Name)").arg(startup->text())); } } if (!services.empty()) { QString path = services[0]->entryPath(); if (path.isEmpty()) { path = services[0]->exec(); } if (!path.isEmpty()) { launcherUrl = QUrl::fromLocalFile(path); } } return launcherUrl; } bool TaskItem::launcherUrlIsKnown(const QUrl &url) { return KService::serviceByStorageId(url.toString()); } QIcon TaskItem::launcherIconFromUrl(const QUrl &url) { if (url.isEmpty()) { return QIcon(); } if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) { KDesktopFile f(url.toLocalFile()); if (f.tryExec()) { return QIcon::fromTheme(f.readIcon()); } } else if (url.scheme() == QLatin1String("preferred")) { //NOTE: preferred is NOT a protocol, it's just a magic string const KService::Ptr service = KService::serviceByStorageId(LauncherItem::defaultApplication(url)); if (service) { QString desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, service->entryPath()); KDesktopFile f(desktopFile); return QIcon::fromTheme(f.readIcon()); } } else { const KFileItem fileItem(url); return QIcon::fromTheme(fileItem.iconName()); } return QIcon(); } void TaskItem::resetLauncherCheck() { if (d->launcherUrl.isEmpty()) { d->launcherUrlLookupDone = false; } } void TaskItem::close() { if (!d->task) { return; } d->task.data()->close(); } bool TaskItem::isActive() const { if (!d->task) { return false; } return d->task.data()->isActive(); } bool TaskItem::demandsAttention() const { if (!d->task) { return false; } return d->task.data()->demandsAttention(); } -} // TaskManager namespace +} // LegacyTaskManager namespace #include "moc_taskitem.cpp" diff --git a/libtaskmanager/taskitem.h b/liblegacytaskmanager/taskitem.h similarity index 92% rename from libtaskmanager/taskitem.h rename to liblegacytaskmanager/taskitem.h index db4f36f74..7bee5956b 100644 --- a/libtaskmanager/taskitem.h +++ b/liblegacytaskmanager/taskitem.h @@ -1,133 +1,133 @@ /***************************************************************** Copyright 2008 Christian Mollekopf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #ifndef TASKITEM_H #define TASKITEM_H #include #include #include -#include +#include #include -namespace TaskManager +namespace LegacyTaskManager { class GroupManager; class TaskItemPrivate; /** * Wrapper class so we do not have to use the Task class directly and the Task* remains guarded */ -class TASKMANAGER_EXPORT TaskItem : public AbstractGroupableItem +class LEGACYTASKMANAGER_EXPORT TaskItem : public AbstractGroupableItem { Q_OBJECT public: /** Creates a taskitem for a task*/ TaskItem(QObject *parent, Task *item); /** Creates a taskitem for a startuptask*/ TaskItem(QObject *parent, Startup *item); ~TaskItem() override; /** Sets the taskpointer after the startup pointer */ void setTaskPointer(Task *task); /** Returns a pointer to the Task; may be NULL */ Task *task() const; WindowList winIds() const override; Startup *startup() const; ItemType itemType() const override; /** * @deprecated: use itemType() instead **/ - TASKMANAGER_DEPRECATED bool isGroupItem() const override; + LEGACYTASKMANAGER_DEPRECATED bool isGroupItem() const override; QIcon icon() const override; QString name() const override; QString taskName() const; QStringList activities() const; QStringList activityNames(bool includeCurrent = true) const; bool isStartupItem() const override; bool isOnCurrentDesktop() const override; bool isOnAllDesktops() const override; int desktop() const override; bool isShaded() const override; bool isMaximized() const override; bool isMinimized() const override; bool isFullScreen() const override; bool isKeptBelowOthers() const override; bool isAlwaysOnTop() const override; bool isActive() const override; bool demandsAttention() const override; bool isActionSupported(NET::Action) const override; void addMimeData(QMimeData *mimeData) const override; void setLauncherUrl(const QUrl &url); void setLauncherUrl(const AbstractGroupableItem *item); QUrl launcherUrl() const override; static QUrl launcherUrlFromTask(GroupManager *groupManager, Task *task, Startup *startup = 0); static bool launcherUrlIsKnown(const QUrl &url); static QIcon launcherIconFromUrl(const QUrl &url); void resetLauncherCheck(); public Q_SLOTS: void toDesktop(int) override; void setShaded(bool) override; void toggleShaded() override; void setMaximized(bool) override; void toggleMaximized() override; void setMinimized(bool) override; void toggleMinimized() override; void setFullScreen(bool) override; void toggleFullScreen() override; void setKeptBelowOthers(bool) override; void toggleKeptBelowOthers() override; void setAlwaysOnTop(bool) override; void toggleAlwaysOnTop() override; void close() override; void taskDestroyed(); Q_SIGNALS: /** Indicates that the startup task now is a normal task */ void gotTaskPointer(); private: - Q_PRIVATE_SLOT(d, void filterChange(::TaskManager::TaskChanges change)) + Q_PRIVATE_SLOT(d, void filterChange(::LegacyTaskManager::TaskChanges change)) friend class TaskItemPrivate; TaskItemPrivate * const d; }; -} // TaskManager namespace +} // LegacyTaskManager namespace #endif diff --git a/libtaskmanager/tasksmodel.cpp b/liblegacytaskmanager/tasksmodel.cpp similarity index 96% rename from libtaskmanager/tasksmodel.cpp rename to liblegacytaskmanager/tasksmodel.cpp index 32ebab17f..e30495a0f 100644 --- a/libtaskmanager/tasksmodel.cpp +++ b/liblegacytaskmanager/tasksmodel.cpp @@ -1,535 +1,535 @@ /***************************************************************** Copyright 2010 Aaron Seigo Copyright 2012-2013 Eike Hein Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *****************************************************************/ #include "tasksmodel.h" #include #include #include #include "groupmanager.h" #include "taskgroup.h" -namespace TaskManager +namespace LegacyTaskManager { class TasksModelPrivate { public: TasksModelPrivate(TasksModel *model, GroupManager *gm); void populateModel(); void populate(const QModelIndex &parent, TaskGroup *group); void itemAboutToBeAdded(AbstractGroupableItem *item, int index); void itemAdded(AbstractGroupableItem *item); void itemAboutToBeRemoved(AbstractGroupableItem *item); void itemRemoved(AbstractGroupableItem *item); void itemAboutToMove(AbstractGroupableItem *item, int currentIndex, int newIndex); void itemMoved(AbstractGroupableItem *item); - void itemChanged(::TaskManager::TaskChanges changes); + void itemChanged(::LegacyTaskManager::TaskChanges changes); int indexOf(AbstractGroupableItem *item); TasksModel *q; QPointer groupManager; TaskGroup *rootGroup; }; TasksModel::TasksModel(GroupManager *groupManager, QObject *parent) : QAbstractItemModel(parent), d(new TasksModelPrivate(this, groupManager)) { if (groupManager) { connect(groupManager, SIGNAL(reload()), this, SLOT(populateModel())); } connect(this, &TasksModel::rowsInserted, this, &TasksModel::countChanged); connect(this, &TasksModel::rowsRemoved, this, &TasksModel::countChanged); } TasksModel::~TasksModel() { delete d; } QHash TasksModel::roleNames() const { // set the role names based on the values of the DisplayRoles enum for the sake of QML static QHash roles; if (roles.isEmpty()) { roles = { { Qt::DisplayRole, "DisplayRole" }, { Qt::DecorationRole, "DecorationRole" } }; QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("DisplayRoles")); for (int i = 0; i < e.keyCount(); ++i) { roles.insert(e.value(i), e.key(i)); } } return roles; } QVariant TasksModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } AbstractGroupableItem *item = static_cast(index.internalPointer()); if (!item) { return QVariant(); } if (role == Qt::DisplayRole) { return item->name(); } else if (role == Qt::DecorationRole) { return item->icon(); } else if (role == TasksModel::Id) { return item->id(); } else if (role == TasksModel::GenericName) { return item->genericName(); } else if (role == TasksModel::IsStartup) { return item->isStartupItem(); } else if (role == TasksModel::IsLauncher) { return item->itemType() == LauncherItemType; } else if (role == TasksModel::OnAllDesktops) { return item->isOnAllDesktops(); } else if (role == TasksModel::Desktop) { return item->desktop(); } else if (role == TasksModel::DesktopName) { return KWindowSystem::desktopName(item->desktop()); } else if (role == TasksModel::OnAllActivities) { // FIXME: 2ac45a07d6 should have put isOnAllActivities() & co // into AbstractGroupableItem to avoid this scaffolding; make // that happen. if (item->itemType() == TaskItemType) { TaskItem *taskItem = static_cast(item); if (taskItem->task()) { return taskItem->task()->isOnAllActivities(); } } return false; } else if (role == TasksModel::ActivityNames) { QVariantList activities; if (item->itemType() == TaskItemType) { foreach(const QString &activity, static_cast(item)->activityNames()) { activities << activity; } } return activities; } else if (role == TasksModel::OtherActivityNames) { QVariantList activities; if (item->itemType() == TaskItemType) { foreach(const QString &activity, static_cast(item)->activityNames(false)) { activities << activity; } } return activities; } else if (role == TasksModel::Shaded) { return item->isShaded(); } else if (role == TasksModel::Maximized) { return item->isMaximized(); } else if (role == TasksModel::Minimized) { return item->isMinimized(); } else if (role == TasksModel::FullScreen) { return item->isFullScreen(); } else if (role == TasksModel::BelowOthers) { return item->isKeptBelowOthers(); } else if (role == TasksModel::AlwaysOnTop) { return item->isAlwaysOnTop(); } else if (role == TasksModel::Active) { return item->isActive(); } else if (role == TasksModel::DemandsAttention) { return item->demandsAttention(); } else if (role == TasksModel::LauncherUrl) { return item->launcherUrl(); } else if (role == TasksModel::WindowList) { QVariantList windows; foreach(const qulonglong winId, item->winIds()) { windows << winId; } return windows; } else if (role == TasksModel::MimeType) { if (item->itemType() == TaskItemType) { return Task::mimetype(); } else if (item->itemType() == GroupItemType) { return Task::groupMimetype(); } } else if (role == TasksModel::MimeData) { QMimeData mimeData; item->addMimeData(&mimeData); if (item->itemType() == TaskItemType) { return QVariant::fromValue(mimeData.data(Task::mimetype())); } else if (item->itemType() == GroupItemType) { return QVariant::fromValue(mimeData.data(Task::groupMimetype())); } } return QVariant(); } int TasksModel::activeTaskId(TaskGroup *group) const { group = group ? group : d->rootGroup; int id = -1; foreach (AbstractGroupableItem *item, group->members()) { if (item->itemType() == TaskItemType) { TaskItem *taskItem = static_cast(item); if (taskItem && taskItem->task() && taskItem->task()->isActive()) { id = item->id(); break; } } else if (item->itemType() == GroupItemType) { id = activeTaskId(static_cast(item)); if (id > -1) { break; } } } return id; } QVariant TasksModel::taskIdList(const QModelIndex& parent, bool recursive) const { QVariantList taskIds; TaskGroup* parentGroup = d->rootGroup; AbstractGroupableItem *parentItem = static_cast(parent.internalPointer()); if (parent.isValid() && parentItem->itemType() == GroupItemType) { parentGroup = static_cast(parentItem); } foreach (AbstractGroupableItem *item, parentGroup->members()) { if (item->itemType() == TaskItemType) { taskIds << item->id(); } else if (recursive) { if (item->itemType() == GroupItemType) { foreach(AbstractGroupableItem *subItem, static_cast(item)->members()) { taskIds << subItem->id(); } } } } return taskIds; } QModelIndex TasksModel::index(int row, int column, const QModelIndex &parent) const { GroupManager *gm = d->groupManager.data(); if (!gm || row < 0 || column < 0 || column > 0) { return QModelIndex(); } //qDebug() << "asking for" << row << column; TaskGroup *group = 0; if (parent.isValid()) { AbstractGroupableItem *item = static_cast(parent.internalPointer()); if (item && item->itemType() == GroupItemType) { group = static_cast(item); } } else { group = gm->rootGroup(); } if (!group || row >= group->members().count()) { return QModelIndex(); } return createIndex(row, column, group->members().at(row)); } QModelIndex TasksModel::parent(const QModelIndex &idx) const { GroupManager *gm = d->groupManager.data(); if (!gm) { return QModelIndex(); } AbstractGroupableItem *item = static_cast(idx.internalPointer()); if (!item) { return QModelIndex(); } TaskGroup *group = item->parentGroup(); if (!group || group == gm->rootGroup() || !group->parentGroup()) { return QModelIndex(); } int row = 0; bool found = false; TaskGroup *grandparent = group->parentGroup(); while (row < grandparent->members().count()) { if (group == grandparent->members().at(row)) { found = true; break; } ++row; } if (!found) { return QModelIndex(); } return createIndex(row, idx.column(), group); } int TasksModel::columnCount(const QModelIndex &) const { return 1; } int TasksModel::rowCount(const QModelIndex &parent) const { if (!d->rootGroup) { return 0; } if (!parent.isValid()) { return d->rootGroup->members().count(); } AbstractGroupableItem *item = static_cast(parent.internalPointer()); if (item && item->itemType() == GroupItemType) { TaskGroup *group = static_cast(item); return group->members().count(); } return 0; } int TasksModel::launcherCount() const { if (!d->rootGroup) { return 0; } int launcherCount = 0; foreach (AbstractGroupableItem *item, d->rootGroup->members()) { if (item->itemType() == LauncherItemType) { ++launcherCount; } } return launcherCount; } TasksModelPrivate::TasksModelPrivate(TasksModel *model, GroupManager *gm) : q(model), groupManager(gm), rootGroup(0) { } void TasksModelPrivate::populateModel() { GroupManager *gm = groupManager.data(); if (!gm) { rootGroup = 0; return; } if (rootGroup != gm->rootGroup()) { if (rootGroup) { QObject::disconnect(rootGroup, 0, q, 0); } rootGroup = gm->rootGroup(); } q->beginResetModel(); const QModelIndex idx; populate(idx, rootGroup); q->endResetModel(); } void TasksModelPrivate::populate(const QModelIndex &parent, TaskGroup *group) { QObject::connect(group, SIGNAL(itemAboutToBeAdded(AbstractGroupableItem*, int)), q, SLOT(itemAboutToBeAdded(AbstractGroupableItem*, int)), Qt::UniqueConnection); QObject::connect(group, SIGNAL(itemAdded(AbstractGroupableItem*)), q, SLOT(itemAdded(AbstractGroupableItem*)), Qt::UniqueConnection); QObject::connect(group, SIGNAL(itemAboutToBeRemoved(AbstractGroupableItem*)), q, SLOT(itemAboutToBeRemoved(AbstractGroupableItem*)), Qt::UniqueConnection); QObject::connect(group, SIGNAL(itemRemoved(AbstractGroupableItem*)), q, SLOT(itemRemoved(AbstractGroupableItem*)), Qt::UniqueConnection); QObject::connect(group, SIGNAL(itemAboutToMove(AbstractGroupableItem*, int, int)), q, SLOT(itemAboutToMove(AbstractGroupableItem*, int, int)), Qt::UniqueConnection); QObject::connect(group, SIGNAL(itemPositionChanged(AbstractGroupableItem*)), q, SLOT(itemMoved(AbstractGroupableItem*)), Qt::UniqueConnection); if (group->members().isEmpty()) { return; } typedef QPair idxGroupPair; QList childGroups; int i = 0; foreach (AbstractGroupableItem * item, group->members()) { if (item->itemType() == GroupItemType) { QModelIndex idx(q->index(i, 0, parent)); childGroups << idxGroupPair(idx, static_cast(item)); } - QObject::connect(item, SIGNAL(changed(::TaskManager::TaskChanges)), q, SLOT(itemChanged(::TaskManager::TaskChanges)), Qt::UniqueConnection); + QObject::connect(item, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), q, SLOT(itemChanged(::LegacyTaskManager::TaskChanges)), Qt::UniqueConnection); ++i; } foreach (const idxGroupPair & pair, childGroups) { populate(pair.first, pair.second); } } int TasksModelPrivate::indexOf(AbstractGroupableItem *item) { Q_ASSERT(item != rootGroup); int row = 0; if (!item->parentGroup()) return -1; foreach (const AbstractGroupableItem * child, item->parentGroup()->members()) { if (child == item) { break; } ++row; } return row; } void TasksModelPrivate::itemAboutToBeAdded(AbstractGroupableItem *item, int index) { TaskGroup *parent = item->parentGroup(); QModelIndex parentIdx; if (parent->parentGroup()) { parentIdx = q->createIndex(indexOf(parent), 0, parent); } - QObject::connect(item, SIGNAL(changed(::TaskManager::TaskChanges)), q, SLOT(itemChanged(::TaskManager::TaskChanges)), Qt::UniqueConnection); + QObject::connect(item, SIGNAL(changed(::LegacyTaskManager::TaskChanges)), q, SLOT(itemChanged(::LegacyTaskManager::TaskChanges)), Qt::UniqueConnection); q->beginInsertRows(parentIdx, index, index); if (item->parentGroup() == rootGroup) { QMetaObject::invokeMethod(q, "countChanged", Qt::QueuedConnection); } if (item->itemType() == LauncherItemType) { QMetaObject::invokeMethod(q, "launcherCountChanged", Qt::QueuedConnection); } } void TasksModelPrivate::itemAdded(AbstractGroupableItem *item) { Q_UNUSED(item); q->endInsertRows(); } void TasksModelPrivate::itemAboutToBeRemoved(AbstractGroupableItem *item) { TaskGroup *parent = static_cast(q->sender()); QModelIndex parentIdx; if (parent && parent->parentGroup()) { parentIdx = q->createIndex(indexOf(parent), 0, parent); } const int index = indexOf(item); q->beginRemoveRows(parentIdx, index, index); if (item->parentGroup() == rootGroup) { QMetaObject::invokeMethod(q, "countChanged", Qt::QueuedConnection); } if (item->itemType() == LauncherItemType) { QMetaObject::invokeMethod(q, "launcherCountChanged", Qt::QueuedConnection); } } void TasksModelPrivate::itemRemoved(AbstractGroupableItem *item) { Q_UNUSED(item); q->endRemoveRows(); } void TasksModelPrivate::itemAboutToMove(AbstractGroupableItem *item, int currentIndex, int newIndex) { QModelIndex parentIdx; TaskGroup *parent = item->parentGroup(); if (parent && parent->parentGroup()) { parentIdx = q->createIndex(indexOf(parent), 0, parent); } if (newIndex > currentIndex) { newIndex++; } q->beginMoveRows(parentIdx, currentIndex, currentIndex, parentIdx, newIndex); } void TasksModelPrivate::itemMoved(AbstractGroupableItem *item) { Q_UNUSED(item) q->endMoveRows(); } -void TasksModelPrivate::itemChanged(::TaskManager::TaskChanges changes) +void TasksModelPrivate::itemChanged(::LegacyTaskManager::TaskChanges changes) { Q_UNUSED(changes) AbstractGroupableItem *item = static_cast(q->sender()); const int index = indexOf(item); if (index == -1) { return; } const QModelIndex idx = q->createIndex(index, 0, item); emit q->dataChanged(idx, idx); } } #include "moc_tasksmodel.cpp" diff --git a/libtaskmanager/tasksmodel.h b/liblegacytaskmanager/tasksmodel.h similarity index 94% rename from libtaskmanager/tasksmodel.h rename to liblegacytaskmanager/tasksmodel.h index 581cf1e8c..c7957d6ff 100644 --- a/libtaskmanager/tasksmodel.h +++ b/liblegacytaskmanager/tasksmodel.h @@ -1,109 +1,109 @@ /***************************************************************** Copyright 2010 Aaron Seigo Copyright 2012-2013 Eike Hein Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *****************************************************************/ #ifndef TASKSMODEL_H #define TASKSMODEL_H #include -#include "taskmanager_export.h" +#include "legacytaskmanager_export.h" -namespace TaskManager +namespace LegacyTaskManager { class GroupManager; class TaskGroup; class TasksModelPrivate; -class TASKMANAGER_EXPORT TasksModel : public QAbstractItemModel +class LEGACYTASKMANAGER_EXPORT TasksModel : public QAbstractItemModel { Q_OBJECT Q_ENUMS(DisplayRoles) Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int launcherCount READ launcherCount NOTIFY launcherCountChanged) public: enum DisplayRoles { Id = Qt::UserRole + 1, GenericName = Qt::UserRole + 2, IsStartup = Qt::UserRole + 3, IsLauncher = Qt::UserRole + 4, OnAllDesktops = Qt::UserRole + 5, Desktop = Qt::UserRole + 6, DesktopName = Qt::UserRole + 7, OnAllActivities = Qt::UserRole + 8, ActivityNames = Qt::UserRole + 9, OtherActivityNames = Qt::UserRole + 10, Shaded = Qt::UserRole + 11, Maximized = Qt::UserRole + 12, Minimized = Qt::UserRole + 13, FullScreen = Qt::UserRole + 14, BelowOthers = Qt::UserRole + 15, AlwaysOnTop = Qt::UserRole + 16, Active = Qt::UserRole + 17, DemandsAttention = Qt::UserRole + 18, LauncherUrl = Qt::UserRole + 19, WindowList = Qt::UserRole + 20, MimeType = Qt::UserRole + 21, MimeData = Qt::UserRole + 22 }; explicit TasksModel(GroupManager *groupManager, QObject *parent = 0); ~TasksModel() override; QHash roleNames() const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &index) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_INVOKABLE int launcherCount() const; Q_INVOKABLE int activeTaskId(TaskGroup *group = 0) const; Q_INVOKABLE QVariant taskIdList(const QModelIndex &parent = QModelIndex(), bool recursive = true) const; Q_SIGNALS: void countChanged(); void launcherCountChanged(); private: friend class TasksModelPrivate; TasksModelPrivate * const d; Q_PRIVATE_SLOT(d, void populateModel()) Q_PRIVATE_SLOT(d, void itemAboutToBeAdded(AbstractGroupableItem *, int)) Q_PRIVATE_SLOT(d, void itemAdded(AbstractGroupableItem *)) Q_PRIVATE_SLOT(d, void itemAboutToBeRemoved(AbstractGroupableItem *)) Q_PRIVATE_SLOT(d, void itemRemoved(AbstractGroupableItem *)) Q_PRIVATE_SLOT(d, void itemAboutToMove(AbstractGroupableItem *, int, int)) Q_PRIVATE_SLOT(d, void itemMoved(AbstractGroupableItem *)) - Q_PRIVATE_SLOT(d, void itemChanged(::TaskManager::TaskChanges)) + Q_PRIVATE_SLOT(d, void itemChanged(::LegacyTaskManager::TaskChanges)) }; -} // namespace TaskManager +} // namespace LegacyTaskManager #endif diff --git a/libtaskmanager/LibTaskManagerConfig.cmake.in b/libtaskmanager/LibTaskManagerConfig.cmake.in deleted file mode 100644 index 9386edea5..000000000 --- a/libtaskmanager/LibTaskManagerConfig.cmake.in +++ /dev/null @@ -1,4 +0,0 @@ -@PACKAGE_INIT@ - -find_dependency(KF5SysGuard) -include("${CMAKE_CURRENT_LIST_DIR}/LibTaskManagerLibraryTargets.cmake")