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.
This commit is contained in:
parent
3f1ef8bb8d
commit
7bff89c5e0
3 changed files with 306 additions and 0 deletions
|
@ -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 )
|
||||
|
|
287
scripts/desktopchangeosd/contents/ui/main.qml
Normal file
287
scripts/desktopchangeosd/contents/ui/main.qml
Normal file
|
@ -0,0 +1,287 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
17
scripts/desktopchangeosd/metadata.desktop
Normal file
17
scripts/desktopchangeosd/metadata.desktop
Normal file
|
@ -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
|
Loading…
Reference in a new issue