-- Generated by hyprlang2lua. Review TODOs before reloading Hyprland. local mod = "SUPER" --GENERAL# --Monitor settings hl.monitor({ output = "HDMI-A-2", mode = "2560x1440@280", position = "0x0", scale = 1, vrr = 0, }) hl.monitor({ output = "DP-1", mode = "2560x1440@144", position = "2560x-900", scale = 1, transform = 1, vrr = 0, }) --monitor=DP-1,disable -- WS on HDMI-A-2 hl.workspace_rule({ workspace = "1", monitor = "HDMI-A-2", persistent = true, }) hl.workspace_rule({ workspace = "2", monitor = "HDMI-A-2", persistent = true, }) -- WS on DP-1 hl.workspace_rule({ workspace = "3", monitor = "DP-1", persistent = true, }) hl.workspace_rule({ workspace = "4", monitor = "DP-1", persistent = true, }) hl.workspace_rule({ workspace = "5", monitor = "DP-1", persistent = true, }) hl.window_rule({ name = "windowrule-1", match = { title = "^RuneLite.*", }, float = true, }) hl.window_rule({ name = "windowrule-2", match = { class = "net-runelite-client-RuneLite", title = "win.*", }, no_focus = true, }) hl.window_rule({ name = "windowrule-3", match = { class = ".*", }, immediate = true, }) -- Battle.net (Proton via Faugus). The class is shared by every umu game without -- its own ID, so match on the title too. hl.window_rule({ name = "battlenet-float", match = { class = "^steam_app_default$", title = "^Battle\\.net.*", }, float = true, }) -- xembedsniproxy (pkgs/xembedsniproxy) puts Wine/Proton tray icons such as -- Battle.net into Waybar's tray. It keeps a small helper window mapped for the -- icons it hosts, which Hyprland would otherwise show as a floating window. hl.window_rule({ name = "xembedsniproxy", match = { class = "^xembedsniproxy$", }, opacity = "0.0 override 0.0 override", border_size = 0, no_blur = true, no_shadow = true, no_anim = true, no_focus = true, no_initial_focus = true, }) -- Dolphin transparency now comes from Kvantum's own translucent_windows -- (see kvantum/RiceDark.kvconfig) rather than a forced window opacity here: -- Kvantum punches real per-pixel alpha into the background only, so text and -- icons stay fully opaque and legible, same mechanism as kitty (which also -- has no windowrule here) -- decoration.blur is already global+enabled above -- with ignore_opacity defaulting true, so it blurs through automatically. -- If Dolphin still looks flat/opaque after applying the Kvantum theme, that -- rule can come back as a fallback: -- hl.window_rule({ -- name = "windowrule-4", -- match = { class = "^(org.kde.dolphin)$" }, -- opacity = "0.90 0.80", -- }) -- Claude's desktop app creates its window opaque (transparent: false in the -- Electron bundle) and has no user stylesheet, so unlike kitty and Dolphin it -- can't put alpha in the background only. A forced window opacity is the -- closest it gets: decoration.blur frosts what shows through, at the cost of -- the text being translucent too. hl.window_rule({ name = "claude-frosted", match = { class = "^com\\.anthropic\\.Claude$" }, opacity = "0.80 0.80", }) --windowrulev2 = maxsize 1803 1153,title:^(RuneLite)$ --windowrulev2 = maxsize 1803 1153,title:^(RuneLite)$ hl.layer_rule({ name = "layerrule-1", match = { namespace = "waybar", }, blur = true, ignore_alpha = 0, blur_popups = true, }) hl.layer_rule({ name = "layerrule-2", match = { namespace = "launcher", -- fuzzel }, ignore_alpha = 0, blur = true, }) hl.layer_rule({ name = "layerrule-3", match = { namespace = "notifications", }, ignore_alpha = 0, blur = true, }) hl.layer_rule({ name = "layerrule-4", match = { namespace = "eww-control-center", }, ignore_alpha = 0, blur = true, }) hl.bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd("imsh-shot area -Cufa@~/.config/keys/scrnis -s1")) hl.bind(mod .. " + SHIFT + F", hl.dsp.exec_cmd("imsh-shot screen -Cua@~/.config/keys/scrnis")) hl.bind(mod .. " + SHIFT + R", hl.dsp.exec_cmd("imsh-cast -Cua@~/.config/keys/scrnis")) hl.bind(mod .. " + Return", hl.dsp.exec_cmd("~/.config/fuzzel/launch")) hl.bind(mod .. " + T", hl.dsp.exec_cmd("kitty")) hl.bind(mod .. " + W", hl.dsp.exec_cmd("firefox")) hl.bind(mod .. " + Q", hl.dsp.window.close()) hl.bind(mod .. " + F", hl.dsp.window.float({ action = "toggle" })) hl.bind(mod .. " + G", hl.dsp.window.fullscreen({ mode = "fullscreen", action = "toggle" })) hl.bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "m+1" })) hl.bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "m-1" })) hl.bind(mod .. " + mouse:272", hl.dsp.window.drag()) hl.bind(mod .. " + mouse:273", hl.dsp.window.resize()) hl.bind(mod .. " + Delete", hl.dsp.exit()) hl.env("LIBVA_DRIVER_NAME", "nvidia") hl.env("NVD_BACKEND", "direct") -- libva-nvidia-driver backend (Firefox hardware video decoding) hl.env("MOZ_DISABLE_RDD_SANDBOX", "1") -- let Firefox's video decoder process reach the NVIDIA driver hl.env("XDG_SESSION_TYPE", "wayland") hl.env("GBM_BACKEND", "nvidia-drm") hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia") hl.env("XCURSOR_THEME", "BreezeX-Black") hl.env("XCURSOR_SIZE", "28") hl.env("QT_QPA_PLATFORMTHEME", "qt6ct") hl.config({ general = { border_size = 1, gaps_in = 5, gaps_out = 17, layout = "dwindle", col = { active_border = "rgba(00000000)", inactive_border = "rgba(00000000)", }, allow_tearing = true, }, decoration = { rounding = 10, -- No visible borders; the focused window is the one that isn't dimmed. dim_inactive = true, dim_strength = 0.15, blur = { enabled = true, size = 9, passes = 3, new_optimizations = true, popups = true, -- blur tooltips/context menus (Kvantum's popup_blurring is on for this) }, shadow = { enabled = false, render_power = 3, range = 4, color = "rgba(1a1a1aee)", }, }, input = { kb_layout = "no", follow_mouse = 1, sensitivity = 0, accel_profile = "flat", }, --MISC# misc = { disable_hyprland_logo = true, disable_splash_rendering = true, -- Wallpaper's average colour instead of black, so the moment between the -- login screen and hyprpaper drawing the wallpaper doesn't flash black. background_color = "rgb(121d1a)", }, ecosystem = { no_donation_nag = true, }, --BINDS# binds = { scroll_event_delay = 10, }, --EXEC# --ENVIROMENT# --CURSOR# cursor = { -- Software cursor, for tearing. Hyprland (0.56) refuses to tear while a -- hardware cursor is visible, because the kernel can't update the cursor -- plane during a tearing flip. So with a hardware cursor a game only tears -- while it hides the pointer (e.g. mouselook) and is vsynced otherwise, and -- switching back and forth left WoW's cursor shape stale. With a software -- cursor the game tears all the time; the price is that frames are -- composited (one extra copy) while the pointer is visible. no_hardware_cursors = true, }, render = { -- Fullscreen games (e.g. WoW) scan out straight to the monitor instead of -- being copied by the compositor. With the software cursor above this only -- applies while the game hides the pointer. -- 1 = always; XWayland games don't set a content type, so 2 (auto) won't trigger. direct_scanout = 1, }, }) hl.on("hyprland.start", function() -- Wallpaper, bar, notifications, the control centre, tray helpers, the -- clipboard bridge and the polkit agent are systemd user services now -- (modules/home/services.nix in the dot repo): uwsm starts them with -- graphical-session.target, restarts them if they crash, and -- `systemctl --user status ` / `journalctl --user -u ` show them. -- Apps opened at login, in their usual places (scripts/autostart-apps starts -- them, from autostart-apps.service). These placement rules are switched off -- again after two minutes, so opening the same apps by hand later behaves like -- any other window. local startup_rules = { hl.window_rule({ name = "startup-signal", match = { class = "^signal$" }, workspace = "3 silent", }), hl.window_rule({ name = "startup-discord", match = { class = "^discord$" }, workspace = "3 silent", }), hl.window_rule({ name = "startup-faugus", match = { class = "^io\\.github\\.Faugus\\.faugus-launcher$" }, workspace = "1 silent", float = true, size = { 430, 610 }, move = { 1901, 333 }, }), } hl.timer(function() for _, rule in ipairs(startup_rules) do rule:set_enabled(false) end end, { timeout = 120000, type = "oneshot" }) -- WowUp can't start hidden, so the window it opens at login is sent to a hidden -- workspace and closed again, which leaves it in the tray. That rule must not -- outlive the one window: it is dropped as soon as the window has opened (or -- after a minute if none came), so opening WowUp yourself right after login -- lands on your workspace like any other window. local wowup_rule = hl.window_rule({ name = "startup-wowup", match = { class = "^WowUpCf$" }, workspace = "special:autostart silent", }) local wowup_pending = true local function wowup_done() wowup_pending = false wowup_rule:set_enabled(false) end hl.on("window.open", function(window) if wowup_pending and window.class == "WowUpCf" then wowup_done() -- closing it from inside the open event is too early and gets ignored local address = window.address hl.timer(function() hl.dispatch(hl.dsp.window.close({ window = "address:" .. address })) end, { timeout = 300, type = "oneshot" }) end end) hl.timer(wowup_done, { timeout = 60000, type = "oneshot" }) -- hl.exec_cmd("gsettings set org.gnome.desktop.interface color-scheme prefer-dark") -- hl.exec_cmd("gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark") end)