Two Resolve problems on Omarchy 4.x turned out to be bugs in Omarchy's own Hyprland rules rather than in this installer, so document them as ready-to-raise upstream patches: 001 the status bar covers Resolve's menu bar 002 Resolve's dialogs trap the pointer until Resolve is killed Each file is self-contained: symptom, root cause with captured command output, the exact patch in Omarchy's house style, verification performed, how to re-verify, and reviewer caveats. Both fixes are verified end-to-end on Hyprland 0.56.1 / Omarchy 4.0.0.r1440. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
199 lines
8.8 KiB
Markdown
199 lines
8.8 KiB
Markdown
# Fix 002 — DaVinci Resolve's dialogs trap the pointer until Resolve is killed
|
||
|
||
**Status:** ready to raise — fully verified (§5) · **Target project:** [omarchy](https://github.com/basecamp/omarchy)
|
||
**Target file:** `default/hypr/apps/davinci-resolve.lua`
|
||
**Change type:** append one window rule + comment. Narrows an existing rule; removes nothing.
|
||
|
||
> Self-contained handoff. Problem, root cause, patch and verification are all
|
||
> below. No other file in this repo is required.
|
||
|
||
> Both halves are verified: the trap is measurably gone, and the popup
|
||
> behaviour `stay_focused` protects is confirmed intact. See §7 for the one
|
||
> remaining known limitation and an open design question for the maintainer.
|
||
|
||
---
|
||
|
||
## 1. Symptom
|
||
|
||
Opening certain DaVinci Resolve windows — confirmed with **Preferences** and
|
||
**Project Manager** — traps the pointer. The dialog cannot be dismissed and no
|
||
other window can be clicked. **Quitting Resolve entirely is the only way out.**
|
||
|
||
## 2. Root cause
|
||
|
||
`default/hypr/apps/davinci-resolve.lua` sets `stay_focused = true` on
|
||
`.*[Rr]esolve.*` — that is, on *every* Resolve window.
|
||
|
||
That rule is there for a real reason and **must not simply be deleted**.
|
||
Resolve is not Wayland-native, so Hyprland misreads its transient popups
|
||
(Change Clip Duration, Normalize Audio Levels, …) and they close the moment the
|
||
pointer leaves them unless focus is pinned. See
|
||
[hyprwm/Hyprland#12235](https://github.com/hyprwm/Hyprland/discussions/12235),
|
||
which is where the `stayfocused` workaround originates.
|
||
|
||
The bug is that it is applied **too broadly**. `stayfocused` forces focus onto a
|
||
window while it is visible. When two Resolve windows are visible at once, both
|
||
demand focus and neither yields, so Hyprland flips between them indefinitely.
|
||
|
||
Captured live, sampling `hyprctl activewindow` every 0.4s, with the Project
|
||
Manager and its own child dialog both open:
|
||
|
||
```
|
||
t=361.7 ACTIVE='resolve'|'Create New Project' resolve_windows=['Project Manager', 'Create New Project']
|
||
t=365.4 ACTIVE='resolve'|'Project Manager' resolve_windows=['Project Manager', 'Create New Project']
|
||
t=365.8 ACTIVE='resolve'|'Create New Project' resolve_windows=['Project Manager', 'Create New Project']
|
||
```
|
||
|
||
Focus oscillates between the two. Neither can be acted on, which is exactly what
|
||
"the mouse is captured" looks like from the user's side.
|
||
|
||
## 3. Fix
|
||
|
||
Keep the pin where it is needed — the transient popups — and remove it from the
|
||
windows those popups open *over*. At most one pinned window is then ever
|
||
visible, so nothing can fight.
|
||
|
||
The two parent windows are the main window and the Project Manager:
|
||
|
||
| window | role | pinned after fix |
|
||
|---|---|---|
|
||
| `DaVinci Resolve - <project>` | parent of Preferences, Change Clip Duration, … | no |
|
||
| `Project Manager` | parent of Create New Project | no |
|
||
| `Preferences`, `Create New Project`, transient popups | children | yes |
|
||
|
||
This is a narrowing, not a removal: every window that previously relied on
|
||
`stay_focused` to stay open still has it.
|
||
|
||
## 4. The patch
|
||
|
||
```diff
|
||
--- a/default/hypr/apps/davinci-resolve.lua
|
||
+++ b/default/hypr/apps/davinci-resolve.lua
|
||
@@ -6,3 +6,8 @@
|
||
tag = "-default-opacity",
|
||
opacity = "1 1",
|
||
})
|
||
+
|
||
+-- stay_focused above stops Resolve's transient popups closing on mouse-out
|
||
+-- (hyprwm/Hyprland#12235), but pinning the windows they open over makes two
|
||
+-- windows fight for focus and traps the pointer. Unpin the parents only.
|
||
+o.window({ class = ".*[Rr]esolve.*", title = "^(DaVinci Resolve - .+|Project Manager)$" }, { stay_focused = false })
|
||
```
|
||
|
||
Independent of fix 001 — different property, order between them doesn't matter.
|
||
|
||
## 5. Verification performed
|
||
|
||
Hyprland 0.56.1 / Omarchy 4.0.0.r1440, NVIDIA, 2560×1440 logical.
|
||
|
||
**The override mechanism is confirmed.** A later, more specific rule does beat
|
||
an earlier blanket one, tested in isolation with a throwaway class so nothing
|
||
about Resolve could confound it:
|
||
|
||
```lua
|
||
o.window("^(OVERRIDETEST)$", { float = true })
|
||
o.window({ class = "^(OVERRIDETEST)$", title = "^nofloat$" }, { float = false })
|
||
```
|
||
```
|
||
title='nofloat' floating=False <- later specific rule wins
|
||
title='yesfloat' floating=True <- blanket rule still applies
|
||
```
|
||
|
||
**The oscillation is confirmed** — see the focus log in §2.
|
||
|
||
**The trap is confirmed removed, by cold-start A/B.** Resolve was started fresh
|
||
twice — once with the fix, once with *only* the `stay_focused` exclusion removed
|
||
(fix 001 left in place, so the exclusion was the sole variable). In each run
|
||
Resolve was focused, focus was then dispatched to another window, and the actual
|
||
focus owner sampled 12 times at 0.5s intervals:
|
||
|
||
| run | config | samples where Resolve held focus | verdict |
|
||
|---|---|---|---|
|
||
| A | with fix | **0 / 12** | focus sticks elsewhere — not trapped |
|
||
| B | control, exclusion removed | **11 / 12** | snaps back to Resolve — trapped |
|
||
|
||
The control matters: it demonstrates the test can actually detect the trap, so
|
||
run A's result is meaningful rather than vacuous.
|
||
|
||
Both runs exercised the **Project Manager**, one of the two windows the rule
|
||
excludes and one of the two originally reported.
|
||
|
||
**The main window and the popups were then confirmed by hand.** Resolve always
|
||
requires a project to be selected from the Project Manager before the main
|
||
window opens — it never opens one on its own — so these two checks cannot be
|
||
automated and were driven manually by the reporting user:
|
||
|
||
| check | procedure | result |
|
||
|---|---|---|
|
||
| Main window no longer traps | Open a project, open **Preferences** from the main window | **Pass** — dismissable, and other applications remain clickable while it is open |
|
||
| Popups do not regress | Edit page → right-click clip → **Change Clip Duration**, move pointer off the popup onto the main window | **Pass** — popup stays open |
|
||
|
||
The second row is the one that matters most: it is the behaviour
|
||
`stay_focused` exists to protect, and it survives the narrowing intact.
|
||
|
||
## 6. How to verify properly
|
||
|
||
Both halves must be checked — the fix is only correct if it fixes the trap
|
||
**and** leaves the popups alone.
|
||
|
||
```bash
|
||
# Log every focus transition while you drive Resolve by hand
|
||
while :; do
|
||
hyprctl activewindow -j | jq -r '"ACTIVE=\(.class)|\(.title)"'
|
||
sleep 0.4
|
||
done | uniq
|
||
```
|
||
|
||
Note: Resolve never opens a project on its own — you must select one in the
|
||
Project Manager before the main window appears. Both checks below therefore have
|
||
to be driven by hand; an unattended launch stops at the chooser.
|
||
|
||
1. **The trap is gone** — cold-start Resolve, open Project Manager → Create New
|
||
Project, then select a project and open Preferences from the main window.
|
||
Each dialog should take focus and stay there; you should be able to dismiss
|
||
it and click other apps. The log must show no rapid flip-flopping between two
|
||
`resolve` windows.
|
||
2. **No popup regression** — in the edit page, open a transient popup (right-click
|
||
a clip → Change Clip Duration, or Normalize Audio Levels) and move the pointer
|
||
off it onto the main window. It must **not** vanish. This is the behaviour
|
||
`stay_focused` exists to protect.
|
||
|
||
## 7. Caveats for the reviewer
|
||
|
||
- **The parent list is a blocklist and will need extending.** Only
|
||
`DaVinci Resolve - <project>` and `Project Manager` are excluded. If another
|
||
Resolve window can itself parent a dialog (Project Settings and the Deliver
|
||
page are the likely candidates), it will reintroduce the trap and must be
|
||
added to the alternation.
|
||
- **A cleaner long-term fix may exist.** Hyprland 0.53.3+ added
|
||
`input:mouse_refocus`, and [#12235](https://github.com/hyprwm/Hyprland/discussions/12235)
|
||
notes `mouse_refocus = 0` as an alternative to `stayfocused` entirely. On
|
||
0.56.1 the underlying popup bug may even be fixed, which would make the whole
|
||
`stay_focused` rule obsolete. That was not tested here because
|
||
`mouse_refocus` is a **global** input setting, not a per-window rule, so
|
||
flipping it for every Omarchy user is a much larger decision than this
|
||
narrowing. Worth a maintainer's opinion.
|
||
- Related open issue: [basecamp/omarchy#5887](https://github.com/basecamp/omarchy/issues/5887)
|
||
reports Resolve child windows becoming inaccessible on Omarchy 4.0.0.alpha.
|
||
It doesn't mention `stayfocused`, but "child windows become inaccessible when
|
||
the main panel is clicked" is consistent with this root cause, and this fix
|
||
may resolve it. Worth linking in the PR.
|
||
|
||
## 8. Upstream conventions this follows
|
||
|
||
Same set verified for fix 001 — see
|
||
[`001-resolve-bar-overlap.md`](001-resolve-bar-overlap.md) §6. Specifically:
|
||
3-line comment (house max), table-match form for class+title, single-property
|
||
rule inline on one line, 2-space indent, extends the existing app file rather
|
||
than adding a new one.
|
||
|
||
## 9. Suggested PR text
|
||
|
||
**Title**
|
||
|
||
```
|
||
hypr/apps: stop DaVinci Resolve's dialogs trapping the pointer
|
||
```
|
||
|
||
**Body** — sections 1, 2 and 3 above, then the §5 evidence, then the §7 bullets
|
||
stated as known limitations.
|