diff --git a/contents/config/main.xml b/contents/config/main.xml
index 2a4bda5..b393e7e 100644
--- a/contents/config/main.xml
+++ b/contents/config/main.xml
@@ -12,9 +12,9 @@
true
- 80
- 40
- 150
+ 130
+ 80
+ 200
diff --git a/contents/ui/configGeneral.qml b/contents/ui/configGeneral.qml
index 4e43224..3164469 100644
--- a/contents/ui/configGeneral.qml
+++ b/contents/ui/configGeneral.qml
@@ -26,10 +26,9 @@ Kirigami.FormLayout {
SpinBox {
id: previewSize
Kirigami.FormData.label: i18n("Preview Size:")
- from: 40
- to: 150
+ from: 80
+ to: 200
stepSize: 10
- enabled: showWindowPreviews.checked
textFromValue: function(value) {
return value + " px"
diff --git a/contents/ui/main.qml b/contents/ui/main.qml
index f1756ce..0b4fcd3 100644
--- a/contents/ui/main.qml
+++ b/contents/ui/main.qml
@@ -10,11 +10,38 @@ Item {
id: root
Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
+ // ─────────────────────────────────────────────────────────────────────────
+ // INTERNATIONALIZATION (i18n)
+ // ─────────────────────────────────────────────────────────────────────────
+ readonly property string systemLang: Qt.locale().name.substring(0, 2)
+ readonly property var translations: ({
+ "en": { desktop: "Desktop", add: "Add", desktops: "desktops", rename: "Rename...", delete_: "Delete",
+ renameTitle: "Rename Desktop", switchTo: "Switch to", moveWindowHere: "Move window here",
+ newDesktop: "New Desktop", confirmDelete: "Delete this desktop?" },
+ "es": { desktop: "Escritorio", add: "Agregar", desktops: "escritorios", rename: "Renombrar...", delete_: "Eliminar",
+ renameTitle: "Renombrar Escritorio", switchTo: "Cambiar a", moveWindowHere: "Mover ventana aquí",
+ newDesktop: "Nuevo Escritorio", confirmDelete: "¿Eliminar este escritorio?" },
+ "zh": { desktop: "桌面", add: "添加", desktops: "个桌面", rename: "重命名...", delete_: "删除",
+ renameTitle: "重命名桌面", switchTo: "切换到", moveWindowHere: "移动窗口到此处",
+ newDesktop: "新建桌面", confirmDelete: "删除此桌面?" },
+ "fr": { desktop: "Bureau", add: "Ajouter", desktops: "bureaux", rename: "Renommer...", delete_: "Supprimer",
+ renameTitle: "Renommer le bureau", switchTo: "Basculer vers", moveWindowHere: "Déplacer la fenêtre ici",
+ newDesktop: "Nouveau bureau", confirmDelete: "Supprimer ce bureau ?" },
+ "de": { desktop: "Desktop", add: "Hinzufügen", desktops: "Desktops", rename: "Umbenennen...", delete_: "Löschen",
+ renameTitle: "Desktop umbenennen", switchTo: "Wechseln zu", moveWindowHere: "Fenster hierher verschieben",
+ newDesktop: "Neuer Desktop", confirmDelete: "Diesen Desktop löschen?" },
+ "pt": { desktop: "Área de trabalho", add: "Adicionar", desktops: "áreas de trabalho", rename: "Renomear...", delete_: "Excluir",
+ renameTitle: "Renomear área de trabalho", switchTo: "Mudar para", moveWindowHere: "Mover janela para cá",
+ newDesktop: "Nova área de trabalho", confirmDelete: "Excluir esta área de trabalho?" }
+ })
+ readonly property var t: translations[systemLang] || translations["en"]
+
// ─────────────────────────────────────────────────────────────────────────
// CONFIGURATION
// ─────────────────────────────────────────────────────────────────────────
readonly property bool showPreviews: plasmoid.configuration.showWindowPreviews
readonly property bool showIcons: plasmoid.configuration.showWindowIcons
+ readonly property int previewSize: plasmoid.configuration.previewSize || 130
// ─────────────────────────────────────────────────────────────────────────
// PAGER MODEL (native KDE plugin with real window geometry)
@@ -33,13 +60,18 @@ Item {
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 name || (t.desktop + " " + (pagerModel.currentPage + 1))
}
- return "Desktop"
+ return t.desktop
}
function addDesktop() { pagerModel.addDesktop() }
- function removeDesktop() { pagerModel.removeDesktop() }
+ function removeDesktop(index) {
+ if (pagerModel.count > 1) {
+ pagerModel.changePage(index)
+ pagerModel.removeDesktop()
+ }
+ }
// ─────────────────────────────────────────────────────────────────────────
// HOVER TIMERS
@@ -89,7 +121,7 @@ Item {
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 deskW: previewSize
readonly property real deskH: pagerModel.pagerItemSize.height > 0
? deskW * pagerModel.pagerItemSize.height / pagerModel.pagerItemSize.width
: deskW * 9 / 16
@@ -97,7 +129,7 @@ Item {
readonly property real scaleY: deskH / Math.max(1, pagerModel.pagerItemSize.height)
Layout.preferredWidth: cols * (deskW + 8) + 32
- Layout.preferredHeight: rows * (deskH + 8) + 56
+ Layout.preferredHeight: rows * (deskH + 8) + 70
Layout.minimumWidth: 200
Layout.minimumHeight: 120
@@ -133,25 +165,62 @@ Item {
width: popup.deskW
height: popup.deskH
- readonly property string desktopName: model.display || ("Desktop " + (index + 1))
+ readonly property string desktopName: model.display || (t.desktop + " " + (index + 1))
readonly property bool isActive: index === pagerModel.currentPage
+ property bool isHovered: false
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
+ opacity: isHovered ? 1 : 0.92
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)
+ onEntered: { hoverPopup = true; closeTimer.stop(); desktop.isHovered = true }
+ onExited: { desktop.isHovered = false }
+ onClicked: {
+ if (mouse.button === Qt.RightButton) {
+ ctxMenu.desktopIndex = index
+ ctxMenu.desktopName = desktop.desktopName
+ ctxMenu.popup()
+ } else {
+ pagerModel.changePage(index)
+ plasmoid.expanded = false
+ }
+ }
}
- opacity: 0.92
+ // ─────────────────────────────────────────────────
+ // DELETE BUTTON (top-right, on hover)
+ // ─────────────────────────────────────────────────
+ Rectangle {
+ id: deleteBtn
+ visible: desktop.isHovered && pagerModel.count > 1
+ anchors { top: parent.top; right: parent.right; margins: 2 }
+ width: Math.min(parent.width * 0.25, 44)
+ height: width
+ radius: width / 2
+ color: deleteMouseArea.containsMouse ? "#e74c3c" : Qt.rgba(0,0,0,0.6)
+
+ PlasmaCore.IconItem {
+ anchors.centerIn: parent
+ width: parent.width * 0.6
+ height: width
+ source: "edit-delete"
+ usesPlasmaTheme: false
+ }
+
+ MouseArea {
+ id: deleteMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: removeDesktop(index)
+ }
+ }
// ─────────────────────────────────────────────────
// WINDOWS with real geometry
@@ -193,7 +262,7 @@ Item {
}
// ─────────────────────────────────────────────────
- // DESKTOP LABEL (centered)
+ // DESKTOP LABEL (centered, when no previews)
// ─────────────────────────────────────────────────
Column {
anchors.centerIn: parent
@@ -227,22 +296,6 @@ Item {
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()
- }
- }
}
}
}
@@ -261,25 +314,104 @@ Item {
anchors.fill: parent
spacing: 8
PlasmaComponents.Button {
- icon.name: "list-add"; text: "Add"
+ icon.name: "list-add"; text: t.add
onClicked: pagerModel.addDesktop()
}
Item { Layout.fillWidth: true }
PlasmaComponents.Label {
- text: pagerModel.count + " desktops"
+ text: pagerModel.count + " " + t.desktops
opacity: 0.6; font.pixelSize: 11
}
+
+ // ─────────────────────────────────────────────────
+ // RESIZE HANDLE
+ // ─────────────────────────────────────────────────
+ Rectangle {
+ width: 20; height: 20
+ color: "transparent"
+
+ PlasmaCore.IconItem {
+ anchors.fill: parent
+ source: "transform-scale"
+ opacity: resizeMouseArea.containsMouse ? 1 : 0.5
+ }
+
+ MouseArea {
+ id: resizeMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.SizeFDiagCursor
+
+ property real startX: 0
+ property real startY: 0
+ property int startSize: 0
+
+ onPressed: {
+ startX = mouse.x
+ startY = mouse.y
+ startSize = previewSize
+ }
+ onPositionChanged: {
+ if (pressed) {
+ var delta = (mouse.x - startX + mouse.y - startY) / 2
+ var newSize = Math.max(80, Math.min(200, startSize + delta))
+ plasmoid.configuration.previewSize = Math.round(newSize)
+ }
+ }
+ }
+ }
}
}
}
+ // ─────────────────────────────────────────────────────────────────
+ // CONTEXT MENU
+ // ─────────────────────────────────────────────────────────────────
+ Menu {
+ id: ctxMenu
+ property int desktopIndex: 0
+ property string desktopName: ""
+
+ MenuItem {
+ text: t.switchTo + " \"" + ctxMenu.desktopName + "\""
+ icon.name: "go-jump"
+ onTriggered: {
+ pagerModel.changePage(ctxMenu.desktopIndex)
+ plasmoid.expanded = false
+ }
+ }
+ MenuSeparator {}
+ MenuItem {
+ text: t.rename
+ icon.name: "edit-rename"
+ onTriggered: {
+ renameDlg.idx = ctxMenu.desktopIndex
+ renameDlg.open()
+ renameField.text = ctxMenu.desktopName
+ renameField.selectAll()
+ }
+ }
+ MenuItem {
+ text: t.delete_
+ icon.name: "edit-delete"
+ enabled: pagerModel.count > 1
+ onTriggered: removeDesktop(ctxMenu.desktopIndex)
+ }
+ MenuSeparator {}
+ MenuItem {
+ text: t.newDesktop
+ icon.name: "list-add"
+ onTriggered: pagerModel.addDesktop()
+ }
+ }
+
// ─────────────────────────────────────────────────────────────────
// RENAME DIALOG
// ─────────────────────────────────────────────────────────────────
Dialog {
id: renameDlg
property int idx: 0
- title: "Rename Desktop"
+ title: t.renameTitle
standardButtons: Dialog.Ok | Dialog.Cancel
anchors.centerIn: parent
contentItem: PlasmaComponents.TextField {
@@ -289,7 +421,6 @@ Item {
}
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 '" +