summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2025-08-31 21:57:00 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2025-08-31 21:57:00 +0200
commit466ce70f96f8bdde32260f6951c5cbb62cfc02a7 (patch)
tree3d3120f6a1ace487d2db5a024411a467d55b9632
parent828893e930886872fcf612bc8958d33fee73b5df (diff)
downloadnixos-466ce70f96f8bdde32260f6951c5cbb62cfc02a7.tar
nixos-466ce70f96f8bdde32260f6951c5cbb62cfc02a7.tar.gz
nixos-466ce70f96f8bdde32260f6951c5cbb62cfc02a7.tar.bz2
nixos-466ce70f96f8bdde32260f6951c5cbb62cfc02a7.tar.xz
nixos-466ce70f96f8bdde32260f6951c5cbb62cfc02a7.zip
...
-rw-r--r--accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml3
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Bar.qml10
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Clock.qml241
-rw-r--r--accounts/gkleen@sif/shell/quickshell/KeyboardLayout.qml43
-rw-r--r--accounts/gkleen@sif/shell/quickshell/SystemTray.qml21
-rw-r--r--accounts/gkleen@sif/shell/quickshell/shell.qml12
6 files changed, 204 insertions, 126 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml b/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml
index d7e8e7c5..57ade488 100644
--- a/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml
+++ b/accounts/gkleen@sif/shell/quickshell/ActiveWindowDisplay.qml
@@ -7,10 +7,11 @@ Item {
7 id: activeWindowDisplay 7 id: activeWindowDisplay
8 8
9 required property int maxWidth 9 required property int maxWidth
10 required property var screen
10 11
11 property var activeWindow: { 12 property var activeWindow: {
12 let currWindowId = Array.from(NiriService.workspaces).find(ws => { 13 let currWindowId = Array.from(NiriService.workspaces).find(ws => {
13 return ws.output === bar.screen.name && ws.is_active; 14 return ws.output === screen.name && ws.is_active;
14 })?.active_window_id; 15 })?.active_window_id;
15 16
16 return currWindowId ? Array.from(NiriService.windows).find(win => win.id == currWindowId) : null; 17 return currWindowId ? Array.from(NiriService.windows).find(win => win.id == currWindowId) : null;
diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml
index accad2a9..aab1607f 100644
--- a/accounts/gkleen@sif/shell/quickshell/Bar.qml
+++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml
@@ -5,7 +5,9 @@ import QtQuick
5PanelWindow { 5PanelWindow {
6 id: bar 6 id: bar
7 7
8 property var modelData 8 required property var screen
9
10 property var calendarMouseArea: clock.calendarMouseArea
9 11
10 anchors { 12 anchors {
11 top: true 13 top: true
@@ -17,7 +19,6 @@ PanelWindow {
17 right: 26 + 8 19 right: 26 + 8
18 } 20 }
19 21
20 screen: modelData
21 implicitHeight: 21 22 implicitHeight: 21
22 color: "transparent" 23 color: "transparent"
23 24
@@ -50,6 +51,7 @@ PanelWindow {
50 spacing: 5 51 spacing: 5
51 52
52 ActiveWindowDisplay { 53 ActiveWindowDisplay {
54 screen: bar.screen
53 maxWidth: bar.width - 2*Math.max(left.width, right.width) - 2*8 55 maxWidth: bar.width - 2*Math.max(left.width, right.width) - 2*8
54 } 56 }
55 } 57 }
@@ -78,6 +80,8 @@ PanelWindow {
78 width: 4 80 width: 4
79 } 81 }
80 82
81 Clock {} 83 Clock {
84 id: clock
85 }
82 } 86 }
83} \ No newline at end of file 87} \ No newline at end of file
diff --git a/accounts/gkleen@sif/shell/quickshell/Clock.qml b/accounts/gkleen@sif/shell/quickshell/Clock.qml
index 68efb558..58600adb 100644
--- a/accounts/gkleen@sif/shell/quickshell/Clock.qml
+++ b/accounts/gkleen@sif/shell/quickshell/Clock.qml
@@ -21,12 +21,14 @@ Item {
21 property real angleRem: 0 21 property real angleRem: 0
22 property real sensitivity: 1 / 120 22 property real sensitivity: 1 / 120
23 23
24 onWheel: event => { 24 function scrollYear(event) {
25 angleRem += event.angleDelta.y; 25 angleRem += event.angleDelta.y;
26 const d = Math.round(angleRem * sensitivity); 26 const d = Math.round(angleRem * sensitivity);
27 yearCalendar.year += d; 27 yearCalendar.year += d;
28 angleRem -= d / sensitivity; 28 angleRem -= d / sensitivity;
29 } 29 }
30
31 onWheel: event => scrollYear(event)
30 } 32 }
31 33
32 Text { 34 Text {
@@ -48,11 +50,23 @@ Item {
48 } 50 }
49 51
50 PopupWindow { 52 PopupWindow {
53 id: tooltip
54
55 property bool nextVisible: clockMouseArea.containsMouse || tooltipMouseArea.containsMouse
56
51 anchor { 57 anchor {
52 item: clockMouseArea 58 item: clockMouseArea
53 edges: Edges.Bottom 59 edges: Edges.Bottom | Edges.Left
60 }
61 visible: false
62
63 onNextVisibleChanged: hangTimer.restart()
64
65 Timer {
66 id: hangTimer
67 interval: 100
68 onTriggered: tooltip.visible = tooltip.nextVisible
54 } 69 }
55 visible: clockMouseArea.containsMouse
56 70
57 implicitWidth: clockTooltipContent.width 71 implicitWidth: clockTooltipContent.width
58 implicitHeight: clockTooltipContent.height 72 implicitHeight: clockTooltipContent.height
@@ -64,159 +78,170 @@ Item {
64 clockMouseArea.angleRem = 0; 78 clockMouseArea.angleRem = 0;
65 } 79 }
66 80
67 WrapperItem { 81 WrapperMouseArea {
68 id: clockTooltipContent 82 id: tooltipMouseArea
69
70 margin: 8
71 leftMargin: 0
72 83
73 ColumnLayout { 84 hoverEnabled: true
74 Text { 85 enabled: true
75 id: yearLabel
76 86
77 horizontalAlignment: Text.AlignHCenter 87 onWheel: event => clockMouseArea.scrollYear(event)
78 88
79 font.pointSize: 14 89 anchors.fill: parent
80 font.family: "Fira Sans"
81 font.features: { "tnum": 1 }
82 color: "white"
83 90
84 text: yearCalendar.year 91 WrapperItem {
92 id: clockTooltipContent
85 93
86 Layout.fillWidth: true 94 margin: 8
87 Layout.bottomMargin: 8 95 leftMargin: 0
88 }
89 96
90 GridLayout { 97 ColumnLayout {
91 property int year: { const d = new Date(); return d.getFullYear(); } 98 Text {
99 id: yearLabel
92 100
93 id: yearCalendar 101 horizontalAlignment: Text.AlignHCenter
94 102
95 columns: 3 103 font.pointSize: 14
96 columnSpacing: 16 104 font.family: "Fira Sans"
97 rowSpacing: 16 105 font.features: { "tnum": 1 }
106 color: "white"
98 107
99 Layout.alignment: Qt.AlignHCenter 108 text: yearCalendar.year
100 Layout.fillWidth: false
101 109
102 Repeater { 110 Layout.fillWidth: true
103 model: 12 111 Layout.bottomMargin: 8
104 112 }
105 GridLayout {
106 columns: 2
107 113
108 required property int index 114 GridLayout {
109 property int month: index 115 property int year: { const d = new Date(); return d.getFullYear(); }
110 116
111 id: monthCalendar 117 id: yearCalendar
112 118
113 Layout.alignment: Qt.AlignTop | Qt.AlignRight 119 columns: 3
114 Layout.fillWidth: false 120 columnSpacing: 16
121 rowSpacing: 16
115 122
116 Text { 123 Layout.alignment: Qt.AlignHCenter
117 Layout.column: 1 124 Layout.fillWidth: false
118 Layout.fillWidth: true
119 125
120 horizontalAlignment: Text.AlignHCenter 126 Repeater {
127 model: 12
121 128
122 font.pointSize: 10 129 GridLayout {
123 font.family: "Fira Sans" 130 columns: 2
124 131
125 text: { 132 required property int index
126 const date = Date.fromLocaleDateString(Qt.locale(), `${yearCalendar.year}-${monthCalendar.month + 1}-01`, "yyyy-M-dd"); 133 property int month: index
127 return date.toLocaleString(Qt.locale("en_DK"), "MMMM")
128 }
129 134
130 color: "#ffead3" 135 id: monthCalendar
131 }
132 136
133 DayOfWeekRow { 137 Layout.alignment: Qt.AlignTop | Qt.AlignRight
134 locale: grid.locale 138 Layout.fillWidth: false
135 139
136 Layout.row: 1 140 Text {
137 Layout.column: 1 141 Layout.column: 1
138 Layout.fillWidth: true 142 Layout.fillWidth: true
139 143
140 delegate: Text { 144 horizontalAlignment: Text.AlignHCenter
141 required property string shortName
142 145
143 font.pointSize: 10 146 font.pointSize: 10
144 font.family: "Fira Mono" 147 font.family: "Fira Sans"
145 148
146 text: shortName 149 text: {
147 color: "#ffcc66" 150 const date = Date.fromLocaleDateString(Qt.locale(), `${yearCalendar.year}-${monthCalendar.month + 1}-01`, "yyyy-M-dd");
151 return date.toLocaleString(Qt.locale("en_DK"), "MMMM")
152 }
148 153
149 horizontalAlignment: Text.AlignRight 154 color: "#ffead3"
150 verticalAlignment: Text.AlignVCenter
151 } 155 }
152 }
153 156
154 WeekNumberColumn { 157 DayOfWeekRow {
155 month: grid.month 158 locale: grid.locale
156 year: grid.year
157 locale: grid.locale
158 159
159 Layout.fillHeight: true 160 Layout.row: 1
161 Layout.column: 1
162 Layout.fillWidth: true
160 163
161 delegate: Text { 164 delegate: Text {
162 required property int weekNumber 165 required property string shortName
163 166
164 opacity: { 167 font.pointSize: 10
165 const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7); 168 font.family: "Fira Mono"
166 const dayOfWeek = simple.getDay();
167 const isoWeekStart = simple;
168 169
169 isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1); 170 text: shortName
170 if (dayOfWeek > 4) { 171 color: "#ffcc66"
171 isoWeekStart.setDate(isoWeekStart.getDate() + 7);
172 }
173 172
174 for (let i = 0; i < 7; i++) { 173 horizontalAlignment: Text.AlignRight
175 const dayInWeek = new Date(isoWeekStart); 174 verticalAlignment: Text.AlignVCenter
176 dayInWeek.setDate(dayInWeek.getDate() + i);
177 if (dayInWeek.getMonth() == monthCalendar.month)
178 return 1;
179 }
180
181 return 0;
182 } 175 }
176 }
183 177
184 font.pointSize: 10 178 WeekNumberColumn {
185 font.family: "Fira Sans" 179 month: grid.month
186 font.features: { "tnum": 1 } 180 year: grid.year
187 181 locale: grid.locale
188 text: weekNumber
189 color: "#99ffdd"
190 182
191 horizontalAlignment: Text.AlignRight 183 Layout.fillHeight: true
192 verticalAlignment: Text.AlignVCenter
193 }
194 }
195 184
196 MonthGrid { 185 delegate: Text {
197 id: grid 186 required property int weekNumber
198 187
199 year: yearCalendar.year 188 opacity: {
200 month: monthCalendar.month 189 const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7);
201 locale: Qt.locale("en_DK") 190 const dayOfWeek = simple.getDay();
191 const isoWeekStart = simple;
202 192
203 Layout.fillWidth: true 193 isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1);
204 Layout.fillHeight: true 194 if (dayOfWeek > 4) {
195 isoWeekStart.setDate(isoWeekStart.getDate() + 7);
196 }
205 197
206 delegate: Text { 198 for (let i = 0; i < 7; i++) {
207 required property var model 199 const dayInWeek = new Date(isoWeekStart);
200 dayInWeek.setDate(dayInWeek.getDate() + i);
201 if (dayInWeek.getMonth() == monthCalendar.month)
202 return 1;
203 }
208 204
209 opacity: model.month === monthCalendar.month ? 1 : 0 205 return 0;
206 }
210 207
211 font.pointSize: 10 208 font.pointSize: 10
212 font.family: "Fira Sans" 209 font.family: "Fira Sans"
213 font.features: { "tnum": 1 } 210 font.features: { "tnum": 1 }
214 211
215 text: model.day 212 text: weekNumber
216 color: model.today ? "#ff6699" : "white" 213 color: "#99ffdd"
217 214
218 horizontalAlignment: Text.AlignRight 215 horizontalAlignment: Text.AlignRight
219 verticalAlignment: Text.AlignVCenter 216 verticalAlignment: Text.AlignVCenter
217 }
218 }
219
220 MonthGrid {
221 id: grid
222
223 year: yearCalendar.year
224 month: monthCalendar.month
225 locale: Qt.locale("en_DK")
226
227 Layout.fillWidth: true
228 Layout.fillHeight: true
229
230 delegate: Text {
231 required property var model
232
233 opacity: model.month === monthCalendar.month ? 1 : 0
234
235 font.pointSize: 10
236 font.family: "Fira Sans"
237 font.features: { "tnum": 1 }
238
239 text: model.day
240 color: model.today ? "#ff6699" : "white"
241
242 horizontalAlignment: Text.AlignRight
243 verticalAlignment: Text.AlignVCenter
244 }
220 } 245 }
221 } 246 }
222 } 247 }
diff --git a/accounts/gkleen@sif/shell/quickshell/KeyboardLayout.qml b/accounts/gkleen@sif/shell/quickshell/KeyboardLayout.qml
index 710ea10c..b9f91580 100644
--- a/accounts/gkleen@sif/shell/quickshell/KeyboardLayout.qml
+++ b/accounts/gkleen@sif/shell/quickshell/KeyboardLayout.qml
@@ -1,6 +1,7 @@
1import Quickshell 1import Quickshell
2import QtQuick 2import QtQuick
3import qs.Services 3import qs.Services
4import Quickshell.Widgets
4 5
5Rectangle { 6Rectangle {
6 id: kbdWidget 7 id: kbdWidget
@@ -27,6 +28,9 @@ Rectangle {
27 onClicked: { 28 onClicked: {
28 NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": "Next" } } }, _ => {}) 29 NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": "Next" } } }, _ => {})
29 } 30 }
31 onWheel: event => {
32 NiriService.sendCommand({ "Action": { "SwitchLayout": { "layout": event.angleDelta > 0 ? "Next" : "Prev" } } }, _ => {})
33 }
30 } 34 }
31 35
32 Text { 36 Text {
@@ -50,28 +54,47 @@ Rectangle {
50 } 54 }
51 55
52 PopupWindow { 56 PopupWindow {
57 id: tooltip
58
59 property bool nextVisible: kbdMouseArea.containsMouse || tooltipMouseArea.containsMouse
60
53 anchor { 61 anchor {
54 item: kbdMouseArea 62 item: kbdMouseArea
55 edges: Edges.Bottom 63 edges: Edges.Bottom | Edges.Left
64 }
65 visible: false
66
67 onNextVisibleChanged: hangTimer.restart()
68
69 Timer {
70 id: hangTimer
71 interval: 100
72 onTriggered: tooltip.visible = tooltip.nextVisible
56 } 73 }
57 visible: kbdMouseArea.containsMouse
58 74
59 implicitWidth: kbdTooltipText.contentWidth + 16 75 implicitWidth: kbdTooltipText.contentWidth + 16
60 implicitHeight: kbdTooltipText.contentHeight + 16 76 implicitHeight: kbdTooltipText.contentHeight + 16
61 color: "black" 77 color: "black"
62 78
63 Text { 79 WrapperMouseArea {
64 id: kbdTooltipText 80 id: tooltipMouseArea
81
82 hoverEnabled: true
83 enabled: true
65 84
66 anchors.centerIn: parent 85 anchors.centerIn: parent
67 86
68 font.pointSize: 10 87 Text {
69 font.family: "Fira Sans" 88 id: kbdTooltipText
70 color: "white" 89
90 font.pointSize: 10
91 font.family: "Fira Sans"
92 color: "white"
71 93
72 text: { 94 text: {
73 const currentLayout = NiriService.keyboardLayouts?.names?.[NiriService.keyboardLayouts.current_idx]; 95 const currentLayout = NiriService.keyboardLayouts?.names?.[NiriService.keyboardLayouts.current_idx];
74 return currentLayout || ""; 96 return currentLayout || "";
97 }
75 } 98 }
76 } 99 }
77 } 100 }
diff --git a/accounts/gkleen@sif/shell/quickshell/SystemTray.qml b/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
index afed4bf0..ba678138 100644
--- a/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
+++ b/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
@@ -91,18 +91,35 @@ Item {
91 } 91 }
92 92
93 PopupWindow { 93 PopupWindow {
94 id: tooltip
95
96 property bool nextVisible: (trayItem.tooltipTitle || trayItem.tooltipDescription) && (trayItemArea.containsMouse || tooltipMouseArea.containsMouse) && !menuAnchor.visible
97
94 anchor { 98 anchor {
95 item: trayItemArea 99 item: trayItemArea
96 edges: Edges.Bottom 100 edges: Edges.Bottom
97 } 101 }
98 visible: (trayItem.tooltipTitle || trayItem.tooltipDescription) && trayItemArea.containsMouse && !menuAnchor.visible 102
103 visible: false
104 onNextVisibleChanged: hangTimer.restart()
105
106 Timer {
107 id: hangTimer
108 interval: 100
109 onTriggered: tooltip.visible = tooltip.nextVisible
110 }
99 111
100 color: "black" 112 color: "black"
101 113
102 implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16 114 implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16
103 implicitHeight: tooltipTitle.contentHeight + tooltipDescription.contentHeight + 16 115 implicitHeight: tooltipTitle.contentHeight + tooltipDescription.contentHeight + 16
104 116
105 WrapperItem { 117 WrapperMouseArea {
118 id: tooltipMouseArea
119
120 hoverEnabled: true
121 enabled: true
122
106 margin: 8 123 margin: 8
107 124
108 Column { 125 Column {
diff --git a/accounts/gkleen@sif/shell/quickshell/shell.qml b/accounts/gkleen@sif/shell/quickshell/shell.qml
index 2abd1fef..4934cd4d 100644
--- a/accounts/gkleen@sif/shell/quickshell/shell.qml
+++ b/accounts/gkleen@sif/shell/quickshell/shell.qml
@@ -8,8 +8,16 @@ ShellRoot {
8 Variants { 8 Variants {
9 model: Quickshell.screens 9 model: Quickshell.screens
10 10
11 delegate: Bar { 11 delegate: Scope {
12 modelData: item 12 id: screenScope
13
14 required property var modelData
15
16 Bar {
17 id: bar
18
19 screen: screenScope.modelData
20 }
13 } 21 }
14 } 22 }
15} 23}