aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/deckit/DeckItWindowsPage.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/deckit/DeckItWindowsPage.qml')
-rw-r--r--desktop/modules/deckit/DeckItWindowsPage.qml151
1 files changed, 151 insertions, 0 deletions
diff --git a/desktop/modules/deckit/DeckItWindowsPage.qml b/desktop/modules/deckit/DeckItWindowsPage.qml
new file mode 100644
index 0000000..c7cd11c
--- /dev/null
+++ b/desktop/modules/deckit/DeckItWindowsPage.qml
@@ -0,0 +1,151 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// 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.
+
+import Quickshell
+import QtQuick
+import "../.."
+import "../qtmaildir"
+
+// deck-it's Windows page: the launcher buttons and the workspaces shown.
+Column {
+ id: col
+ spacing: 6
+ readonly property var st: DeckIt.store
+ function def(section, key) { return col.st.fallback(section, key); }
+
+ // The launcher list, in button order.
+ readonly property var apps: col.st.value("launch", "apps") ?? []
+ property string query: ""
+ // Installed apps not yet listed, for the picker. Terminal apps are left
+ // out, as the Autostart page does: gtk-launch would need a terminal for them.
+ readonly property var candidates: {
+ const q = col.query.trim().toLowerCase();
+ return DesktopEntries.applications.values
+ .filter(a => !a.noDisplay && !a.runInTerminal && a.execString && !col.apps.includes(a.id)
+ && (q === "" || a.name.toLowerCase().includes(q) || a.id.toLowerCase().includes(q)))
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .slice(0, 8);
+ }
+ function setApps(list) { col.st.put("launch", "apps", list); }
+
+ Small { visible: DeckIt.defaultsError !== ""; color: Theme.red; text: DeckIt.defaultsError }
+
+ Heading { objectName: "launch/apps"; text: "Launchers" }
+ Small { text: "Buttons on the Windows tab, in this order. Each runs its app through gtk-launch." }
+ Repeater {
+ model: col.apps
+ delegate: Item {
+ id: row
+ required property string modelData
+ required property int index
+ readonly property var entry: DesktopEntries.byId(row.modelData)
+ width: col.width
+ height: 34
+ Image {
+ id: appIcon
+ anchors { left: parent.left; leftMargin: 8; verticalCenter: parent.verticalCenter }
+ width: 20; height: 20
+ sourceSize: Qt.size(20, 20)
+ source: row.entry ? Quickshell.iconPath(row.entry.icon, true) : ""
+ }
+ Text {
+ anchors { left: appIcon.right; leftMargin: 10; right: up.left; rightMargin: 8; verticalCenter: parent.verticalCenter }
+ elide: Text.ElideRight
+ text: row.entry ? row.entry.name + " " + row.modelData : row.modelData + " not installed"
+ color: row.entry ? Theme.text : Theme.red
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ }
+ Button {
+ id: up
+ anchors { right: del.left; rightMargin: 6; verticalCenter: parent.verticalCenter }
+ text: "Up"
+ enabled: row.index > 0
+ onClicked: {
+ const a = col.apps.slice();
+ a.splice(row.index - 1, 0, a.splice(row.index, 1)[0]);
+ col.setApps(a);
+ }
+ }
+ Button {
+ id: del
+ anchors { right: parent.right; verticalCenter: parent.verticalCenter }
+ text: "Remove"
+ danger: true
+ onClicked: col.setApps(col.apps.filter(a => a !== row.modelData))
+ }
+ }
+ }
+ Rectangle {
+ width: col.width
+ height: 34
+ radius: 8
+ color: Theme.surface
+ TextInput {
+ id: search
+ activeFocusOnTab: true
+ anchors { fill: parent; leftMargin: 10; rightMargin: 10 }
+ verticalAlignment: TextInput.AlignVCenter
+ clip: true
+ selectByMouse: true
+ color: Theme.text
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ onTextEdited: col.query = text
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ visible: parent.text === ""
+ text: "add an app: search installed apps"
+ color: Theme.subtext
+ font: parent.font
+ }
+ }
+ }
+ Repeater {
+ model: col.candidates
+ delegate: Rectangle {
+ id: app
+ required property var modelData
+ width: col.width
+ height: 32
+ radius: 8
+ color: appArea.containsMouse ? Qt.alpha(Theme.text, 0.06) : "transparent"
+ Image {
+ id: candIcon
+ anchors { left: parent.left; leftMargin: 8; verticalCenter: parent.verticalCenter }
+ width: 20; height: 20
+ sourceSize: Qt.size(20, 20)
+ source: Quickshell.iconPath(app.modelData.icon, true)
+ }
+ Text {
+ anchors { left: candIcon.right; leftMargin: 10; right: parent.right; rightMargin: 8; verticalCenter: parent.verticalCenter }
+ elide: Text.ElideRight
+ text: app.modelData.name + " " + app.modelData.id
+ color: Theme.text
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ }
+ MouseArea {
+ id: appArea
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ col.setApps(col.apps.concat([app.modelData.id]));
+ col.query = "";
+ search.text = "";
+ }
+ }
+ }
+ }
+
+ Heading { text: "Workspaces" }
+ Setting { store: col.st; section: "windows"; key: "workspaces"; label: "Workspaces"
+ placeholder: col.st.placeholder("windows", "workspaces")
+ hint: "Numbers on the Windows tab, separated by spaces, shown even when empty." }
+}