···
29
29
}
30
30
];
31
31
layout = {
32
32
+
focus-ring = {
33
33
+
width = 2;
34
34
+
active.color = "#8caaee";
35
35
+
inactive.color = "#414559";
36
36
+
};
32
37
struts = {
33
33
-
top = 0;
34
34
-
bottom = 0;
35
35
-
left = 8;
36
36
-
right = 8;
38
38
+
top = -6;
39
39
+
bottom = -6;
40
40
+
left = 0;
41
41
+
right = 0;
37
42
};
38
43
gaps = 8;
39
44
};
···
97
102
"Mod+2".action = {
98
103
set-column-width = "50%";
99
104
};
105
105
+
"Mod+Minus".action = {
106
106
+
set-column-width = "-10%";
107
107
+
};
108
108
+
"Mod+Equal".action = {
109
109
+
set-column-width = "+10%";
110
110
+
};
100
111
"XF86MonBrightnessDown".action.spawn = [
101
112
"brightnessctl"
102
113
"set"
···
175
186
spawn-at-startup = [
176
187
{ command = [ "xwayland-satellite" ]; }
177
188
{ command = [ "swww-daemon" ]; }
178
178
-
{ command = [ "mako" ]; }
179
179
-
{ command = [ "quickshell" "-p" "${./quickshell/shell.qml}" ]; }
189
189
+
{ command = [ "quickshell" ]; }
180
190
{ command = [ "wl-paste --watch cliphist store" ]; }
181
191
];
182
192
environment = {
···
192
202
"libsoup-2.74.3"
193
203
];
194
204
195
195
-
# Quickshell status bar (QML config in ./quickshell/shell.qml)
205
205
+
# Quickshell status bar
206
206
+
xdg.configFile."quickshell/shell.qml".source = ./quickshell/shell.qml;
196
207
197
208
programs.ssh = {
198
209
enable = true;
···
227
238
bemoji # emoji picker
228
239
networkmanager_dmenu # network picker for fuzzel
229
240
quickshell # Status bar (QML-based)
230
230
-
mako # Notification daemon
231
241
swww # For setting wallpapers
232
242
cliphist # Clipboard history manager
233
243
pavucontrol # GUI for PulseAudio/PipeWire volume control
···
262
272
docker-compose
263
273
discord
264
274
prismlauncher # minecraft launcher
265
265
-
atuin
275
275
+
neofetch
266
276
267
277
# --- FONTS ARE IMPORTANT ---
268
278
# Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons
···
282
292
automount = true;
283
293
};
284
294
295
295
+
services.mako = {
296
296
+
enable = true;
297
297
+
borderRadius = 8;
298
298
+
borderSize = 2;
299
299
+
padding = "12";
300
300
+
margin = "12";
301
301
+
font = "BerkeleyMono Nerd Font 11";
302
302
+
};
303
303
+
285
304
catppuccin = {
286
305
enable = true;
287
306
flavor = "frappe";
···
291
310
292
311
programs.direnv.enable = true;
293
312
313
313
+
programs.atuin = {
314
314
+
enable = true;
315
315
+
enableFishIntegration = true;
316
316
+
settings = {
317
317
+
filter_mode_shell_up_key_binding = "session";
318
318
+
};
319
319
+
};
320
320
+
294
321
programs.zellij = {
295
322
enable = true;
296
323
settings = {
···
306
333
};
307
334
};
308
335
pane_frames = false;
336
336
+
show_startup_tips = false;
309
337
ui = {
310
338
pane_frames.hide_session_name = true;
311
339
};
···
365
393
if test -f ~/.config/op/plugins.sh
366
394
source ~/.config/op/plugins.sh
367
395
end
368
368
-
# Initialize atuin shell history
369
369
-
atuin init fish | source
396
396
+
# Show neofetch when inside zellij
397
397
+
if set -q ZELLIJ
398
398
+
neofetch
399
399
+
end
370
400
371
401
function y
372
402
set tmp (mktemp -t "yazi-cwd.XXXXXX")
···
396
426
programs.alacritty = {
397
427
enable = true;
398
428
settings = {
429
429
+
terminal.shell = {
430
430
+
program = "zellij";
431
431
+
args = [ "options" "--on-force-close" "detach" ];
432
432
+
};
399
433
window = {
400
434
decorations = "none";
401
435
opacity = 0.9;
···
5
5
import QtQuick.Layouts
6
6
7
7
ShellRoot {
8
8
+
Variants {
9
9
+
model: Quickshell.screens
10
10
+
8
11
PanelWindow {
9
12
id: root
13
13
+
screen: modelData
10
14
11
15
// Catppuccin Frappe palette
12
16
readonly property color colBase: "#303446"
···
36
40
readonly property string iconVolMute: "\uf6a9"
37
41
// Network
38
42
readonly property string iconWifi: "\uf1eb"
43
43
+
readonly property string iconEthernet: "\udb80\ude00"
39
44
// Power profiles
40
45
readonly property string iconBolt: "\uf0e7"
41
46
readonly property string iconBalance: "\uf24e"
···
69
74
property string networkName: ""
70
75
property int networkStrength: 0
71
76
property bool networkConnected: false
77
77
+
property bool networkIsEthernet: false
72
78
property int volume: 0
73
79
property bool volumeMuted: false
74
80
property int brightness: 0
75
81
property int batteryPercent: 0
76
82
property string batteryStatus: ""
77
83
property string powerProfile: ""
84
84
+
property string weather: ""
78
85
79
86
anchors {
80
87
top: true
···
137
144
Component.onCompleted: running = true
138
145
}
139
146
140
140
-
// Network
147
147
+
// Network - check ethernet first, then wifi
141
148
Process {
142
149
id: netProc
143
143
-
command: ["sh", "-c", "nmcli -t -f ACTIVE,SSID,SIGNAL dev wifi | grep '^yes' | head -1"]
150
150
+
command: ["sh", "-c", "eth=$(nmcli -t -f TYPE,STATE,CONNECTION dev | grep '^ethernet:connected:' | head -1); if [ -n \"$eth\" ]; then echo \"ethernet:$(echo $eth | cut -d: -f3)\"; else nmcli -t -f ACTIVE,SSID,SIGNAL dev wifi | grep '^yes' | head -1; fi"]
144
151
stdout: SplitParser {
145
152
onRead: data => {
146
153
if (!data || data.trim() === "") {
147
154
root.networkConnected = false
155
155
+
root.networkIsEthernet = false
148
156
root.networkName = "Disconnected"
149
157
root.networkStrength = 0
150
158
return
151
159
}
152
152
-
var parts = data.trim().split(":")
153
153
-
root.networkConnected = true
154
154
-
root.networkName = parts[1] || ""
155
155
-
root.networkStrength = parseInt(parts[2]) || 0
160
160
+
var trimmed = data.trim()
161
161
+
if (trimmed.startsWith("ethernet:")) {
162
162
+
root.networkConnected = true
163
163
+
root.networkIsEthernet = true
164
164
+
root.networkName = trimmed.split(":")[1] || "Ethernet"
165
165
+
root.networkStrength = 100
166
166
+
} else {
167
167
+
var parts = trimmed.split(":")
168
168
+
root.networkConnected = true
169
169
+
root.networkIsEthernet = false
170
170
+
root.networkName = parts[1] || ""
171
171
+
root.networkStrength = parseInt(parts[2]) || 0
172
172
+
}
156
173
}
157
174
}
158
175
Component.onCompleted: running = true
···
226
243
Component.onCompleted: running = true
227
244
}
228
245
246
246
+
// Weather
247
247
+
Process {
248
248
+
id: weatherProc
249
249
+
command: ["sh", "-c", "curl -sf 'wttr.in/?format=%c+%t' | tr -d '+'"]
250
250
+
stdout: SplitParser {
251
251
+
onRead: data => {
252
252
+
if (!data) return
253
253
+
root.weather = data.trim()
254
254
+
}
255
255
+
}
256
256
+
Component.onCompleted: running = true
257
257
+
}
258
258
+
259
259
+
// Weather timer (refresh every 15 minutes)
260
260
+
Timer {
261
261
+
interval: 900000
262
262
+
running: true
263
263
+
repeat: true
264
264
+
onTriggered: weatherProc.running = true
265
265
+
}
266
266
+
229
267
// Update timer
230
268
Timer {
231
269
interval: 2000
···
244
282
}
245
283
}
246
284
285
285
+
// Center section - absolutely positioned
247
286
RowLayout {
248
248
-
anchors.fill: parent
249
249
-
anchors.leftMargin: 12
250
250
-
anchors.rightMargin: 12
251
251
-
spacing: 0
287
287
+
anchors.centerIn: parent
288
288
+
spacing: 12
289
289
+
290
290
+
Text {
291
291
+
color: root.colText
292
292
+
font { family: root.fontFamily; pixelSize: root.fontSize }
293
293
+
text: root.weather
294
294
+
visible: root.weather !== ""
295
295
+
}
252
296
253
253
-
// Clock
254
297
Text {
255
298
id: clockText
256
299
color: root.colBlue
···
263
306
onTriggered: clockText.text = Qt.formatDateTime(new Date(), "dd-MM-yyyy HH:mm")
264
307
}
265
308
}
266
266
-
267
267
-
Item { Layout.fillWidth: true }
309
309
+
}
268
310
269
269
-
// Right section
270
270
-
RowLayout {
271
271
-
spacing: 12
311
311
+
// Right section - anchored to right edge
312
312
+
RowLayout {
313
313
+
anchors.right: parent.right
314
314
+
anchors.rightMargin: 12
315
315
+
anchors.verticalCenter: parent.verticalCenter
316
316
+
spacing: 12
272
317
273
318
// Volume
274
319
Text {
···
293
338
Text {
294
339
color: root.colGreen
295
340
font { family: root.fontFamily; pixelSize: root.fontSize }
296
296
-
text: root.networkConnected ? root.networkName + " (" + root.networkStrength + "%) " + root.iconWifi : "Disconnected \u26a0"
341
341
+
text: {
342
342
+
if (!root.networkConnected) return "Disconnected \u26a0"
343
343
+
if (root.networkIsEthernet) return root.networkName + " " + root.iconEthernet
344
344
+
return root.networkName + " (" + root.networkStrength + "%) " + root.iconWifi
345
345
+
}
297
346
}
298
347
299
348
Rectangle { width: 1; height: 16; color: root.colOverlay0 }
···
385
434
}
386
435
}
387
436
}
437
437
+