diff --git a/.config/opencode/AGENTS.md b/.config/opencode/AGENTS.md new file mode 100644 index 0000000..1103442 --- /dev/null +++ b/.config/opencode/AGENTS.md @@ -0,0 +1,3 @@ +# Agent Instructions + +If you're not sure about something, search it up on the web. diff --git a/.config/opencode/config.json b/.config/opencode/config.json index 70758c3..285d94e 100644 --- a/.config/opencode/config.json +++ b/.config/opencode/config.json @@ -1,12 +1,13 @@ { "$schema": "https://opencode.ai/config.json", + "instructions": ["AGENTS.md"], "provider": { "openwebui": { "npm": "@ai-sdk/openai-compatible", "name": "OpenWebUI", "options": { "baseURL": "https://ai.zamudio.dev/api", - "apiKey": "sk-777ecee5bc6f498bbd2c01b26677526c" + "apiKey": "{env:OPENWEBUI_API_KEY}" }, "models": { "Qwen3.6-35B-A3B": { diff --git a/.config/sway/config b/.config/sway/config index 215b4ee..48028c9 100644 --- a/.config/sway/config +++ b/.config/sway/config @@ -35,6 +35,8 @@ include ~/.config/sway/config.d/* bindswitch --reload --locked lid:on output $laptop disable bindswitch --reload --locked lid:off output $laptop enable exec_always --no-startup-id '/home/work/.config/sway/scripts/clamshell-mode.sh' +# Re-apply shikane display profile (scaling) after every sway reload +exec_always --no-startup-id shikanectl reload #input "1267:12792:ELAN067B:00_04F3:31F8_Touchpad" { # dwt enabled @@ -55,17 +57,18 @@ seat seat0 xcursor_theme Adwaita 35 exec systemctl --user start xdg-desktop-portal-wlr.service #exec pipewire exec swaync -exec shikane +exec_always --no-startup-id pkill -x waybar; waybar -c ~/.config/sway/waybar/config.jsonc -s ~/.config/sway/waybar/style.css exec nm-applet exec blueman-applet exec hypridle exec systemctl --user start hyperolkitagent -exec waybar -c ~/.config/sway/waybar/config.jsonc -s ~/.config/sway/waybar/style.css exec flatpak run com.github.wwmm.easyeffects -w exec xrdb -merge ~/.Xresources exec wl-paste -t text --watch clipman store --no-persist +exec tlpctl power-saver + #exec gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" #exec mpd @@ -90,7 +93,7 @@ bindsym $mod+Ctrl+y exec : | wl-copy -p #better audio #exec easyeffects -w -l Laptop -#default_border pixel 2 +default_border pixel 2 #default_floating_border pixel 2 exec systemctl --user import-environment XDG_SESSION_TYPE XDG_CURRENT_DESKTOP WAYLAND_DISPLAY SWAYSOCK exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP=sway XDG_SESSION_DESKTOP=sway diff --git a/.config/sway/config.d/keybinds b/.config/sway/config.d/keybinds index c4bfa24..cd00efb 100644 --- a/.config/sway/config.d/keybinds +++ b/.config/sway/config.d/keybinds @@ -13,7 +13,9 @@ bindsym $mod+d exec $menu # Despite the name, also works for non-floating windows. # Change normal to inverse to use left mouse button for resizing and right # mouse button for dragging. -floating_modifier $mod normal +# DISABLED 2026-09-28: experiment for windows popping out (accidental mod+click) +#floating_modifier $mod normal +floating_modifier none # Reload the configuration file bindsym $mod+Shift+c reload diff --git a/.config/sway/config.d/swayfx b/.config/sway/config.d/swayfx index 1039db9..8bd7b45 100644 --- a/.config/sway/config.d/swayfx +++ b/.config/sway/config.d/swayfx @@ -1,34 +1,45 @@ #smart_corner_radius on -gaps inner 2 +# ╔══════════════════════════════════════════════════════════════════╗ +# ║ COLOR PALETTE ║ +# ║ To change colors: ║ +# ║ 1. Edit the $base00–$base0F values below ║ +# ║ 2. Mirror those hex values in ~/.config/sway/waybar/style.css ║ +# ║ (search for @define-color and replace the hex codes) ║ +# ║ 3. Run: swaymsg reload ║ +# ╚══════════════════════════════════════════════════════════════════╝ + +gaps inner 2 default_border pixel 2 -#corner_radius 8 -#blur enable -#blur_passes 2 -#blur_radius 2 -#layer_effects "waybar" "blur enable"; shadows enable -#shadows on -#shadow_blur_radius 5 +# ╔══════════════════════════════════════════════════════════════════╗ +# ║ COLOR PALETTE (your 5 colors + black) ║ +# ║ ║ +# ║ To change colors: ║ +# ║ 1. Edit the $base00–$base0F hex values below ║ +# ║ 2. Mirror those hex values in ~/.config/sway/waybar/style.css ║ +# ║ (search for @define-color and replace the hex codes) ║ +# ║ 3. Run: swaymsg reload ║ +# ╚══════════════════════════════════════════════════════════════════╝ -#https://github.com/rkubosz/base16-sway +set $base00 #000000 +set $base01 #111111 +set $base02 #222222 +set $base03 #333333 +set $base04 #666666 +set $base05 #999999 +set $base06 #CCCCCC +set $base07 #FFFFFF +set $base08 #999999 +set $base09 #999999 +set $base0A #CCCCCC +set $base0B #999999 +set $base0C #CCCCCC +set $base0D #999999 +set $base0E #CCCCCC +set $base0F #666666 -set $base00 #031A16 -set $base01 #0B342D -set $base02 #184E45 -set $base03 #2B685E -set $base04 #5F9C92 -set $base05 #81B5AC -set $base06 #A7CEC8 -set $base07 #D2E7E4 -set $base08 #3E9688 -set $base09 #3E7996 -set $base0A #3E4C96 -set $base0B #883E96 -set $base0C #963E4C -set $base0D #96883E -set $base0E #4C963E -set $base0F #3E965B +# base00-02=bg #3E3B33, base03=olive #8C9A6B, base04=peach #F3B49F, base05=rust #D9714C, base06-07=cream #FFE8DB #set $base00 #000000 #set $base01 #121212 @@ -48,9 +59,9 @@ set $base0F #3E965B #set $base0F #444444 # Property Name Border BG Text Indicator Child Border -client.focused $base05 $base0D $base00 $base0D $base0D -client.focused_inactive $base01 $base01 $base05 $base03 $base01 -client.unfocused $base01 $base00 $base05 $base01 $base01 -client.urgent $base08 $base08 $base00 $base08 $base08 +client.focused #FFFFFF $base00 #FFFFFF #FFFFFF $base00 +client.focused_inactive $base02 $base00 $base05 $base03 $base02 +client.unfocused $base01 $base00 $base05 $base03 $base01 +client.urgent #FFA14C #FFA14C $base00 #FFA14C #FFA14C client.placeholder $base00 $base00 $base05 $base00 $base00 -client.background $base07 +client.background $base00 diff --git a/.config/sway/config.d/windows b/.config/sway/config.d/windows index 4382ab1..0e70bb7 100644 --- a/.config/sway/config.d/windows +++ b/.config/sway/config.d/windows @@ -10,7 +10,7 @@ for_window [window_type="menu"] floating enable for_window [shell="xwayland"] title_format "[XWayland] %title" for_window [title="LUCID"] floating enable -for_window [title="Pydm|pydm"] floating enable +for_window [title="(?i)pydm"] floating enable for_window [title="Form"] floating enable for_window [title="zoom"] floating enable diff --git a/.config/sway/quickshell/shell.qml b/.config/sway/quickshell/shell.qml new file mode 100644 index 0000000..d6e4526 --- /dev/null +++ b/.config/sway/quickshell/shell.qml @@ -0,0 +1,357 @@ +import Quickshell._Window +import Quickshell.I3 +import Quickshell.Services.UPower +import Quickshell.Services.Pipewire +import Quickshell.Services.SystemTray +import Quickshell +import Quickshell.Widgets +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +FloatingWindow { + id: root + title: "Quickshell Bar" + visible: true + implicitWidth: 1920 + implicitHeight: 40 + + property string mode: "" + property string windowTitle: "" + + Component.onCompleted: { + I3.rawEvent.connect(handleRawEvent) + pollWindowTitle() + pinBar() + } + + function pinBar() { + I3.dispatch('[title="Quickshell Bar"] floating enable') + I3.dispatch('[title="Quickshell Bar"] move absolute position 0 0') + I3.dispatch('[title="Quickshell Bar"] resize set 1920 40') + I3.dispatch('[title="Quickshell Bar"] sticky enable') + } + + function handleRawEvent(event) { + if (event.type === "mode") { + root.mode = event.data === "default" ? "" : event.data + } + if (event.type === "window" || event.type === "workspace") { + pollWindowTitle() + } + } + + function pollWindowTitle() { + try { + var ws = I3.focusedWorkspace + if (ws && ws.lastIpcObject) { + root.windowTitle = findFocusedTitle(ws.lastIpcObject.nodes || []) + } + } catch (e) { root.windowTitle = "" } + } + + function findFocusedTitle(nodes) { + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i] + if (n.focused && n.name && !["$external", "i3bar"].includes(n.name)) { + return n.name + } + if (n.nodes && findFocusedTitle(n.nodes)) return findFocusedTitle(n.nodes) + if (n.floating_nodes) { + for (var j = 0; j < n.floating_nodes.length; j++) { + var fn = n.floating_nodes[j] + if (fn.focused && fn.name && fn.name !== "$external") return fn.name + } + } + } + return "" + } + + function wsColor(num) { + var colors = ["#eb4d4b", "#64727D", "#f7ca18", "#fb6f92", + "#2ecc71", "#2980b9", "#f7768e", "#667581"] + return colors[num % 8] || colors[0] + } + + function updateBattery() { + if (!UPower.displayDevice || !UPower.displayDevice.isReady || + !UPower.displayDevice.powerSupply) { + batteryLabel.text = "" + return + } + var dev = UPower.displayDevice + var pct = Math.round(dev.percentage) + var state = dev.state + batteryItem.isCritical = pct <= 15 && state === 2 + + if (state === 4) { batteryLabel.text = pct + "%"; return } + + var timeStr = "" + var seconds = 0 + if (state === 1 || state === 5) seconds = dev.timeToFull * 60 + else if (state === 2 || state === 6) seconds = dev.timeToEmpty * 60 + + if (seconds > 0 && seconds < 86400) { + var h = Math.floor(seconds / 3600) + var m = Math.floor((seconds % 3600) / 60) + timeStr = h > 0 ? h + ":" + m.toString().padStart(2, '0') + " " : m + "m " + } + + var suffix = "" + if (state === 1 || state === 5) suffix = " C" + else if (state === 3) suffix = " P" + + batteryLabel.text = timeStr + pct + "%" + suffix + } + + // Background + Rectangle { + anchors.fill: parent + color: "black" + z: 0 + } + + // Bar content + RowLayout { + anchors.fill: parent + anchors.leftMargin: 4 + anchors.rightMargin: 4 + anchors.top: parent.top + anchors.bottom: parent.bottom + spacing: 2 + z: 1 + + // LEFT SECTION + Item { + Layout.fillWidth: true + Layout.maximumWidth: root.implicitWidth * 0.33 + + RowLayout { + anchors.fill: parent + spacing: 2 + + // Workspaces + RowLayout { + Layout.fillWidth: true + Layout.maximumWidth: 600 + spacing: 2 + + Repeater { + model: I3.workspaces + + delegate: QQC2.ToolButton { + id: wsBtn + property bool isFocused: modelData.focused + property int wsNum: modelData.number + + text: modelData.name + visible: modelData.active || modelData.focused || modelData.urgent + highlighted: isFocused + checkable: true + checked: isFocused + down: isFocused + + onClicked: { + if (modelData.activate) modelData.activate() + else I3.dispatch(`workspace ${modelData.name}`) + } + + font.pixelSize: 14 + font.bold: true + width: implicitWidth + 8 + padding: 0 + + palette { + button: isFocused ? wsColor(wsNum) : "transparent" + buttonText: "#ffffff" + } + + // Hover underline + background: Rectangle { + anchors.fill: parent + color: "transparent" + Rectangle { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 3 + color: wsBtn.hovered || wsBtn.isFocused ? "#ffffff" : "transparent" + } + } + } + } + } + + // Mode indicator + QQC2.Label { + text: root.mode + visible: root.mode !== "" + color: "#64727D" + font.pixelSize: 14 + font.bold: true + font.italic: true + padding: 10 + } + + // Window title + QQC2.Label { + text: root.windowTitle + visible: root.windowTitle !== "" + Layout.fillWidth: true + Layout.maximumWidth: 300 + elide: Text.ElideMiddle + color: "#ffffff" + font.pixelSize: 14 + font.bold: true + padding: 10 + } + } + } + + // Spacer + Item { Layout.fillWidth: true } + + // RIGHT SECTION + RowLayout { + spacing: 2 + + // Volume + Item { + height: parent.height + + QQC2.Label { + id: volumeLabel + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + anchors.verticalCenter: parent.verticalCenter + color: "#ffffff" + font.pixelSize: 14 + font.bold: true + horizontalAlignment: Text.AlignHCenter + + text: { + if (!Pipewire.ready || !Pipewire.defaultAudioSink) return "" + var sink = Pipewire.defaultAudioSink + var vol = sink.audio ? sink.audio.averageVolume * 100 : 0 + var muted = sink.audio ? sink.audio.isMuted : false + return muted ? "Muted" : Math.round(vol) + "%" + } + + MouseArea { + anchors.fill: parent + onClicked: Qt.shellCommand("pavucontrol") + onWheel: function(event) { + if (Pipewire.ready && Pipewire.defaultAudioSink && + Pipewire.defaultAudioSink.audio) { + var v = Pipewire.defaultAudioSink.audio.averageVolume + var step = event.angleDelta.y > 0 ? 0.05 : -0.05 + Pipewire.defaultAudioSink.audio.averageVolume = + Math.max(0, Math.min(1, v + step)) + } + } + } + } + } + + // Battery + Item { + id: batteryItem + height: parent.height + property bool isCritical: false + + QQC2.Label { + id: batteryLabel + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + anchors.verticalCenter: parent.verticalCenter + color: batteryItem.isCritical ? "#f53c3c" : "#ffffff" + font.pixelSize: 14 + font.bold: true + horizontalAlignment: Text.AlignHCenter + } + + Timer { + interval: 5000 + running: true + repeat: true + onTriggered: root.updateBattery() + } + + Component.onCompleted: root.updateBattery() + } + + // Clock + Item { + height: parent.height + + QQC2.Label { + id: clockLabel + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + anchors.verticalCenter: parent.verticalCenter + color: "#ffffff" + font.pixelSize: 14 + font.bold: true + horizontalAlignment: Text.AlignHCenter + } + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + var now = new Date() + var h = now.getHours() + var ampm = h >= 12 ? "PM" : "AM" + h = h % 12 || 12 + var time = h + ":" + now.getMinutes().toString().padStart(2, '0') + + ":" + now.getSeconds().toString().padStart(2, '0') + " " + ampm + var date = now.getFullYear() + "-" + + (now.getMonth()+1).toString().padStart(2, '0') + "-" + + now.getDate().toString().padStart(2, '0') + clockLabel.text = time + " " + date + } + } + } + + // System Tray + Item { + id: trayContainer + height: parent.height + + Repeater { + model: SystemTray.items + + delegate: Item { + width: 24 + height: trayContainer.height + + IconImage { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 2 + width: 22 + height: 22 + source: modelData.iconName || "" + visible: source !== "" + + MouseArea { + anchors.fill: parent + onClicked: function(mouse) { + if (modelData.hasMenu) { + modelData.display(QsWindowAttached.window, 0, 0) + } else { + modelData.activate() + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/.config/sway/waybar/config.jsonc b/.config/sway/waybar/config.jsonc index d9160df..4ba8575 100644 --- a/.config/sway/waybar/config.jsonc +++ b/.config/sway/waybar/config.jsonc @@ -4,6 +4,7 @@ "modules-left": [ "sway/workspaces", "sway/submap", + "sway/scratchpad", "sway/window" ], //"modules-center": [ @@ -22,7 +23,7 @@ "format": "{}" }, "sway/scratchpad": { - "format": "{count}", + "format": "S{count}", "show-empty": false, "tooltip": true, "tooltip-format": "{app}: {title}" diff --git a/.config/sway/waybar/style.css b/.config/sway/waybar/style.css index e1ecc95..510756d 100644 --- a/.config/sway/waybar/style.css +++ b/.config/sway/waybar/style.css @@ -1,17 +1,51 @@ +/* + * Waybar theme — unified with sway color palette. + * + * ╔══════════════════════════════════════════════════════════════════╗ + * ║ COLOR PALETTE ║ + * ║ To change colors: ║ + * ║ 1. Edit the $base00–$base0F values in ║ + * ║ ~/.config/sway/config.d/swayfx ║ + * ║ 2. Mirror those hex values in the @define-color block below ║ + * ║ 3. Run: swaymsg reload ║ + * ╚══════════════════════════════════════════════════════════════════╝ + */ + +/* ── Palette (your 5 colors + black) ── */ +@define-color bg #000000; +@define-color bg-dark #000000; +@define-color bg-mid #000000; +@define-color bg-light #333333; +@define-color fg-dim #666666; +@define-color fg #999999; +@define-color fg-bright #CCCCCC; +@define-color fg-max #FFFFFF; +@define-color teal #999999; +@define-color blue #999999; +@define-color indigo #CCCCCC; +@define-color magenta #999999; +@define-color red #CCCCCC; +@define-color yellow #999999; +@define-color orange #999999; +@define-color green #CCCCCC; +@define-color cyan #666666; + +/* ── Semantic aliases ── */ +@define-color highlight @blue; +@define-color accent @teal; +@define-color urgent @red; +@define-color warning @yellow; +@define-color success @green; + * { - /* `otf-font-awesome` is required to be installed for icons */ - /*font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif; */ - /*font-family: "JetBrainsMono NF";*/ font-family: "JetBrainsMonoNFM-Regular"; font-size: 14px; font-weight: bold; } window#waybar { - /*background-color: rgba(43, 48, 59, 0.5); - border-bottom: 3px solid rgba(100, 114, 125, 0.5); */ - background-color: rgba(0, 0, 0, 1); - color: #ffffff; + background-color: @bg; + color: @fg; transition-property: background-color; transition-duration: .5s; } @@ -20,57 +54,44 @@ window#waybar.hidden { opacity: 0.2; } -window#waybar.empty { - /*background-color: transparent;*/ -} -window#waybar.solo { - /*background-color: #FFFFFF;*/ -} - - +/* ── Buttons ── */ button { - /* Use box-shadow instead of border so the text isn't offset */ box-shadow: inset 0 -3px transparent; - /* Avoid rounded borders under each button name */ border: none; border-radius: 0; } -/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ button:hover { background: inherit; - box-shadow: inset 0 -3px #ffffff; -} - -/* you can set a style on hover for any module like this */ -#pulseaudio:hover { - /*background-color: #a37800;*/ + box-shadow: inset 0 -3px @fg-bright; } +/* ── Workspaces ── */ #workspaces button { padding: 0 4px; - /*background-color: transparent;*/ - color: #ffffff; + color: @fg-dim; } #workspaces button:hover { - background: rgba(0, 0, 0, 0.2); + background: @bg-mid; } #workspaces button.focused { - background-color: #64727D; - /*box-shadow: inset 0 -3px #ffffff;*/ + background-color: @highlight; + color: @bg; } #workspaces button.urgent { - background-color: #eb4d4b; + background-color: @urgent; } +/* ── Mode indicator ── */ #mode { - background-color: #64727D; - box-shadow: inset 0 -3px #ffffff; + background-color: @blue; + box-shadow: inset 0 -3px @fg-bright; } +/* ── Common module spacing ── */ #clock, #battery, #cpu, @@ -89,49 +110,38 @@ button:hover { #power-profiles-daemon, #mpd { padding: 0 10px; - color: #ffffff; + color: @fg; } +/* ── Window & workspace margins ── */ #window, #workspaces { margin: 0 4px; } -/* If workspaces is the leftmost module, omit left margin */ .modules-left > widget:first-child > #workspaces { margin-left: 0; } -/* If workspaces is the rightmost module, omit right margin */ .modules-right > widget:last-child > #workspaces { margin-right: 0; } -#clock { - /* background-color: #64727D;*/ -} - -#battery { - /*background-color: #ffffff; - color: #000000;*/ -} - +/* ── Battery ── */ #battery.charging, #battery.plugged { - /*color: #ffffff; - background-color: #26A65B;*/ + color: @teal; } @keyframes blink { to { - background-color: #ffffff; - color: #000000; + background-color: @fg-bright; + color: @bg; } } -/* Using steps() instead of linear as a timing function to limit cpu usage */ #battery.critical:not(.charging) { - background-color: #f53c3c; - color: #ffffff; + background-color: @urgent; + color: @fg-max; animation-name: blink; animation-duration: 0.5s; animation-timing-function: steps(12); @@ -139,146 +149,191 @@ button:hover { animation-direction: alternate; } +/* ── Power profiles ── */ #power-profiles-daemon { padding-right: 15px; } #power-profiles-daemon.performance { - background-color: #f53c3c; - color: #ffffff; + background-color: @urgent; + color: @fg-max; } #power-profiles-daemon.balanced { - background-color: #2980b9; - color: #ffffff; + background-color: @blue; + color: @fg-max; } #power-profiles-daemon.power-saver { - background-color: #2ecc71; - color: #000000; + background-color: @success; + color: @bg; } -label:focus { - background-color: #000000; +/* ── Scratchpad ── */ +#scratchpad { + background-color: transparent; + color: @fg-dim; + opacity: 0.5; + padding: 0 6px; } -#cpu { - background-color: #2ecc71; - color: #000000; +#scratchpad:hover { + opacity: 0.8; } -#memory { - background-color: #9b59b6; +#scratchpad.empty { + background-color: transparent; } -#disk { - background-color: #964B00; +/* ── Clock ── */ +#clock { + /* background-color: @highlight; */ } -#backlight { - background-color: #90b1b1; -} - -#network { - /*background-color: #2980b9;*/ -} - -#network.disconnected { - /*background-color: #f53c3c;*/ -} - -#pulseaudio { - /*background-color: #f1c40f;*/ - /*color: #000000;*/ -} - -#pulseaudio.muted { - /*background-color: #90b1b1;*/ - /*color: #2a5c45;*/ -} - -#wireplumber { - background-color: #fff0f5; - color: #000000; -} - -#wireplumber.muted { - background-color: #f53c3c; -} - -#custom-media { - background-color: #66cc99; - color: #2a5c45; - min-width: 100px; -} - -#custom-media.custom-spotify { - background-color: #66cc99; -} - -#custom-media.custom-vlc { - background-color: #ffa000; -} - -#temperature { - background-color: #f0932b; -} - -#temperature.critical { - background-color: #eb4d4b; -} - -#tray { - /*background-color: #2980b9;*/ +/* ── Battery ── */ +#battery { + /* background-color: @fg-max; + color: @bg; */ } +/* ── Tray ── */ #tray > .passive { -gtk-icon-effect: dim; } #tray > .needs-attention { -gtk-icon-effect: highlight; - background-color: #eb4d4b; + background-color: @urgent; } +/* ── Pulseaudio ── */ +#pulseaudio:hover { + /* hover style optional */ +} + +#pulseaudio.muted { + color: @fg-dim; +} + +/* ── Idle inhibitor ── */ #idle_inhibitor { - background-color: #2d3436; + background-color: @bg-dark; } #idle_inhibitor.activated { - background-color: #ecf0f1; - color: #2d3436; + background-color: @fg-bright; + color: @bg-dark; +} + +label:focus { + background-color: @bg; +} + +/* ── Legacy module styles (if ever enabled) ── */ +#cpu { + background-color: @success; + color: @bg; +} + +#memory { + background-color: @magenta; +} + +#disk { + background-color: @warning; +} + +#backlight { + background-color: @bg-light; +} + +#network.disconnected { + background-color: @urgent; +} + +#wireplumber { + background-color: @fg-max; + color: @bg; +} + +#wireplumber.muted { + background-color: @urgent; +} + +#custom-media { + background-color: @cyan; + color: @bg-dark; + min-width: 100px; +} + +#custom-media.custom-spotify { + background-color: @cyan; +} + +#custom-media.custom-vlc { + background-color: @warning; +} + +#temperature { + background-color: @warning; +} + +#temperature.critical { + background-color: @urgent; } #mpd { - background-color: #66cc99; - color: #2a5c45; + background-color: @cyan; + color: @bg-dark; } #mpd.disconnected { - background-color: #f53c3c; + background-color: @urgent; } #mpd.stopped { - background-color: #90b1b1; + background-color: @bg-light; } #mpd.paused { - background-color: #51a37a; + background-color: @accent; } +/* ── Privacy items ── */ +#privacy { + padding: 0; +} + +#privacy-item { + padding: 0 5px; + color: @fg-max; +} + +#privacy-item.screenshare { + background-color: @orange; +} + +#privacy-item.audio-in { + background-color: @success; +} + +#privacy-item.audio-out { + background-color: @blue; +} + +/* ── Language & keyboard ── */ #language { - background: #00b093; - color: #740864; + background: @teal; + color: @bg; padding: 0 5px; margin: 0 5px; min-width: 16px; } #keyboard-state { - background: #97e1ad; - color: #000000; - padding: 0 0px; + background: @teal; + color: @bg; + padding: 0; margin: 0 5px; min-width: 16px; } @@ -288,34 +343,5 @@ label:focus { } #keyboard-state > label.locked { - background: rgba(0, 0, 0, 0.2); -} - -#scratchpad { - background: rgba(0, 0, 0, 0.2); -} - -#scratchpad.empty { - background-color: transparent; -} - -#privacy { - padding: 0; -} - -#privacy-item { - padding: 0 5px; - color: white; -} - -#privacy-item.screenshare { - background-color: #cf5700; -} - -#privacy-item.audio-in { - background-color: #1ca000; -} - -#privacy-item.audio-out { - background-color: #0069d4; -} + background: @bg-dark; +} \ No newline at end of file diff --git a/.config/systemd/user/shikane.service b/.config/systemd/user/shikane.service index 6ada273..df8b41a 100644 --- a/.config/systemd/user/shikane.service +++ b/.config/systemd/user/shikane.service @@ -1,10 +1,17 @@ [Unit] Description=shikane +PartOf=graphical-session.target +After=graphical-session.target +Requisite=graphical-session.target +# Recover from crashes without giving up permanently +StartLimitIntervalSec=60 +StartLimitBurst=10 [Service] +Type=simple ExecStart=/usr/bin/shikane -Restart=always -RestartSec=1 +Restart=on-failure +RestartSec=2 [Install] -WantedBy=default.target +WantedBy=sway-session.target diff --git a/.config/systemd/user/sway-session.target b/.config/systemd/user/sway-session.target new file mode 100644 index 0000000..30151b3 --- /dev/null +++ b/.config/systemd/user/sway-session.target @@ -0,0 +1,6 @@ +[Unit] +Description=sway compositor session +Documentation=man:systemd.special(7) +BindsTo=graphical-session.target +Wants=graphical-session-pre.target +After=graphical-session-pre.target diff --git a/.config/systemd/user/default.target.wants/shikane.service b/.config/systemd/user/sway-session.target.wants/shikane.service similarity index 100% rename from .config/systemd/user/default.target.wants/shikane.service rename to .config/systemd/user/sway-session.target.wants/shikane.service