summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml')
-rw-r--r--accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml204
1 files changed, 204 insertions, 0 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml b/accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml
new file mode 100644
index 00000000..3ae94346
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/WorkspaceSwitcher.qml
@@ -0,0 +1,204 @@
1import Quickshell
2import QtQuick
3import qs.Services
4import Quickshell.Widgets
5import QtQuick.Layouts
6
7Row {
8 id: workspaces
9
10 required property var screen
11
12 property var ignoreWorkspaces: @ignore_workspaces@
13
14 height: parent.height
15 anchors.verticalCenter: parent.verticalCenter
16 spacing: 0
17
18 Repeater {
19 model: ScriptModel {
20 values: {
21 let currWorkspaces = NiriService.workspaces;
22 const ignoreWorkspaces = Array.from(workspaces.ignoreWorkspaces);
23 currWorkspaces = currWorkspaces.filter(ws => ws.output == workspaces.screen.name).filter(ws => ws.is_active || ignoreWorkspaces.every(iws => iws !== ws.name));
24 currWorkspaces.sort((a, b) => {
25 if (NiriService.outputs?.[a.output]?.logical?.x !== NiriService.outputs?.[b.output]?.logical?.x)
26 return NiriService.outputs?.[a.output]?.logical?.x - NiriService.outputs?.[b.output]?.logical?.x
27 if (NiriService.outputs?.[a.output]?.logical?.y !== NiriService.outputs?.[b.output]?.logical?.y)
28 return NiriService.outputs?.[a.output]?.logical?.y - NiriService.outputs?.[b.output]?.logical?.y
29 return a.idx - b.idx;
30 });
31 return currWorkspaces;
32 }
33 }
34
35 Item {
36 id: wsItem
37
38 property var workspaceData: modelData
39
40 width: wsLabel.contentWidth + 8
41 height: parent.height
42 anchors.verticalCenter: parent.verticalCenter
43
44 WrapperMouseArea {
45 id: mouseArea
46
47 anchors.fill: parent
48
49 hoverEnabled: true
50 cursorShape: Qt.PointingHandCursor
51 enabled: true
52 onClicked: {
53 NiriService.sendCommand({ "Action": { "FocusWorkspace": { "reference": { "Id": workspaceData.id } } } }, _ => {});
54 }
55
56 Rectangle {
57 anchors.fill: parent
58
59 color: {
60 if (mouseArea.containsMouse) {
61 return "#33808080";
62 }
63 return "transparent";
64 }
65
66 Text {
67 id: wsLabel
68
69 anchors.centerIn: parent
70
71 font.pointSize: 10
72 font.family: "Fira Sans"
73 color: {
74 if (workspaceData.is_active)
75 return "#23fd00";
76 if (workspaceData.active_window_id === null)
77 return "#555";
78 return "white";
79 }
80
81 text: workspaceData.name ? workspaceData.name : workspaceData.idx
82 }
83 }
84 }
85
86 PopupWindow {
87 id: tooltip
88
89 property bool nextVisible: (mouseArea.containsMouse || tooltipMouseArea.containsMouse) && [...windowsModel.values].length > 0
90
91 anchor {
92 item: mouseArea
93 edges: Edges.Bottom | Edges.Left
94 }
95 visible: false
96
97 onNextVisibleChanged: hangTimer.restart()
98
99 Timer {
100 id: hangTimer
101 interval: 100
102 onTriggered: tooltip.visible = tooltip.nextVisible
103 }
104
105 implicitWidth: tooltipContent.implicitWidth
106 implicitHeight: tooltipContent.implicitHeight
107 color: "black"
108
109 WrapperMouseArea {
110 id: tooltipMouseArea
111
112 hoverEnabled: true
113 enabled: true
114
115 anchors.fill: parent
116
117 WrapperItem {
118 id: tooltipContent
119
120 margin: 0
121
122 ColumnLayout {
123 spacing: 0
124
125 Repeater {
126 model: ScriptModel {
127 id: windowsModel
128
129 values: {
130 let currWindows = Array.from(NiriService.windows).filter(win => win.workspace_id == wsItem.workspaceData.id);
131 currWindows.sort((a, b) => {
132 if (a.is_floating !== b.is_floating)
133 return b.is_floating - a.is_floating;
134 if (a.layout.tile_pos_in_workspace_view?.[0] !== b.layout.tile_pos_in_workspace_view?.[0])
135 return a.layout.tile_pos_in_workspace_view?.[0] - b.layout.tile_pos_in_workspace_view?.[0]
136 if (a.layout.tile_pos_in_workspace_view?.[1] !== b.layout.tile_pos_in_workspace_view?.[1])
137 return a.layout.tile_pos_in_workspace_view?.[1] - b.layout.tile_pos_in_workspace_view?.[1]
138 if (a.layout.pos_in_scrolling_layout?.[0] !== b.layout.pos_in_scrolling_layout?.[0])
139 return a.layout.pos_in_scrolling_layout?.[0] - b.layout.pos_in_scrolling_layout?.[0]
140 if (a.layout.pos_in_scrolling_layout?.[1] !== b.layout.pos_in_scrolling_layout?.[1])
141 return a.layout.pos_in_scrolling_layout?.[1] - b.layout.pos_in_scrolling_layout?.[1]
142 if (a.app_id !== b.app_id)
143 return a.app_id.localeCompare(b.app_id);
144
145 return a.title.localeCompare(b.title);
146 });
147 return currWindows;
148 }
149 }
150
151 WrapperMouseArea {
152 id: windowMouseArea
153
154 required property int index
155 required property var modelData
156 property var windowData: modelData
157
158 hoverEnabled: true
159 cursorShape: Qt.PointingHandCursor
160 enabled: true
161
162 Layout.fillWidth: true
163
164 onClicked: {
165 NiriService.sendCommand({ "Action": { "FocusWindow": { "id": windowData.id } } }, _ => {})
166 }
167
168 WrapperRectangle {
169 color: windowMouseArea.containsMouse ? "#33808080" : "transparent";
170
171 WrapperItem {
172 rightMargin: 8
173 leftMargin: 8
174 topMargin: windowMouseArea.index == 0 ? 8 : 4
175 bottomMargin: windowMouseArea.index == windowsModel.values.length - 1 ? 8 : 4
176
177 Text {
178 id: windowLabel
179
180 font.pointSize: 10
181 font.family: "Fira Sans"
182 color: {
183 if (windowData.is_focused)
184 return "#23fd00";
185 if (NiriService.workspaces.find(ws => ws.id == windowData.workspace_id)?.active_window_id == windowData.id)
186 return "white";
187 return "#555";
188 }
189
190 text: windowData.title
191
192 horizontalAlignment: Text.AlignLeft
193 }
194 }
195 }
196 }
197 }
198 }
199 }
200 }
201 }
202 }
203 }
204}