feat(monitors): main external display, Samsung ultrawide support
monitors.lua picks the main external (Studio Display, else the Samsung S34CG50 ultrawide, matched on EDID) and reloads the config when it changes. Workspaces 1-4, the Wacom mapping, and its active-area aspect follow it. eDP-1 uses auto-right so it sits beside whichever external is connected. Also unbinds SUPER+RETURN / SUPER+SHIFT+RETURN (terminal and browser live on SUPER+CTRL+ALT+J/K) and pins the Fastmail/Beeper scratch workspaces' comments to eDP-1.
This commit is contained in:
1 parent
de202fb5f8
commit
95c8d15814
4 files changed
+85
-27
No files matched your search
+10
-8
@@ -7,8 +7,9 @@
|
|||||||
|
|
||||||
-- ─── Window management ──────────────────────────────────────────────────────
|
-- ─── Window management ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
-- Spawn Terminal
|
-- Terminal and browser live on SUPER + CTRL + ALT + J / K (Applications, below).
|
||||||
-- hl.unbind("SUPER + RETURN") -- was: toggle window transparency
|
hl.unbind("SUPER + RETURN") -- was: launch terminal
|
||||||
|
hl.unbind("SUPER + SHIFT + RETURN") -- was: launch browser
|
||||||
|
|
||||||
-- Mod+Q -> close. Omarchy already binds this, so it is only made explicit.
|
-- Mod+Q -> close. Omarchy already binds this, so it is only made explicit.
|
||||||
hl.unbind("SUPER + Q")
|
hl.unbind("SUPER + Q")
|
||||||
@@ -141,7 +142,7 @@ o.bind("SUPER + A", "Toggle scratch workspace", "omarchy-toggle-scratch scratchp
|
|||||||
o.bind("SUPER + CTRL + ALT + H", "Toggle Tern 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")
|
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
|
-- Workspaces 1 to 4 (main external 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
|
-- 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
|
-- 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.
|
-- monitor. No Omarchy default uses ALT with a letter, so nothing is unbound.
|
||||||
@@ -242,9 +243,10 @@ 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 + O", "Obsidian", "omarchy-cycle obsidian")
|
||||||
o.bind("SUPER + CTRL + ALT + F", "File manager", "omarchy-launch-or-focus nautilus \"gtk-launch org.gnome.Nautilus\"")
|
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
|
-- 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
|
-- workspace (window rules in hypr/hyprland.lua); the toggle reveals it (on
|
||||||
-- focused monitor and starts the app only when no window of it exists -- the
|
-- eDP-1 for Fastmail and Beeper, else the focused monitor) and starts the app
|
||||||
-- web-app launcher would otherwise open a second window every time.
|
-- 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 + E", "Fastmail", "omarchy-toggle-scratch fastmail")
|
||||||
o.bind("SUPER + CTRL + ALT + M", "Beeper", "omarchy-toggle-scratch beeper")
|
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 + H", "Google Home", "omarchy-toggle-scratch home")
|
||||||
@@ -306,8 +308,8 @@ hl.unbind("SUPER + SPACE") -- was: pseudo window
|
|||||||
-- o.bind("ALT + SPACE", "Toggle Launcher", "omarchy-menu toggle launcher")
|
-- o.bind("ALT + SPACE", "Toggle Launcher", "omarchy-menu toggle launcher")
|
||||||
|
|
||||||
-- Mod+Shift+Return was the vicinae window switcher. ScrollOverview on
|
-- Mod+Shift+Return was the vicinae window switcher. ScrollOverview on
|
||||||
-- ALT + TAB below takes that job, so SUPER + SHIFT + RETURN keeps its default
|
-- ALT + TAB below takes that job; SUPER + SHIFT + RETURN is unbound
|
||||||
-- job of opening the browser.
|
-- (Window management, above).
|
||||||
--
|
--
|
||||||
-- flea --default: begin. Written by `flea --default`; `flea --default off` removes the block whole.
|
-- flea --default: begin. Written by `flea --default`; `flea --default off` removes the block whole.
|
||||||
hl.unbind("SUPER + SHIFT + F")
|
hl.unbind("SUPER + SHIFT + F")
|
||||||
|
|||||||
+16
-7
@@ -28,19 +28,28 @@ require("default.hypr.toggles")
|
|||||||
-- Add any other personal Hyprland configuration below.
|
-- Add any other personal Hyprland configuration below.
|
||||||
-- o.window("qemu", { workspace = "5" })
|
-- o.window("qemu", { workspace = "5" })
|
||||||
|
|
||||||
-- Pin workspaces to monitors: 1-4 on the Studio Display, 5-8 on the laptop
|
-- 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
|
-- 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).
|
-- stay on their monitor (the bar's workspace dots list them per monitor).
|
||||||
-- Matched on EDID description for the external display so it survives
|
-- The main external is picked at config load, and hypr/monitors.lua reloads
|
||||||
-- landing on a different DP connector after re-docking.
|
-- 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
|
for id = 1, 8 do
|
||||||
hl.workspace_rule({
|
hl.workspace_rule({
|
||||||
workspace = tostring(id),
|
workspace = tostring(id),
|
||||||
monitor = id <= 4 and "desc:Apple Computer Inc StudioDisplay 0x984262A7" or "eDP-1",
|
monitor = id <= 4 and (external or monitors.externals[1]) or "eDP-1",
|
||||||
default = id == 1 or id == 5,
|
default = id == 1 or id == 5,
|
||||||
persistent = true,
|
persistent = true,
|
||||||
})
|
})
|
||||||
end
|
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
|
-- Always open these apps on a fixed workspace and follow them there. Classes
|
||||||
-- come from `hyprctl clients` -- the desktop files' StartupWMClass hints
|
-- come from `hyprctl clients` -- the desktop files' StartupWMClass hints
|
||||||
@@ -59,12 +68,12 @@ o.window([[^tldraw-offline$]], { workspace = "5", fullscreen = true })
|
|||||||
-- each resident gets its own column, in the order they appear.
|
-- each resident gets its own column, in the order they appear.
|
||||||
--
|
--
|
||||||
-- SUPER + A / SUPER + CTRL + S: Tern; SUPER + SHIFT + A: Claude Desktop.
|
-- SUPER + A / SUPER + CTRL + S: Tern; SUPER + SHIFT + A: Claude Desktop.
|
||||||
-- Each alone on its own workspace, Studio Display. Tern has no per-window
|
-- Each alone on its own workspace, main external display. Tern has no per-window
|
||||||
-- class flag, so every Tern window lands on the scratchpad.
|
-- class flag, so every Tern window lands on the scratchpad.
|
||||||
o.window([[^so\.stencil\.tern$]], { workspace = "special:scratchpad silent" })
|
o.window([[^so\.stencil\.tern$]], { workspace = "special:scratchpad silent" })
|
||||||
o.window([[^com\.anthropic\.Claude$]], { workspace = "special:claude silent" })
|
o.window([[^com\.anthropic\.Claude$]], { workspace = "special:claude silent" })
|
||||||
-- SUPER + CTRL + ALT + E / M: Fastmail and Beeper, each alone on the
|
-- SUPER + CTRL + ALT + E / M: Fastmail and Beeper, each alone on its own
|
||||||
-- focused monitor.
|
-- workspace, laptop panel (eDP-1).
|
||||||
o.window([[^com\.fastmail\.Fastmail$]], { workspace = "special:fastmail silent" })
|
o.window([[^com\.fastmail\.Fastmail$]], { workspace = "special:fastmail silent" })
|
||||||
o.window([[^Beeper$]], { workspace = "special:beeper silent" })
|
o.window([[^Beeper$]], { workspace = "special:beeper silent" })
|
||||||
-- SUPER + CTRL + H: Google Home (Brave web app), on the focused monitor.
|
-- SUPER + CTRL + H: Google Home (Brave web app), on the focused monitor.
|
||||||
|
|||||||
@@ -111,18 +111,23 @@ hl.device({ name = "elan9008:00-04f3:43c7", output = "eDP-1" })
|
|||||||
-- flips arbitration to ignore-all. Cost: no tilt in drawing apps. The 90ms
|
-- 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.
|
-- 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
|
-- Wacom Intuos BT S: pinned to the main external display (Studio Display or
|
||||||
-- so it survives a different DP connector after re-docking. With that display
|
-- Samsung ultrawide, see hypr/monitors.lua, which reloads the config when it
|
||||||
-- absent, Hyprland maps across the whole layout, which undocked is just eDP-1.
|
-- changes). With neither connected it keeps the Studio Display selector,
|
||||||
|
-- which matches nothing, so Hyprland maps across the whole layout
|
||||||
|
-- (undocked: just eDP-1).
|
||||||
--
|
--
|
||||||
-- The tablet is 152x95mm (16:10) and the display is 16:9, so the active area is
|
-- The tablet is 152x95mm (16:10). The active area is cropped to a full-width
|
||||||
-- cropped to a 152x85.5mm (16:9) band to keep strokes undistorted while still
|
-- band with the display's aspect ratio (152x85.5mm for the 16:9 Studio
|
||||||
-- reaching every pixel. The band starts at the top edge, leaving the bottom
|
-- Display, 152x63.6mm for the 3440x1440 ultrawide) to keep strokes
|
||||||
-- 9.5mm of the tablet as dead space (the pen there parks at the screen bottom).
|
-- undistorted while still reaching every pixel. The band starts at the top
|
||||||
|
-- edge; below it is dead space (the pen there parks at the screen bottom).
|
||||||
|
local monitors = require("hypr.monitors")
|
||||||
|
local external, monitor = monitors.external()
|
||||||
hl.device({
|
hl.device({
|
||||||
name = "wacom-intuos-bt-s-pen",
|
name = "wacom-intuos-bt-s-pen",
|
||||||
output = "desc:Apple Computer Inc StudioDisplay 0x984262A7",
|
output = external or monitors.externals[1],
|
||||||
active_area_size = { 152, 85.5 },
|
active_area_size = { 152, monitor and 152 * monitor.height / monitor.width or 85.5 },
|
||||||
active_area_position = { 0, 0 },
|
active_area_position = { 0, 0 },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+45
-3
@@ -7,13 +7,55 @@ local omarchy_monitor_scale = 3.2
|
|||||||
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
|
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
|
||||||
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
|
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
|
||||||
|
|
||||||
-- Apple Studio Display (DP-4) on the left, laptop panel (eDP-1) on the right.
|
-- The main external display sits on the left, the laptop panel (eDP-1) to its
|
||||||
-- Logical widths at scale 2: 5120/2 = 2560, so eDP-1 starts at x=2560.
|
-- right; auto-right puts eDP-1 at the external's logical width (2560 for the
|
||||||
hl.monitor({ output = "eDP-1", mode = "2560x1600@180", position = "2560x0", scale = 2 })
|
-- Studio Display at scale 2, 3440 for the ultrawide at scale 1), or at 0x0
|
||||||
|
-- when undocked. Apple Studio Display over Thunderbolt, Samsung ultrawide on
|
||||||
|
-- a USB-C to HDMI cable from the iGPU (DP alt mode, so it shows up as DP-n;
|
||||||
|
-- matched on EDID, so the connector name doesn't matter).
|
||||||
|
hl.monitor({ output = "eDP-1", mode = "2560x1600@180", position = "auto-right", scale = 2 })
|
||||||
hl.monitor({ output = "DP-4", mode = "5120x2880@60", position = "0x0", scale = 2 })
|
hl.monitor({ output = "DP-4", mode = "5120x2880@60", position = "0x0", scale = 2 })
|
||||||
|
hl.monitor({ output = "desc:Samsung Electric Company S34CG50 HNTY501103", mode = "3440x1440@100", position = "0x0", scale = 1 })
|
||||||
|
|
||||||
-- Configure a specific monitor.
|
-- Configure a specific monitor.
|
||||||
-- hl.monitor({ output = "DP-2", mode = "2560x1440@144", position = "0x0", scale = 1 })
|
-- hl.monitor({ output = "DP-2", mode = "2560x1440@144", position = "0x0", scale = 1 })
|
||||||
|
|
||||||
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°).
|
-- Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°).
|
||||||
-- hl.monitor({ output = "DP-2", mode = "preferred", position = "auto", scale = 1, transform = 1 })
|
-- hl.monitor({ output = "DP-2", mode = "preferred", position = "auto", scale = 1, transform = 1 })
|
||||||
|
|
||||||
|
-- Main external display: the first of these that is connected. Workspaces
|
||||||
|
-- 1-4 (hypr/hyprland.lua) and the Wacom tablet (hypr/input.lua) follow it.
|
||||||
|
-- Entries are Hyprland monitor selectors: a connector name or
|
||||||
|
-- desc:<EDID description>.
|
||||||
|
local M = {
|
||||||
|
externals = {
|
||||||
|
"desc:Apple Computer Inc StudioDisplay 0x984262A7",
|
||||||
|
"desc:Samsung Electric Company S34CG50 HNTY501103",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- The connected main external as (selector, monitor), or nil.
|
||||||
|
function M.external()
|
||||||
|
for _, selector in ipairs(M.externals) do
|
||||||
|
for _, monitor in ipairs(hl.get_monitors()) do
|
||||||
|
if selector == monitor.name or selector == "desc:" .. monitor.description then
|
||||||
|
return selector, monitor
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Workspace rules only create persistent workspaces at config load, so a
|
||||||
|
-- change of main external reloads the config rather than patching rules in
|
||||||
|
-- place; the reload re-runs every user of M.external() against the new
|
||||||
|
-- monitor. Omarchy's reload guard skips it mid package update.
|
||||||
|
local loaded = M.external()
|
||||||
|
local function reload_on_change()
|
||||||
|
if M.external() ~= loaded then
|
||||||
|
hl.exec_cmd("omarchy-hyprland-reload-guard paused || hyprctl reload")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hl.on("monitor.added", reload_on_change)
|
||||||
|
hl.on("monitor.removed", reload_on_change)
|
||||||
|
|
||||||
|
return M
|
||||||
Reference in new issue
Block a user