From a9e520e3da8f6808decc6e6b0faa73bfe32a302b Mon Sep 17 00:00:00 2001 From: Steve Beaulac Date: Sun, 31 May 2026 14:06:55 -0400 Subject: [PATCH] feat: moving all service from hyprland config to systemd user services. --- config/hypr/hyprland.lua | 410 ++++++++++++++++-------- config/systemd/user/awww-daemon.service | 13 + config/systemd/user/mako.service | 12 + installer/10-base-desktop.sh | 3 +- installer/desktop.sh | 17 +- packages/sjb-desktop.packages | 4 + 6 files changed, 322 insertions(+), 137 deletions(-) create mode 100644 config/systemd/user/awww-daemon.service create mode 100644 config/systemd/user/mako.service diff --git a/config/hypr/hyprland.lua b/config/hypr/hyprland.lua index 4086682..f2c7bba 100644 --- a/config/hypr/hyprland.lua +++ b/config/hypr/hyprland.lua @@ -1,26 +1,32 @@ -- require("keybinds.lua") -hl.monitor({output = "eDP-1", mode = "highrr", position = "0x0", scale = 1 }) +hl.monitor({ output = "eDP-1", mode = "highrr", position = "0x0", scale = 1 }) -hl.monitor({output = "desc:BNQ BenQ EX3203R 7CL00509019", mode = "preferred", position="auto", scale = 1 }) -hl.monitor({output = "desc:Lenovo Group Limited L15 U133R0A2", mode = "preferred", position="auto-left", scale = 1 }) -hl.monitor({output = "desc:Lenovo Group Limited M15 V30F2A15", mode = "preferred", position="auto-left", scale = 1 }) +hl.monitor({ output = "desc:BNQ BenQ EX3203R 7CL00509019", mode = "preferred", position = "auto", scale = 1 }) +hl.monitor({ output = "desc:Lenovo Group Limited L15 U133R0A2", mode = "preferred", position = "auto-left", scale = 1 }) +hl.monitor({ output = "desc:Lenovo Group Limited M15 V30F2A15", mode = "preferred", position = "auto-left", scale = 1 }) -- hl.monitor({output = "desc:LG Electronics LG HDR WQHD 0x0006530C", mode = "3440x1440@75.05", position = "auto-up", scale = "1.0" }) -- hl.monitor({output = "desc:LG Electronics LG HDR WQHD 0x0006530C", mode = "preferred", position = "0x0", scale = "1.0" }) -- hl.monitor({output = "desc:Ancor Communications Inc ASUS MG28U 0x00009B77", mode = "3840x2160@60.00", position = "auto-left", scale = "1.333333" }) -hl.monitor({output = "desc:Lenovo Group Limited 0x41A0", mode = "preferred", position = "0x0", scale = "1.0" }) -hl.monitor({output = "desc:LG Electronics LG HDR 4K 406NTZN74597", mode = "preferred", position = "auto-left", scale = "1.333333" }) -hl.monitor({output = "desc:GWD ARZOPA 000000000000", mode = "preferred", position = "auto-left", scale = "1.0" }) -hl.monitor({output = "desc:Proteon TYPE-C 8R33926O00QS", mode = "preferred", position = "auto-right", scale = "1.0" }) -hl.monitor({output = "desc:LG Electronics LG HDR WQHD 0x0006530C", mode = "preferred", position = "auto-up", scale = "1.0" }) -hl.monitor({output = "desc:Ancor Communications Inc ASUS MG28U 0x00009B77", mode = "preferred", position = "auto-left", scale = "1.333333" }) -hl.monitor({output = "desc:Stargate Technology TYPE-C", mode = "preferred", position = "auto-right", scale = "1.0" }) +hl.monitor({ output = "desc:Lenovo Group Limited 0x41A0", mode = "preferred", position = "0x0", scale = "1.0" }) +hl.monitor({ output = "desc:LG Electronics LG HDR 4K 406NTZN74597", mode = "preferred", position = "auto-left", scale = +"1.333333" }) +hl.monitor({ output = "desc:GWD ARZOPA 000000000000", mode = "preferred", position = "auto-left", scale = "1.0" }) +hl.monitor({ output = "desc:Proteon TYPE-C 8R33926O00QS", mode = "preferred", position = "auto-right", scale = "1.0" }) +hl.monitor({ output = "desc:LG Electronics LG HDR WQHD 0x0006530C", mode = "preferred", position = "auto-up", scale = +"1.0" }) +hl.monitor({ output = "desc:Ancor Communications Inc ASUS MG28U 0x00009B77", mode = "preferred", position = "auto-left", scale = +"1.333333" }) +hl.monitor({ output = "desc:Stargate Technology TYPE-C", mode = "preferred", position = "auto-right", scale = "1.0" }) -hl.monitor({output = "desc:BNQ BenQ EX3501R N4M05650019", mode = "preferred", position = "auto-right", scale = "1.0" }) -hl.monitor({output = "desc:Dell Inc. DELL U3818DW 97F8P8AD0HEL", mode = "preferred", position = "auto-left", scale = "1.0" }) -hl.monitor({output = "desc:Microstep MSI MAG342CQR DB6H252300057", mode = "preferred", position = "auto-right", scale = "1.0" }) -hl.monitor({output = "desc:Ancor Communications Inc ASUS PB238 DCLMTF074371", mode = "preferred", position = "auto", scale = "1.0" }) +hl.monitor({ output = "desc:BNQ BenQ EX3501R N4M05650019", mode = "preferred", position = "auto-right", scale = "1.0" }) +hl.monitor({ output = "desc:Dell Inc. DELL U3818DW 97F8P8AD0HEL", mode = "preferred", position = "auto-left", scale = +"1.0" }) +hl.monitor({ output = "desc:Microstep MSI MAG342CQR DB6H252300057", mode = "preferred", position = "auto-right", scale = +"1.0" }) +hl.monitor({ output = "desc:Ancor Communications Inc ASUS PB238 DCLMTF074371", mode = "preferred", position = "auto", scale = +"1.0" }) hl.config({ input = { @@ -148,16 +154,16 @@ hl.config({ } }) -hl.curve( "almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1.0} } }) -hl.curve( "generic", { type = "bezier", points = { {0.5, 0.9}, {0.1, 1.08} } }) -hl.curve( "quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1.0} } }) -hl.curve( "overshoot", { type = "bezier", points = { {0.5, 0.9}, {0.1, 1.1} } } ) -hl.curve( "rubber", { type = "spring", mass = 1, stiffness = 70, dampening = 10 } ) +hl.curve("almostLinear", { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1.0 } } }) +hl.curve("generic", { type = "bezier", points = { { 0.5, 0.9 }, { 0.1, 1.08 } } }) +hl.curve("quick", { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1.0 } } }) +hl.curve("overshoot", { type = "bezier", points = { { 0.5, 0.9 }, { 0.1, 1.1 } } }) +hl.curve("rubber", { type = "spring", mass = 1, stiffness = 70, dampening = 10 }) hl.animation({ leaf = "windows", enabled = true, speed = 3, bezier = "almostLinear" }) hl.animation({ leaf = "border", enabled = true, speed = 1, spring = "rubber" }) hl.animation({ leaf = "workspaces", enabled = true, speed = 1, bezier = "quick" }) -hl.animation({ leaf = "layers", enabled = true, speed = 3 , bezier = "quick" }) +hl.animation({ leaf = "layers", enabled = true, speed = 3, bezier = "quick" }) hl.animation({ leaf = "fade", enabled = true, speed = 3, bezier = "almostLinear" }) -- local terminal = "ghostty -e" @@ -179,29 +185,92 @@ function sysinfo() local workspace_id = monitor.active_workspace.id local mesg = "System Info" .. "\nDate: " .. time - .. "\nFocused monitor: " .. monitor.name + .. "\nFocused monitor: " .. monitor.name .. "\nWorkspace: " .. workspace_id .. "\nBattery: " .. battery .. "CPU: " .. cpu .. " MEM: " .. mem - + hl.notification.create({ text = mesg, icon = "hint", duration = 5000 }) end -hl.bind(LEADER .. "return", hl.dsp.exec_raw(terminal .. " tmux new -A -s main")) +function focus_or_launch(opts) + return function() + local match = opts.match + local cmd = opts.cmd + local field = opts.field or "class" -- class, title, initialClass, initialTitle + local use_workspace = opts.use_workspace ~= false + + local clients = hl.get_windows() + + for _, client in ipairs(clients) do + local value = client[field] + if value and string.find(string.lower(value), string.lower(match), 1, true) then + if use_workspace and client.workspace and client.workspace.id then + hl.dispatch(hl.dsp.focus({ + workspace = client.workspace.id, + on_current_monitor = true, + })) + end + + hl.dispatch(hl.dsp.focus({ + window = "address:" .. client.address + })) + return + end + end + + hl.exec_cmd(cmd) + end +end + +function toggle_master() + local ws = hl.get_active_workspace() + if not ws then + return + end + + local mfact = nil + + for _, win in ipairs(ws:get_windows()) do + local layout = win.layout + if layout and layout.name == "master" and layout.is_master then + mfact = math.floor(layout.perc_master * 100 + 0.5) / 100 + break + end + end + + if mfact == 0.7 then + mfact = 0.5 + else + mfact = 0.7 + end + hl.dispatch(hl.dsp.layout("mfact exact " .. mfact)) +end + +hl.bind(LEADER .. "return", + focus_or_launch({ + match = terminal, + field = "class", + cmd = terminal .. " tmux new -A -s main" + }), { description = "Open terminal" }) + hl.bind(LEADER .. "SHIFT + return", hl.dsp.exec_raw(terminal .. " nvim")) hl.bind(LEADER .. "B", hl.dsp.exec_raw(browser), { description = "Open browser" }) hl.bind(LEADER .. "T", hl.dsp.exec_raw(terminal .. " -e btop"), { description = "Open system monitor" }) hl.bind(LEADER .. "S", hl.dsp.exec_raw("rofi -show recursivebrowser"), { description = "Open finder" }) -- hl.bind(LEADER .. "I", hl.dsp.exec_cmd(notify_cmd .. " $(~/.local/bin/sysinfo)"), { description = "Show system info" }) -hl.bind(LEADER .. "I", function () +hl.bind(LEADER .. "I", function() sysinfo() end, { description = "Show system info" }) -- Open rofi on first press, closes it on second hl.bind(LEADER .. "Space", hl.dsp.exec_raw("rofi -show drun"), { release = true, description = "Open Application Menu" }) -hl.bind(LEADER .. "SHIFT + SPACE", hl.dsp.exec_cmd("~/.local/bin/hyprland-fetch-client"), { release = true, description = "Fetch client" }) -hl.bind(LEADER .. "CONTROL + SPACE", hl.dsp.exec_cmd("~/.local/bin/hyprland-focus-client"), { release = true, description = "Focus client" }) -hl.bind(LEADER .. "CONTROL + return", hl.dsp.exec_cmd("~/.local/bin/hyprland-tmux-session"), { release = true, description = "Tmux session switcher" }) +hl.bind(LEADER .. "SHIFT + SPACE", hl.dsp.exec_cmd("~/.local/bin/hyprland-fetch-client"), + { release = true, description = "Fetch client" }) +hl.bind(LEADER .. "CONTROL + SPACE", hl.dsp.exec_cmd("~/.local/bin/hyprland-focus-client"), + { release = true, description = "Focus client" }) +hl.bind(LEADER .. "CONTROL + return", hl.dsp.exec_cmd("~/.local/bin/hyprland-tmux-session"), + { release = true, description = "Tmux session switcher" }) hl.bind(HYPR .. "V", hl.dsp.exec_cmd("pavucontrol"), { description = "Volume control" }) @@ -209,53 +278,100 @@ hl.bind(HYPR .. "B", hl.dsp.exec_cmd("blueberry"), { description = "Bluetooth ma hl.bind(HYPR .. "semicolon", hl.dsp.exec_cmd("~/.local/bin/bing-wallpaper"), { description = "get new wallpaper" }) -hl.bind(HYPR .. "A", hl.dsp.exec_cmd("gtk-launch goose-desktop.desktop"), { description = "Goose Desktop" }) -hl.bind(HYPR .. "C", hl.dsp.exec_cmd(webapp .. "https://outlook.office.com/calendar/view/month"), { description = "Calendar" }) -hl.bind(HYPR .. "E", hl.dsp.exec_cmd(webapp .. "https://outlook.office.com/mail"), { description = "Email" }) -hl.bind(HYPR .. "U", hl.dsp.exec_cmd(webapp .. "https://teams.microsoft.com/v2/"), { description = "UWO Team" }) -hl.bind(HYPR .. "Y", hl.dsp.exec_cmd(webapp .. "https://youtube.com/"), { description = "YouTube" }) -hl.bind(HYPR .. "W", hl.dsp.exec_cmd(webapp .. "https://web.whatsapp.com/"), { description = "WhatsApp" }) -hl.bind(HYPR .. "G", hl.dsp.exec_cmd(webapp .. "https://www.gmail.com/"), { description = "Google" }) -hl.bind(HYPR .. "O", hl.dsp.exec_cmd(webapp .. "https://chatgpt.com"), { description = "ChatGPT" }) +hl.bind(HYPR .. "A", focus_or_launch({ + match = "Goose", + field = "class", + cmd = "gtk-launch goose-desktop.desktop" +}), { description = "Goose Desktop" }) -hl.bind(HYPR .. "M", hl.dsp.exec_cmd(music), { description = "Music" }) -hl.bind(HYPR .. "F", hl.dsp.exec_cmd("pcmanfm"), { description = "File Manager" }) +hl.bind(HYPR .. "C", focus_or_launch({ + match = "chrome-chatgpt.com", + cmd = "gtk-launch ChatGPT.desktop", +}), { description = "ChatGPT" }) + +hl.bind(HYPR .. "O", focus_or_launch({ + match = "chrome-outlook.office.com", + cmd = "gtk-launch Outlook.desktop", +}), { description = "Email" }) + +hl.bind(HYPR .. "T", focus_or_launch({ + match = "chrome-teams.microsoft.com", + cmd = "gtk-launch Team.desktop", +}), { description = "UWO Team" }) + +hl.bind(HYPR .. "Y", focus_or_launch({ + match = "chrome-youtube.com", + cmd = "gtk-launch YouTube.desktop", +}), { description = "YouTube" }) + +hl.bind(HYPR .. "W", focus_or_launch({ + match = "chrome-web.whatsapp.com", + cmd = "gtk-launch WhatsApp.desktop", +}), { description = "WhatsApp" }) + +hl.bind(HYPR .. "G", focus_or_launch({ + match = "chrome-www.gmail.com", + cmd = webapp .. "https://www.gmail.com/", +}), { description = "Google" }) + +hl.bind(HYPR .. "D", focus_or_launch({ + match = "chrome-discord.com", + cmd = "gtk-launch Discord.desktop" +}), { description = "Discord" }) + +hl.bind(HYPR .. "M", focus_or_launch({ + match = "chrome-messages.google.com", + cmd = "gtk-launch \"Google Messages.desktop\"", +}), { description = "Google Messages" }) + +hl.bind(HYPR .. "S", focus_or_launch({ + match = "Spotify", + cmd = music, +}), { description = "Music" }) + +hl.bind(HYPR .. "F", focus_or_launch({ + match = "pcmanfm", + cmd = "pcmanfm", +}), { description = "File Manager" }) hl.bind(LEADER .. "slash", hl.dsp.exec_cmd("ROFI_PASS_BACKEND=wtype ROFI_PASS_CLIPBOARD_BACKEND=wl-clipboard ~/.local/bin/rofi-pass")) -hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { repeating = true }) -hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { repeating = true }) -hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")) -hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle")) -hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { repeating = true }) -hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { repeating = true }) -hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause")) -hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous")) -hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next")) +hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { repeating = true, description = "Volume down" }) +hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { repeating = true, description = "Volume up" }) +hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { description = "Toggle mute" }) +hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { description = "Toggle mic mute" }) +hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { repeating = true, description = "Brightness up" }) +hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { repeating = true, description = "Brightness down" }) +hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { description = "Play/pause media" }) +hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { description = "Previous media" }) +hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { description = "Next media" }) hl.bind(LEADER .. "Y", hl.dsp.exec_cmd("makoctl dismiss"), { description = "Dismiss notifications" }) hl.bind(LEADER .. "W", hl.dsp.window.close(), { description = "Window: Close" }) -hl.bind(LEADER .. "F", hl.dsp.window.fullscreen({mode = "fullscreen", action = "toggle"}), { description = "Window: Toggle fullscreen" }) -hl.bind(LEADER .. "CTRL + F", hl.dsp.window.fullscreen_state({internal = 2 , client = 0, action = "toggle"}), { description = "Window: Toggle fullscreen state 2" }) -hl.bind(LEADER .. "ALT + F", hl.dsp.window.fullscreen_state({internal = 0 , client = 2, action = "toggle"}), { description = "Window: Toggle fullscreen state 2" }) -hl.bind(LEADER .. "SHIFT + F", hl.dsp.window.float({action = "toggle"}), { description = "Window: Toggle floating" }) +hl.bind(LEADER .. "F", hl.dsp.window.fullscreen({ mode = "fullscreen", action = "toggle" }), + { description = "Window: Toggle fullscreen" }) +hl.bind(LEADER .. "CTRL + F", hl.dsp.window.fullscreen_state({ internal = 2, client = 0, action = "toggle" }), + { description = "Window: Toggle fullscreen state 2" }) +hl.bind(LEADER .. "ALT + F", hl.dsp.window.fullscreen_state({ internal = 0, client = 2, action = "toggle" }), + { description = "Window: Toggle fullscreen state 2" }) +hl.bind(LEADER .. "SHIFT + F", hl.dsp.window.float({ action = "toggle" }), { description = "Window: Toggle floating" }) hl.bind(LEADER .. "P", hl.dsp.window.pseudo(), { description = "Window: Toggle pseudo tiling" }) -hl.bind(LEADER .. "A", hl.dsp.window.alter_zorder({mode= "top"}), { description = "Window: Move to top" }) +hl.bind(LEADER .. "A", hl.dsp.window.alter_zorder({ mode = "top" }), { description = "Window: Move to top" }) -hl.bind(LEADER .. "left", hl.dsp.focus({ direction = "l"}), { description = "Window: Focus left" }) -hl.bind(LEADER .. "right", hl.dsp.focus({ direction = "r"}), { description = "Window: Focus right" }) -hl.bind(LEADER .. "up", hl.dsp.focus({ direction = "u"}), { description = "Window: Focus up" }) -hl.bind(LEADER .. "down", hl.dsp.focus({ direction = "d"}), { description = "Window: Focus down" }) +hl.bind(LEADER .. "left", hl.dsp.focus({ direction = "l" }), { description = "Window: Focus left" }) +hl.bind(LEADER .. "right", hl.dsp.focus({ direction = "r" }), { description = "Window: Focus right" }) +hl.bind(LEADER .. "up", hl.dsp.focus({ direction = "u" }), { description = "Window: Focus up" }) +hl.bind(LEADER .. "down", hl.dsp.focus({ direction = "d" }), { description = "Window: Focus down" }) -hl.bind(LEADER .. "H", hl.dsp.focus({ direction = "l"}), { description = "Window: Focus left" }) -hl.bind(LEADER .. "L", hl.dsp.focus({ direction = "r"}), { description = "Window: Focus right" }) -hl.bind(LEADER .. "K", hl.dsp.focus({ direction = "u"}), { description = "Window: Focus up" }) -hl.bind(LEADER .. "J", hl.dsp.focus({ direction = "d"}), { description = "Window: Focus down" }) -- hl.bind("SUPER + H", hl.dsp.window.resize("left"), { repeating = true, description = "Window: Resize left" }) +hl.bind(LEADER .. "H", hl.dsp.focus({ direction = "l" }), { description = "Window: Focus left" }) +hl.bind(LEADER .. "L", hl.dsp.focus({ direction = "r" }), { description = "Window: Focus right" }) +hl.bind(LEADER .. "K", hl.dsp.focus({ direction = "u" }), { description = "Window: Focus up" }) +hl.bind(LEADER .. "J", hl.dsp.focus({ direction = "d" }), { description = "Window: Focus down" }) -- hl.bind("SUPER + H", hl.dsp.window.resize("left"), { repeating = true, description = "Window: Resize left" }) -- hl.bind(LEADER .. "z", hl.dsp.focus({ last = true }), { description = "Window: Focus last" }) hl.bind(LEADER .. "Z", hl.dsp.focus({ urgent_or_last = true }), { description = "Window: Focus last" }) @@ -264,26 +380,30 @@ hl.bind(LEADER .. "ALT + comma", hl.dsp.window.swap({ prev = true }), { descript hl.bind("ALT + Tab", hl.dsp.window.cycle_next(), { description = "Window: Cycle next" }) hl.bind("ALT + SHIFT + Tab", hl.dsp.window.cycle_next({ next = false }), { description = "Window: Cycle prev" }) -hl.bind(LEADER .. "ALT + Tab", hl.dsp.focus({ workspace = "previous", on_current_monitor = true }), { description = "Window: Focus previous in workspace" }) +hl.bind(LEADER .. "ALT + Tab", hl.dsp.focus({ workspace = "previous", on_current_monitor = true }), + { description = "Window: Focus previous in workspace" }) -- arrange split ratio -hl.bind(LEADER .. "X", hl.dsp.layout("mfact exact 0.7")) -hl.bind(LEADER .. "equal", hl.dsp.layout("mfact exact 0.5")) +hl.bind(LEADER .. "X", function() + toggle_master() +end) +-- hl.bind(LEADER .. "equal", hl.dsp.layout("mfact exact 0.5")) hl.bind(LEADER .. "M", hl.dsp.layout("swapwithmaster")) -- hl.bind(LEADER .. "M", hl.dsp.layout("rollnext")) hl.bind(LEADER .. "period", function() hl.dispatch(hl.dsp.layout("cyclenext")) -- hl.dispatch(hl.dsp.layout("focus r")) -end) +end, { description = "Layout: Cycle next" }) hl.bind(LEADER .. "comma", function() hl.dispatch(hl.dsp.layout("cycleprev")) -- hl.dispatch(hl.dsp.layout("focus l")) -end) +end, { description = "Layout: Cycle previous" }) hl.bind(LEADER .. "semicolon", hl.dsp.workspace.toggle_special("special")) -hl.bind(LEADER .. "SHIFT + semicolon", hl.dsp.window.move({ workspace = "special:special", follow = false}), { description = "Window: Move to special workspace" }) +hl.bind(LEADER .. "SHIFT + semicolon", hl.dsp.window.move({ workspace = "special:special", follow = false }), + { description = "Window: Move to special workspace" }) hl.bind(LEADER .. "C", hl.dsp.window.center(), { description = "Window: Center" }) @@ -306,7 +426,7 @@ hl.bind(LEADER .. "SHIFT + CTRL + escape", hl.dsp.exec_raw("systemctl poweroff") -- bind = SUPER SHIFT, Z, exec, $notifycmd "Toggled All Pseudo Mode" hl.on("keybinds.submap", function(name) - if name == "" then + if name == "" then hl.notification.create({ text = "Exited submap", duration = 2000, icon = "hint" }) return end @@ -326,11 +446,11 @@ function window_resize_percentage(px, py) local sx = math.floor(mon.size.width * px) local sy = math.floor(mon.size.height * py) if not win.floating then - hl.dispatch(hl.dsp.window.float({action = "set"})) + hl.dispatch(hl.dsp.window.float({ action = "set" })) end if win.fullscreen then - hl.dispatch(hl.dsp.window.fullscreen({ action = "unset"})) - end + hl.dispatch(hl.dsp.window.fullscreen({ action = "unset" })) + end hl.dispatch(hl.dsp.window.resize({ x = sx, y = sy, relative = false })) end @@ -361,35 +481,41 @@ end) hl.bind(LEADER .. "F9", hl.dsp.submap("resize")) hl.define_submap("resize", function() - hl.bind("period", hl.dsp.window.resize({ x = 10, y = 10, relative = true}), { repeating = true }) - hl.bind("comma", hl.dsp.window.resize({ x = -10, y = -10, relative = true}), { repeating = true }) + hl.bind("period", hl.dsp.window.resize({ x = 10, y = 10, relative = true }), { repeating = true }) + hl.bind("comma", hl.dsp.window.resize({ x = -10, y = -10, relative = true }), { repeating = true }) hl.bind("R", function() window_resize_percentage(0.5, 0.5) - end) + end, { description = "Resize: Reset" }) hl.bind("S", function() window_resize_percentage(0.25, 0.25) - end) + end, { description = "Resize: Small" }) hl.bind("D", function() window_resize_percentage(0.7, 0.96) hl.dispatch(hl.dsp.window.center()) - end) - hl.bind("C", hl.dsp.window.center()) - hl.bind("P", hl.dsp.window.pin()) - hl.bind("up", hl.dsp.window.move({ direction = "up" })) - hl.bind("down", hl.dsp.window.move({ direction = "down" })) - hl.bind("left", hl.dsp.window.move({ direction = "left" })) - hl.bind("right", hl.dsp.window.move({ direction = "right" })) - hl.bind("escape", hl.dsp.submap("reset")) - hl.bind("catchall", hl.dsp.submap("reset")) + end, { description = "Resize: Large" }) + hl.bind("C", hl.dsp.window.center(), { description = "Resize: Center" }) + hl.bind("P", hl.dsp.window.pin(), { description = "Resize: Pin" }) + hl.bind("up", hl.dsp.window.move({ direction = "up" }), { description = "Resize: Move up" }) + hl.bind("down", hl.dsp.window.move({ direction = "down" }), { description = "Resize: Move down" }) + hl.bind("left", hl.dsp.window.move({ direction = "left" }), { description = "Resize: Move left" }) + hl.bind("right", hl.dsp.window.move({ direction = "right" }), { description = "Resize: Move right" }) + hl.bind("escape", hl.dsp.submap("reset"), { desceription = "Resize: Exit" }) + hl.bind("catchall", hl.dsp.submap("reset"), { description = "Resize: Exit" }) end) -hl.bind(LEADER .. "tab", hl.dsp.focus({ monitor = "+1"}), { description = "Monitor: move focus to next monitor" }) +hl.bind(LEADER .. "tab", hl.dsp.focus({ monitor = "+1" }), { description = "Monitor: move focus to next monitor" }) -hl.bind(LEADER .. "SHIFT + comma", hl.dsp.window.move({ workspace = "-1" }), { description = "Window: Move to previous workspace" }) -hl.bind(LEADER .. "SHIFT + period", hl.dsp.window.move({ workspace = "+1"}), { description = "Window: Move to next workspace" }) +hl.bind(LEADER .. "SHIFT + comma", hl.dsp.window.move({ workspace = "-1" }), + { description = "Window: Move to previous workspace" }) -hl.bind(LEADER .. "CONTROL + comma", hl.dsp.workspace.move({ monitor = "-1" }), { description = "Window: Move to previous workspace and follow" }) -hl.bind(LEADER .. "CONTROL + period", hl.dsp.workspace.move({ monitor = "+1" }), { description = "Window: Move to next workspace and follow" }) +hl.bind(LEADER .. "SHIFT + period", hl.dsp.window.move({ workspace = "+1" }), + { description = "Window: Move to next workspace" }) + +hl.bind(LEADER .. "CONTROL + comma", hl.dsp.workspace.move({ monitor = "-1" }), + { description = "Window: Move to previous workspace and follow" }) + +hl.bind(LEADER .. "CONTROL + period", hl.dsp.workspace.move({ monitor = "+1" }), + { description = "Window: Move to next workspace and follow" }) local workspaceGroupSize = 10 local numberkey = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 } @@ -400,7 +526,7 @@ function workspace_in_group(i) return newVal end -for i = 1, 10 do +for i = 1, 10 do hl.bind(LEADER .. "CONTROL + code:" .. numberkey[i], function() hl.dispatch(hl.dsp.workspace.move({ monitor = "+1", workspace = workspace_in_group(i), follow = true })) end) @@ -408,7 +534,7 @@ end for i = 1, 10 do hl.bind(LEADER .. "SHIFT + code:" .. numberkey[i], function() - hl.dispatch(hl.dsp.window.move({ workspace = workspace_in_group(i), follow = true})) + hl.dispatch(hl.dsp.window.move({ workspace = workspace_in_group(i), follow = true })) end) end @@ -420,12 +546,12 @@ end -- Scroll through existing workspaces with mainMod + scroll hl.bind(LEADER .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) -hl.bind(LEADER .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) +hl.bind(LEADER .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) -- Move/resize windows with mainMod + LMB/RMB and dragging -hl.bind(LEADER .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) +hl.bind(LEADER .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) hl.bind(LEADER .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) -hl.bind("mouse:275", hl.dsp.exec_cmd("wl-copy $(wl-paste -p)"), { mouse = true}) +hl.bind("mouse:275", hl.dsp.exec_cmd("wl-copy $(wl-paste -p)"), { mouse = true }) hl.bind("mouse:276", hl.dsp.exec_cmd("wtype -M ctrl -M shift v -m ctrl -m shift"), { mouse = true }) -- hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" }) @@ -438,62 +564,84 @@ hl.bind("mouse:276", hl.dsp.exec_cmd("wtype -M ctrl -M shift v -m ctrl -m shift" -- hl.gesture({ fingers = 2, direction = "pinch", action = "cursorZoom", zoom_level = 1, mode = "live" }) hl.workspace_rule({ workspace = "special:special", border_size = 3 }) -hl.window_rule({ match = { class = "(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float|org.pulseaudio.pavucontrol)" }, tag = "+floating-window"}) -hl.window_rule({ match = { - class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors)", - title = "^(Open.*Files?|Save.*Files?|Save.*As|All Files|Save)" -}, tag = "+floating-window"}) +hl.window_rule({ match = { class = "(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float|org.pulseaudio.pavucontrol)" }, tag = +"+floating-window" }) +hl.window_rule({ + match = { + class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors)", + title = "^(Open.*Files?|Save.*Files?|Save.*As|All Files|Save)" + }, + tag = "+floating-window" +}) -hl.window_rule({match = { tag = "floating-window" }, float = true, center = true, size = { 800, 600 }}) +hl.window_rule({ + match= {class="code"}, + fullscreen_state=1, +}) -hl.window_rule({match = { class = "(rofi|wofi)" }, tag = "+user-menu"}) -hl.window_rule({match = { class = "^(pinentry-)" }, tag = "+user-menu"}) -hl.window_rule({match = { class = "^(gcr-prompter)$" }, tag = "+user-menu"}) -hl.window_rule({match = { tag = "user-menu"}, stay_focused = true, no_anim = true, float = true, center = true, size = { 600, 400 }}) +hl.window_rule({ + -- Fix some dragging issues with XWayland + name = "fix-xwayland-drags", + match = { + class = "^$", + title = "^$", + xwayland = true, + float = true, + fullscreen = false, + pin = false, + }, + + no_focus = true, +}) + +hl.window_rule({ match = { tag = "floating-window" }, float = true, center = true, size = { "monitor_w/2", "monitor_h/2" } }) + +hl.window_rule({ match = { class = "(rofi|wofi)" }, tag = "+user-menu" }) +hl.window_rule({ match = { class = "^(pinentry-)" }, tag = "+user-menu" }) +hl.window_rule({ match = { class = "^(gcr-prompter)$" }, tag = "+user-menu" }) +hl.window_rule({ match = { tag = "user-menu" }, stay_focused = true, no_anim = true, float = true, center = true, size = { "monitor_w/3", "monitor_h/3" } }) + +hl.window_rule({ + name = "Picture in Picture windows", + match = { title = "^.*[Pp]icture[ -][Ii]n[ -][Pp]icture.*$" }, + float = true, + pin = true, + rounding = 7, + opacity = "1 1", + move = { "monitor_w-window_w-10", "monitor_h-window_h-10" }, + size = { "monitor_w/4", "monitor_h/4" }, +}) -- Cursor size -hl.env("XCURSOR_SIZE","24") -hl.env("HYPRCURSOR_SIZE","24") +hl.env("XCURSOR_SIZE", "24") +hl.env("HYPRCURSOR_SIZE", "24") -- Force all apps to use Wayland -hl.env("GDK_BACKEND","wayland,x11,*") -hl.env("QT_QPA_PLATFORM","wayland;xcb") -hl.env("QT_STYLE_OVERRIDE","kvantum") -hl.env("SDL_VIDEODRIVER","wayland") -hl.env("MOZ_ENABLE_WAYLAND","1") -hl.env("ELECTRON_OZONE_PLATFORM_HINT","wayland") -hl.env("OZONE_PLATFORM","wayland") -hl.env("XDG_SESSION_TYPE","wayland") +hl.env("GDK_BACKEND", "wayland,x11,*") +hl.env("QT_QPA_PLATFORM", "wayland;xcb") +hl.env("QT_STYLE_OVERRIDE", "kvantum") +hl.env("SDL_VIDEODRIVER", "wayland") +hl.env("MOZ_ENABLE_WAYLAND", "1") +hl.env("ELECTRON_OZONE_PLATFORM_HINT", "wayland") +hl.env("OZONE_PLATFORM", "wayland") +hl.env("XDG_SESSION_TYPE", "wayland") -- Allow better support for screen sharing (Google Meet"," Discord, etc) -hl.env("XDG_CURRENT_DESKTOP","Hyprland") -hl.env("XDG_SESSION_DESKTOP","Hyprland") +hl.env("XDG_CURRENT_DESKTOP", "Hyprland") +hl.env("XDG_SESSION_DESKTOP", "Hyprland") -- Use XCompose file -hl.env("XCOMPOSEFILE","~/.XCompose") +hl.env("XCOMPOSEFILE", "~/.XCompose") -- Make Chromium use XCompose and all Wayland hl.env("CHROMIUM_FLAGS", "--enable-features=UseOzonePlatform --ozone-platform=wayland --gtk-version=4") -- Make .desktop files available for wofi -hl.env("XDG_DATA_DIRS","/usr/share:/usr/local/share:~/.local/share") +hl.env("XDG_DATA_DIRS", "/usr/share:/usr/local/share:~/.local/share") -- TODO: add theme link require("theme") -hl.on("hyprland.start", function () - - hl.exec_cmd("dbus-update-activation-environment --systemd --all") - hl.exec_cmd("systemctl --user start hyprpolkitagent") - +hl.on("hyprland.start", function() hl.exec_cmd("hyprctl setcursor Pop 24") - hl.exec_cmd("hypridle") - hl.exec_cmd("mako") - -- hl.exec_cmd("fxitx5") - hl.exec_cmd("udiskie -a -n -T &") - hl.exec_cmd("awww-daemon") - - hl.exec_cmd("gnome-keyring-daemon --replace --daemonize --components=pkcs11,secrets,gpg") - -- hl.exec_cmd("systemctl --user import-environment $(env | cut -d'=' -f 1)") - hl.exec_cmd("systemctl --user import-environment DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS LANG PATH") end) diff --git a/config/systemd/user/awww-daemon.service b/config/systemd/user/awww-daemon.service new file mode 100644 index 0000000..b7f3ed5 --- /dev/null +++ b/config/systemd/user/awww-daemon.service @@ -0,0 +1,13 @@ +[Unit] +Description=Awww wallpaper daemon +PartOf=graphical-session.target +After=graphical-session.target + +[Service] +Type=simple +ExecStart=/usr/bin/awww-daemon +Restart=always +RestartSec=2 + +[Install] +WantedBy=graphical-session.target diff --git a/config/systemd/user/mako.service b/config/systemd/user/mako.service new file mode 100644 index 0000000..a00a251 --- /dev/null +++ b/config/systemd/user/mako.service @@ -0,0 +1,12 @@ +[Unit] +Description=Mako Notifications +After=graphical-session.target +PartOf=graphical-session.target + +[Service] +ExecStart=/usr/bin/mako +Restart=on-failure + +[Install] +WantedBy=graphical-session.target + diff --git a/installer/10-base-desktop.sh b/installer/10-base-desktop.sh index 5c5548c..08f797d 100755 --- a/installer/10-base-desktop.sh +++ b/installer/10-base-desktop.sh @@ -16,5 +16,6 @@ else fi if [[ -x "$(command -v systemctl)" ]]; then - sudo systemctl enable --now lemurs.service + sudo systemctl enable --now sddm.service + sudo systemctl enable --now udisks2.service fi diff --git a/installer/desktop.sh b/installer/desktop.sh index b645653..a89f86a 100755 --- a/installer/desktop.sh +++ b/installer/desktop.sh @@ -23,11 +23,6 @@ sjb-script-installer ${SJB_CONF_DIR}/bin/bing-wallpaper ${DOTFILES_DIR}/sync-script script/bing-wallpaper -if [[ -x "$(command -v systemctl)" ]]; then - ${DOTFILES_DIR}/sync-config config/systemd - systemctl --user enable --now wallpaper.timer -fi - if [[ ! -x "$(command -v gsettings)" ]]; then gsettings set org.gnome.desktop.interface gtk-enable-primary-paste true fi @@ -36,6 +31,7 @@ ${DOTFILES_DIR}/sync-config config/rofi ${DOTFILES_DIR}/sync-config config/mako ln -snf ${THEMES_DIR}/current/theme/mako.ini ${HOME}/.config/mako/config + ${DOTFILES_DIR}/sync-config config/ghostty ln -snf ${THEMES_DIR}/current/theme/ghostty ${HOME}/.config/ghostty/theme @@ -44,3 +40,14 @@ ${DOTFILES_DIR}/sync-config config/chromium-flags.conf xdg-settings set default-web-browser firefox.desktop +if [[ -x "$(command -v systemctl)" ]]; then + ${DOTFILES_DIR}/sync-config config/systemd + systemctl --user enable mako.service + systemctl --user enable hypridle.service + systemctl --user enable awww-daemon.service + systemctl --user enable gnome-keyring-daemon.service + systemctl --user enable hyprpolkitagent.service + systemctl --user enable wallpaper.timer +fi + + diff --git a/packages/sjb-desktop.packages b/packages/sjb-desktop.packages index 7724df3..82ba71f 100644 --- a/packages/sjb-desktop.packages +++ b/packages/sjb-desktop.packages @@ -1,4 +1,5 @@ awesome-terminal-fonts +adwaita-icon-theme brightnessctl chromium blueberry @@ -66,6 +67,9 @@ playerctl poppler-glib qt6-declarative qt6-wayland +qt5ct +qt6ct +papirus-icon-theme rofi satty slurp