Initial release: Virtual Desktop Switcher for KDE Plasma
Features: - Real-time desktop name display in panel - Hover to open popup with desktop grid - Real window geometry using native PagerModel - Window icons in previews - Proper screen aspect ratio - Desktop management (add, rename, delete) - Scroll wheel navigation - High performance native implementation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
commit
d867b3591f
|
|
@ -0,0 +1,4 @@
|
|||
*.qmlc
|
||||
*.jsc
|
||||
.directory
|
||||
*~
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2025 Andres Garcia
|
||||
|
||||
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 3 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 <https://www.gnu.org/licenses/>.
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
# Virtual Desktop Switcher
|
||||
|
||||
A KDE Plasma 5 widget that displays the current virtual desktop name and provides a visual overview of all desktops with real window positions.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- **Real-time desktop name** in panel - Shows active virtual desktop name
|
||||
- **Hover to open** - Popup appears automatically when hovering (80ms delay)
|
||||
- **Real window geometry** - Windows displayed in actual positions using native KDE pager API
|
||||
- **Window icons** - Application icons shown inside window previews
|
||||
- **Proper aspect ratio** - Desktop previews match your screen proportions
|
||||
- **Grid layout** - Automatically arranges desktops in optimal columns/rows
|
||||
- **Desktop management**:
|
||||
- Click to switch desktop
|
||||
- Right-click to rename or delete
|
||||
- Add new desktops with "Add" button
|
||||
- Scroll wheel to cycle through desktops
|
||||
- **High performance** - Uses native `PagerModel` instead of shell commands
|
||||
|
||||
## Screenshots
|
||||
|
||||
The widget shows a grid of desktop previews with:
|
||||
- Window outlines in real positions
|
||||
- Application icons inside windows
|
||||
- Desktop number and name badge
|
||||
- Active desktop highlighted
|
||||
|
||||
## Installation
|
||||
|
||||
### Manual Installation
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/andresgarcia0313/plasma-virtual-desktop-switcher.git
|
||||
|
||||
# Copy to Plasma plasmoids directory
|
||||
cp -r plasma-virtual-desktop-switcher ~/.local/share/plasma/plasmoids/org.kde.virtualdesktopswitcher
|
||||
|
||||
# Restart Plasma
|
||||
kquitapp5 plasmashell && kstart5 plasmashell
|
||||
```
|
||||
|
||||
### Add to Panel
|
||||
|
||||
1. Right-click on your panel → **Add Widgets**
|
||||
2. Search for **"Virtual Desktop Switcher"**
|
||||
3. Drag to your panel
|
||||
|
||||
## Configuration
|
||||
|
||||
Right-click on the widget → **Configure Virtual Desktop Switcher**
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| Show window previews | Display window outlines inside desktop previews |
|
||||
| Show window icons | Display application icons on window rectangles |
|
||||
| Preview size | Adjust the size of preview area (40-150px) |
|
||||
|
||||
## Usage
|
||||
|
||||
| Action | Result |
|
||||
|--------|--------|
|
||||
| **Hover** | Opens desktop overview popup |
|
||||
| **Click** on desktop | Switches to that desktop |
|
||||
| **Right-click** on desktop | Context menu (Rename, Delete) |
|
||||
| **Scroll wheel** | Cycles through desktops |
|
||||
| **Add button** | Creates new virtual desktop |
|
||||
|
||||
## Requirements
|
||||
|
||||
- KDE Plasma 5.27 or later
|
||||
- KWin window manager
|
||||
- Qt 5.15+
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Architecture
|
||||
|
||||
The widget uses the native KDE pager plugin (`org.kde.plasma.private.pager`) which provides:
|
||||
|
||||
- `PagerModel` - Virtual desktop model with real-time updates
|
||||
- `TasksModel` - Window information including geometry
|
||||
- `pagerItemSize` - Screen dimensions for aspect ratio
|
||||
|
||||
### Key Files
|
||||
|
||||
```
|
||||
org.kde.virtualdesktopswitcher/
|
||||
├── metadata.desktop # Plugin metadata
|
||||
├── contents/
|
||||
│ ├── config/
|
||||
│ │ ├── main.xml # Configuration schema
|
||||
│ │ └── config.qml # Config page registration
|
||||
│ └── ui/
|
||||
│ ├── main.qml # Main widget code
|
||||
│ └── configGeneral.qml # Settings UI
|
||||
```
|
||||
|
||||
### QML Imports Used
|
||||
|
||||
```qml
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.plasma.private.pager 2.0 // Native pager API
|
||||
```
|
||||
|
||||
### Window Geometry Scaling
|
||||
|
||||
Windows are scaled from screen coordinates to preview size:
|
||||
|
||||
```qml
|
||||
readonly property real scaleX: deskW / pagerModel.pagerItemSize.width
|
||||
readonly property real scaleY: deskH / pagerModel.pagerItemSize.height
|
||||
|
||||
x: Math.round(model.Geometry.x * scaleX)
|
||||
y: Math.round(model.Geometry.y * scaleY)
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Testing Changes
|
||||
|
||||
```bash
|
||||
# Edit files in
|
||||
~/.local/share/plasma/plasmoids/org.kde.virtualdesktopswitcher/
|
||||
|
||||
# Restart Plasma to see changes
|
||||
kquitapp5 plasmashell && kstart5 plasmashell
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
```bash
|
||||
# View Plasma logs
|
||||
journalctl -f | grep -i plasma
|
||||
|
||||
# Check QML errors
|
||||
QT_LOGGING_RULES="qml.debug=true" plasmashell
|
||||
```
|
||||
|
||||
### KWin D-Bus API
|
||||
|
||||
```bash
|
||||
# List virtual desktops
|
||||
gdbus call --session --dest org.kde.KWin \
|
||||
--object-path /VirtualDesktopManager \
|
||||
--method org.freedesktop.DBus.Properties.Get \
|
||||
org.kde.KWin.VirtualDesktopManager desktops
|
||||
|
||||
# Get current desktop
|
||||
qdbus org.kde.KWin /VirtualDesktopManager current
|
||||
|
||||
# Rename desktop
|
||||
qdbus org.kde.KWin /VirtualDesktopManager setDesktopName '<id>' 'New Name'
|
||||
|
||||
# Create desktop
|
||||
qdbus org.kde.KWin /VirtualDesktopManager createDesktop <position> 'Name'
|
||||
|
||||
# Remove desktop
|
||||
qdbus org.kde.KWin /VirtualDesktopManager removeDesktop '<id>'
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Test thoroughly
|
||||
5. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GPL-3.0 License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## Credits
|
||||
|
||||
- Uses KDE Plasma's native pager plugin for window geometry
|
||||
- Inspired by the official KDE Pager widget
|
||||
|
||||
## Author
|
||||
|
||||
**Andres Garcia** - [GitHub](https://github.com/andresgarcia0313)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import QtQuick 2.15
|
||||
import org.kde.plasma.configuration 2.0
|
||||
|
||||
ConfigModel {
|
||||
ConfigCategory {
|
||||
name: i18n("General")
|
||||
icon: "preferences-desktop-virtual"
|
||||
source: "configGeneral.qml"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
|
||||
<kcfgfile name=""/>
|
||||
<group name="General">
|
||||
<entry name="showWindowPreviews" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="showWindowIcons" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="previewSize" type="Int">
|
||||
<default>80</default>
|
||||
<min>40</min>
|
||||
<max>150</max>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: page
|
||||
|
||||
property alias cfg_showWindowPreviews: showWindowPreviews.checked
|
||||
property alias cfg_showWindowIcons: showWindowIcons.checked
|
||||
property alias cfg_previewSize: previewSize.value
|
||||
|
||||
CheckBox {
|
||||
id: showWindowPreviews
|
||||
Kirigami.FormData.label: i18n("Window Previews:")
|
||||
text: i18n("Show window outlines in popup")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: showWindowIcons
|
||||
Kirigami.FormData.label: i18n("Window Icons:")
|
||||
text: i18n("Show application icons on windows")
|
||||
enabled: showWindowPreviews.checked
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: previewSize
|
||||
Kirigami.FormData.label: i18n("Preview Size:")
|
||||
from: 40
|
||||
to: 150
|
||||
stepSize: 10
|
||||
enabled: showWindowPreviews.checked
|
||||
|
||||
textFromValue: function(value) {
|
||||
return value + " px"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.plasma.private.pager 2.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// CONFIGURATION
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
readonly property bool showPreviews: plasmoid.configuration.showWindowPreviews
|
||||
readonly property bool showIcons: plasmoid.configuration.showWindowIcons
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// PAGER MODEL (native KDE plugin with real window geometry)
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
PagerModel {
|
||||
id: pagerModel
|
||||
enabled: root.visible
|
||||
showDesktop: false
|
||||
pagerType: PagerModel.VirtualDesktops
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// HELPER FUNCTIONS
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
function currentDesktopName() {
|
||||
if (pagerModel.count > 0 && pagerModel.currentPage >= 0) {
|
||||
var idx = pagerModel.index(pagerModel.currentPage, 0)
|
||||
var name = pagerModel.data(idx, Qt.DisplayRole)
|
||||
return name || ("Desktop " + (pagerModel.currentPage + 1))
|
||||
}
|
||||
return "Desktop"
|
||||
}
|
||||
|
||||
function addDesktop() { pagerModel.addDesktop() }
|
||||
function removeDesktop() { pagerModel.removeDesktop() }
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// HOVER TIMERS
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
property bool hoverCompact: false
|
||||
property bool hoverPopup: false
|
||||
Timer { id: openTimer; interval: 80; onTriggered: plasmoid.expanded = true }
|
||||
Timer { id: closeTimer; interval: 300; onTriggered: if (!hoverCompact && !hoverPopup) plasmoid.expanded = false }
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// COMPACT REPRESENTATION
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
Plasmoid.compactRepresentation: MouseArea {
|
||||
id: compactArea
|
||||
Layout.minimumWidth: compactLabel.implicitWidth + 16
|
||||
hoverEnabled: true
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: parent.containsMouse ? PlasmaCore.Theme.highlightColor : "transparent"
|
||||
opacity: 0.2; radius: 3
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: compactLabel
|
||||
anchors.centerIn: parent
|
||||
text: currentDesktopName()
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
onEntered: { hoverCompact = true; closeTimer.stop(); openTimer.start() }
|
||||
onExited: { hoverCompact = false; openTimer.stop(); if (!hoverPopup) closeTimer.start() }
|
||||
onClicked: { openTimer.stop(); closeTimer.stop(); plasmoid.expanded = !plasmoid.expanded }
|
||||
onWheel: {
|
||||
var next = wheel.angleDelta.y > 0
|
||||
? (pagerModel.currentPage - 1 + pagerModel.count) % pagerModel.count
|
||||
: (pagerModel.currentPage + 1) % pagerModel.count
|
||||
pagerModel.changePage(next)
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// FULL REPRESENTATION
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
Plasmoid.fullRepresentation: Item {
|
||||
id: popup
|
||||
|
||||
readonly property int cols: Math.max(1, Math.ceil(Math.sqrt(pagerModel.count)))
|
||||
readonly property int rows: Math.max(1, Math.ceil(pagerModel.count / cols))
|
||||
readonly property real deskW: 130
|
||||
readonly property real deskH: pagerModel.pagerItemSize.height > 0
|
||||
? deskW * pagerModel.pagerItemSize.height / pagerModel.pagerItemSize.width
|
||||
: deskW * 9 / 16
|
||||
readonly property real scaleX: deskW / Math.max(1, pagerModel.pagerItemSize.width)
|
||||
readonly property real scaleY: deskH / Math.max(1, pagerModel.pagerItemSize.height)
|
||||
|
||||
Layout.preferredWidth: cols * (deskW + 8) + 32
|
||||
Layout.preferredHeight: rows * (deskH + 8) + 56
|
||||
Layout.minimumWidth: 200
|
||||
Layout.minimumHeight: 120
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: { hoverPopup = true; closeTimer.stop() }
|
||||
onExited: { hoverPopup = false; if (!hoverCompact) closeTimer.start() }
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 8
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// DESKTOP GRID
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
Grid {
|
||||
id: desktopGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
columns: popup.cols
|
||||
spacing: 6
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: pagerModel
|
||||
|
||||
Rectangle {
|
||||
id: desktop
|
||||
width: popup.deskW
|
||||
height: popup.deskH
|
||||
|
||||
readonly property string desktopName: model.display || ("Desktop " + (index + 1))
|
||||
readonly property bool isActive: index === pagerModel.currentPage
|
||||
|
||||
color: isActive ? Qt.darker(PlasmaCore.Theme.highlightColor, 1.3) : PlasmaCore.Theme.backgroundColor
|
||||
border.width: isActive ? 2 : 1
|
||||
border.color: isActive ? PlasmaCore.Theme.highlightColor : PlasmaCore.Theme.disabledTextColor
|
||||
radius: 4
|
||||
clip: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onEntered: { hoverPopup = true; closeTimer.stop(); parent.opacity = 1 }
|
||||
onExited: parent.opacity = 0.92
|
||||
onClicked: mouse.button === Qt.RightButton ? ctxMenu.popup() : (pagerModel.changePage(index), plasmoid.expanded = false)
|
||||
}
|
||||
|
||||
opacity: 0.92
|
||||
|
||||
// ─────────────────────────────────────────────────
|
||||
// WINDOWS with real geometry
|
||||
// ─────────────────────────────────────────────────
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
clip: true
|
||||
visible: showPreviews
|
||||
|
||||
Repeater {
|
||||
model: TasksModel
|
||||
|
||||
Rectangle {
|
||||
readonly property rect geo: model.Geometry
|
||||
readonly property bool minimized: model.IsMinimized === true
|
||||
|
||||
x: Math.round(geo.x * popup.scaleX)
|
||||
y: Math.round(geo.y * popup.scaleY)
|
||||
width: Math.max(8, Math.round(geo.width * popup.scaleX))
|
||||
height: Math.max(6, Math.round(geo.height * popup.scaleY))
|
||||
visible: !minimized
|
||||
|
||||
color: model.IsActive ? Qt.rgba(1,1,1,0.4) : Qt.rgba(1,1,1,0.2)
|
||||
border.width: 1
|
||||
border.color: model.IsActive ? PlasmaCore.Theme.highlightColor : PlasmaCore.Theme.textColor
|
||||
radius: 2
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
visible: showIcons && parent.width > 16 && parent.height > 12
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width - 4, parent.height - 4, 20)
|
||||
height: width
|
||||
source: model.decoration || "application-x-executable"
|
||||
usesPlasmaTheme: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────
|
||||
// DESKTOP LABEL (centered)
|
||||
// ─────────────────────────────────────────────────
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
visible: !showPreviews
|
||||
PlasmaComponents.Label {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: index + 1
|
||||
font.bold: true; font.pixelSize: 18
|
||||
color: desktop.isActive ? PlasmaCore.Theme.highlightedTextColor : PlasmaCore.Theme.textColor
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: desktop.desktopName
|
||||
font.pixelSize: 10
|
||||
color: desktop.isActive ? PlasmaCore.Theme.highlightedTextColor : PlasmaCore.Theme.textColor
|
||||
width: popup.deskW - 10
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
// Badge when previews enabled
|
||||
Rectangle {
|
||||
visible: showPreviews
|
||||
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 3 }
|
||||
width: badgeLbl.implicitWidth + 12; height: badgeLbl.implicitHeight + 4
|
||||
color: Qt.rgba(0,0,0,0.7); radius: 3
|
||||
PlasmaComponents.Label {
|
||||
id: badgeLbl; anchors.centerIn: parent
|
||||
text: (index + 1) + " " + desktop.desktopName
|
||||
font.pixelSize: 11; font.bold: true; color: "white"
|
||||
}
|
||||
}
|
||||
|
||||
// Context menu
|
||||
Menu {
|
||||
id: ctxMenu
|
||||
MenuItem {
|
||||
text: "Rename..."
|
||||
icon.name: "edit-rename"
|
||||
onTriggered: { renameDlg.idx = index; renameDlg.open(); renameField.text = desktop.desktopName; renameField.selectAll() }
|
||||
}
|
||||
MenuItem {
|
||||
text: "Delete"
|
||||
icon.name: "edit-delete"
|
||||
enabled: pagerModel.count > 1
|
||||
onTriggered: pagerModel.removeDesktop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// BOTTOM BAR
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
MouseArea {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 36
|
||||
hoverEnabled: true
|
||||
onEntered: { hoverPopup = true; closeTimer.stop() }
|
||||
onExited: { hoverPopup = false; if (!hoverCompact) closeTimer.start() }
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 8
|
||||
PlasmaComponents.Button {
|
||||
icon.name: "list-add"; text: "Add"
|
||||
onClicked: pagerModel.addDesktop()
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
PlasmaComponents.Label {
|
||||
text: pagerModel.count + " desktops"
|
||||
opacity: 0.6; font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
// RENAME DIALOG
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
Dialog {
|
||||
id: renameDlg
|
||||
property int idx: 0
|
||||
title: "Rename Desktop"
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
anchors.centerIn: parent
|
||||
contentItem: PlasmaComponents.TextField {
|
||||
id: renameField
|
||||
Layout.preferredWidth: 180
|
||||
onAccepted: renameDlg.accept()
|
||||
}
|
||||
onAccepted: {
|
||||
if (renameField.text.trim()) {
|
||||
// Use KWin DBus to rename
|
||||
var desktopItem = repeater.itemAt(idx)
|
||||
if (desktopItem) {
|
||||
execSource.connectSource("qdbus org.kde.KWin /VirtualDesktopManager setDesktopName '" +
|
||||
pagerModel.data(pagerModel.index(idx, 0), 0x0100 + 1) + "' '" +
|
||||
renameField.text.trim().replace(/'/g, "'\\''") + "'")
|
||||
}
|
||||
pagerModel.refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: execSource
|
||||
engine: "executable"
|
||||
onNewData: disconnectSource(sourceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Desktop Entry]
|
||||
Name=Virtual Desktop Switcher
|
||||
Comment=Shows current virtual desktop and allows switching with window previews
|
||||
Icon=preferences-desktop-virtual
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=Plasma/Applet
|
||||
X-Plasma-API=declarativeappletscript
|
||||
X-Plasma-MainScript=ui/main.qml
|
||||
X-Plasma-ConfigPlugins=org.kde.virtualdesktopswitcher
|
||||
X-KDE-PluginInfo-Name=org.kde.virtualdesktopswitcher
|
||||
X-KDE-PluginInfo-Version=1.1
|
||||
X-KDE-PluginInfo-Author=Andres Garcia
|
||||
X-KDE-PluginInfo-License=GPL-3.0
|
||||
X-KDE-PluginInfo-Category=Windows and Tasks
|
||||
X-KDE-FormFactors=desktop,panel
|
||||
Loading…
Reference in New Issue