-- Learn how to configure Hyprland: https://wiki.hypr.land/Configuring/Start/ -- Omarchy's bootstrap keeps path setup out of this user config. dofile((os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/default/hypr/bootstrap.lua") -- Disable all Omarchy default bindings. Add your own in hypr/bindings.lua. -- omarchy_default_bindings = false -- -- Or disable only bindings for Omarchy's preinstalled apps/web apps while -- keeping core window-manager bindings: -- omarchy_preinstalled_bindings = false -- Load Omarchy defaults. require("default.hypr.omarchy") -- Put your personal overrides in these files. They're loaded after Omarchy's -- defaults so package updates can improve the defaults without rewriting your -- ~/.config/hypr files. require("hypr.monitors") require("hypr.input") require("hypr.bindings") require("hypr.looknfeel") require("hypr.autostart") -- Toggle config flags dynamically. require("default.hypr.toggles") -- Omarchy's default/hypr/nvidia.lua sees the RTX 5060 Ti and points VA-API -- and GLX at the NVIDIA driver, as if it drove the display. It is a -- Thunderbolt eGPU for CUDA only (see uwsm/env-hyprland for the EGL, Vulkan -- and KMS side). With LIBVA_DRIVER_NAME=nvidia every Chromium/Electron GPU process -- opens the first render node (the eGPU, renderD128) and nvidia-vaapi-driver -- brings up a CUDA context + NVDEC on it before the window even appears; -- launching LM Studio took the whole machine down with it. Last env wins, -- so this must come after the Omarchy defaults above. hl.env("LIBVA_DRIVER_NAME", "radeonsi") hl.env("__GLX_VENDOR_LIBRARY_NAME", "mesa") -- Add any other personal Hyprland configuration below. -- o.window("qemu", { workspace = "5" }) -- Pin workspaces to monitors: 1-4 on the main external display (Studio -- Display or Samsung ultrawide, see hypr/monitors.lua), 5-8 on the laptop -- panel; 1 and 5 are what each shows on connect. Persistent so empty ones -- stay on their monitor (the bar's workspace dots list them per monitor). -- The main external is picked at config load, and hypr/monitors.lua reloads -- the config when it changes. Workspaces 1-4 that already exist are moved -- over, since rules only place workspaces when they are created. local monitors = require("hypr.monitors") local external = monitors.external() for id = 1, 8 do hl.workspace_rule({ workspace = tostring(id), monitor = id <= 4 and (external or monitors.externals[1]) or "eDP-1", default = id == 1 or id == 5, persistent = true, }) end if external then for id = 1, 4 do hl.dispatch(hl.dsp.workspace.move({ workspace = tostring(id), monitor = external })) end end -- Always open these apps on a fixed workspace and follow them there. Classes -- come from `hyprctl clients` -- the desktop files' StartupWMClass hints -- disagree with reality for Beeper (claims BeeperTexts, actually reports -- Beeper). Add " silent" to a workspace prop to place a window without -- switching the view to it. o.window([[^brave-www\.tldraw\.com__-Default$]], { workspace = "3" }) -- tldraw-offline gets workspace 5 to itself on the laptop panel, fullscreen. o.window([[^tldraw-offline$]], { workspace = "5", fullscreen = true }) -- Scratch workspaces, toggled by ~/.local/bin/omarchy-toggle-scratch, which -- also starts any resident that is missing and picks the monitor. Pinning -- the residents here means they land on their workspace no matter who starts -- them; "silent" leaves the reveal to the script. Under the scrolling layout -- each resident gets its own column, in the order they appear. -- -- SUPER + A / SUPER + CTRL + S: Tern; SUPER + SHIFT + A: Claude Desktop. -- Each alone on its own workspace, main external display. Tern has no per-window -- class flag, so every Tern window lands on the scratchpad. o.window([[^so\.stencil\.tern$]], { workspace = "special:scratchpad silent" }) o.window([[^com\.anthropic\.Claude$]], { workspace = "special:claude silent" }) -- SUPER + CTRL + ALT + E / M: Fastmail and Beeper, each alone on its own -- workspace, laptop panel (eDP-1). o.window([[^com\.fastmail\.Fastmail$]], { workspace = "special:fastmail silent" }) o.window([[^Beeper$]], { workspace = "special:beeper silent" }) -- SUPER + CTRL + H: Google Home (Brave web app), on the focused monitor. o.window([[^brave-home\.google\.com__.*]], { workspace = "special:home silent" }) -- SUPER + CTRL + L: LM Studio, on the focused monitor. o.window([[^ai\.elementlabs\.lmstudio$]], { workspace = "special:lmstudio silent" }) -- SUPER + CTRL + ALT + Y / SUPER + SHIFT + Y: the YouTube web app, summoned -- by ~/.local/bin/omarchy-summon. Not a scratch workspace: a floating, -- pinned window parked in the bottom-left corner at 30% of the monitor on -- both axes, inset by general:gaps_out -- the same fit ~/.local/bin/omarchy-pip -- applies (SUPER + SHIFT + T, and the summon after a monitor move); keep the -- fraction and inset in sync. Chromium derives the class from the app URL -- and the host spelling has varied (youtube.com vs www.youtube.com) once a -- video plays, so match the family. Its picture-in-picture overlay shares -- the class; the "negative:" title match keeps it out so Omarchy's pip rule -- (float + pin, top right) still applies. Rule regexes are RE2 full matches: -- no lookahead, and a pattern must cover the whole string. o.window( { class = [[brave-(www\.)?youtube\.com__.*]], title = [[negative:.*Picture.?in.?[Pp]icture.*]] }, { float = true, pin = true, size = { "(monitor_w*0.3)", "(monitor_h*0.3)" }, -- Spelled from monitor_h, not window_h: move is evaluated against the -- size Chromium asked for, not the one the size rule imposes, and that -- put the window top-left. move = { "10", "(monitor_h*0.7-10)" }, } ) -- >>> altscape >>> -- Window switcher keybind, managed by Altscape (change it in its settings). do local altscape_manifest = io.open("/home/prad/.config/omarchy/plugins/io.github.qempexe.altscape/manifest.json", "r") if altscape_manifest then altscape_manifest:close() hl.unbind("ALT + TAB") hl.unbind("ALT + SHIFT + TAB") o.bind("ALT + TAB", "Altscape: next window", "omarchy-shell shell summon io.github.qempexe.altscape next") o.bind("ALT + SHIFT + TAB", "Altscape: previous window", "omarchy-shell shell summon io.github.qempexe.altscape prev") -- Letting go of the modifier picks the selected window. o.bind("ALT + ALT_L", "Altscape: switch on release", "omarchy-shell shell summon io.github.qempexe.altscape release", { release = true }) o.bind("ALT + ALT_R", "Altscape: switch on release", "omarchy-shell shell summon io.github.qempexe.altscape release", { release = true }) -- Opens the settings (again to close). o.bind("SUPER + ALT + SHIFT + S", "Altscape settings", "omarchy-shell io.github.qempexe.altscape settings") end end -- <<< altscape <<<