quickshell: clock, calendar, battery; remove waybar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4905389a3c
commit
8e914e3131
1 changed files with 205 additions and 137 deletions
|
|
@ -60,7 +60,6 @@ in
|
||||||
networkmanagerapplet
|
networkmanagerapplet
|
||||||
pavucontrol
|
pavucontrol
|
||||||
polkit_gnome
|
polkit_gnome
|
||||||
] ++ lib.optionals isGaming [
|
|
||||||
quickshell
|
quickshell
|
||||||
qt6.qt5compat
|
qt6.qt5compat
|
||||||
];
|
];
|
||||||
|
|
@ -423,145 +422,11 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Scope all HM Wayland services (hyprpaper, waybar, …) to the
|
# Scope all HM Wayland services (hyprpaper, etc.) to the
|
||||||
# Hyprland session so they don't crash-loop in a GNOME session.
|
# Hyprland session so they don't crash-loop in a GNOME session.
|
||||||
wayland.systemd.target = "hyprland-session.target";
|
wayland.systemd.target = "hyprland-session.target";
|
||||||
|
|
||||||
programs.waybar = {
|
xdg.configFile."quickshell/shell.qml" = {
|
||||||
enable = true;
|
|
||||||
systemd.enable = true;
|
|
||||||
|
|
||||||
settings.mainBar = {
|
|
||||||
layer = "top";
|
|
||||||
position = "top";
|
|
||||||
height = 30;
|
|
||||||
spacing = 6;
|
|
||||||
|
|
||||||
modules-left = [ "hyprland/workspaces" ];
|
|
||||||
modules-center = [ "clock" ];
|
|
||||||
modules-right = lib.optionals isMacbook [ "battery" ] ++ [ "group/tray-drawer" ];
|
|
||||||
|
|
||||||
"hyprland/workspaces" = {
|
|
||||||
format = "{name}";
|
|
||||||
on-click = "activate";
|
|
||||||
sort-by-number = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
clock = {
|
|
||||||
format = "{:%H:%M}";
|
|
||||||
tooltip-format = "<big>{:%A, %d %B %Y}</big>\n<tt><small>{calendar}</small></tt>";
|
|
||||||
};
|
|
||||||
|
|
||||||
"group/tray-drawer" = {
|
|
||||||
orientation = "horizontal";
|
|
||||||
drawer = {
|
|
||||||
transition-duration = 500;
|
|
||||||
transition-left-to-right = false;
|
|
||||||
};
|
|
||||||
modules = [ "custom/tray-handle" "pulseaudio" "tray" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"custom/tray-handle" = {
|
|
||||||
format = builtins.fromJSON ''"\ue0b2"''; # U+E0B2 Nerd Font powerline filled left-arrow
|
|
||||||
tooltip = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Pulseaudio module, now conditionally visible
|
|
||||||
pulseaudio = {
|
|
||||||
format = "{icon} {volume}%";
|
|
||||||
format-muted = " muted";
|
|
||||||
format-icons = {
|
|
||||||
default = [ "" "" "" ];
|
|
||||||
headphone = "";
|
|
||||||
headset = "";
|
|
||||||
};
|
|
||||||
on-click = "pavucontrol";
|
|
||||||
scroll-step = 5;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Tray module, now conditionally visible
|
|
||||||
tray = {
|
|
||||||
icon-size = 16;
|
|
||||||
spacing = 8;
|
|
||||||
};
|
|
||||||
} // lib.optionalAttrs isMacbook {
|
|
||||||
battery = {
|
|
||||||
format = "{capacity}% {icon}";
|
|
||||||
format-charging = "{capacity}% ";
|
|
||||||
format-icons = [ "" "" "" "" "" ];
|
|
||||||
states = { warning = 30; critical = 15; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
style = ''
|
|
||||||
* {
|
|
||||||
font-family: "FiraMono Nerd Font", monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
min-height: 0;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background: alpha(@base00, 0.82);
|
|
||||||
color: @base05;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button {
|
|
||||||
padding: 0 8px;
|
|
||||||
color: @base03;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.active {
|
|
||||||
color: @base05;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button:hover {
|
|
||||||
background: alpha(@base05, 0.08);
|
|
||||||
color: @base05;
|
|
||||||
box-shadow: none;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#clock {
|
|
||||||
color: @base05;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio,
|
|
||||||
#tray {
|
|
||||||
padding: 0 10px;
|
|
||||||
color: @base05;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio.muted {
|
|
||||||
color: @base03;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray {
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-tray-handle {
|
|
||||||
padding: 0 0px;
|
|
||||||
color: @base05;
|
|
||||||
}
|
|
||||||
|
|
||||||
#battery {
|
|
||||||
padding: 0 10px;
|
|
||||||
color: @base05;
|
|
||||||
}
|
|
||||||
#battery.warning { color: @base0A; }
|
|
||||||
#battery.critical { color: @base08; }
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
xdg.configFile."quickshell/shell.qml" = lib.mkIf isGaming {
|
|
||||||
text = ''
|
text = ''
|
||||||
//@ pragma UseQApplication
|
//@ pragma UseQApplication
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
|
@ -637,6 +502,32 @@ in
|
||||||
// Spacer
|
// Spacer
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
Text {
|
||||||
|
id: clockText
|
||||||
|
property date now: new Date()
|
||||||
|
text: now.toLocaleTimeString(Qt.locale(), "HH:mm")
|
||||||
|
color: "#${c.base05}"
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.weight: Font.Medium
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: clockText.now = new Date()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: calPopup.visible = !calPopup.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spacer
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
// Network status
|
// Network status
|
||||||
Item {
|
Item {
|
||||||
id: netWidget
|
id: netWidget
|
||||||
|
|
@ -703,6 +594,78 @@ in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${lib.optionalString isMacbook ''
|
||||||
|
// Battery
|
||||||
|
Item {
|
||||||
|
id: batteryWidget
|
||||||
|
Layout.preferredHeight: 30
|
||||||
|
Layout.preferredWidth: batteryRow.width
|
||||||
|
Layout.rightMargin: 10
|
||||||
|
|
||||||
|
property int batteryLevel: 0
|
||||||
|
property bool charging: false
|
||||||
|
property string batteryIcon: "\u{f008e}"
|
||||||
|
|
||||||
|
function updateIcon() {
|
||||||
|
if (charging) { batteryIcon = "\u{f0084}"; return; }
|
||||||
|
if (batteryLevel >= 90) batteryIcon = "\u{f0079}";
|
||||||
|
else if (batteryLevel >= 70) batteryIcon = "\u{f0082}";
|
||||||
|
else if (batteryLevel >= 50) batteryIcon = "\u{f007f}";
|
||||||
|
else if (batteryLevel >= 30) batteryIcon = "\u{f007c}";
|
||||||
|
else if (batteryLevel >= 15) batteryIcon = "\u{f007a}";
|
||||||
|
else batteryIcon = "\u{f008e}";
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 10000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
onTriggered: batteryProc.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: batteryProc
|
||||||
|
command: ["sh", "-c", "cat /sys/class/power_supply/BAT0/capacity; cat /sys/class/power_supply/BAT0/status"]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: data => {
|
||||||
|
let trimmed = data.trim();
|
||||||
|
if (/^\\d+$/.test(trimmed)) {
|
||||||
|
batteryWidget.batteryLevel = parseInt(trimmed);
|
||||||
|
} else {
|
||||||
|
batteryWidget.charging = (trimmed === "Charging");
|
||||||
|
}
|
||||||
|
batteryWidget.updateIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: batteryRow
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: batteryWidget.batteryLevel + "%"
|
||||||
|
color: batteryWidget.batteryLevel <= 15 ? "#${c.base08}"
|
||||||
|
: batteryWidget.batteryLevel <= 30 ? "#${c.base0A}"
|
||||||
|
: "#${c.base05}"
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 13
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: batteryWidget.batteryIcon
|
||||||
|
color: batteryWidget.batteryLevel <= 15 ? "#${c.base08}"
|
||||||
|
: batteryWidget.batteryLevel <= 30 ? "#${c.base0A}"
|
||||||
|
: "#${c.base05}"
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''}
|
||||||
|
|
||||||
// Tray icons inline
|
// Tray icons inline
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: trayArea
|
id: trayArea
|
||||||
|
|
@ -851,6 +814,111 @@ in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calendar popup
|
||||||
|
PopupWindow {
|
||||||
|
id: calPopup
|
||||||
|
anchor.item: clockText
|
||||||
|
anchor.edges: Edges.Bottom
|
||||||
|
anchor.gravity: Edges.Bottom
|
||||||
|
anchor.adjustment: PopupAdjustment.Slide
|
||||||
|
grabFocus: true
|
||||||
|
visible: false
|
||||||
|
color: "transparent"
|
||||||
|
implicitWidth: calContent.width + 2
|
||||||
|
implicitHeight: calContent.height + 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: calContent
|
||||||
|
width: calCol.width + 32
|
||||||
|
height: calCol.height + 24
|
||||||
|
color: "#${c.base00}"
|
||||||
|
border.color: "#${c.base03}"
|
||||||
|
border.width: 1
|
||||||
|
radius: 8
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: calCol
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
// Date header
|
||||||
|
Text {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: clockText.now.toLocaleDateString(Qt.locale(), "dddd, d MMMM yyyy")
|
||||||
|
color: "#${c.base05}"
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
// Day headers
|
||||||
|
Row {
|
||||||
|
spacing: 0
|
||||||
|
Repeater {
|
||||||
|
model: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]
|
||||||
|
Text {
|
||||||
|
required property var modelData
|
||||||
|
width: 28
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: modelData
|
||||||
|
color: "#${c.base03}"
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calendar grid
|
||||||
|
Grid {
|
||||||
|
columns: 7
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: calRepeater
|
||||||
|
model: 42
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
required property int index
|
||||||
|
width: 28
|
||||||
|
height: 24
|
||||||
|
radius: 4
|
||||||
|
color: {
|
||||||
|
let d = clockText.now;
|
||||||
|
let first = new Date(d.getFullYear(), d.getMonth(), 1);
|
||||||
|
let startDay = (first.getDay() + 6) % 7;
|
||||||
|
let dayNum = index - startDay + 1;
|
||||||
|
let daysInMonth = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
||||||
|
return (dayNum === d.getDate() && dayNum >= 1 && dayNum <= daysInMonth)
|
||||||
|
? "#${c.base02}" : "transparent";
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: {
|
||||||
|
let d = clockText.now;
|
||||||
|
let first = new Date(d.getFullYear(), d.getMonth(), 1);
|
||||||
|
let startDay = (first.getDay() + 6) % 7;
|
||||||
|
let dayNum = parent.index - startDay + 1;
|
||||||
|
let daysInMonth = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
||||||
|
return (dayNum >= 1 && dayNum <= daysInMonth) ? dayNum.toString() : "";
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
let d = clockText.now;
|
||||||
|
let first = new Date(d.getFullYear(), d.getMonth(), 1);
|
||||||
|
let startDay = (first.getDay() + 6) % 7;
|
||||||
|
let dayNum = parent.index - startDay + 1;
|
||||||
|
return (dayNum === d.getDate()) ? "#${c.base05}" : "#${c.base04}";
|
||||||
|
}
|
||||||
|
font.family: "FiraMono Nerd Font"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue