From d1c676ca00b7eaef96d209fb0cd04594af1b63e5 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 22 Sep 2026 10:42:20 -0400 Subject: [PATCH] feat(config): add smart-move corner floats, pip toggle, and floating YouTube --- dot_config/hypr/bindings.lua | 36 +++++++++++++++++++++++------------- dot_config/hypr/hyprland.lua | 29 +++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/dot_config/hypr/bindings.lua b/dot_config/hypr/bindings.lua index 58f43e0..3130722 100644 --- a/dot_config/hypr/bindings.lua +++ b/dot_config/hypr/bindings.lua @@ -99,11 +99,19 @@ o.bind("SUPER + L", "Focus on right window", hl.dsp.focus({ direction = "r" })) 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", "omarchy-smart-move l") -o.bind("SUPER + SHIFT + J", "Move or merge down", "omarchy-smart-move d") -o.bind("SUPER + SHIFT + K", "Move or merge up", "omarchy-smart-move u") -o.bind("SUPER + SHIFT + L", "Move or merge right", "omarchy-smart-move r") +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 ──────────────────────────────────────────────── @@ -121,9 +129,8 @@ o.bind("SUPER + CTRL + K", "Previous workspace", hl.dsp.focus({ workspace = "e-1 -- (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, Beeper and YouTube have their own scratch --- workspaces under SUPER + CTRL + ALT + E / M / Y in the Applications block --- below. +-- 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 o.bind("SUPER + CTRL + S", "Toggle scratch workspace", "omarchy-toggle-scratch scratchpad") o.bind("SUPER + A", "Toggle scratch workspace", "omarchy-toggle-scratch scratchpad") @@ -185,15 +192,18 @@ 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 and the YouTube web app 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. +-- Fastmail and Beeper 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 + ALT + Y", "YouTube", "omarchy-toggle-scratch youtube") -- was: web apps cycle +-- 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-toggle-scratch youtube") +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 diff --git a/dot_config/hypr/hyprland.lua b/dot_config/hypr/hyprland.lua index 6d6ac60..b28b0a0 100644 --- a/dot_config/hypr/hyprland.lua +++ b/dot_config/hypr/hyprland.lua @@ -57,14 +57,27 @@ o.window([[^kitty-herdr$]], { workspace = "special:scratchpad silent" }) -- focused monitor. o.window([[^com\.fastmail\.Fastmail$]], { workspace = "special:fastmail silent" }) o.window([[^Beeper$]], { workspace = "special:beeper silent" }) --- SUPER + CTRL + ALT + Y / SUPER + SHIFT + Y: the YouTube web app. 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) still applies. --- Rule regexes are RE2 full matches: no lookahead, and a pattern must cover --- the whole string. + +-- 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.*]] }, - { workspace = "special:youtube silent" } + { + 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)" }, + } )