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