summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell/Bar.qml
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell/Bar.qml')
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Bar.qml321
1 files changed, 14 insertions, 307 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml
index 09554a39..38225d74 100644
--- a/accounts/gkleen@sif/shell/quickshell/Bar.qml
+++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml
@@ -1,16 +1,11 @@
1import Quickshell 1import Quickshell
2import Quickshell.Io
3import Quickshell.Services.SystemTray
4import Quickshell.Widgets
5import Custom as Custom
6import QtQuick 2import QtQuick
7import qs.Services
8 3
9 4
10PanelWindow { 5PanelWindow {
11 id: bar 6 id: bar
12 7
13 property var modelData 8 required property var screen
14 9
15 anchors { 10 anchors {
16 top: true 11 top: true
@@ -22,12 +17,11 @@ PanelWindow {
22 right: 26 + 8 17 right: 26 + 8
23 } 18 }
24 19
25 screen: modelData
26 implicitHeight: 21 20 implicitHeight: 21
27 color: "transparent" 21 color: "transparent"
28 22
29 Rectangle { 23 Rectangle {
30 color: Qt.rgba(0, 0, 0, 0.66) 24 color: Qt.rgba(0, 0, 0, 0.75)
31 anchors.fill: parent 25 anchors.fill: parent
32 // bottomLeftRadius: 8 26 // bottomLeftRadius: 8
33 // bottomRightRadius: 8 27 // bottomRightRadius: 8
@@ -43,74 +37,7 @@ PanelWindow {
43 anchors.verticalCenter: parent.verticalCenter 37 anchors.verticalCenter: parent.verticalCenter
44 spacing: 8 38 spacing: 8
45 39
46 Row { 40 WorkspaceSwitcher {}
47 id: workspaces
48
49 property var ignoreWorkspaces: @ignore_workspaces@
50
51 height: parent.height
52 anchors.verticalCenter: parent.verticalCenter
53 spacing: 0
54
55 Repeater {
56 model: {
57 let currWorkspaces = NiriService.workspaces;
58 const ignoreWorkspaces = Array.from(workspaces.ignoreWorkspaces);
59 currWorkspaces = currWorkspaces.filter(ws => ws.is_active || ignoreWorkspaces.every(iws => iws !== ws.name));
60 currWorkspaces.sort((a, b) => {
61 if (NiriService.outputs?.[a.output]?.logical?.x !== NiriService.outputs?.[b.output]?.logical?.x)
62 return NiriService.outputs?.[a.output]?.logical?.x - NiriService.outputs?.[b.output]?.logical?.x
63 if (NiriService.outputs?.[a.output]?.logical?.y !== NiriService.outputs?.[b.output]?.logical?.y)
64 return NiriService.outputs?.[a.output]?.logical?.y - NiriService.outputs?.[b.output]?.logical?.y
65 return a.idx - b.idx;
66 });
67 return currWorkspaces;
68 }
69
70 Rectangle {
71 property var workspaceData: modelData
72
73 width: wsLabel.contentWidth + 8
74 color: {
75 if (mouseArea.containsMouse) {
76 return "#33808080";
77 }
78 return "transparent";
79 }
80 height: parent.height
81 anchors.verticalCenter: parent.verticalCenter
82
83 MouseArea {
84 id: mouseArea
85
86 anchors.fill: parent
87 hoverEnabled: true
88 cursorShape: Qt.PointingHandCursor
89 enabled: true
90 onClicked: {
91 NiriService.sendCommand({ "Action": { "FocusWorkspace": { "reference": { "Id": workspaceData.id } } } }, _ => {})
92 }
93 }
94
95 Text {
96 id: wsLabel
97
98 font.pointSize: 10
99 font.family: "Fira Sans"
100 color: {
101 if (workspaceData.active_window_id === null)
102 return "#555";
103 if (workspaceData.is_active)
104 return "#23fd00";
105 return "white";
106 }
107 anchors.centerIn: parent
108
109 text: workspaceData.name ? workspaceData.name : workspaceData.idx
110 }
111 }
112 }
113 }
114 } 41 }
115 42
116 Row { 43 Row {
@@ -121,91 +48,9 @@ PanelWindow {
121 anchors.centerIn: parent 48 anchors.centerIn: parent
122 spacing: 5 49 spacing: 5
123 50
124 Item { 51 ActiveWindowDisplay {
125 id: activeWindowDisplay 52 screen: bar.screen
126 53 maxWidth: bar.width - 2*Math.max(left.width, right.width) - 2*8
127 property var activeWindow: {
128 let currWindowId = Array.from(NiriService.workspaces).find(ws => {
129 return ws.output === bar.screen.name && ws.is_active;
130 })?.active_window_id;
131
132 return currWindowId ? Array.from(NiriService.windows).find(win => win.id == currWindowId) : null;
133 }
134 property var windowEntry: activeWindow ? DesktopEntries.heuristicLookup(activeWindow.app_id) : null
135
136 anchors.verticalCenter: parent.verticalCenter
137 width: activeWindowDisplayContent.width
138 height: parent.height
139
140 Row {
141 id: activeWindowDisplayContent
142
143 width: childrenRect.width
144 height: parent.height
145 anchors.verticalCenter: parent.verticalCenter
146 spacing: 8
147
148 IconImage {
149 id: activeWindowIcon
150
151 height: 14
152 width: 14
153
154 anchors.verticalCenter: parent.verticalCenter
155
156 source: {
157 let icon = activeWindowDisplay.windowEntry?.icon
158 if (typeof icon === 'string' || icon instanceof String) {
159 if (icon.includes("?path=")) {
160 const split = icon.split("?path=")
161 if (split.length !== 2)
162 return icon
163 const name = split[0]
164 const path = split[1]
165 const fileName = name.substring(
166 name.lastIndexOf("/") + 1)
167 return `file://${path}/${fileName}`
168 } else
169 icon = Quickshell.iconPath(icon);
170 return icon
171 }
172 return ""
173 }
174 asynchronous: true
175 smooth: true
176 mipmap: true
177 }
178
179 Text {
180 id: windowTitle
181
182 width: Math.min(implicitWidth, bar.width - 2*Math.max(left.width, right.width) - 2*8 - activeWindowIcon.width - activeWindowDisplayContent.spacing)
183
184 property var appAliases: { "Firefox": "Mozilla Firefox", "mpv Media Player": "mpv", "Thunderbird": "Mozilla Thunderbird", "Thunderbird (LMU)": "Mozilla Thunderbird" }
185
186 elide: Text.ElideRight
187 maximumLineCount: 1
188 color: "white"
189 anchors.verticalCenter: parent.verticalCenter
190 text: {
191 if (!activeWindowDisplay.activeWindow)
192 return "";
193
194 var title = activeWindowDisplay.activeWindow.title;
195 var appName = activeWindowDisplay.windowEntry?.name;
196 if (appAliases[appName])
197 appName = appAliases[appName];
198 if (appName && title.endsWith(appName)) {
199 const oldTitle = title;
200 title = title.substring(0, title.length - appName.length);
201 title = title.replace(/\s*(—|-)\s*$/, "");
202 if (!title)
203 title = oldTitle;
204 }
205 return title;
206 }
207 }
208 }
209 } 54 }
210 } 55 }
211 56
@@ -217,160 +62,22 @@ PanelWindow {
217 anchors.right: parent.right 62 anchors.right: parent.right
218 anchors.rightMargin: 8 63 anchors.rightMargin: 8
219 anchors.verticalCenter: parent.verticalCenter 64 anchors.verticalCenter: parent.verticalCenter
220 spacing: 8 65 spacing: 0
221
222 Rectangle {
223 id: kbdWidget
224 66
225 property var keyboardAbbrev: { "English (programmer Dvorak)": "dvp", "English (US)": "us" } 67 SystemTray {}
226 68
227 width: kbdLabel.contentWidth 69 Item {
228 color: {
229 /* if (kbdMouseArea.containsMouse) {
230 return "#33808080";
231 } */
232 return "transparent";
233 }
234 height: parent.height 70 height: parent.height
235 anchors.verticalCenter: parent.verticalCenter 71 width: 4
236
237 MouseArea {
238 id: kbdMouseArea
239
240 anchors.fill: parent
241 hoverEnabled: true
242 cursorShape: Qt.PointingHandCursor
243 enabled: true
244 onClicked: {
245 NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": "Next" } } }, _ => {})
246 }
247 }
248
249 Text {
250 id: kbdLabel
251
252 font.pointSize: 10
253 font.family: "Fira Sans"
254 color: {
255 if (NiriService.keyboardLayouts?.current_idx === 0)
256 return "#555";
257 return "white";
258 }
259 anchors.centerIn: parent
260
261 text: {
262 const currentLayout = NiriService.keyboardLayouts?.names?.[NiriService.keyboardLayouts.current_idx];
263 return kbdWidget.keyboardAbbrev[currentLayout] ? kbdWidget.keyboardAbbrev[currentLayout] : currentLayout;
264 }
265 }
266 } 72 }
267 73
74 KeyboardLayout {}
75
268 Item { 76 Item {
269 anchors.verticalCenter: parent.verticalCenter
270 width: systemTrayRow.childrenRect.width
271 height: parent.height 77 height: parent.height
272 clip: true 78 width: 4
273
274 Row {
275 id: systemTrayRow
276 anchors.centerIn: parent
277 width: childrenRect.width
278 height: parent.height
279 spacing: 0
280
281 Repeater {
282 model: SystemTray.items.values
283
284 delegate: Item {
285 property var trayItem: modelData
286 property string iconSource: {
287 let icon = trayItem && trayItem.icon
288 if (typeof icon === 'string' || icon instanceof String) {
289 if (icon.includes("?path=")) {
290 const split = icon.split("?path=")
291 if (split.length !== 2)
292 return icon
293 const name = split[0]
294 const path = split[1]
295 const fileName = name.substring(
296 name.lastIndexOf("/") + 1)
297 return `file://${path}/${fileName}`
298 }
299 return icon
300 }
301 return ""
302 }
303
304 width: 16
305 height: parent.height
306 anchors.verticalCenter: parent.verticalCenter
307
308 IconImage {
309 anchors.centerIn: parent
310 width: parent.width
311 height: parent.width
312 source: parent.iconSource
313 asynchronous: true
314 smooth: true
315 mipmap: true
316 }
317
318 MouseArea {
319 id: trayItemArea
320
321 anchors.fill: parent
322 acceptedButtons: Qt.LeftButton | Qt.RightButton
323 hoverEnabled: true
324 cursorShape: Qt.PointingHandCursor
325 onClicked: mouse => {
326 if (!trayItem)
327 return
328
329 if (mouse.button === Qt.LeftButton
330 && !trayItem.onlyMenu) {
331 trayItem.activate()
332 return
333 }
334
335 if (trayItem.hasMenu) {
336 var globalPos = mapToGlobal(0, 0)
337 var currentScreen = screen || Screen
338 var screenX = currentScreen.x || 0
339 var relativeX = globalPos.x - screenX
340 menuAnchor.menu = trayItem.menu
341 menuAnchor.anchor.window = bar
342 menuAnchor.anchor.rect = Qt.rect(
343 relativeX,
344 21,
345 parent.width, 1)
346 menuAnchor.open()
347 }
348 }
349 }
350 }
351 }
352 }
353 QsMenuAnchor {
354 id: menuAnchor
355 }
356 } 79 }
357 80
358 Text { 81 Clock {}
359 id: clock
360 color: "white"
361
362 anchors.verticalCenter: parent.verticalCenter
363
364 Custom.Chrono {
365 id: chrono
366 format: "W{0:%V-%u} {0:%F} {0:%H:%M:%S%Ez}"
367 }
368
369 text: chrono.date
370
371 font.pointSize: 10
372 font.family: "Fira Sans"
373 font.features: { "tnum": 1 }
374 }
375 } 82 }
376} \ No newline at end of file 83} \ No newline at end of file