PRs basecamp/omarchy#6429 and #6430. Both target `quattro` — upstream `master` is still Omarchy 3 and has no default/hypr/apps/davinci-resolve.lua at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
10 KiB
Fix 001 — DaVinci Resolve's main window is covered by the Omarchy bar
Status: raised — basecamp/omarchy#6429 · Target project: omarchy
Target branch: quattro (Omarchy 4 lives there; master is still Omarchy 3 and has no Lua config)
Target file: default/hypr/apps/davinci-resolve.lua
Change type: append one window rule + explanatory comment. No new deps, no other app affected.
This file is a self-contained handoff. Everything needed to raise the PR — problem, root cause, exact patch, and reproduction/verification steps — is below. No other file in this repo is required.
1. Symptom
On Omarchy 4.x, launching DaVinci Resolve leaves Resolve's own menu bar (File / Edit / Trim / Timeline / Clip / …) hidden underneath the Omarchy status bar, so those menus cannot be clicked.
2. Root cause
omarchy-bar is a layer-shell surface on Hyprland's top layer with a 26px
exclusive zone:
$ hyprctl layers
Layer level 2 (top):
Layer ...: xywh: 0 0 2560 26, a: 1, namespace: omarchy-bar, pid: 1582
That reserved zone only constrains tiled windows. It is being honoured
correctly — hyprctl monitors reports reserved: [0, 26, 0, 0], and tiled
windows start at y=38 as expected.
The problem is that Resolve is not tiled. default/hypr/apps/davinci-resolve.lua
floats every Resolve window, which is the right call — Resolve's many child
windows tile badly. But floating windows are positioned by the client, and
Resolve's XWayland main window places itself at 0,0 at the full monitor
size, ignoring the reserved zone entirely:
class='resolve' title='DaVinci Resolve - New Project 2' at=[0, 0] size=[2560, 1440] float=True fs=0
So the bar, being on the top layer, draws over it.
3. Fix
Hyprland renders a fullscreen window above top-layer layer-shell surfaces.
Opening Resolve's main window fullscreen therefore puts Resolve over the bar
instead of under it. The bar is not modified, hidden, or killed — it behaves
normally again as soon as you leave fullscreen or focus another window.
Why the title match must be narrow
Every Resolve window shares the same class, and only the main one may be fullscreened. Windows observed during a cold start:
| window | title | size | fullscreened |
|---|---|---|---|
| splash screen | resolve |
740×326 | no |
| project chooser | Project Manager |
900×512 | no |
| modal dialogs | e.g. Preferences |
630×534 | no |
| main window | DaVinci Resolve - <project name> |
2560×1440 | yes |
Requiring the " - <project>" suffix leaves the splash, the Project Manager and
Resolve's modal dialogs floating at their natural size. A class-only rule would
fullscreen all of them, which is why the rule is title-scoped.
The class pattern .*[Rr]esolve.* is kept byte-identical to the existing rule in
this file for consistency; the title is what does the scoping. Both patterns
were verified together as the exact string in the patch (see §5), not inferred
from testing the two halves separately.
4. The patch
Four lines: a blank, a three-line comment, and the rule. Apply with git apply:
--- a/default/hypr/apps/davinci-resolve.lua
+++ b/default/hypr/apps/davinci-resolve.lua
@@ -6,3 +6,9 @@
tag = "-default-opacity",
opacity = "1 1",
})
+
+-- Resolve's floating main window ignores the bar's reserved zone, so the bar
+-- covers its menu bar; fullscreen renders above top-layer surfaces. Scoped by
+-- title so the splash and Project Manager keep their natural size.
+o.window({ class = ".*[Rr]esolve.*", title = "^DaVinci Resolve - .+$" }, { fullscreen = true })
If the diff doesn't apply cleanly (upstream moved), the change is just append the comment and this line to the end of the file:
o.window({ class = ".*[Rr]esolve.*", title = "^DaVinci Resolve - .+$" }, { fullscreen = true })
Resulting complete file
-- DaVinci Resolve window focus handling. Kept fully opaque: the default
-- translucency distorts colour-critical grading work.
o.window(".*[Rr]esolve.*", {
float = true,
stay_focused = true,
tag = "-default-opacity",
opacity = "1 1",
})
-- Resolve's floating main window ignores the bar's reserved zone, so the bar
-- covers its menu bar; fullscreen renders above top-layer surfaces. Scoped by
-- title so the splash and Project Manager keep their natural size.
o.window({ class = ".*[Rr]esolve.*", title = "^DaVinci Resolve - .+$" }, { fullscreen = true })
Optional, once the PR is open
default/hypr/apps/jetbrains.lua sets the precedent of keeping the code terse
and parking the deep rationale behind a link:
-- Disable mouse focus (see https://github.com/basecamp/omarchy/pull/5183#issuecomment-4189299971).
If a reviewer wants more detail inline than the three lines give, follow that
pattern — append (see <this PR's URL>) to the comment rather than expanding
the comment block.
5. Verification performed
Tested on Hyprland 0.56.1 / Omarchy 4.0.0.r1440, NVIDIA, 2560×1440 logical (3840×2160 physical, scale 1.5).
Method: sample the top 26px strip with grim. Bar colour is (26,27,38);
Resolve's UI chrome is (23,24,26).
Before — bar covers Resolve:
y= 5 [(26, 27, 38), (26, 27, 38), (26, 27, 38)] <- bar
y= 20 [(26, 27, 38), (26, 27, 38), (26, 27, 38)] <- bar
y= 35 [(26, 27, 38), (26, 27, 38), (26, 27, 38)] <- bar
y= 45 [(23, 24, 26), (23, 24, 26), (23, 24, 26)] <- Resolve only starts here
After — Resolve renders over the bar, its menu text now visible at y=35:
y= 5 [(23, 24, 26), (23, 24, 26), (23, 24, 26)]
y= 20 [(23, 24, 26), (23, 24, 26), (23, 24, 26)]
y= 35 [(179, 180, 180), (23, 24, 26), (23, 24, 26)] <- menu text
y= 45 [(23, 24, 26), (23, 24, 26), (23, 24, 26)]
With the exact rule string above installed, a cold start produces precisely the intended scoping — only the main window is fullscreened, and a modal dialog that happened to open during the run was correctly left alone:
title='resolve' size=[740, 326] FULLSCREEN=0
title='Project Manager' size=[900, 512] FULLSCREEN=0
title='DaVinci Resolve - New Project 2' size=[2560, 1440] FULLSCREEN=2
title='Preferences' size=[630, 534] FULLSCREEN=0
That Preferences line is the important one: it is the failure mode a
class-only rule would produce (a 630×534 dialog blown up to fill the screen),
and it demonstrably does not happen.
Also confirmed visually by the reporting user.
How to re-verify
# 1. Watch what Resolve opens, and at what size / fullscreen state
(while :; do
hyprctl clients -j | jq -r '.[] | select(.class=="resolve")
| "title=\(.title) size=\(.size) FULLSCREEN=\(.fullscreen)"'
sleep 2
done) | sort -u &
# 2. Launch Resolve, then SELECT A PROJECT in the Project Manager.
# Resolve never opens a project on its own, so an unattended launch stops
# at the chooser and the main window never appears.
# 3. Confirm the top strip belongs to Resolve, not the bar
grim -g "0,0 1200x60" /tmp/top.png
Expect the splash and Project Manager at FULLSCREEN=0, and only
DaVinci Resolve - <project> at FULLSCREEN=2.
6. Upstream conventions this follows
Checked against every file in default/hypr/apps/ on omarchy 4.0.0.r1440, not
assumed. Keep these in mind if the patch is reworked.
| Convention | Evidence upstream | How this patch complies |
|---|---|---|
Comments are terse — 3 lines is the maximum anywhere in apps/ |
longest are webcam-overlay.lua, system.lua, omarchy-shell.lua at 3 lines; most files have 0–1 |
3-line comment |
| Deep rationale goes in the PR, linked from code — not expanded inline | jetbrains.lua links a PR comment for its one-line rule |
full rationale lives in this file / the PR; optional link noted above |
Class+title matching uses the table form o.window({ class = …, title = … }, { … }) |
battlenet.lua, omarchy-shell.lua, system.lua |
same form |
| Single-property rules stay inline on one line; only multi-property rules break across lines | moonlight.lua, geforce.lua, qemu.lua inline vs retroarch.lua, pip.lua multi-line |
one property (fullscreen = true), inline |
fullscreen = true is the established idiom for this |
moonlight.lua, retroarch.lua, system.lua (screensaver) |
same property |
| Long lines are acceptable — no wrapping for its own sake | omarchy-shell.lua (~180 chars), browser.lua (~150) |
rule line is ~95 chars |
Regex metacharacters escaped as \\. in Lua strings |
battlenet.lua: "^Battle\\.net$" |
no literal dot in the title; .+ is intentional |
| 2-space indent, double-quoted strings | throughout | matches |
| One app per file, named after the app | the whole directory | extends the existing davinci-resolve.lua rather than adding a file |
Note the packaged copy of Omarchy ships no stylua.toml, .editorconfig or
CONTRIBUTING.md (they aren't included in the package), so style here is
inferred from the source files themselves. Check the GitHub repo for a
formatter config before raising, and run it if one exists.
7. Suggested PR text
Title
hypr/apps: open DaVinci Resolve's main window fullscreen so it isn't covered by the bar
Body — sections 1, 2, 3 and 5 above, in that order.
8. Caveats for the reviewer
- Only the main window is fullscreened; splash, Project Manager and modal dialogs are untouched. This is the whole point of the title scoping.
- If a user leaves fullscreen manually, the bar covers Resolve again — inherent
to the approach, and recoverable with
SUPER + F. - The title is matched at window-open time. If a future Resolve release changes
its main-window title format away from
DaVinci Resolve - <project>, the rule silently stops matching and the old behaviour returns. It fails safe: no window gets wrongly fullscreened. - An alternative considered and rejected: having Resolve's launcher run
omarchy toggle bar offand restore it on exit. It needs no window titles, but hides the bar system-wide across all workspaces for as long as Resolve is open, and leaves the bar hidden if the process is killed uncleanly.