6 Commits
Author SHA1 Message Date
jozamudi 63345e51e3 unify color palette, harden shikane service, misc sway/opencode updates
sway:
- config: re-apply shikane profile after every reload
  (exec_always shikanectl reload); restart waybar on reload
  (exec_always pkill+waybar); enable default_border pixel 2;
  add tlpctl power-saver at startup
- keybinds: disable floating_modifier (was "$mod normal") -
  experiment for windows popping out via accidental mod+click
- windows: case-insensitive pydm title match for floating rule
- swayfx + waybar style: unified 5-color palette (base00-0F) with
  doc headers; waybar theme restyled to match the sway palette
- waybar config: scratchpad module in left bar, "S{count}" format
- new quickshell shell.qml bar

systemd user units:
- shikane.service: bind to graphical-session/sway-session targets,
  Type=simple, Restart=on-failure (2s) with start limits so crashes
  recover without giving up permanently
- new sway-session.target and its wants/ symlinks

opencode:
- load AGENTS.md as instructions (new file)
- move OpenWebUI API key from hardcoded to {env:OPENWEBUI_API_KEY}
2026-09-28 14:04:22 -07:00
jozamudi e338d15922 add shikane-watchdog user service to auto-recover shikane deadlocks 2026-09-28 14:04:22 -07:00
jozamudi e3643c3ae2 fix(nvim): use clipboard:append for unnamedplus; add sway dbus-update script 2026-07-06 16:13:38 -07:00
jozamudi cc949db097 Fix sway session setup and migrate waybar to sway modules
- Start xdg-desktop-portal-wlr and sway-session.target for proper portal init
- Re-enable systemd/dbus environment import for Wayland session vars
- Move hypridle startup earlier
- Switch waybar left modules from hyprland/* to sway/*
2026-06-10 18:10:43 -07:00
jozamudi b4b2ca0d43 refactor: strip waybar icons, disable pseudotile/VFR, clean up configs
Waybar:
- Remove Nerd Font icons from battery, power, audio, media modules
- Switch power profile to text format, simplify all format strings
- Mango config: switch sway/* to hyprland/* modules, remove unused modules

Hyprland:
- Disable pseudotile and VFR

Sway:
- Fix clamshell script path (jozamudi -> work)
- Comment out gsettings, systemctl, dbus exec lines
- Delete unused env.sh script

Other:
- Delete nvim llm plugin and opencode coding-partner agent
- Delete Zoom and Nextcloud desktop entries
- Migrate Discord to Flatpak
- Rotate opencode API key
- Add extended-keys to tmux config
- Clear defaults.list
2026-06-03 10:11:06 -07:00
jozamudi b52849f1dc add opencode configuration with symlink support 2026-05-07 09:52:03 -07:00
31 changed files with 848 additions and 769 deletions

No files matched your search

+2 -2
View File
@@ -196,7 +196,7 @@ animations {
# See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more
dwindle {
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
#pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # You probably want this
}
@@ -209,7 +209,7 @@ master {
misc {
force_default_wallpaper = 0 # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = true# If true disables the random hyprland logo / anime girl background. :(
vfr = true
#vfr = true
}
xwayland {
+19 -32
View File
@@ -22,9 +22,8 @@
"format": "<span style=\"italic\">{}</span>"
},
"sway/scratchpad": {
"format": "{icon} {count}",
"format": "{count}",
"show-empty": false,
"format-icons": ["", ""],
"tooltip": true,
"tooltip-format": "{app}: {title}"
},
@@ -49,65 +48,53 @@
"warning": 30,
"critical": 15
},
"format": "{time} {capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format": "{time} {capacity}%",
"format-full": "{capacity}%",
"format-charging": "{capacity}% C",
"format-plugged": "{capacity}% P",
"format-alt": "{time} {icon}",
"format-alt": "{time}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
"bat": "BAT2"
},
"power-profiles-daemon": {
"format": "{icon}",
"format": "{profile}",
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
"tooltip": true,
"format-icons": {
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
"format-icons": {"default": [""]}
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected ⚠",
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected",
"format-disconnected": "Disconnected",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"pulseaudio": {
// "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon}  {format_source}",
"format-bluetooth-muted": " {icon}  {format_source}",
"format": "{volume}% {format_source}",
"format-bluetooth": "{volume}% {format_source}",
"format-bluetooth-muted": " {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}%",
"format-source-muted": "",
"format-source": "{volume}%",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
"default": [""]
},
"on-click": "pavucontrol"
},
"custom/media": {
"format": "{icon} {text}",
"format": "{text}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
"default": ""
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
+28 -176
View File
@@ -1,125 +1,32 @@
// -*- mode: jsonc -*-
{
// "layer": "top", // Waybar at top layer
// "position": "bottom", // Waybar position (top|bottom|left|right)
//"height": 10, // Waybar height (to be removed for auto height)
// "width": 1280, // Waybar width
"spacing": 6, // Gaps between modules (4px)
// Choose the order of the modules
"spacing": 2, // Gaps between modules (4px)
"modules-left": [
"ext/workspaces",
"dwl/window",
"sway/mode",
"sway/scratchpad",
"custom/media"
"hyprland/workspaces",
"hyprland/submap",
"hyprland/window"
],
//"modules-center": [
//"sway/window"
//],
"modules-right": [
"mpd",
"custom/audio_idle_inhibitor",
//"mpd",
"pulseaudio",
"network",
//"power-profiles-daemon",
//"cpu",
//"memory",
//"temperature",
//"backlight",
//"keyboard-state",
//"sway/language",
//"network",
"battery",
//"battery#bat2",
"clock",
"tray"
//"custom/power"
],
"ext/workspaces": {
"format": "{icon}",
"ignore-hidden": true,
"on-click": "activate",
"on-click-right": "deactivate",
"sort-by-id": true,
},
"dwl/tags": {
"num-tags":9,
},
"dwl/window": {
"format": "[{layout}] {title}"
//"format": "[{layout}]"
},
// Modules configuration
// "sway/workspaces": {
// "disable-scroll": true,
// "all-outputs": true,
// "warp-on-scroll": false,
// "format": "{name}: {icon}",
// "format-icons": {
// "1": "",
// "2": "",
// "3": "",
// "4": "",
// "5": "",
// "urgent": "",
// "focused": "",
// "default": ""
// }
// },
"keyboard-state": {
"numlock": true,
"capslock": true,
"format": "{name} {icon}",
"format-icons": {
"locked": "",
"unlocked": ""
}
},
"sway/mode": {
"format": "<span style=\"italic\">{}</span>"
},
"sway/scratchpad": {
"format": "{icon} {count}",
"format": "{count}",
"show-empty": false,
"format-icons": ["", ""],
"tooltip": true,
"tooltip-format": "{app}: {title}"
},
"mpd": {
"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {title} ⸨{songPosition}|{queueLength}⸩% ",
"format-alt": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩% ",
"format-disconnected": "Disconnected ",
//"format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ",
"format-stopped": "",
//"unknown-tag": "N/A",
"unknown-tag": "",
"interval": 5,
"consume-icons": {
"on": " "
},
"random-icons": {
"off": "<span color=\"#f53c3c\"></span> ",
"on": " "
},
"repeat-icons": {
"on": " "
},
"single-icons": {
"on": "1 "
},
"state-icons": {
"paused": "",
"playing": ""
},
"tooltip-format": "MPD (connected)",
"tooltip-format-disconnected": "MPD (disconnected)"
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "",
"deactivated": ""
}
},
"tray": {
// "icon-size": 21,
"spacing": 10,
@@ -135,117 +42,62 @@
//"format": "{:%R %p %Y-%m-%d}",
//"format-alt": "{:%Y-%m-%d}"
},
"cpu": {
"format": "{usage}% ",
"tooltip": false
},
"memory": {
"format": "{}% "
},
"temperature": {
// "thermal-zone": 2,
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
"critical-threshold": 80,
// "format-critical": "{temperatureC}°C {icon}",
"format": "{temperatureC}°C {icon}",
"format-icons": ["", "", ""]
},
"backlight": {
// "device": "acpi_video1",
"format": "{percent}% {icon}",
"format-icons": ["", "", "", "", "", "", "", "", ""]
},
"battery": {
"states": {
// "good": 95,
"warning": 30,
"critical": 15
},
"format": "{time} {capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format": "{time} {capacity}%",
"format-full": "{capacity}%",
"format-charging": "{capacity}% C",
"format-plugged": "{capacity}% P",
"format-alt": "{time} {icon}",
"format-alt": "{time}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
"bat": "BAT2"
},
"power-profiles-daemon": {
"format": "{icon}",
"format": "{profile}",
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
"tooltip": true,
"format-icons": {
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
"format-icons": {"default": [""]}
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
"format-wifi": "{essid} ({signalStrength}%) ",
"format-ethernet": "{ipaddr}/{cidr} ",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected",
"format-disconnected": "Disconnected",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"pulseaudio": {
// "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon}  {format_source}",
"format-bluetooth-muted": " {icon} {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}%",
"format-source-muted": "",
"format": "{volume}% {format_source}",
"format-bluetooth": "{volume}% {format_source}",
"format-bluetooth-muted": " {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}%",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
"default": [""]
},
"on-click": "pavucontrol"
},
"custom/media": {
"format": "{icon} {text}",
"format": "{text}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
"default": ""
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
},
"custom/power": {
"format" : "⏻ ",
"tooltip": false,
"menu": "on-click",
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
"menu-actions": {
"shutdown": "shutdown",
"reboot": "reboot",
"suspend": "systemctl suspend",
"hibernate": "systemctl hibernate"
}
},
"custom/audio_idle_inhibitor": {
"format": "{icon} ",
"exec": "sway-audio-idle-inhibit --dry-print-both-waybar",
"exec-if": "which sway-audio-idle-inhibit",
"return-type": "json",
"format-icons": {
"output": "",
"input": "",
"output-input": " ",
"none": ""
}
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ vim.o.background = "dark" -- or "light" for light mode
--vim.cmd("colorscheme gruvbox ")
--vim.cmd("colorscheme retrobox")
-- vim.opt.clipboard = "unnamedplus" -- uses the clipboard register for all operations except yank.
vim.opt.clipboard:append("unnamedplus") -- sync yank/delete/put with system clipboard
vim.cmd("set nocompatible")
vim.cmd("syntax on")
-52
View File
@@ -1,52 +0,0 @@
return {
"huggingface/llm.nvim",
config = function()
local llm = require('llm')
llm.setup({
api_token = nil, -- cf Install paragraph
model = "Qwen/Qwen3.5-9B", -- the model ID, behavior depends on backend
backend = "openai", -- backend ID, "huggingface" | "ollama" | "openai" | "tgi"
url = "http://192.168.200.12:8123", -- the http url of the backend
tokens_to_clear = { "<|endoftext|>" }, -- tokens to remove from the model's output
-- parameters that are added to the request body, values are arbitrary, you can set any field:value pair here it will be passed as is to the backend
request_body = {
temperature=0.6,
top_p=0.95,
top_k=20,
min_p=0.0,
presence_penalty=0.0,
repetition_penalty=1.0,
max_new_tokens = 2000,
chat_template_kwargs='{"enable_thinking": False}',
},
-- set this if the model supports fill in the middle
fim = {
enabled = true,
prefix = "<|fim_prefix|>",
middle = "<|fim_middle|>",
suffix = "<|fim_suffix|>",
},
debounce_ms = 100,
accept_keymap = "<Tab>",
dismiss_keymap = "<S-Tab>",
tls_skip_verify_insecure = false,
-- llm-ls configuration, cf llm-ls section
--lsp = {
-- bin_path = nil,
-- host = nil,
-- port = nil,
-- cmd_env = nil, -- or { LLM_LOG_LEVEL = "DEBUG" } to set the log level of llm-ls
-- version = "0.5.3",
--},
tokenizer = {
repository = "Qwen/Qwen3.5-9B",
api_token = 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,
}, -- cf Tokenizer paragraph
context_window = 5000, -- max number of tokens for the context window
enable_suggestions_on_startup = false,
enable_suggestions_on_files = "*", -- pattern matching syntax to enable suggestions on specific files, either a string or a list of strings
disable_url_path_completion = false, -- cf Backend
})
end
}
+3
View File
@@ -0,0 +1,3 @@
# Agent Instructions
If you're not sure about something, search it up on the web.
+22
View File
@@ -0,0 +1,22 @@
{
"$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": "{env:OPENWEBUI_API_KEY}"
},
"models": {
"Qwen3.6-35B-A3B": {
"name": "Qwen3.6-35B-A3B"
},
"Qwen3.6-27B": {
"name": "Qwen3.6-27B"
}
}
}
}
}
+14 -8
View File
@@ -34,7 +34,9 @@ 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/jozamudi/.config/sway/scripts/clamshell-mode.sh'
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
@@ -52,20 +54,22 @@ exec_always --no-startup-id '/home/jozamudi/.config/sway/scripts/clamshell-mode.
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 hypridle
exec gsettings set org.gnome.desktop.interface color-scheme "prefer-dark"
exec tlpctl power-saver
#exec gsettings set org.gnome.desktop.interface color-scheme "prefer-dark"
#exec mpd
#exec syncthing
@@ -89,9 +93,11 @@ 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
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
# Activate graphical-session.target so xdg-desktop-portal (Requisite=graphical-session.target) can start
exec systemctl --user start sway-session.target
#exec --no-startup-id dbus-update-activation-environment --all
+3 -1
View File
@@ -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
+41 -30
View File
@@ -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
+1 -1
View File
@@ -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
+357
View File
@@ -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()
}
}
}
}
}
}
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
dbus-update-activation-environment --systemd \
WAYLAND_DISPLAY \
DISPLAY \
SWAYSOCK \
XDG_SESSION_DESKTOP=sway \
XDG_SESSION_CLASS=user \
XDG_SEAT=seat0 \
XCURSOR_THEME=Adwaita \
XCURSOR_SIZE=35 \
GDK_BACKEND=wayland \
SDL_VIDEODRIVER=wayland \
"QT_QPA_PLATFORM=wayland-egl;xcb" \
MOZ_ENABLE_WAYLAND=1 \
WLR_DRM_NO_MODIFIERS=1 \
XWAYLAND_NO_SCALE=1
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
export MOZ_ENABLE_WAYLAND=1
export WLR_DRM_NO_MODIFIERS=1
export QT_QPA_PLATFORM="wayland-egl;xcb"
export SDL_VIDEODRIVER=wayland
export XDG_SESSION_TYPE=wayland
export XDG_CURRENT_DESKTOP=sway
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
# shikane-watchdog: auto-recover shikane from its deadlock bug.
#
# Bug (shikane 1.1.1): if a variant application is discarded mid-way
# (e.g. by a failing DP atomic commit), the daemon gets stuck in
# VariantInProgress/Discarded and keeps logging
# [WARN shikane::variant] Received invalid input AtomicChangeDone at state Discarded
# `shikanectl reload` does not recover it; a service restart does
# (re-applies the active profile in ~1s).
#
# A healthy daemon's last state-machine line is "VariantApplied".
set -u
unit=shikane
stuck=0
logs3=$(journalctl --user -u "$unit" -q --since "-3min" 2>/dev/null)
[ -z "$logs3" ] && exit 0
latest3=$(printf '%s\n' "$logs3" | grep 'daemon::state_machine' | tail -1)
if [ -n "$latest3" ]; then
case "$latest3" in
*VariantApplied*)
: ;; # healthy
*)
# InProgress/Discarded within the last 3 min: only a deadlock
# if the WARN signature is present (a legitimate slow transition
# has no WARN)
printf '%s\n' "$logs3" | grep -q 'invalid input' && stuck=1
;;
esac
else
# No state change in the last 3 min — check the last known state
last10=$(journalctl --user -u "$unit" -q --since "-10min" 2>/dev/null \
| grep 'daemon::state_machine' | tail -1)
case "$last10" in
'' | *VariantApplied*)
: ;; # stable and applied, or nothing to check
*)
stuck=1 ;; # stuck in-progress/discarded for >3 min
esac
fi
if [ "$stuck" -eq 1 ]; then
echo "shikane-watchdog: shikane stuck, restarting" >&2
systemctl --user restart "$unit"
fi
+20 -33
View File
@@ -3,7 +3,7 @@
"spacing": 2, // Gaps between modules (4px)
"modules-left": [
"sway/workspaces",
"sway/mode",
"sway/submap",
"sway/scratchpad",
"sway/window"
],
@@ -23,9 +23,8 @@
"format": "<span style=\"italic\">{}</span>"
},
"sway/scratchpad": {
"format": "{icon} {count}",
"format": "S{count}",
"show-empty": false,
"format-icons": ["", ""],
"tooltip": true,
"tooltip-format": "{app}: {title}"
},
@@ -50,65 +49,53 @@
"warning": 30,
"critical": 15
},
"format": "{time} {capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format": "{time} {capacity}%",
"format-full": "{capacity}%",
"format-charging": "{capacity}% C",
"format-plugged": "{capacity}% P",
"format-alt": "{time} {icon}",
"format-alt": "{time}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
"bat": "BAT2"
},
"power-profiles-daemon": {
"format": "{icon}",
"format": "{profile}",
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
"tooltip": true,
"format-icons": {
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
"format-icons": {"default": [""]}
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected ⚠",
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected",
"format-disconnected": "Disconnected",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"pulseaudio": {
// "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon}  {format_source}",
"format-bluetooth-muted": " {icon}  {format_source}",
"format": "{volume}% {format_source}",
"format-bluetooth": "{volume}% {format_source}",
"format-bluetooth-muted": " {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}%",
"format-source-muted": "",
"format-source": "{volume}%",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
"default": [""]
},
"on-click": "pavucontrol"
},
"custom/media": {
"format": "{icon} {text}",
"format": "{text}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
"default": ""
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
+191 -165
View File
@@ -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;
}
@@ -0,0 +1,6 @@
[Unit]
Description=shikane watchdog - restart shikane if its state machine is stuck
[Service]
Type=oneshot
ExecStart=/home/work/.config/sway/scripts/shikane-watchdog.sh
@@ -0,0 +1,10 @@
[Unit]
Description=Run shikane watchdog every 2 minutes
[Timer]
OnBootSec=2min
OnUnitInactiveSec=2min
AccuracySec=5s
[Install]
WantedBy=timers.target
+10 -3
View File
@@ -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
+6
View File
@@ -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
@@ -0,0 +1 @@
/home/work/.config/systemd/user/shikane-watchdog.timer
+1
View File
@@ -1,5 +1,6 @@
set-option -sa terminal-overrides ",xterm*:Tc"
set -g default-terminal "xterm-256color"
set -g extended-keys on
bind-key r source-file ~/.config/tmux/tmux.conf \; display "Reloaded!"
+19 -32
View File
@@ -22,9 +22,8 @@
"format": "<span style=\"italic\">{}</span>"
},
"sway/scratchpad": {
"format": "{icon} {count}",
"format": "{count}",
"show-empty": false,
"format-icons": ["", ""],
"tooltip": true,
"tooltip-format": "{app}: {title}"
},
@@ -49,65 +48,53 @@
"warning": 30,
"critical": 15
},
"format": "{time} {capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format": "{time} {capacity}%",
"format-full": "{capacity}%",
"format-charging": "{capacity}% C",
"format-plugged": "{capacity}% P",
"format-alt": "{time} {icon}",
"format-alt": "{time}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
"bat": "BAT2"
},
"power-profiles-daemon": {
"format": "{icon}",
"format": "{profile}",
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
"tooltip": true,
"format-icons": {
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
"format-icons": {"default": [""]}
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected ⚠",
//"format-wifi": "{essid} ({signalStrength}%)",
//"format-ethernet": "{ipaddr}/{cidr}",
//"tooltip-format": "{ifname} via {gwaddr}",
//"format-linked": "{ifname} (No IP)",
//"format-disconnected": "Disconnected",
"format-disconnected": "Disconnected",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"pulseaudio": {
// "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon}  {format_source}",
"format-bluetooth-muted": " {icon}  {format_source}",
"format": "{volume}% {format_source}",
"format-bluetooth": "{volume}% {format_source}",
"format-bluetooth-muted": " {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}%",
"format-source-muted": "",
"format-source": "{volume}%",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
"default": [""]
},
"on-click": "pavucontrol"
},
"custom/media": {
"format": "{icon} {text}",
"format": "{text}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
"default": ""
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
+4
View File
@@ -1 +1,5 @@
.config/nvim/lazy-lock.json
.config/opencode/node_modules/
.config/opencode/package.json
.config/opencode/bun.lock
.config/opencode/package-lock.json
+22
View File
@@ -11,3 +11,25 @@ stow .
```
If stow is not installed use ./install.sh from .dotfiles repo
# User services
## shikane-watchdog
`.config/systemd/user/shikane-watchdog.timer` (every 2 min, user unit)
runs `.config/sway/scripts/shikane-watchdog.sh`, which restarts the
`shikane` user service if its state machine is stuck.
Why: shikane 1.1.1 deadlocks when a profile application is discarded
mid-way (e.g. by a failing DP atomic commit on the external display).
The daemon then keeps logging
`[WARN shikane::variant] Received invalid input AtomicChangeDone at state Discarded`
and `shikanectl reload` no longer recovers it. The watchdog detects
that signature in the journal and runs `systemctl --user restart shikane`
(re-applies the active profile in ~1s). It never restarts a healthy
or legitimately transitioning daemon.
```console
systemctl --user status shikane-watchdog.timer # check it's active
systemctl --user disable --now shikane-watchdog.timer # disable
```
-13
View File
@@ -1,13 +0,0 @@
[Desktop Entry]
Name=Zoom Workplace
Comment=Zoom Video Conference
Exec=/usr/bin/zoom %U
Icon=Zoom
Terminal=false
Type=Application
Encoding=UTF-8
Categories=Network;Application;
StartupWMClass=zoom
MimeType=x-scheme-handler/zoommtg;x-scheme-handler/zoomus;x-scheme-handler/tel;x-scheme-handler/callto;x-scheme-handler/zoomphonecall;x-scheme-handler/zoomphonesms;x-scheme-handler/zoomcontactcentercall;application/x-zoom
X-KDE-Protocols=zoommtg;zoomus;tel;callto;zoomphonecall;zoomphonesms;zoomcontactcentercall;
Name[en_US]=Zoom Workplace
@@ -1,209 +0,0 @@
[Desktop Entry]
Categories=Utility;X-SuSE-SyncUtility;
Type=Application
Exec=nextcloud %u
Name=Nextcloud Desktop
Comment=Nextcloud desktop synchronization client
GenericName=Folder Sync
Icon=Nextcloud
Keywords=Nextcloud;syncing;file;sharing;
X-GNOME-Autostart-Delay=3
MimeType=application/vnd.nextcloud;x-scheme-handler/nc;
Actions=Quit;
# Translations
Comment[oc]=Nextcloud sincronizacion del client
GenericName[oc]=Dorsièr de Sincronizacion
Name[oc]=Nextcloud sincronizacion del client
Icon[oc]=Nextcloud
Comment[ar]=Nextcloud زبون مزامنة مكتبي
GenericName[ar]=مزامنة المجلد
Name[ar]=Nextcloud زبون مزامنة مكتبي
Icon[ar]=Nextcloud
Comment[bg_BG]=Nextcloud клиент за десктоп синхронизация
GenericName[bg_BG]=Синхронизиране на папката
Name[bg_BG]=Nextcloud клиент десктоп синхронизация
Icon[bg_BG]=Nextcloud
Comment[ca]=Client de sincronització d'escriptori Nextcloud
GenericName[ca]=Sincronització de carpetes
Name[ca]=Client de sincronització d'escriptori Nextcloud
Icon[ca]=Nextcloud
Comment[da]=Nextcloud skrivebordsklient til synkronisering
GenericName[da]=Mappesynkronisering
Name[da]=Nextcloud skrivebordsklient til synk
Icon[da]=Nextcloud
Comment[de]=Nextcloud Desktop-Synchronisationsclient
GenericName[de]=Ordner-Synchronisation
Name[de]=Nextcloud Desktop-Synchronisationsclient
Icon[de]=Nextcloud
Comment[ja_JP]=Nextcloud デスクトップ同期クライアント
GenericName[ja_JP]=フォルダー同期
Name[ja_JP]=Nextcloud デスクトップ同期クライアント
Icon[ja_JP]=Nextcloud
Comment[el]=Nextcloud συγχρονισμός επιφάνειας εργασίας πελάτη
GenericName[el]=Συγχρονισμός φακέλου
Name[el]=Nextcloud συγχρονισμός επιφάνειας εργασίας πελάτη
Icon[el]=Nextcloud
Comment[en_GB]=Nextcloud desktop synchronisation client
GenericName[en_GB]=Folder Sync
Name[en_GB]=Nextcloud desktop sync client
Icon[en_GB]=Nextcloud
Comment[es]=Nextcloud cliente de sincronización de escritorio
GenericName[es]=Sincronización de carpeta
Name[es]=Nextcloud cliente de sincronización de escritorio
Icon[es]=Nextcloud
Comment[de_DE]=Nextcloud Desktop-Synchronisationsclient
GenericName[de_DE]=Ordner-Synchronisation
Name[de_DE]=Nextcloud Desktop-Synchronisationsclient
Icon[de_DE]=Nextcloud
Comment[eu]=Nextcloud mahaigaineko sinkronizazio bezeroa
GenericName[eu]=Karpetaren sinkronizazioa
Name[eu]=Nextcloud mahaigaineko sinkronizazio bezeroa
Icon[eu]=Nextcloud
GenericName[fa]=همسان سازی پوشه‌ها
Name[fa]=nextcloud نسخه‌ی همسان سازی مشتری
Icon[fa]=Nextcloud
Comment[fr]=Synchronisez vos dossiers avec un serveur Nextcloud
GenericName[fr]=Synchronisation de dossier
Name[fr]=Client de synchronisation Nextcloud
Icon[fr]=Nextcloud
Comment[gl]=Nextcloud cliente de sincronización para escritorio
GenericName[gl]=Sincronizar Cartafol
Name[gl]=Nextcloud cliente de sincronización para escritorio
Icon[gl]=Nextcloud
Comment[he]=Nextcloud לקוח סנכון שולחן עבודה
GenericName[he]=סנכון תיקייה
Name[he]=Nextcloud לקוח סנכרון שולחן עבודה
Icon[he]=Nextcloud
Comment[ia]=Nextcloud cliente de synchronisation pro scriptorio
GenericName[ia]=Synchronisar Dossier
Name[ia]=Nextcloud cliente de synchronisation pro scriptorio
Icon[ia]=Nextcloud
Comment[id]=Klien sinkronisasi desktop Nextcloud
GenericName[id]=Folder Sync
Name[id]=Klien sync desktop Nextcloud
Icon[id]=Nextcloud
Comment[is]=Nextcloud skjáborðsforrit samstillingar
GenericName[is]=Samstilling möppu
Name[is]=Nextcloud skjáborðsforrit samstillingar
Icon[is]=Nextcloud
Comment[it]=Client di sincronizzazione del desktop di Nextcloud
GenericName[it]=Sincronizzazione cartella
Name[it]=Client di sincronizzazione del desktop di Nextcloud
Icon[it]=Nextcloud
Comment[ko]=Nextcloud 데스크톱 동기화 클라이언트
GenericName[ko]=폴더 동기화
Name[ko]=Nextcloud 데스크톱 동기화 클라이언트
Icon[ko]=Nextcloud
Comment[hu_HU]=Nextcloud asztali szinkronizációs kliens
GenericName[hu_HU]=Könyvtár szinkronizálás
Name[hu_HU]=Nextcloud asztali szinkr. kliens
Icon[hu_HU]=Nextcloud
Comment[af_ZA]=Nextcloud werkskermsinchroniseerkliënt
GenericName[af_ZA]=Vouersinchronisering
Name[af_ZA]=Nextcloud werkskermsinchroniseerkliënt
Icon[af_ZA]=Nextcloud
Comment[nl]=Nextcloud desktop synchronisatie client
GenericName[nl]=Mappen sync
Name[nl]=Nextcloud desktop sync client
Icon[nl]=Nextcloud
Comment[et_EE]=Nextcloud sünkroonimise klient töölauale
GenericName[et_EE]=Kaustade sünkroonimine
Name[et_EE]=Nextcloud sünkroonimise klient töölauale
Icon[et_EE]=Nextcloud
Comment[pl]=Nextcloud klient synchronizacji dla komputerów stacjonarnych
GenericName[pl]=Folder Synchronizacji
Name[pl]=Nextcloud klient synchronizacji dla komputerów stacjonarnych
Icon[pl]=Nextcloud
Comment[pt_BR]=Nextcloud cliente de sincronização do computador
GenericName[pt_BR]=Sincronização de Pasta
Name[pt_BR]=Nextcloud cliente de sincronização de desktop
Icon[pt_BR]=Nextcloud
Comment[cs_CZ]=Nextcloud počítačový synchronizační klient
GenericName[cs_CZ]=Synchronizace adresáře
Name[cs_CZ]=Nextcloud počítačový synchronizační klient
Icon[cs_CZ]=Nextcloud
Comment[ru]=Настольный клиент синхронизации Nextcloud
GenericName[ru]=Синхронизация каталогов
Name[ru]=Настольный клиент синхронизации Nextcloud
Icon[ru]=Nextcloud
Comment[sl]=Nextcloud ‒ Program za usklajevanje datotek z namizjem
GenericName[sl]=Usklajevanje map
Name[sl]=Nextcloud ‒ Program za usklajevanje datotek z namizjem
Icon[sl]=Nextcloud
Comment[sq]=Klient njëkohësimesh Nextcloud për desktop
GenericName[sq]=Njëkohësim Dosjesh
Name[sq]=Klient njëkohësimesh Nextcloud për desktop
Icon[sq]=Nextcloud
Comment[fi_FI]=Nextcloud työpöytäsynkronointisovellus
GenericName[fi_FI]=Kansion synkronointi
Name[fi_FI]=Nextcloud työpöytäsynkronointisovellus
Icon[fi_FI]=Nextcloud
Comment[sv]=Nextcloud desktop synkroniseringsklient
GenericName[sv]=Mappsynk
Name[sv]=Nextcloud desktop synk-klient
Icon[sv]=Nextcloud
Comment[tr]=Nextcloud masaüstü eşitleme istemcisi
GenericName[tr]=Dosya Eşitleme
Name[tr]=Nextcloud masaüstü eşitleme istemcisi
Icon[tr]=Nextcloud
Comment[uk]=Настільний клієнт синхронізації Nextcloud
GenericName[uk]=Синхронізація теки
Name[uk]=Настільний клієнт синхронізації Nextcloud
Icon[uk]=Nextcloud
Comment[ro]=Nextcloud client de sincronizare pe desktop
GenericName[ro]=Sincronizare director
Name[ro]=Nextcloud client de sincronizare pe desktop
Icon[ro]=Nextcloud
Comment[zh_CN]=Nextcloud 桌面同步客户端
GenericName[zh_CN]=文件夹同步
Name[zh_CN]=Nextcloud 桌面同步客户端
Icon[zh_CN]=Nextcloud
Comment[zh_HK]=桌面版同步客户端
Comment[zh_TW]=Nextcloud 桌面同步客戶端
GenericName[zh_TW]=資料夾同步
Name[zh_TW]=Nextcloud 桌面同步客戶端
Icon[zh_TW]=Nextcloud
Comment[es_AR]=Cliente de sincronización para escritorio Nextcloud
GenericName[es_AR]=Sincronización de directorio
Name[es_AR]=Cliente de sincronización para escritorio Nextcloud
Icon[es_AR]=Nextcloud
Comment[lt_LT]=Nextcloud darbalaukio sinchronizavimo programa
GenericName[lt_LT]=Katalogo sinchnorizacija
Name[lt_LT]=Nextcloud darbalaukio programa
Icon[lt_LT]=Nextcloud
Comment[th_TH]=Nextcloud ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
Name[th_TH]= Nextcloud ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
Icon[th_TH]=Nextcloud
Comment[es_MX]=Cliente de escritorio para sincronziación de Nextcloud
GenericName[es_MX]=Sincronización de Carpetas
Name[es_MX]=Cliente de escritorio para sincronziación de Nextcloud
Icon[es_MX]=Nextcloud
Comment[nb_NO]=Nextcloud skrivebordssynkroniseringsklient
GenericName[nb_NO]=Mappesynkronisering
Name[nb_NO]=Nextcloud skrivebordssynkroniseringsklient
Icon[nb_NO]=Nextcloud
Comment[nn_NO]=Nextcloud klient for å synkronisera frå skrivebord
GenericName[nn_NO]=Mappe synkronisering
Name[nn_NO]=Nextcloud klient for å synkronisera frå skrivebord
Icon[nn_NO]=Nextcloud
Comment[pt_PT]=Nextcloud - Cliente de Sincronização para PC
GenericName[pt_PT]=Sincronizar Pasta
Name[pt_PT]=Nextcloud - Cliente de Sincronização para PC
Icon[pt_PT]=Nextcloud
Icon[km]=Nextcloud
Comment[lb]=Nextcloud Desktop Synchronisatioun Client
GenericName[lb]=Dossier Dync
Name[lb]=Nextcloud Desktop Sync Client
Icon[lb]=Nextcloud
Implements=org.freedesktop.CloudProviders
[org.freedesktop.CloudProviders]
BusName=com.nextcloudgmbh.Nextcloud
ObjectPath=/com/nextcloudgmbh/Nextcloud
[Desktop Action Quit]
Exec=nextcloud --quit
Name=Quit Nextcloud
Icon=nextcloud
-2
View File
@@ -1,2 +0,0 @@
inode/directory=thunar.desktop
x-directory/normal=thunar.desktop
+2 -1
View File
@@ -3,7 +3,8 @@ Name=Discord
StartupWMClass=discord
Comment=All-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone.
GenericName=Internet Messenger
Exec=/usr/lib/discord/Discord --enable-features=UseOzonePlatform --ozone-platform=wayland
Exec=/usr/bin/flatpak run --socket=wayland com.discordapp.Discord --enable-features=UseOzonePlatform --ozone-platform=wayland
#Exec=/usr/lib/discord/Discord --enable-features=UseOzonePlatform --ozone-platform=wayland
#Exec=/usr/lib/discord/Discord
Icon=discord
Type=Application