From 7bff89c5e015f3bdd3e1e8a825f62b817a2e6511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 19 Feb 2012 15:47:59 +0100 Subject: [PATCH] Introduce a desktop change OSD as a declarative script This QML based version of the desktop change OSD is intended to replace the C++ version of it. It currently supports all of the features except adjusting to config options, which is not yet available at all to scripts. --- scripts/CMakeLists.txt | 2 + scripts/desktopchangeosd/contents/ui/main.qml | 287 ++++++++++++++++++ scripts/desktopchangeosd/metadata.desktop | 17 ++ 3 files changed, 306 insertions(+) create mode 100644 scripts/desktopchangeosd/contents/ui/main.qml create mode 100644 scripts/desktopchangeosd/metadata.desktop diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index ccde1fc57b..2b1d360c70 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -1,7 +1,9 @@ # packages install( DIRECTORY videowall DESTINATION ${DATA_INSTALL_DIR}/kwin/scripts ) install( DIRECTORY synchronizeskipswitcher DESTINATION ${DATA_INSTALL_DIR}/kwin/scripts ) +install( DIRECTORY desktopchangeosd DESTINATION ${DATA_INSTALL_DIR}/kwin/scripts ) # service files install( FILES videowall/metadata.desktop DESTINATION ${SERVICES_INSTALL_DIR} RENAME kwin-script-videowall.desktop ) install( FILES synchronizeskipswitcher/metadata.desktop DESTINATION ${SERVICES_INSTALL_DIR} RENAME kwin-script-synchronizeskipswitcher.desktop ) +install( FILES desktopchangeosd/metadata.desktop DESTINATION ${SERVICES_INSTALL_DIR} RENAME kwin-script-desktopchangeosd.desktop ) diff --git a/scripts/desktopchangeosd/contents/ui/main.qml b/scripts/desktopchangeosd/contents/ui/main.qml new file mode 100644 index 0000000000..0a5aece52e --- /dev/null +++ b/scripts/desktopchangeosd/contents/ui/main.qml @@ -0,0 +1,287 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2012 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +import QtQuick 1.1; +import org.kde.plasma.core 0.1 as PlasmaCore; +import org.kde.plasma.components 0.1 as Plasma; +import org.kde.qtextracomponents 0.1 as QtExtra; +import org.kde.kwin 0.1; + +Item { + id: root + property int screenWidth: 0 + property int screenHeight: 0 + // we count desktops starting from 0 to have it better match the layout in the Grid + property int currentDesktop: 0 + property int previousDesktop: 0 + // TODO: read from config + property int animationDuration: 1000 + property bool showGrid: true + Component.onCompleted: { + var screen = workspace.clientArea(KWin.FullScreenArea, workspace.activeScreen, workspace.currentDesktop); + root.screenWidth = screen.width; + root.screenHeight = screen.height; + } + PlasmaCore.Dialog { + id: dialog + visible: false + windowFlags: Qt.X11BypassWindowManagerHint + + mainItem: Item { + id: dialogItem + width: childrenRect.width + height: childrenRect.height + Plasma.Label { + id: textElement + anchors.top: root.showGrid ? parent.top : undefined + anchors.horizontalCenter: parent.horizontalCenter + text: workspace.desktopName(workspace.currentDesktop) + } + Grid { + id: view + property int itemWidth: root.screenWidth * 0.1 + property int itemHeight: root.screenHeight * 0.1 + anchors.top: textElement.bottom + visible: root.showGrid + Repeater { + model: workspace.desktops + Item { + width: view.itemWidth + height: view.itemHeight + PlasmaCore.FrameSvgItem { + anchors.fill: parent + imagePath: "widgets/pager" + prefix: "normal" + } + PlasmaCore.FrameSvgItem { + id: activeElement + anchors.fill: parent + imagePath: "widgets/pager" + prefix: "active" + opacity: 0.0 + Behavior on opacity { + NumberAnimation { duration: root.animationDuration/2 } + } + } + Item { + id: arrowsContainer + anchors.fill: parent + QtExtra.QIconItem { + anchors.fill: parent + icon: "go-up" + visible: false + } + QtExtra.QIconItem { + anchors.fill: parent + icon: "go-down" + visible: { + if (root.currentDesktop <= index) { + // don't show for target desktop + return false; + } + if (index < root.previousDesktop) { + return false; + } + if (root.currentDesktop < root.previousDesktop) { + // we only go down if the new desktop is higher + return false; + } + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // don't show icons in same row as target desktop + return false; + } + if (root.previousDesktop % view.columns == index % view.columns) { + // show arrows for icons in same column as the previous desktop + return true; + } + return false; + } + } + QtExtra.QIconItem { + anchors.fill: parent + icon: "go-up" + visible: { + if (root.currentDesktop >= index) { + // don't show for target desktop + return false; + } + if (index > root.previousDesktop) { + return false; + } + if (root.currentDesktop > root.previousDesktop) { + // we only go down if the new desktop is higher + return false; + } + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // don't show icons in same row as target desktop + return false; + } + if (root.previousDesktop % view.columns == index % view.columns) { + // show arrows for icons in same column as the previous desktop + return true; + } + return false; + } + } + QtExtra.QIconItem { + anchors.fill: parent + icon: "go-next" + visible: { + if (root.currentDesktop <= index) { + // we don't show for desktops not on the path + return false; + } + if (index < root.previousDesktop) { + // we might have to show this icon in case we go up and to the right + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // can only happen in same row + if (index % view.columns >= root.previousDesktop % view.columns) { + // but only for items in the same column or after of the previous desktop + return true; + } + } + return false; + } + if (root.currentDesktop < root.previousDesktop) { + // we only go right if the new desktop is higher + return false; + } + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // show icons in same row as target desktop + if (index % view.columns < root.previousDesktop % view.columns) { + // but only for items in the same column or after of the previous desktop + return false; + } + return true; + } + return false; + } + } + QtExtra.QIconItem { + anchors.fill: parent + icon: "go-previous" + visible: { + if (root.currentDesktop >= index) { + // we don't show for desktops not on the path + return false; + } + if (index > root.previousDesktop) { + // we might have to show this icon in case we go down and to the left + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // can only happen in same row + if (index % view.columns <= root.previousDesktop % view.columns) { + // but only for items in the same column or before the previous desktop + return true; + } + } + return false; + } + if (root.currentDesktop > root.previousDesktop) { + // we only go left if the new desktop is lower + return false; + } + if (Math.floor(root.currentDesktop/view.columns) == Math.floor(index/view.columns)) { + // show icons in same row as target desktop + if (index % view.columns > root.previousDesktop % view.columns) { + // but only for items in the same column or before of the previous desktop + return false; + } + return true; + } + return false; + } + } + } + states: [ + State { + name: "NORMAL" + when: index != root.currentDesktop + PropertyChanges { + target: activeElement + opacity: 0.0 + } + }, + State { + name: "SELECTED" + when: index == root.currentDesktop + PropertyChanges { + target: activeElement + opacity: 1.0 + } + } + ] + Component.onCompleted: { + view.state = (index == root.currentDesktop) ? "SELECTED" : "NORMAL" + } + } + } + Component.onCompleted: { + columns = workspace.desktopGridWidth; + rows = workspace.desktopGridHeight; + if (!root.showGrid) { + width = 0; + height = 0; + } + } + } + } + } + + Timer { + id: timer + repeat: false + interval: root.animationDuration + onTriggered: dialog.visible = false + } + + Connections { + target: workspace + onCurrentDesktopChanged: { + if (root.currentDesktop == workspace.currentDesktop - 1) { + return; + } + root.previousDesktop = root.currentDesktop; + timer.stop(); + root.currentDesktop = workspace.currentDesktop - 1; + textElement.text = workspace.desktopName(workspace.currentDesktop); + // screen geometry might have changed + var screen = workspace.clientArea(KWin.FullScreenArea, workspace.activeScreen, workspace.currentDesktop); + root.screenWidth = screen.width; + root.screenHeight = screen.height; + if (root.showGrid) { + // non dependable properties might have changed + view.columns = workspace.desktopGridWidth; + view.rows = workspace.desktopGridHeight; + view.width = workspace.desktopGridWidth * view.itemWidth; + view.height = workspace.desktopGridHeight * view.itemHeight; + } else { + view.width = 0; + view.height = 0; + dialogItem.width = textElement.width; + dialogItem.height = textElement.height; + } + // position might have changed + dialog.x = screen.x + screen.width/2 - dialogItem.width/2; + dialog.y = screen.y + screen.height/2 - dialogItem.height/2; + // start the hide timer + timer.start(); + dialog.visible = true; + } + } +} diff --git a/scripts/desktopchangeosd/metadata.desktop b/scripts/desktopchangeosd/metadata.desktop new file mode 100644 index 0000000000..ff2578c58b --- /dev/null +++ b/scripts/desktopchangeosd/metadata.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Name=Desktop Change OSD +Comment=An on screen display indicating the desktop change +Icon=preferences-system-windows-script-test + +X-Plasma-API=declarativescript +X-Plasma-MainScript=ui/main.qml + +X-KDE-PluginInfo-Author=Martin Gräßlin +X-KDE-PluginInfo-Email=mgraesslin@kde.org +X-KDE-PluginInfo-Name=desktopchangeosd +X-KDE-PluginInfo-Version=1.0 + +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-ServiceTypes=KWin/Script +Type=Service