-- wm host layer — loaded by gui/.config/hypr/hyprland.lua via check_require("host"). -- Ports wm/.config/hypr/{monitors,host,nvidia}.conf to the Lua chain. -- ── Monitors ───────────────────────────────────────────────────────────────── -- DP-2 (the LG 4K) is the only fixed screen. Anything else works when plugged in, -- without editing this file: the 1080 Ti has four other connectors (DP-1, DVI-D-1, -- HDMI-A-1, HDMI-A-2), so extras are read from hl.get_monitors() in connection -- order instead of being named here. The first extra sits right of DP-2 and owns -- workspaces 11-20, a second sits left and owns 21-30. local mainScreen = "DP-2" local mainW, mainH, mainScale = 3840, 2160, 1.25 hl.monitor({ output = mainScreen, mode = mainW .. "x" .. mainH .. "@60", position = "0x0", scale = mainScale }) -- Catch-all for a screen with no rule of its own yet (the empty output name is -- the default rule) — covers the moment between plug-in and the re-pin reload. -- Not scale "auto": that picked 2 for a 1080p screen. hl.monitor({ output = "", mode = "preferred", position = "auto-right", scale = 1 }) local function extra_screens() local ok, monitors = pcall(hl.get_monitors) local found = {} for _, m in ipairs(ok and monitors or {}) do if m.name ~= mainScreen and not m.is_mirror then found[#found + 1] = m end end table.sort(found, function(a, b) return a.id < b.id end) return found end -- A 4K extra gets DP-2's scale, anything smaller 1; placed beside DP-2 and -- vertically centred on it (what the old fixed 3072x350 rule approximated). local function place(m, side) local scale = m.width >= 3840 and mainScale or 1 local w, h = math.floor(m.width / scale), math.floor(m.height / scale) local x = side == "right" and math.floor(mainW / mainScale) or -w local y = math.max(0, math.floor((mainH / mainScale - h) / 2)) hl.monitor({ output = m.name, mode = "preferred", position = x .. "x" .. y, scale = scale }) end local extras = extra_screens() local rightScreen, leftScreen if extras[1] then rightScreen = extras[1].name place(extras[1], "right") end if extras[2] then leftScreen = extras[2].name place(extras[2], "left") end -- ── Workspace pins (1-10 main, 11-20 right, 21-30 left) ────────────────────── -- These are what make the r~N binds land on the focused monitor's set. for i = 1, 10 do hl.workspace_rule({ workspace = tostring(i), monitor = mainScreen, default = (i == 1) }) if rightScreen then hl.workspace_rule({ workspace = tostring(i + 10), monitor = rightScreen, default = (i == 1) }) end if leftScreen then hl.workspace_rule({ workspace = tostring(i + 20), monitor = leftScreen, default = (i == 1) }) end end -- Pins are only computed at load, so a hotplug that changes the set of extras -- reloads once to re-pin. DP-2's own link drop/return (it sleeps as a hotplug) -- leaves the extras unchanged and does not reload. local function names(list) local out = {} for i, m in ipairs(list) do out[i] = m.name end return table.concat(out, ",") end local pinned = names(extras) local function repin_if_changed() if names(extra_screens()) ~= pinned then hl.exec_cmd("hyprctl reload") end end hl.on("monitor.added", repin_if_changed) hl.on("monitor.removed", repin_if_changed) -- ── Theme overrides (was host.conf) ────────────────────────────────────────── -- Loads after dynamic.lua's theme state, so these still win over the theme. hl.config({ general = { gaps_in = 2, gaps_out = 4 }, decoration = { rounding = 8 }, }) -- ── NVIDIA extras (was nvidia.conf) ────────────────────────────────────────── -- LIBVA_DRIVER_NAME / __GLX_VENDOR_LIBRARY_NAME / GBM_BACKEND are already set -- by HyDE's env.lua when the driver probe passes; only the two extras remain. hl.env("NVD_BACKEND", "direct") -- va-api via libva-nvidia-driver hl.config({ cursor = { no_hardware_cursors = true } }) -- avoid cursor hitches