DaVinci-Resolve-Omarchy/omarchy-upstream-fixes/001-resolve-bar-overlap.md
28allday a1c5971702 Mark upstream fixes 001/002 as raised, record quattro as the target branch
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>
2026-07-29 17:02:33 +01:00

10 KiB
Raw Blame History

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 01 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 off and 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.