diff --git a/applets/kicker/package/contents/ui/FullRepresentation.qml b/applets/kicker/package/contents/ui/FullRepresentation.qml index 75b84023f..a2e710d56 100644 --- a/applets/kicker/package/contents/ui/FullRepresentation.qml +++ b/applets/kicker/package/contents/ui/FullRepresentation.qml @@ -1,407 +1,399 @@ /*************************************************************************** * Copyright (C) 2013-2014 by Eike Hein * * * * 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 . * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents Item { id: root Layout.minimumWidth: sideBar.width + mainRow.spacing + Math.max(rootList.width, runnerColumns.width) Layout.maximumWidth: sideBar.width + mainRow.spacing + Math.max(rootList.width, runnerColumns.width) Layout.minimumHeight: (rootModel.count * rootList.itemHeight) + searchField.height + (2 * units.smallSpacing) Layout.maximumHeight: (rootModel.count * rootList.itemHeight) + searchField.height + (2 * units.smallSpacing) signal appendSearchText(string text) - property bool hideOnWindowDeactivate: true - function reset() { rootList.currentIndex = -1; searchField.text = ""; searchField.focus = true; } - Binding { - target: plasmoid - property: "hideOnWindowDeactivate" - value: hideOnWindowDeactivate - } - Row { id: mainRow height: parent.height spacing: units.smallSpacing LayoutMirroring.enabled: ((plasmoid.location == PlasmaCore.Types.RightEdge) || (Qt.application.layoutDirection == Qt.RightToLeft)) PlasmaCore.FrameSvgItem { id: sideBar width: units.iconSizes.medium + margins.left + margins.right height: parent.height imagePath: "widgets/frame" prefix: "plain" SideBarSection { id: favoriteApps anchors.top: parent.top anchors.topMargin: sideBar.margins.top height: (sideBar.height - sideBar.margins.top - sideBar.margins.bottom - favoriteSystemActions.height - sidebarSeparator.height - (4 * units.smallSpacing)) model: rootModel.favoritesModelForPrefix("app") states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteApps anchors.top: undefined anchors.bottom: parent.bottom } PropertyChanges { target: favoriteApps anchors.topMargin: undefined anchors.bottomMargin: sideBar.margins.bottom } }] } ShaderEffectSource { id: favoriteAppsWrapper anchors.fill: favoriteApps enabled: true visible: false live: enabled hideSource: enabled sourceItem: favoriteApps } LinearGradient { id: maskGradient enabled: favoriteAppsWrapper.enabled anchors.fill: favoriteApps visible: false property int cutoff: 5 start: Qt.point(0, Math.max(0, height - 10)) end: Qt.point(0, height) gradient: Gradient { GradientStop { position: 0.0; color: "#FF000000" } GradientStop { position: 1.0; color: "#00000000" } } } OpacityMask { anchors.fill: favoriteApps enabled: favoriteAppsWrapper.enabled visible: enabled source: favoriteAppsWrapper maskSource: maskGradient } PlasmaCore.SvgItem { id: sidebarSeparator anchors.bottom: favoriteSystemActions.top anchors.bottomMargin: (2 * units.smallSpacing) anchors.horizontalCenter: parent.horizontalCenter width: units.iconSizes.medium height: lineSvg.horLineHeight svg: lineSvg elementId: "horizontal-line" states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: sidebarSeparator anchors.top: favoriteSystemActions.bottom anchors.bottom: undefined } PropertyChanges { target: sidebarSeparator anchors.topMargin: (2 * units.smallSpacing) anchors.bottomMargin: undefined } }] } SideBarSection { id: favoriteSystemActions anchors.bottom: parent.bottom anchors.bottomMargin: sideBar.margins.bottom model: rootModel.favoritesModelForPrefix("sys") states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteSystemActions anchors.top: parent.top anchors.bottom: undefined } PropertyChanges { target: favoriteSystemActions anchors.topMargin: sideBar.margins.top anchors.bottomMargin: undefined } }] } } ItemListView { id: rootList anchors.top: parent.top height: (rootModel.count * rootList.itemHeight) visible: (searchField.text == "") iconsEnabled: false model: rootModel states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: rootList anchors.top: undefined anchors.bottom: parent.bottom } }] KeyNavigation.up: searchField KeyNavigation.down: searchField } Row { id: runnerColumns height: parent.height signal focusChanged() visible: (searchField.text != "" && runnerModel.count > 0) Repeater { id: runnerColumnsRepeater model: runnerModel delegate: RunnerResultsList { id: runnerMatches onFocusChanged: { if (focus) { runnerColumns.focusChanged(); } } function focusChanged() { if (!runnerMatches.focus && runnerMatches.currentIndex != -1) { runnerMatches.currentIndex = -1; } } Keys.onPressed: { var target = null; if (event.key == Qt.Key_Right) { if (index < (runnerColumnsRepeater.count - 1)) { target = runnerColumnsRepeater.itemAt(index + 1); } else { target = runnerColumnsRepeater.itemAt(0); } } else if (event.key == Qt.Key_Left) { if (index == 0) { target = runnerColumnsRepeater.itemAt(0); } else { target = runnerColumnsRepeater.itemAt(index - 1); } } if (target) { currentIndex = -1; target.currentIndex = 0; target.focus = true; } } Component.onCompleted: { runnerColumns.focusChanged.connect(focusChanged); } Component.onDestruction: { runnerColumns.focusChanged.disconnect(focusChanged); } KeyNavigation.up: (index == 0) ? searchField : null KeyNavigation.down: (index == 0) ? searchField : null } } } } PlasmaComponents.TextField { id: searchField anchors.bottom: mainRow.bottom anchors.left: parent.left anchors.leftMargin: sideBar.width + mainRow.spacing + units.smallSpacing width: rootList.width - (2 * units.smallSpacing) focus: true placeholderText: i18n("Search...") onTextChanged: { runnerModel.query = text; } onFocusChanged: { if (focus) { // FIXME: Cleanup arbitration between rootList/runnerCols here and in Keys. if (rootList.visible) { rootList.currentIndex = -1; } if (runnerColumns.visible) { runnerColumnsRepeater.itemAt(0).currentIndex = -1; } } } states: [ State { name: "top" when: plasmoid.location == PlasmaCore.Types.TopEdge AnchorChanges { target: searchField anchors.top: mainRow.top anchors.bottom: undefined anchors.left: parent.left anchors.right: undefined } PropertyChanges { target: searchField anchors.leftMargin: sideBar.width + mainRow.spacing + units.smallSpacing anchors.rightMargin: undefined } }, State { name: "right" when: plasmoid.location == PlasmaCore.Types.RightEdge AnchorChanges { target: searchField anchors.top: undefined anchors.bottom: mainRow.bottom anchors.left: undefined anchors.right: parent.right } PropertyChanges { target: searchField anchors.leftMargin: undefined anchors.rightMargin: sideBar.width + mainRow.spacing + units.smallSpacing } }] Keys.onPressed: { if (event.key == Qt.Key_Up) { if (rootList.visible) { rootList.currentIndex = rootList.model.count - 1; } if (runnerColumns.visible) { runnerColumnsRepeater.itemAt(0).currentIndex = runnerModel.modelForRow(0).count - 1; } } else if (event.key == Qt.Key_Down) { if (rootList.visible) { rootList.currentIndex = 0; } if (runnerColumns.visible) { runnerColumnsRepeater.itemAt(0).currentIndex = 0; } } } function appendText(newText) { focus = true; text = text + newText; } } Keys.onPressed: { if (event.key == Qt.Key_Escape) { plasmoid.expanded = false; } } Component.onCompleted: { appendSearchText.connect(searchField.appendText); kicker.reset.connect(reset); } } diff --git a/applets/kicker/package/contents/ui/ItemListDialog.qml b/applets/kicker/package/contents/ui/ItemListDialog.qml index 66f5fa262..f9d32ca95 100644 --- a/applets/kicker/package/contents/ui/ItemListDialog.qml +++ b/applets/kicker/package/contents/ui/ItemListDialog.qml @@ -1,74 +1,59 @@ /*************************************************************************** * Copyright (C) 2013-2014 by Eike Hein * * * * 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 . * ***************************************************************************/ import QtQuick 2.0 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.private.kicker 0.1 as Kicker Kicker.SubMenu { id: itemDialog property alias focusParent: itemListView.focusParent property alias model: itemListView.model visible: false + hideOnWindowDeactivate: plasmoid.hideOnWindowDeactivate location: PlasmaCore.Types.Floating + onWindowDeactivated: { + plasmoid.expanded = false; + } + mainItem: ItemListView { id: itemListView height: model != undefined ? Math.min((Math.floor((itemDialog.availableScreenRectForItem(itemListView).height - itemDialog.margins.top - itemDialog.margins.bottom) / itemHeight) * itemHeight), model.count * itemHeight) : 0 iconsEnabled: true dialog: itemDialog } - onFocusLost: { - var close = true; - - var target = focusParent; - - while (target) { - if (windowSystem.isActive(target)) { - close = false; - - break; - } - - target = target.focusParent; - } - - if (plasmoid.hideWindowOnDeactivate && close) { - plasmoid.expanded = false; - } - } - function delayedDestroy() { var timer = Qt.createQmlObject('import QtQuick 2.0; Timer { onTriggered: itemDialog.destroy() }', itemDialog); timer.interval = 0; timer.start(); } } diff --git a/applets/kicker/package/contents/ui/main.qml b/applets/kicker/package/contents/ui/main.qml index d685a361a..c8ffbd80b 100644 --- a/applets/kicker/package/contents/ui/main.qml +++ b/applets/kicker/package/contents/ui/main.qml @@ -1,186 +1,188 @@ /*************************************************************************** * Copyright (C) 2014 by Eike Hein * * * * 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 . * ***************************************************************************/ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.private.kicker 0.1 as Kicker Item { id: kicker anchors.fill: parent signal reset Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation Plasmoid.compactRepresentation: CompactRepresentation {} Plasmoid.fullRepresentation: FullRepresentation { id: fullRepr } property QtObject itemListDialogComponent: Qt.createComponent("ItemListDialog.qml"); property Item dragSource: null function action_menuedit() { processRunner.runMenuEditor(); } function updateSvgMetrics() { lineSvg.horLineHeight = lineSvg.elementSize("horizontal-line").height; lineSvg.vertLineWidth = lineSvg.elementSize("vertical-line").width; } Kicker.RootModel { id: rootModel appNameFormat: plasmoid.configuration.appNameFormat flat: plasmoid.configuration.limitDepth onRecentAppsModelChanged: { recentAppsModel.recentApps = plasmoid.configuration.recentApps; runnerModel.appLaunched.connect(recentAppsModel.addApp); } Component.onCompleted: { favoritesModelForPrefix("app").favorites = plasmoid.configuration.favoriteApps; favoritesModelForPrefix("sys").favorites = plasmoid.configuration.favoriteSystemActions; recentAppsModel.recentApps = plasmoid.configuration.recentApps; runnerModel.appLaunched.connect(recentAppsModel.addApp); } } Connections { target: plasmoid.configuration onFavoriteAppsChanged: { rootModel.favoritesModelForPrefix("app").favorites = plasmoid.configuration.favoriteApps; } onFavoriteSystemActionsChanged: { rootModel.favoritesModelForPrefix("sys").favorites = plasmoid.configuration.favoriteSystemActions; } onRecentAppsChanged: { rootModel.recentAppsModel.recentApps = plasmoid.configuration.recentApps; } } Connections { target: rootModel.favoritesModelForPrefix("app") onFavoritesChanged: { plasmoid.configuration.favoriteApps = target.favorites; } } Connections { target: rootModel.favoritesModelForPrefix("sys") onFavoritesChanged: { plasmoid.configuration.favoriteSystemActions = target.favorites; } } Connections { target: rootModel.recentAppsModel onRecentAppsChanged: { plasmoid.configuration.recentApps = target.recentApps; } } Kicker.RunnerModel { id: runnerModel runners: plasmoid.configuration.useExtraRunners ? new Array("services").concat(plasmoid.configuration.extraRunners) : "services" } Kicker.DragHelper { id: dragHelper } Kicker.ProcessRunner { id: processRunner; } Kicker.WindowSystem { id: windowSystem; } PlasmaCore.FrameSvgItem { id : highlightItemSvg visible: false imagePath: "widgets/viewitem" prefix: "hover" } PlasmaCore.Svg { id: arrows imagePath: "widgets/arrows" size: "16x16" } PlasmaCore.Svg { id: lineSvg imagePath: "widgets/line" property int horLineHeight property int vertLineWidth } Timer { id: justOpenedTimer repeat: false interval: 600 } Connections { target: plasmoid onExpandedChanged: { if (expanded) { justOpenedTimer.start(); } else { kicker.reset(); } } } function resetDragSource() { dragSource = null; } Component.onCompleted: { + plasmoid.hideOnWindowDeactivate = true; + plasmoid.setAction("menuedit", i18n("Edit Applications...")); updateSvgMetrics(); theme.themeChanged.connect(updateSvgMetrics); rootModel.refreshing.connect(reset); dragHelper.dropped.connect(resetDragSource); } } diff --git a/applets/kicker/plugin/submenu.cpp b/applets/kicker/plugin/submenu.cpp index 11e30f293..570614f4a 100644 --- a/applets/kicker/plugin/submenu.cpp +++ b/applets/kicker/plugin/submenu.cpp @@ -1,95 +1,82 @@ /*************************************************************************** * Copyright (C) 2014 by David Edmundson * * Copyright (C) 2014 by Eike Hein * * * * 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 "submenu.h" #include #include #include #include SubMenu::SubMenu(QQuickItem *parent) : PlasmaQuick::Dialog(parent) , m_facingLeft(false) { KWindowSystem::setType(winId(), NET::Menu); } SubMenu::~SubMenu() { } QPoint SubMenu::popupPosition(QQuickItem* item, const QSize& size) { QPointF pos = item->mapToScene(QPointF(0, 0)); pos = item->window()->mapToGlobal(pos.toPoint()); pos.setX(pos.x() + item->width()); QRect avail = availableScreenRectForItem(item); if (pos.x() + size.width() > avail.right()) { pos.setX(pos.x() - item->width() - size.width()); m_facingLeft = true; emit facingLeftChanged(); } pos.setY(pos.y() - margins()->property("top").toInt()); if (pos.y() + size.height() > avail.bottom()) { int overshoot = (avail.bottom() - (pos.y() + size.height())) * -1; pos.setY(pos.y() - overshoot - item->height() - 1 // FIXME HACK ... around off-by-one. + margins()->property("bottom").toInt() + margins()->property("top").toInt()); } return pos.toPoint(); } QRect SubMenu::availableScreenRectForItem(QQuickItem *item) const { QScreen *screen = QGuiApplication::primaryScreen(); const QPoint globalPosition = item->window()->mapToGlobal(item->position().toPoint()); foreach(QScreen *s, QGuiApplication::screens()) { if (s->geometry().contains(globalPosition)) { screen = s; } } return screen->availableGeometry(); } - - -void SubMenu::focusOutEvent(QFocusEvent *ev) -{ - const QWindow *focusWindow = QGuiApplication::focusWindow(); - - if (!(focusWindow && focusWindow->isActive() && isAncestorOf(focusWindow))) { - emit focusLost(); - } - - QQuickWindow::focusOutEvent(ev); -} - diff --git a/applets/kicker/plugin/submenu.h b/applets/kicker/plugin/submenu.h index 29212ec5f..600b8ce6b 100644 --- a/applets/kicker/plugin/submenu.h +++ b/applets/kicker/plugin/submenu.h @@ -1,55 +1,51 @@ /*************************************************************************** * Copyright (C) 2014 by David Edmundson * * Copyright (C) 2014 by Eike Hein * * * * 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 SUBMENU_H #define SUBMENU_H #include class QScreen; class SubMenu : public PlasmaQuick::Dialog { Q_OBJECT Q_PROPERTY(bool facingLeft READ facingLeft NOTIFY facingLeftChanged) public: SubMenu(QQuickItem *parent = 0); ~SubMenu(); Q_INVOKABLE QRect availableScreenRectForItem(QQuickItem *item) const; QPoint popupPosition(QQuickItem *item, const QSize &size); bool facingLeft() const { return m_facingLeft; } Q_SIGNALS: void facingLeftChanged() const; - void focusLost() const; - - protected: - void focusOutEvent(QFocusEvent *ev); private: bool m_facingLeft; }; #endif diff --git a/applets/taskmanager/plugin/backend.cpp b/applets/taskmanager/plugin/backend.cpp index 9845275a6..6f5c8d05e 100644 --- a/applets/taskmanager/plugin/backend.cpp +++ b/applets/taskmanager/plugin/backend.cpp @@ -1,285 +1,286 @@ /*************************************************************************** * Copyright (C) 2007 by Robert Knight * * Copyright (C) 2008 by Alexis Ménard * * Copyright (C) 2012-2013 by Eike Hein * * * * 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 "backend.h" #include #include #include #include #include #include #include #include //FIXME TODO HACK See comment in Backend::activateItem(). #include #include #include #include Backend::Backend(QObject* parent) : QObject(parent), m_groupManager(new TaskManager::GroupManager(this)), m_tasksModel(new TaskManager::TasksModel(m_groupManager, this)), + m_taskManagerItem(0), m_lastWindowId(0), m_highlightWindows(false) { connect(m_groupManager, SIGNAL(launcherListChanged()), this, SLOT(updateLaunchersCache())); } Backend::~Backend() { } TaskManager::GroupManager* Backend::groupManager() const { return m_groupManager; } TaskManager::TasksModel* Backend::tasksModel() const { return m_tasksModel; } QQuickItem* Backend::taskManagerItem() const { return m_taskManagerItem; } void Backend::setTaskManagerItem(QQuickItem* item) { if (item != m_taskManagerItem) { m_taskManagerItem = item; emit taskManagerItemChanged(item); } } bool Backend::anyTaskNeedsAttention() const { return groupManager()->rootGroup()->demandsAttention(); } bool Backend::highlightWindows() const { return m_highlightWindows; } void Backend::setHighlightWindows(bool highlight) { if (highlight != m_highlightWindows) { m_highlightWindows = highlight; emit highlightWindowsChanged(highlight); } } int Backend::groupingStrategy() const { return m_groupManager->groupingStrategy(); } void Backend::setGroupingStrategy(int groupingStrategy) { // FIXME TODO: This is fucking terrible. m_groupManager->setGroupingStrategy(static_cast(groupingStrategy)); } int Backend::sortingStrategy() const { return m_groupManager->sortingStrategy(); } void Backend::setSortingStrategy(int sortingStrategy) { // FIXME TODO: This is fucking terrible. m_groupManager->setSortingStrategy(static_cast(sortingStrategy)); } void Backend::updateLaunchersCache() { const QList launcherList = m_groupManager->launcherList(); QStringList launchers; foreach(const QUrl& launcher, launcherList) { launchers.append(launcher.toString()); } QString joined(launchers.join(',')); if (joined != m_launchers) { m_launchers = joined; emit launchersChanged(); } } QString Backend::launchers() const { return m_launchers; } void Backend::setLaunchers(const QString& launchers) { if (launchers == m_launchers) { return; } m_launchers = launchers; QList launcherList; foreach(const QString& launcher, launchers.split(',')) { launcherList.append(launcher); } disconnect(m_groupManager, SIGNAL(launcherListChanged()), this, SLOT(updateLaunchersCache())); m_groupManager->setLauncherList(launcherList); connect(m_groupManager, SIGNAL(launcherListChanged()), this, SLOT(updateLaunchersCache())); emit launchersChanged(); } void Backend::activateItem(int id, bool toggle) { TaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(id); if (!item) { return; } if (item->itemType() == TaskManager::TaskItemType && !item->isStartupItem()) { TaskManager::TaskItem* taskItem = static_cast(item); if (toggle) { taskItem->task()->activateRaiseOrIconify(); } else { taskItem->task()->activate(); } //FIXME TODO HACK This papers over XSendEvent() calls lacking an explicit flush in //KWindowSystem; not addressed there due to pending xcb port. XFlush(QX11Info::display()); } else if (item->itemType() == TaskManager::LauncherItemType) { static_cast(item)->launch(); } } void Backend::activateWindow(int winId) { KWindowSystem::forceActiveWindow(winId); } void Backend::itemContextMenu(QQuickItem *item, QObject *configAction) { TaskManager::AbstractGroupableItem* agItem = m_groupManager->rootGroup()->getMemberById(item->property("itemId").toInt()); if (!KAuthorized::authorizeKAction("kwin_rmb") || !item || !item->window() || !agItem) { return; } QList actionList; QAction *action = static_cast(configAction); if (action && action->isEnabled()) { actionList << action; } TaskManager::BasicMenu* menu = 0; if (agItem->itemType() == TaskManager::TaskItemType && !agItem->isStartupItem()) { TaskManager::TaskItem* taskItem = static_cast(agItem); menu = new TaskManager::BasicMenu(0, taskItem, m_groupManager, actionList); } else if (agItem->itemType() == TaskManager::GroupItemType) { TaskManager::TaskGroup* taskGroup = static_cast(agItem); const int maxWidth = 0.8 * item->window()->screen()->size().width(); menu = new TaskManager::BasicMenu(0, taskGroup, m_groupManager, actionList, QList (), maxWidth); } else if (agItem->itemType() == TaskManager::LauncherItemType) { menu = new TaskManager::BasicMenu(0, static_cast(agItem), m_groupManager, actionList); } if (!menu) { return; } menu->adjustSize(); if (!taskManagerItem()->property("vertical").toBool()) { menu->setMinimumWidth(item->width()); } menu->exec(QCursor::pos()); menu->deleteLater(); } void Backend::itemHovered(int id, bool hovered) { TaskManager::AbstractGroupableItem* item = m_groupManager->rootGroup()->getMemberById(id); if (!item) { return; } if (hovered && m_highlightWindows && m_taskManagerItem->window()) { m_lastWindowId = m_taskManagerItem->window()->winId(); KWindowEffects::highlightWindows(m_lastWindowId, QList::fromSet(item->winIds())); } else if (m_highlightWindows && m_lastWindowId) { KWindowEffects::highlightWindows(m_lastWindowId, QList()); } } void Backend::itemMove(int id, int newIndex) { m_groupManager->manualSortingRequest(m_groupManager->rootGroup()->getMemberById(id), newIndex); } void Backend::itemGeometryChanged(QQuickItem *item, int id) { TaskManager:: AbstractGroupableItem *agItem = m_groupManager->rootGroup()->getMemberById(id); if (!item || !item->window() || !agItem || agItem->itemType() != TaskManager::TaskItemType) { return; } TaskManager::TaskItem *taskItem = static_cast(agItem); if (!taskItem->task()) { return; } QRect iconRect(item->x(), item->y(), item->width(), item->height()); iconRect.moveTopLeft(item->parentItem()->mapToScene(iconRect.topLeft()).toPoint()); iconRect.moveTopLeft(item->window()->mapToGlobal(iconRect.topLeft())); taskItem->task()->publishIconGeometry(iconRect); } void Backend::presentWindows(int groupParentId) { TaskManager:: AbstractGroupableItem *item = m_groupManager->rootGroup()->getMemberById(groupParentId); if (item && m_taskManagerItem->window()) { KWindowEffects::presentWindows(m_taskManagerItem->window()->winId(), QList::fromSet(item->winIds())); } }