Skip to content

fix(windows): keep interactive elements clickable through the titlebar drag region - #229

Open
Pasumao wants to merge 1 commit into
dataelement:mainfrom
Pasumao:fix/windows-titlebar-no-drag-patches
Open

fix(windows): keep interactive elements clickable through the titlebar drag region#229
Pasumao wants to merge 1 commit into
dataelement:mainfrom
Pasumao:fix/windows-titlebar-no-drag-patches

Conversation

@Pasumao

@Pasumao Pasumao commented Aug 29, 2026

Copy link
Copy Markdown

Problem (Windows)

Every interactive control that lives inside the 36px Windows titlebar strip is unclickable: the session header buttons, the sidebar collapse button, and the top rows of any third-party client plugin (e.g. a file-explorer column header). Clicks there either do nothing or start a window drag.

Root cause

mountWindowsTitlebarLayout injects a full-width drag region at z-index: 2147483644 with -webkit-app-region: drag. Because it sits on top of all page content, -webkit-app-region resolves to drag for the entire strip: app-region is won by the topmost painted element that declares it, and pointer-events: none does not opt out of that resolution. The global �utton { -webkit-app-region: no-drag !important } escape hatch therefore never applies — those buttons are below the overlay, so the drag region swallows their clicks.

Fix

Punch transparent no-drag holes one layer above the drag region (z-index: 2147483645) for every interactive element (�utton, a, input, select, textarea, [role=button], [data-dsh-no-drag]) whose rect intersects the strip:

  • patches are pointer-events: none, so real clicks fall through to the controls underneath;
  • patches only cover the part of the element inside the strip — empty strip areas keep dragging the window;
  • a MutationObserver plus scroll (capture) /
    esize listeners keep the patches in sync, rAF-throttled;
  • works for any renderer content, including third-party client plugins — no per-app DOM contract needed.

Verification

Windows 11, DSH Desktop with Harness 0.1.1-rc.2: before the patch, the session header controls, sidebar collapse and third-party plugin headers inside the strip were all dead; after reloading, they are clickable again and the window still drags from empty top areas. Message buttons that scroll under the strip also become clickable while intersecting it.

Tests

Extended est/windows-titlebar.test.ts (same source-assertion style as the existing suite): 8/8 passing, pnpm typecheck clean.

…r drag region

The injected full-width drag region sits above every page element at z-index 2147483644, so -webkit-app-region resolves to drag for the whole 36px strip and the global no-drag rule on buttons below it never wins (app-region is resolved by paint order; pointer-events does not opt out). Every interactive control that lives inside the strip - the session header, sidebar collapse, third-party plugin headers - was unclickable on Windows.

Fix: punch transparent no-drag patches one layer above the drag region for every interactive element intersecting the strip, tracked with a MutationObserver plus scroll/resize listeners (rAF-throttled). Patches are pointer-events:none so real clicks fall through to the controls; empty strip areas keep dragging the window. Works for any renderer content, including third-party client plugins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant