Import from root chezmoi source
This commit is contained in:
commit
f4b5663ddf
9 files changed
+753
No files matched your search
@@ -0,0 +1,2 @@
|
||||
-- Extra autostart processes.
|
||||
-- o.launch_on_start("my-service")
|
||||
+331
@@ -0,0 +1,331 @@
|
||||
-- ============================================================================
|
||||
-- Personal overrides, ported from the niri config.
|
||||
-- Append to ~/.config/hypr/hyprland.lua, after require("default.hypr.omarchy").
|
||||
-- Every rebind of an Omarchy default is unbound first. The comment after each
|
||||
-- unbind says what the key did before.
|
||||
-- ============================================================================
|
||||
|
||||
-- ─── Window management ──────────────────────────────────────────────────────
|
||||
|
||||
-- Spawn Terminal
|
||||
-- hl.unbind("SUPER + RETURN") -- was: toggle window transparency
|
||||
|
||||
-- Mod+Q -> close. Omarchy already binds this, so it is only made explicit.
|
||||
hl.unbind("SUPER + Q")
|
||||
o.bind("SUPER + Q", "Close window", hl.dsp.window.close())
|
||||
|
||||
-- Mod+W was tabbed display. Here it flips the workspace layout, and sets every
|
||||
-- column to 50% of the screen (niri's default-column-width) when the
|
||||
-- workspace turns to scrolling. Dwindle needs no widths, because it re-tiles
|
||||
-- on its own. Needs ~/.local/bin/omarchy-toggle-layout.
|
||||
hl.unbind("SUPER + W") -- was: close window
|
||||
o.bind("SUPER + W", "Toggle workspace layout", "omarchy-toggle-layout 0.5")
|
||||
|
||||
-- Mod+BackSpace -> last window.
|
||||
hl.unbind("SUPER + BACKSPACE") -- was: toggle window transparency
|
||||
o.bind("SUPER + BACKSPACE", "Focus last window", hl.dsp.focus({ last = true }))
|
||||
|
||||
-- Mod+Tab -> switch windows inside the focused workspace. Omarchy parks the
|
||||
-- workspace hop here, but SUPER + CTRL + J/K already does that, so the key is
|
||||
-- free. SUPER + CTRL + TAB (former workspace) keeps its default job.
|
||||
--
|
||||
-- cyclenext is deliberately not used: it walks into a hidden special
|
||||
-- workspace and drags the scratchpad into view. This ring is built from the
|
||||
-- windows of the active workspace alone, and a workspace lives on exactly one
|
||||
-- monitor, so focus never leaves the display. Grouped windows stay in the
|
||||
-- ring (focusing a hidden member just flips the group to that tab); anything
|
||||
-- else hidden is skipped. stable_id fixes the order, so repeated presses walk
|
||||
-- the same ring instead of following focus history.
|
||||
local function cycle_in_workspace(step)
|
||||
return function()
|
||||
local active = hl.get_active_window()
|
||||
local workspace = active and active.workspace or hl.get_active_workspace()
|
||||
if not workspace then
|
||||
return
|
||||
end
|
||||
|
||||
local ring = {}
|
||||
for _, window in ipairs(hl.get_workspace_windows(workspace.id)) do
|
||||
if window.mapped and (window.group or not window.hidden) then
|
||||
ring[#ring + 1] = window
|
||||
end
|
||||
end
|
||||
if #ring < 2 then
|
||||
return
|
||||
end
|
||||
table.sort(ring, function(a, b)
|
||||
return a.stable_id < b.stable_id
|
||||
end)
|
||||
|
||||
local current = 1
|
||||
for index, window in ipairs(ring) do
|
||||
if active and window.address == active.address then
|
||||
current = index
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Raise after the focus, so a floating window comes up on top instead of
|
||||
-- staying buried, the way Omarchy's ALT + TAB does.
|
||||
hl.dispatch(hl.dsp.focus({ window = ring[(current - 1 + step) % #ring + 1] }))
|
||||
hl.dispatch(hl.dsp.window.bring_to_top())
|
||||
end
|
||||
end
|
||||
|
||||
hl.unbind("SUPER + TAB") -- was: next workspace
|
||||
hl.unbind("SUPER + SHIFT + TAB") -- was: previous workspace
|
||||
o.bind("SUPER + TAB", "Focus on next window in workspace", cycle_in_workspace(1))
|
||||
o.bind("SUPER + SHIFT + TAB", "Focus on previous window in workspace", cycle_in_workspace(-1))
|
||||
|
||||
-- Tabs. Hyprland groups are the nearest thing to a niri tabbed column.
|
||||
-- SUPER + G (group) and SUPER + ALT + TAB (next in group) are Omarchy defaults.
|
||||
|
||||
-- ─── Focus and swap: hjkl ───────────────────────────────────────────────────
|
||||
|
||||
-- Focus steps through the windows of a group first, and leaves the group only
|
||||
-- at the ends. This is the focus half of the smart-move behavior below, and
|
||||
-- Hyprland does it on its own, so no script is needed.
|
||||
hl.config({ binds = { movefocus_cycles_groupfirst = true } })
|
||||
|
||||
hl.unbind("SUPER + J") -- was: toggle window split
|
||||
hl.unbind("SUPER + K") -- was: keybindings menu
|
||||
hl.unbind("SUPER + L") -- was: toggle workspace layout
|
||||
|
||||
o.bind("SUPER + H", "Focus on left window", hl.dsp.focus({ direction = "l" }))
|
||||
o.bind("SUPER + J", "Focus on below window", hl.dsp.focus({ direction = "d" }))
|
||||
o.bind("SUPER + K", "Focus on above window", hl.dsp.focus({ direction = "u" }))
|
||||
o.bind("SUPER + L", "Focus on right window", hl.dsp.focus({ direction = "r" }))
|
||||
|
||||
-- The old SUPER + J job, moved to a free key. Dwindle only; toggling needs
|
||||
-- dwindle.preserve_split, which Omarchy already sets.
|
||||
o.bind("SUPER + D", "Toggle window split", hl.dsp.layout("togglesplit"))
|
||||
|
||||
-- Smart move: merge into the neighboring group if there is one, else swap.
|
||||
-- A floating window is parked in a monitor corner instead, clockwise from
|
||||
-- the bottom left: H bottom-left, J top-left, K top-right, L bottom-right.
|
||||
-- Needs ~/.local/bin/omarchy-smart-move.
|
||||
o.bind("SUPER + SHIFT + H", "Move or merge left / float to bottom-left", "omarchy-smart-move l")
|
||||
o.bind("SUPER + SHIFT + J", "Move or merge down / float to top-left", "omarchy-smart-move d")
|
||||
o.bind("SUPER + SHIFT + K", "Move or merge up / float to top-right", "omarchy-smart-move u")
|
||||
o.bind("SUPER + SHIFT + L", "Move or merge right / float to bottom-right", "omarchy-smart-move r")
|
||||
|
||||
-- Picture-in-picture for any window: float + pin, 30% of the focused
|
||||
-- monitor on both axes, bottom-left corner; press again to tile it back.
|
||||
-- Needs ~/.local/bin/omarchy-pip (omarchy-summon shares it). SUPER + SHIFT
|
||||
-- + T is free in Omarchy; SUPER + T (toggle floating) stays as is.
|
||||
o.bind("SUPER + SHIFT + T", "Toggle picture-in-picture", "omarchy-pip")
|
||||
|
||||
-- ─── Workspaces and monitors ────────────────────────────────────────────────
|
||||
|
||||
hl.unbind("SUPER + CTRL + K") -- was: Herdr keybindings
|
||||
o.bind("SUPER + CTRL + J", "Next workspace", hl.dsp.focus({ workspace = "e+1" }))
|
||||
o.bind("SUPER + CTRL + K", "Previous workspace", hl.dsp.focus({ workspace = "e-1" }))
|
||||
|
||||
-- Scratch workspaces. Omarchy's SUPER + S is taken by the region screenshot
|
||||
-- below, so the main toggle (Tern) lands on SUPER + CTRL + S, with
|
||||
-- SUPER + A (free in Omarchy) as the home-row alias. Claude Desktop has its
|
||||
-- own scratch workspace on SUPER + CTRL + ALT + L. SUPER + ALT + S (send
|
||||
-- window to the scratchpad) is still the Omarchy default and needs no line.
|
||||
--
|
||||
-- All of them go through ~/.local/bin/omarchy-toggle-scratch rather than the
|
||||
-- raw special-workspace toggle: it opens each workspace on its home monitor
|
||||
-- (the raw toggle uses the focused one), and on reveal it starts whichever
|
||||
-- resident is missing instead of sliding an empty workspace into view. The
|
||||
-- residents are pinned to their workspaces by window rules in
|
||||
-- hypr/hyprland.lua. Fastmail and Beeper have their own scratch workspaces
|
||||
-- under SUPER + CTRL + ALT + E / M in the Applications block below.
|
||||
hl.unbind("SUPER + CTRL + S") -- was: share menu
|
||||
hl.unbind("SUPER + SHIFT + A") -- was: ChatGPT web app
|
||||
|
||||
o.bind("SUPER + A", "Toggle scratch workspace", "omarchy-toggle-scratch scratchpad")
|
||||
o.bind("SUPER + CTRL + ALT + H", "Toggle Tern scratch workspace", "omarchy-toggle-scratch scratchpad")
|
||||
o.bind("SUPER + CTRL + ALT + L", "Toggle Claude scratch workspace", "omarchy-toggle-scratch claude")
|
||||
|
||||
-- Workspaces 1 to 4 (Studio Display) on Q W E R and 5 to 8 (laptop panel) on
|
||||
-- Y U I O: ALT to focus, ALT + SHIFT to send the window there. The pinning
|
||||
-- lives in hypr/hyprland.lua, so focusing a workspace also moves to its
|
||||
-- monitor. No Omarchy default uses ALT with a letter, so nothing is unbound.
|
||||
for index, key in ipairs({ "Q", "W", "E", "R", "Y", "U", "I", "O" }) do
|
||||
local workspace = tostring(index)
|
||||
|
||||
o.bind("ALT + " .. key, "Switch to workspace " .. workspace, hl.dsp.focus({ workspace = workspace }))
|
||||
o.bind("ALT + SHIFT + " .. key, "Move window to workspace " .. workspace, hl.dsp.window.move({ workspace = workspace }))
|
||||
end
|
||||
|
||||
hl.unbind("SUPER + O") -- was: pop window out
|
||||
hl.unbind("SUPER + SHIFT + O") -- was: Obsidian (moved to SUPER + CTRL + ALT + O)
|
||||
o.bind("SUPER + O", "Focus next monitor", hl.dsp.focus({ monitor = "+1" }))
|
||||
o.bind("SUPER + SHIFT + O", "Move window to next monitor", hl.dsp.window.move({ monitor = "+1" }))
|
||||
|
||||
o.bind("ALT + SHIFT + J", "Move window to next monitor", hl.dsp.window.move({ monitor = "+1" }))
|
||||
o.bind("ALT + SHIFT + K", "Move window to previous monitor", hl.dsp.window.move({ monitor = "-1" }))
|
||||
|
||||
-- Named workspaces, in place of niri-dynamic-workspaces.
|
||||
o.bind("SUPER + SHIFT + CTRL + ALT + W", "Workspace w", hl.dsp.focus({ workspace = "name:w" }))
|
||||
o.bind("SUPER + SHIFT + CTRL + ALT + H", "Workspace h", hl.dsp.focus({ workspace = "name:h" }))
|
||||
o.bind("SUPER + CTRL + ALT + X", "Workspace x", hl.dsp.focus({ workspace = "name:x" }))
|
||||
|
||||
-- ─── Sizing ─────────────────────────────────────────────────────────────────
|
||||
|
||||
-- Mod+R / Mod+Shift+R. Needs ~/.local/bin/omarchy-cycle-window-size.
|
||||
o.bind("SUPER + R", "Cycle window size", "omarchy-cycle-window-size")
|
||||
o.bind("SUPER + SHIFT + R", "Cycle window size back", "omarchy-cycle-window-size prev")
|
||||
|
||||
-- Hyprland resizes by pixels, not by percent, so 100 px replaces the niri
|
||||
-- 10%. ALT + SHIFT + H / L step the width (ALT + SHIFT + J / K move the
|
||||
-- window between monitors, above).
|
||||
o.bind("ALT + SHIFT + H", "Shrink window width", hl.dsp.window.resize({ x = -100, y = 0, relative = true }))
|
||||
o.bind("ALT + SHIFT + L", "Grow window width", hl.dsp.window.resize({ x = 100, y = 0, relative = true }))
|
||||
|
||||
hl.unbind("SUPER + CTRL + H") -- was: toggle window gaps (now Google Home; SUPER + comma shrinks width)
|
||||
hl.unbind("SUPER + CTRL + L") -- was: toggle window gaps (now LM Studio; SUPER + period grows width)
|
||||
hl.unbind("SUPER + CTRL + K") -- was: toggle window gaps
|
||||
hl.unbind("SUPER + CTRL + J") -- was: toggle window gaps
|
||||
|
||||
o.bind("SUPER + CTRL + K", "Shrink window height", hl.dsp.window.resize({ x = 0, y = -100, relative = true }))
|
||||
o.bind("SUPER + CTRL + J", "Grow window height", hl.dsp.window.resize({ x = 0, y = 100, relative = true }))
|
||||
|
||||
-- Same width steps on SUPER + , / SUPER + . (the < and > keys). Key names are
|
||||
-- the lower-case xkb keysyms; "COMMA"/"PERIOD" would not match.
|
||||
hl.unbind("SUPER + comma") -- was: dismiss last notification (now SUPER + SHIFT + BACKSPACE)
|
||||
o.bind("SUPER + comma", "Shrink window width", hl.dsp.window.resize({ x = -100, y = 0, relative = true }))
|
||||
o.bind("SUPER + period", "Grow window width", hl.dsp.window.resize({ x = 100, y = 0, relative = true }))
|
||||
|
||||
-- The notification dismiss SUPER + comma gave up. SUPER + SHIFT + comma still
|
||||
-- dismisses all.
|
||||
hl.unbind("SUPER + SHIFT + BACKSPACE") -- was: toggle window gaps
|
||||
o.bind("SUPER + SHIFT + BACKSPACE", "Dismiss last notification", "omarchy-shell notifications dismissOne")
|
||||
|
||||
-- Column fitting. These are scrolling layout messages, so they do nothing on
|
||||
-- a dwindle workspace. Mod+F (expand to available width) has no exact match;
|
||||
-- the Omarchy default SUPER + ALT + F (full width) is the closest.
|
||||
o.bind("SUPER + ALT + C", "Fit active column", hl.dsp.layout("fit active"))
|
||||
o.bind("SUPER + SHIFT + ALT + C", "Fit visible columns", hl.dsp.layout("fit visible"))
|
||||
|
||||
-- Super+C (niri center-column). Floating windows go through centerwindow.
|
||||
-- On a scrolling workspace the column is re-focused with focus_fit_method
|
||||
-- briefly set to 0 (center), then restored, so plain focus moves keep
|
||||
-- niri's center-focused-column "never". A relative "move" can't do this: the
|
||||
-- tape stops at its first column, so the leftmost window never reaches the
|
||||
-- middle. Dwindle and master have nothing to scroll; the key does nothing.
|
||||
local function center_window()
|
||||
local window = hl.get_active_window()
|
||||
if not window then
|
||||
return
|
||||
end
|
||||
if window.floating then
|
||||
hl.dispatch(hl.dsp.window.center())
|
||||
return
|
||||
end
|
||||
if not window.workspace or window.workspace.tiled_layout ~= "scrolling" then
|
||||
return
|
||||
end
|
||||
local fit_method = hl.get_config("scrolling.focus_fit_method")
|
||||
hl.config({ scrolling = { focus_fit_method = 0 } })
|
||||
hl.dispatch(hl.dsp.focus({ window = window }))
|
||||
hl.config({ scrolling = { focus_fit_method = fit_method } })
|
||||
end
|
||||
|
||||
hl.unbind("SUPER + C") -- was: universal copy
|
||||
o.bind("SUPER + C", "Center window / column", center_window)
|
||||
|
||||
-- ─── Applications ───────────────────────────────────────────────────────────
|
||||
-- Same modifier block as the niri config. Each one focuses an open window
|
||||
-- before it launches a new one. The launch command uses the same desktop
|
||||
-- entry the vicinae URLs named, so no binary names are guessed.
|
||||
|
||||
hl.unbind("SUPER + CTRL + A") -- was: audio panel
|
||||
|
||||
o.bind("SUPER + CTRL + ALT + J", "Terminals", "omarchy-cycle-terminal")
|
||||
o.bind("SUPER + CTRL + ALT + K", "Browsers", "omarchy-cycle-browser")
|
||||
o.bind("SUPER + CTRL + ALT + G", "Ghostty", "omarchy-cycle ghostty")
|
||||
o.bind("SUPER + CTRL + ALT + O", "Obsidian", "omarchy-cycle obsidian")
|
||||
o.bind("SUPER + CTRL + ALT + F", "File manager", "omarchy-launch-or-focus nautilus \"gtk-launch org.gnome.Nautilus\"")
|
||||
-- Fastmail, Beeper, Google Home and LM Studio each live on their own scratch
|
||||
-- workspace (window rules in hypr/hyprland.lua); the toggle reveals it on the
|
||||
-- focused monitor and starts the app only when no window of it exists -- the
|
||||
-- web-app launcher would otherwise open a second window every time.
|
||||
o.bind("SUPER + CTRL + ALT + E", "Fastmail", "omarchy-toggle-scratch fastmail")
|
||||
o.bind("SUPER + CTRL + ALT + M", "Beeper", "omarchy-toggle-scratch beeper")
|
||||
o.bind("SUPER + CTRL + H", "Google Home", "omarchy-toggle-scratch home")
|
||||
o.bind("SUPER + CTRL + L", "LM Studio", "omarchy-toggle-scratch lmstudio")
|
||||
-- YouTube is a floating pinned window in the bottom-left corner (window rule
|
||||
-- in hypr/hyprland.lua). The summon launches it when no window exists,
|
||||
-- otherwise carries the window to the focused monitor and focuses it.
|
||||
o.bind("SUPER + CTRL + ALT + Y", "YouTube", "omarchy-summon youtube") -- was: web apps cycle
|
||||
hl.unbind("SUPER + SHIFT + Y") -- was: YouTube via the desktop entry (new window every press)
|
||||
o.bind("SUPER + SHIFT + Y", "YouTube", "omarchy-summon youtube")
|
||||
|
||||
hl.unbind("SUPER + CTRL + ALT + T") -- was: show time
|
||||
-- Pattern is the exact class from `hyprctl clients`; the window rule in
|
||||
-- hypr/hyprland.lua sends it to workspace 5 on eDP-1 fullscreen.
|
||||
o.bind("SUPER + CTRL + ALT + T", "tldraw offline", "omarchy-launch-or-focus tldraw-offline \"gtk-launch tldraw-offline\"")
|
||||
|
||||
hl.unbind("SUPER + CTRL + ALT + W") -- was: toggle weather
|
||||
-- gtk-launch takes the desktop-entry id: TLDraw.desktop, not tldraw_offline,
|
||||
-- which does not exist (the old command could only focus, never launch).
|
||||
|
||||
hl.unbind("SUPER + SHIFT + M") -- was: Spotify
|
||||
hl.unbind("SUPER + SHIFT + G") -- was: Signal
|
||||
-- The ssh/mosh command and tmux keymaps live in ~/.config/kitty/goliath.conf
|
||||
-- (kitty cannot take --config from a `launch` action, hence a separate kitty
|
||||
-- process, same trick as SUPER + T / SUPER + A). kitty-goliath is the app-id
|
||||
-- looknfeel.lua's terminal blur rule expects.
|
||||
o.bind("SUPER + SHIFT + G", "Goliath", { launch = "kitty --class=kitty-goliath --title=goliath --config ~/.config/kitty/goliath.conf" })
|
||||
|
||||
-- ─── Screenshots ────────────────────────────────────────────────────────────
|
||||
|
||||
hl.unbind("SUPER + S") -- was: toggle scratchpad (now SUPER + CTRL + S)
|
||||
hl.unbind("SUPER + SHIFT + S") -- was: Google Maps
|
||||
o.bind("SUPER + S", "Screenshot region", "omarchy-capture-screenshot region")
|
||||
o.bind("SUPER + SHIFT + S", "Screenshot window", "omarchy-capture-screenshot windows")
|
||||
-- Monitor capture moved off SUPER + CTRL + S when the scratchpad took that key.
|
||||
o.bind("SUPER + SHIFT + ALT + S", "Screenshot monitor", "omarchy-capture-screenshot fullscreen")
|
||||
|
||||
-- ─── Session ────────────────────────────────────────────────────────────────
|
||||
|
||||
hl.unbind("SUPER + SHIFT + E") -- was: Email (Fastmail is on SUPER + CTRL + ALT + E)
|
||||
o.bind("SUPER + SHIFT + E", "System menu", "omarchy-menu toggle system")
|
||||
o.bind("SUPER + SHIFT + Q", "System menu", "omarchy-menu toggle system")
|
||||
|
||||
-- ─── Dictation ──────────────────────────────────────────────────────────────
|
||||
|
||||
o.bind("SUPER + F24", "Dictate to Hermes", "voxtype record toggle --profile hermes")
|
||||
|
||||
-- ─── Menus, in place of vicinae ─────────────────────────────────────────────
|
||||
-- Same keys as the niri config, pointed at the Omarchy menus.
|
||||
|
||||
-- Mod+Space (vicinae toggle) needs no line: SUPER + SPACE is already the
|
||||
-- Omarchy menu. SUPER + ALT + SPACE is the apps menu.
|
||||
|
||||
hl.unbind("SUPER + SHIFT + SPACE") -- was: toggle top bar
|
||||
hl.unbind("SUPER + P") -- was: pseudo window
|
||||
hl.unbind("SUPER + SPACE") -- was: pseudo window
|
||||
|
||||
-- Omarchy's SUPER + SPACE is ALT + SPACE, so the key is free in Omarchy.
|
||||
-- o.bind("ALT + SPACE", "Toggle Launcher", "omarchy-menu toggle launcher")
|
||||
|
||||
-- Mod+Shift+Return was the vicinae window switcher. ScrollOverview on
|
||||
-- ALT + TAB below takes that job, so SUPER + SHIFT + RETURN keeps its default
|
||||
-- job of opening the browser.
|
||||
--
|
||||
-- flea --default: begin. Written by `flea --default`; `flea --default off` removes the block whole.
|
||||
hl.unbind("SUPER + SHIFT + F")
|
||||
o.bind("SUPER + SHIFT + F", "File manager", { launch = 'flea --gui' })
|
||||
hl.unbind("SUPER + ALT + SHIFT + F")
|
||||
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { launch = 'flea --gui "$(omarchy-cmd-terminal-cwd)"' })
|
||||
-- flea --default: end.
|
||||
|
||||
-- flea --picker: begin. Written by `flea --picker`; `flea --picker off` removes the block whole.
|
||||
o.window("com.thisisgm.flea.picker", { tag = "+floating-window" })
|
||||
-- flea --picker: end.
|
||||
|
||||
-- niri-style: SUPER + F maximizes (Omarchy's SUPER + ALT + F "Full width"),
|
||||
-- SUPER + SHIFT + F goes true fullscreen. Kept below the flea blocks so it
|
||||
-- wins over the file-manager bind `flea --default` writes onto
|
||||
-- SUPER + SHIFT + F; flea stays on SUPER + ALT + SHIFT + F, Nautilus on
|
||||
-- SUPER + CTRL + ALT + F.
|
||||
hl.unbind("SUPER + F") -- was: full screen
|
||||
o.bind("SUPER + F", "Maximize", hl.dsp.window.fullscreen({ mode = "maximized" }))
|
||||
hl.unbind("SUPER + SHIFT + F") -- was: file manager (flea --gui)
|
||||
o.bind("SUPER + SHIFT + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"workspace": {
|
||||
"library": [
|
||||
"/usr/share/hypr/stubs"
|
||||
],
|
||||
"checkThirdParty": false
|
||||
},
|
||||
"diagnostics": {
|
||||
"globals": ["hl", "o"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
-- 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")
|
||||
|
||||
-- Add any other personal Hyprland configuration below.
|
||||
-- o.window("qemu", { workspace = "5" })
|
||||
|
||||
-- Pin workspaces to monitors: 1-4 on the Studio Display, 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).
|
||||
-- Matched on EDID description for the external display so it survives
|
||||
-- landing on a different DP connector after re-docking.
|
||||
for id = 1, 8 do
|
||||
hl.workspace_rule({
|
||||
workspace = tostring(id),
|
||||
monitor = id <= 4 and "desc:Apple Computer Inc StudioDisplay 0x984262A7" or "eDP-1",
|
||||
default = id == 1 or id == 5,
|
||||
persistent = true,
|
||||
})
|
||||
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, Studio 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 the
|
||||
-- focused monitor.
|
||||
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)" },
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
# Makes hyprsunset do nothing to the screen by default
|
||||
# Without this, the default applies some tint to the monitor
|
||||
profile {
|
||||
time = 07:00
|
||||
identity = true
|
||||
}
|
||||
|
||||
# To enable auto switch to nightlight, add to your .config/hypr/autostart.lua:
|
||||
# o.launch_on_start("hyprsunset")
|
||||
# and use the following:
|
||||
# profile {
|
||||
# time = 20:00
|
||||
# temperature = 4000
|
||||
# }
|
||||
@@ -0,0 +1,132 @@
|
||||
-- Keep only your personal input overrides here. Uncommented settings below
|
||||
-- replace Omarchy's defaults.
|
||||
|
||||
-- Key repeat: Omarchy's 250ms delay kept, rate raised 40 -> 50Hz. 200 / 50 was
|
||||
-- tried and felt too fast; the "typing lag" it was meant to fix turned out to be the
|
||||
-- Pilot W-Corne's firmware (55d4:0461, Vial/QMK over a 2.4GHz dongle)
|
||||
-- resolving its MT(LGUI,SPC) / MT(LCTL,SPC) thumb keys as holds the moment
|
||||
-- another key went down. Fixed on the board itself: Vial QMK Settings ->
|
||||
-- Tap-Hold -> "Ignore Mod Tap Interrupt" (qsid 8 bit 1), tapping term 150ms.
|
||||
--
|
||||
-- The rest of the keystroke path was checked and is already optimal: the
|
||||
-- dongle advertises bInterval=1 (1000Hz polling), udev pins power/control=on
|
||||
-- (no USB autosuspend), nothing polls its raw-HID interface, WiFi sits on
|
||||
-- 5GHz, and render:new_render_scheduling is off (no triple-buffer frame).
|
||||
-- Remaining latency is the 60Hz Studio Display refresh and the fcitx5
|
||||
-- input-method hop (see omarchy-fcitx5.service), neither an input option.
|
||||
hl.config({
|
||||
input = {
|
||||
repeat_delay = 250,
|
||||
repeat_rate = 50,
|
||||
|
||||
-- niri has no focus-follows-mouse: hovering gives a window pointer focus
|
||||
-- (scroll goes there) but keyboard focus moves only on click. Also keeps
|
||||
-- the scrolling tape from jumping when the cursor brushes a neighbour.
|
||||
follow_mouse = 2,
|
||||
|
||||
-- niri: touchpad { natural-scroll; tap; }. Tap-to-click is libinput's
|
||||
-- default already.
|
||||
touchpad = {
|
||||
natural_scroll = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- niri's built-in touchpad gestures: three fingers sideways scroll the tape,
|
||||
-- up/down switch workspace.
|
||||
hl.gesture({ fingers = 3, direction = "horizontal", action = "scroll_move" })
|
||||
hl.gesture({ fingers = 3, direction = "vertical", action = "workspace" })
|
||||
|
||||
-- Keyboard layout and options.
|
||||
-- See https://wiki.hypr.land/Configuring/Basics/Variables/#input
|
||||
-- hl.config({
|
||||
-- input = {
|
||||
-- -- Use multiple keyboard layouts and switch between them with Left Alt + Right Alt.
|
||||
-- kb_layout = "us,dk,eu",
|
||||
-- kb_options = "compose:caps,shift:both_capslock_cancel,grp:alts_toggle",
|
||||
--
|
||||
-- -- Use a specific keyboard variant if needed (e.g. intl for international keyboards).
|
||||
-- kb_variant = "intl",
|
||||
--
|
||||
-- -- Change speed of keyboard repeat.
|
||||
-- repeat_rate = 40,
|
||||
-- repeat_delay = 250,
|
||||
--
|
||||
-- -- Start with numlock on by default.
|
||||
-- numlock_by_default = true,
|
||||
--
|
||||
-- -- Increase sensitivity for mouse/trackpad (default: 0).
|
||||
-- sensitivity = 0.35,
|
||||
--
|
||||
-- -- Turn off mouse acceleration (default: adaptive).
|
||||
-- accel_profile = "flat",
|
||||
--
|
||||
-- touchpad = {
|
||||
-- -- Use natural (inverse) scrolling.
|
||||
-- natural_scroll = true,
|
||||
--
|
||||
-- -- Use two-finger clicks for right-click instead of lower-right corner.
|
||||
-- clickfinger_behavior = true,
|
||||
--
|
||||
-- -- Control the speed of your scrolling.
|
||||
-- scroll_factor = 0.4,
|
||||
--
|
||||
-- -- Enable the touchpad while typing.
|
||||
-- disable_while_typing = false,
|
||||
--
|
||||
-- -- Left-click-and-drag with three fingers.
|
||||
-- drag_3fg = 1,
|
||||
-- },
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- App-specific touchpad scroll speeds.
|
||||
-- o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
|
||||
-- o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
|
||||
|
||||
-- Touchpad gestures live in the override block at the top of this file.
|
||||
|
||||
-- Tablets / pens.
|
||||
-- Hyprland maps a tablet across the *whole* monitor layout by default
|
||||
-- (input.tablet.output is empty), so a pen stretches over eDP-1 + the external
|
||||
-- display at once. Pin each tablet to a single output instead.
|
||||
-- Device names come from `hyprctl devices` (the "Tablet" entry, not "Tablet Pad").
|
||||
|
||||
-- Built-in digitizer of the Flow Z13: it physically *is* the laptop panel.
|
||||
-- Pen and finger are separate devices; the finger one is the "Touch" entry.
|
||||
hl.device({ name = "elan9008:00-04f3:43c7-stylus", output = "eDP-1" })
|
||||
-- Unbound, Hyprland maps a touch onto whichever monitor is *focused*
|
||||
-- (onTouchDown falls back to the focused monitor when the device has no
|
||||
-- output), so a tap on the panel landed on the Studio Display. Bound, the tap
|
||||
-- focuses eDP-1 and then the window under the finger.
|
||||
hl.device({ name = "elan9008:00-04f3:43c7", output = "eDP-1" })
|
||||
--
|
||||
-- Palm rejection while writing is libinput's job, not Hyprland's: with the
|
||||
-- pen in proximity it drops touches on the paired touchscreen (same
|
||||
-- LIBINPUT_DEVICE_GROUP) -- *all* of them only if the pen reports no tilt;
|
||||
-- with tilt it drops just a 200x250mm rectangle whose side is guessed from
|
||||
-- the tilt sign, and this pen reports ABS_TILT_X/Y, so a resting palm kept
|
||||
-- landing as taps and scrolls. /etc/libinput/local-overrides.quirks (not
|
||||
-- chezmoi-managed; the Flow Z13 stylus section) strips the tilt axes, which
|
||||
-- flips arbitration to ignore-all. Cost: no tilt in drawing apps. The 90ms
|
||||
-- re-enable after the pen leaves proximity is hard-coded in libinput.
|
||||
|
||||
-- Wacom Intuos BT S: pinned to the Studio Display, matched on EDID description
|
||||
-- so it survives a different DP connector after re-docking. With that display
|
||||
-- absent, Hyprland maps across the whole layout, which undocked is just eDP-1.
|
||||
--
|
||||
-- The tablet is 152x95mm (16:10) and the display is 16:9, so the active area is
|
||||
-- cropped to a 152x85.5mm (16:9) band to keep strokes undistorted while still
|
||||
-- reaching every pixel. The band starts at the top edge, leaving the bottom
|
||||
-- 9.5mm of the tablet as dead space (the pen there parks at the screen bottom).
|
||||
hl.device({
|
||||
name = "wacom-intuos-bt-s-pen",
|
||||
output = "desc:Apple Computer Inc StudioDisplay 0x984262A7",
|
||||
active_area_size = { 152, 85.5 },
|
||||
active_area_position = { 0, 0 },
|
||||
})
|
||||
|
||||
-- Left-handed use rotates the tablet 180 degrees: left_handed = true
|
||||
|
||||
-- The 4 ExpressKeys ("Tablet Pad") cannot be bound from Hyprland; only apps
|
||||
-- that implement the tablet-v2 pad protocol (e.g. Krita) see them.
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
-- Change the default Omarchy look'n'feel.
|
||||
--
|
||||
-- Load order is Omarchy defaults -> current theme's hyprland.lua -> this file
|
||||
-- (see $OMARCHY_PATH/default/hypr/omarchy.lua), so whatever is set here is the
|
||||
-- last writer and wins over the theme. That is the point of this file: a theme
|
||||
-- picks colours, the compositor's feel stays ours.
|
||||
|
||||
-- Flat by default, glass for terminals only.
|
||||
--
|
||||
-- Stock quattro is rounding 0, blur off, shadow off
|
||||
-- ($OMARCHY_PATH/default/hypr/looknfeel.lua); themes that ship a hyprland.lua
|
||||
-- turn all three on for every window (Cyberdream and Spectra both did), which
|
||||
-- on this box is a bad trade: blur over an eDP panel plus a 5K Studio Display
|
||||
-- is real frame time on an iGPU sharing system memory, and Chromium/Electron
|
||||
-- windows cannot paint a transparent background, so fading them just shows
|
||||
-- wallpaper where page background should be.
|
||||
--
|
||||
-- Blur has to be enabled globally to exist at all -- there is no positive
|
||||
-- `blur` window rule, only `no_blur`, and kitty's own `background_blur` (the
|
||||
-- ext-background-effect-v1 protocol, which Hyprland 0.56 does implement) is a
|
||||
-- no-op while decoration:blur:enabled is false. So: switch it on here, then
|
||||
-- opt every window out again except the terminals below.
|
||||
hl.config({
|
||||
general = {
|
||||
-- Scrolling (niri-style tape) instead of Omarchy's dwindle. Per-workspace
|
||||
-- layouts saved by omarchy-hyprland-workspace-layout-toggle (SUPER + W;
|
||||
-- ~/.local/state/omarchy/workspace-layouts/*.lua) still win for the
|
||||
-- workspaces they name.
|
||||
layout = "scrolling",
|
||||
},
|
||||
|
||||
decoration = {
|
||||
rounding = 0,
|
||||
|
||||
-- Backdrop behind every scratch (special) workspace: the desktop under it
|
||||
-- is darkened by this fraction.
|
||||
dim_special = 0.33,
|
||||
|
||||
blur = {
|
||||
enabled = true,
|
||||
-- Cheaper than the themes' size 6 / 3 passes; with only terminals
|
||||
-- blurred this is a handful of quads per frame, not the whole screen.
|
||||
size = 5,
|
||||
passes = 2,
|
||||
brightness = 0.8,
|
||||
contrast = 1.1,
|
||||
vibrancy = 0.15,
|
||||
noise = 0.01,
|
||||
new_optimizations = true,
|
||||
popups = false,
|
||||
},
|
||||
|
||||
shadow = {
|
||||
enabled = false,
|
||||
},
|
||||
},
|
||||
|
||||
group = {
|
||||
groupbar = {
|
||||
-- Square tab plates, to match rounding = 0 above.
|
||||
gradient_rounding = 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Omarchy tags every mapped window `default-opacity` and fades it to
|
||||
-- 0.985 / 0.96 ($OMARCHY_PATH/default/hypr/windows.lua); that stock fade is
|
||||
-- kept. Rules are last-match-wins, so this only opts every window out of the
|
||||
-- blur enabled above -- the few percent of wallpaper that shows through an
|
||||
-- inactive window is the same as stock, where blur is off entirely.
|
||||
o.window({ tag = "default-opacity" }, { no_blur = true })
|
||||
|
||||
-- The exception: terminals carry their own alpha (kitty's
|
||||
-- `background_opacity`, 0.9 in ~/.config/kitty/kitty.conf), so they are the one
|
||||
-- surface where blurring the backdrop buys anything. Full class list because
|
||||
-- the kitty hosts run under their own app-ids (kitty-herdr, kitty-tmux,
|
||||
-- kitty-goliath) and Omarchy tags nothing as `terminal`.
|
||||
o.window(
|
||||
"^(kitty(-.*)?|Alacritty|com\\.mitchellh\\.ghostty|foot|org\\.codeberg\\.dnkl\\.foot|wezterm)$",
|
||||
{ no_blur = false }
|
||||
)
|
||||
|
||||
-- Themes are also free to re-enable the workspace slide (Spectra sets
|
||||
-- `workspaces` with its "flow" bezier); Omarchy's default is off. Restate it.
|
||||
-- workspacesIn/workspacesOut are not overridden anywhere, so they inherit this.
|
||||
hl.animation({ leaf = "workspaces", enabled = false })
|
||||
|
||||
-- Slow, constant rotation of the active-border gradient (the theme's
|
||||
-- hyprland_active_border; Cyberdream's is accent -> cyan). `loop` restarts
|
||||
-- the angle each turn so it never eases or stops; speed is deciseconds per
|
||||
-- revolution, so 100 = one lap every 10 s. Costs a redraw of the border each
|
||||
-- frame while a window is mapped.
|
||||
hl.animation({ leaf = "borderangle", enabled = true, speed = 100, bezier = "linear", style = "loop" })
|
||||
|
||||
-- https://wiki.hypr.land/Configuring/Basics/Variables/#general
|
||||
-- hl.config({
|
||||
-- general = {
|
||||
-- -- No gaps between windows or borders.
|
||||
-- gaps_in = 0,
|
||||
-- gaps_out = 0,
|
||||
-- border_size = 0,
|
||||
--
|
||||
-- -- Change to niri-like side-scrolling layout.
|
||||
-- layout = "scrolling",
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- https://wiki.hypr.land/Configuring/Basics/Variables/#animations
|
||||
-- hl.config({
|
||||
-- animations = {
|
||||
-- -- Disable all animations.
|
||||
-- enabled = false,
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- https://wiki.hypr.land/Configuring/Basics/Variables/#layout
|
||||
-- hl.config({
|
||||
-- layout = {
|
||||
-- -- Avoid overly wide single-window layouts on wide screens.
|
||||
-- single_window_aspect_ratio = { 1, 1 },
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- Scrolling layout, matched to niri's layout block
|
||||
-- (~/.config/niri/config.d/20-layout-and-overview.kdl). Wins over Omarchy's
|
||||
-- column_width = 0.49.
|
||||
hl.config({
|
||||
scrolling = {
|
||||
-- default-column-width { proportion 0.5; }
|
||||
column_width = 0.5,
|
||||
-- preset-column-widths; SUPER + R / SUPER + SHIFT + R cycle these
|
||||
-- (colresize +conf / -conf via omarchy-cycle-window-size).
|
||||
explicit_column_widths = "0.333, 0.5, 0.667",
|
||||
-- center-focused-column "never": scroll only as far as needed to fit the
|
||||
-- focused column. SUPER + C centers on demand.
|
||||
focus_fit_method = 1,
|
||||
-- niri keeps a lone column at its own width instead of filling the screen.
|
||||
fullscreen_on_one_column = false,
|
||||
-- niri stops at the first/last column instead of wrapping around.
|
||||
wrap_focus = false,
|
||||
wrap_swapcol = false,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
|
||||
-- List current monitors and supported resolutions with: hyprctl monitors all
|
||||
|
||||
local omarchy_gdk_scale = 3
|
||||
local omarchy_monitor_scale = 3.2
|
||||
|
||||
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
|
||||
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
|
||||
|
||||
-- Laptop panel (eDP-1) on the left, Apple Studio Display on the right.
|
||||
-- Logical widths at scale 2: 2560/2 = 1280, so DP-4 starts at x=1280.
|
||||
hl.monitor({ output = "eDP-1", mode = "2560x1600@180", position = "0x0", scale = 2 })
|
||||
hl.monitor({ output = "DP-4", mode = "5120x2880@60", position = "1280x0", scale = 2 })
|
||||
|
||||
-- Configure a specific monitor.
|
||||
-- hl.monitor({ output = "DP-2", mode = "2560x1440@144", position = "0x0", scale = 1 })
|
||||
|
||||
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°).
|
||||
-- hl.monitor({ output = "DP-2", mode = "preferred", position = "auto", scale = 1, transform = 1 })
|
||||
Reference in new issue
Block a user