From b94a8b62a3a69391b8458720aee1de514c7b21ab Mon Sep 17 00:00:00 2001 From: bullshar-k <273740932+bullshar-k@users.noreply.github.com> Date: Fri, 16 Oct 2026 09:22:39 +0000 Subject: [PATCH] commit after getting everything working on desktop hyprland --- desktop/hyprland.lua | 86 ++++++++++++++++-- desktop/waybar/config.jsonc | 27 +++--- .../__pycache__/logout-menu.cpython-314.pyc | Bin 0 -> 1796 bytes desktop/waybar/scripts/logout-menu.py | 37 ++++++++ desktop/waybar/scripts/notifications.sh | 21 +++++ desktop/waybar/style.css | 4 +- 6 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 desktop/waybar/scripts/__pycache__/logout-menu.cpython-314.pyc create mode 100755 desktop/waybar/scripts/logout-menu.py create mode 100755 desktop/waybar/scripts/notifications.sh diff --git a/desktop/hyprland.lua b/desktop/hyprland.lua index 7340667..74da621 100644 --- a/desktop/hyprland.lua +++ b/desktop/hyprland.lua @@ -9,19 +9,21 @@ hl.monitor({ scale = "auto", }) --- Samsung Odyssey G61SH primary +-- Samsung Odyssey G61SH (DP-3) — primary, landscape hl.monitor({ - output = "DP-2", - mode = "2560x1440@240", - position = "0x363", + output = "DP-3", + mode = "2560x1440@120", + position = "0x0", scale = 1, }) --- MSI G274QPX — secondary, portrait rotated 90 right +-- MSI G274QPX (DP-2) — secondary, portrait, rotated 90° to the right. +-- Both panels are 27"; the portrait screen is vertically centred against the +-- Samsung, i.e. y = (1440 - 2560) / 2 = -560 (negative y moves it up). hl.monitor({ - output = "DP-1", - mode = "2560x1440@120", - position = "2560x0", + output = "DP-2", + mode = "2560x1440@240", + position = "2560x-560", scale = 1, transform = 1, }) @@ -45,7 +47,7 @@ hl.on("hyprland.start", function () hl.exec_cmd(waybarCmd) -- wallpaper - hl.exec_cmd("swaybg -i /home/shark/pictures/wall/wall.png -m fill") + hl.exec_cmd("swaybg -i /home/shark/wall/wall.png -m fill") -- clipboard history (wl-cliphist) hl.exec_cmd("wl-paste --type text --watch cliphist store") @@ -303,6 +305,72 @@ hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = tr hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) +------------------------------- +---- WINDOW SNAPPING ---- +------------------------------- +-- Snap the focused window into a fractional region of the monitor it is on. +-- fx/fy = top-left corner, fw/fh = size, each a fraction (0..1) of the +-- monitor's *usable* area (the monitor minus whatever waybar reserves). +-- Windows are made floating first, since exact geometry only sticks to +-- floating windows. +local function snapWindow(fx, fy, fw, fh) + local w = hl.get_active_window() + if not w then return end + + -- Leave fullscreen so the new geometry is actually visible. + if w.fullscreen ~= 0 then + hl.dispatch(hl.dsp.window.fullscreen({ action = "unset" })) + end + + -- Exact move/resize only applies to floating windows. + if not w.floating then + hl.dispatch(hl.dsp.window.float({ action = "set" })) + end + + local m = w.monitor or hl.get_active_monitor() + if not m then return end + + -- width/height are the *untransformed* pixel size, so swap them on + -- 90°/270°-rotated (portrait) screens like DP-2. + local mw, mh = m.width, m.height + if m.transform % 2 == 1 then + mw, mh = mh, mw + end + + local r = m.reserved or {} + local rl, rt = r.left or 0, r.top or 0 + local rr, rb = r.right or 0, r.bottom or 0 + + local ux, uy = m.x + rl, m.y + rt -- usable top-left (global coords) + local uw, uh = mw - rl - rr, mh - rt - rb -- usable size + + local tx = math.floor(ux + fx * uw) + local ty = math.floor(uy + fy * uh) + local tw = math.floor(fw * uw) + local th = math.floor(fh * uh) + + -- resize() takes an absolute size; move() takes a global top-left coord. + hl.dispatch(hl.dsp.window.resize({ x = tw, y = th, relative = false, window = w })) + hl.dispatch(hl.dsp.window.move({ x = tx, y = ty, relative = false, window = w })) +end + +-- Your programming-course layout: browser on the left 2/3, helix in the +-- top 2/3 of what's left, compile/run terminal in the bottom 1/3. +hl.bind(mainMod .. " + CTRL + B", function() snapWindow(0, 0, 2/3, 1 ) end) -- browser -> left 2/3 +hl.bind(mainMod .. " + CTRL + H", function() snapWindow(2/3, 0, 1/3, 2/3 ) end) -- helix -> top-right 1/3 x 2/3 +hl.bind(mainMod .. " + CTRL + R", function() snapWindow(2/3, 2/3, 1/3, 1/3 ) end) -- compile -> bottom-right 1/3 x 1/3 + +-- Generic halves / thirds / fill (handy for other layouts). +hl.bind(mainMod .. " + CTRL + left", function() snapWindow(0, 0, 1/2, 1 ) end) +hl.bind(mainMod .. " + CTRL + right", function() snapWindow(1/2, 0, 1/2, 1 ) end) +hl.bind(mainMod .. " + CTRL + up", function() snapWindow(0, 0, 1, 1/2) end) +hl.bind(mainMod .. " + CTRL + down", function() snapWindow(0, 1/2, 1, 1/2) end) +hl.bind(mainMod .. " + CTRL + 1", function() snapWindow(0, 0, 1/3, 1 ) end) +hl.bind(mainMod .. " + CTRL + 2", function() snapWindow(1/3, 0, 1/3, 1 ) end) +hl.bind(mainMod .. " + CTRL + 3", function() snapWindow(2/3, 0, 1/3, 1 ) end) +hl.bind(mainMod .. " + CTRL + RETURN", function() snapWindow(0, 0, 1, 1 ) end) -- fill usable area + + -------------------------------- ---- WINDOWS AND WORKSPACES ---- -------------------------------- diff --git a/desktop/waybar/config.jsonc b/desktop/waybar/config.jsonc index 79a596d..bca74c5 100644 --- a/desktop/waybar/config.jsonc +++ b/desktop/waybar/config.jsonc @@ -4,8 +4,8 @@ "position": "top", "height": 36, "margin-top": 7, - "margin-left": 446, - "margin-right": 446, + "margin-left": 0, + "margin-right": 0, "spacing": 6, "modules-left": [ "hyprland/workspaces", @@ -34,9 +34,9 @@ "format": "{title}", "max-length": 50, "rewrite": { - "(.*) \u2014 Mozilla Firefox": "\uf279 $1", + "(.*) \u2014 Mozilla Firefox": "\uf269 $1", "(.*) - Chromium": "\uf268 $1", - "(.*) - Visual Studio Code": "\uf121 $1", + "(.*) - Visual Studio Code": "\ue8da $1", "(.*) - zed": "\uf121 $1", "(.*) - Discord": "\uf392 $1", "(.*) - Steam": "\uf1b6 $1" @@ -50,26 +50,27 @@ }, "temperature": { "format": "\uf2c9 {temperatureC}\u00b0", + "hwmon-path": "/sys/class/hwmon/hwmon4/temp1_input", "interval": 2, "tooltip": true, "tooltip-format": "CPU Temp: {temperatureC}\u00b0C" }, "memory": { - "format": "\uefcd {used:0.1f}G", + "format": "\uefc5 {used:0.1f}G", "interval": 2, "tooltip": true, "tooltip-format": "RAM: {used:0.1f}GB / {total:0.1f}GB ({percentage}%)" }, "disk": { - "format": "\uf07a {used}", + "format": "\uf0a0 {used}", "interval": 30, "path": "/", "tooltip": true, "tooltip-format": "Disk: {used} / {total} ({percentage_used}%)" }, "network": { - "format-wifi": "\uf07a {bandwidthDownBytes} \uf07a {bandwidthUpBytes}", - "format-ethernet": "\uf07a {bandwidthDownBytes} \uf07a {bandwidthUpBytes}", + "format-wifi": "\uf1eb \uf063 {bandwidthDownBytes} \uf062 {bandwidthUpBytes}", + "format-ethernet": "\uef44 \uf063 {bandwidthDownBytes} \uf062 {bandwidthUpBytes}", "format-disconnected": "\uf1eb Offline", "interval": 2, "tooltip": true, @@ -91,7 +92,7 @@ }, "pulseaudio": { "format": "{icon} {volume}%", - "format-muted": "\uf2e2 Muted", + "format-muted": "\uf026 Muted", "format-icons": { "default": [ "\uf026", @@ -125,16 +126,16 @@ "tooltip": "Session Menu", "on-click": "python3 $HOME/.config/waybar/scripts/logout-menu.py" }, - "output": "DP-2" + "output": "DP-3" }, { - "output": "DP-1", + "output": "DP-2", "layer": "top", "position": "top", "height": 36, "margin-top": 7, - "margin-left": 50, - "margin-right": 50, + "margin-left": 0, + "margin-right": 0, "spacing": 6, "modules-left": [ "hyprland/workspaces#portrait" diff --git a/desktop/waybar/scripts/__pycache__/logout-menu.cpython-314.pyc b/desktop/waybar/scripts/__pycache__/logout-menu.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb9c4a83f8339fe80196317dfcccf2b4bc0ea178 GIT binary patch literal 1796 zcmZWp&2JM&6rcU_x1BfyET~JyP=#(=+jU6GN25rUAQA$ByNN;%NmiTPwY^~Pu6Ach zvL~zR0T60bRh6iEX{AanLX~>#pOFv{VTjaLJ#iyVtE#uYS=)fZv;1b}y|?f4H}h^T zn?gX^h0^)@X|;f^CY7JhV9TU*vV>^du^hnE9F9Q!QR zu;0?|})1N~g zAS1Z8;sY>bErSdbOfE zcEf5`SE8(|zV2Br@vCj8=>(+A(yX{^G^47TZ97CGrmA`ga5D^l{{XNq`WNN7>@H(> z^k~@wG13_uP#iWU9#(w7ds{P z3|wxWtB>q6hGYHU>#_l?T>jO(W}po#P>(lxb%H^$8A0G;7QLF$q1U}ZC*w+DUaSa% zevTpN2Re?D=xDUcDF8TSS)hF7eJa{o2mGo&^EHmK#{fc;Q%%!0 zS6y$K7CM?`SEkyIuC@K?$_oW+na_Ip45Ds~*6tO)Y2G!yp1WW8&u8uaEPsHTgCLS+ zy8)p&U31|om@0sooke1<63Y9nkT2`9=rK%$@p9Qhf6DoLt9oaz& zRPqVjFDlg?*R*AciYzX>uYS-bG^V#4OE_!g%;QttYA3jP`qJ$sn)q-#H?m!LV>_GwJ1OO2-I?bZlp9@NytVi^i#M})D|@Uv z^V?y3D|=JiP7i%Cy^}fgI8%I(Dc&`{JNMIxjW;JAW=?Kr@=wy4-6T3v+D)KL)&p1| znow1iwW`XJ%v14_qhAjv`}N`S4cuCDJs98FllT!D|R^YQXReIPNN|wXk1kdM~5fyFqGwC#)^!MF~(-XN@dtqRhpWOqMwJP zydkD%t?11#G1YO5plwcjHIT7a**^p9xxjJUAL!$!DEk!UpQ6-XVl2&f*(lBG>-|-07aG literal 0 HcmV?d00001 diff --git a/desktop/waybar/scripts/logout-menu.py b/desktop/waybar/scripts/logout-menu.py new file mode 100755 index 0000000..58fd4a8 --- /dev/null +++ b/desktop/waybar/scripts/logout-menu.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +"""Waybar power button: a small session menu driven by fuzzel.""" +import shutil +import subprocess +import sys + +ENTRIES = [ + ("Lock", "command -v hyprlock >/dev/null 2>&1 && exec hyprlock"), + ("Log out", "hyprctl dispatch exit"), + ("Suspend", "systemctl suspend"), + ("Reboot", "systemctl reboot"), + ("Shut down", "systemctl poweroff"), +] + + +def main() -> int: + if not shutil.which("fuzzel"): + print("fuzzel not found", file=sys.stderr) + return 1 + + menu = "\n".join(name for name, _ in ENTRIES) + "\n" + result = subprocess.run( + ["fuzzel", "--dmenu", "--prompt", "Session: "], + input=menu, + capture_output=True, + text=True, + ) + choice = result.stdout.strip() + for name, command in ENTRIES: + if name == choice: + subprocess.Popen(["sh", "-c", command]) + break + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/desktop/waybar/scripts/notifications.sh b/desktop/waybar/scripts/notifications.sh new file mode 100755 index 0000000..064fdb3 --- /dev/null +++ b/desktop/waybar/scripts/notifications.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Waybar "custom/notifications" module (return-type: json). +# Counts active mako notifications and degrades gracefully when mako is absent. + +count=0 +if command -v makoctl >/dev/null 2>&1; then + count=$(makoctl list 2>/dev/null | grep -c '"id"') +fi +case "$count" in ''|*[!0-9]*) count=0 ;; esac + +if [ "$count" -gt 0 ]; then + text=$(printf '\357\203\263 %s' "$count") + tooltip="$count notification(s)" + class=unread +else + text=$(printf '\357\203\263') + tooltip="No notifications" + class=empty +fi + +printf '{"text":"%s","tooltip":"%s","class":"%s"}\n' "$text" "$tooltip" "$class" diff --git a/desktop/waybar/style.css b/desktop/waybar/style.css index 2b05cf8..0ebd0db 100755 --- a/desktop/waybar/style.css +++ b/desktop/waybar/style.css @@ -4,8 +4,8 @@ * { all: initial; font-family: - "JetBrainsMono Nerd Font", "JetBrains Mono", "Font Awesome 6 Free", - monospace; + "JetBrainsMono Nerd Font", "JetBrains Mono", "Font Awesome 6 Brands", + "Font Awesome 6 Free", monospace; font-size: 13px; font-weight: 500; }