From ea82f91bef4aad60eecadf20bdb79534943bf984 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 7 Sep 2026 21:39:13 -0700 Subject: [PATCH 1/4] fix(desktop): restore layout control hit targets --- apps/web/src/index.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 7987a0657090..db19ddf54830 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1603,6 +1603,15 @@ code { -webkit-app-region: drag; } +/* Electron 44 inherits app-region. A later header child can otherwise add a + drag rectangle over fixed controls that already opted out. Reset children + in the base layer so explicit drag/no-drag utilities still take precedence. */ +@layer base { + .drag-region > * { + -webkit-app-region: none; + } +} + .drag-region button, .drag-region input, .drag-region textarea, From 8aad9a67c81bbf036e4297ef1f8b413d77109b36 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 7 Sep 2026 21:43:14 -0700 Subject: [PATCH 2/4] docs: clarify native drag region reset behavior --- apps/web/src/index.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/web/src/index.css b/apps/web/src/index.css index db19ddf54830..1640bfcc5092 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1604,8 +1604,9 @@ code { } /* Electron 44 inherits app-region. A later header child can otherwise add a - drag rectangle over fixed controls that already opted out. Reset children - in the base layer so explicit drag/no-drag utilities still take precedence. */ + drag rectangle over fixed controls that already opted out. `none` emits no + rectangle, preserving the parent's drag area; `no-drag` would subtract it. + Use the base layer so explicit drag/no-drag utilities still take precedence. */ @layer base { .drag-region > * { -webkit-app-region: none; From f7deb75ad52589524760e8cb199ef2fa0ea21bab Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 7 Sep 2026 22:04:15 -0700 Subject: [PATCH 3/4] fix(web): keep PR layout controls above native drag regions --- apps/web/src/routes/_chat.pull-requests.tsx | 34 ++++++--------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/apps/web/src/routes/_chat.pull-requests.tsx b/apps/web/src/routes/_chat.pull-requests.tsx index 99986567cbfa..b0ac463ebeb1 100644 --- a/apps/web/src/routes/_chat.pull-requests.tsx +++ b/apps/web/src/routes/_chat.pull-requests.tsx @@ -1786,22 +1786,7 @@ function PullRequestsRouteView() { } /> ), - titlebarControls: - // While the panel is closed the strip lives inside the header: a no-drag - // descendant beats the header's desktop drag-region, where a floating - // sibling loses (app-region hit-testing ignores z-index). While the - // floating strip crosses the header during motion, the narrow extension - // keeps that overlap non-draggable without moving the toggle. - pullRequestsSupported ? ( - rightPanelPresent ? ( - - ) : ( - openPanelControls - ) - ) : null, + titlebarControls: pullRequestsSupported && !rightPanelPresent ? openPanelControls : null, rightPanelOpen: rightPanelState.isOpen, listBody, scrollRef, @@ -1884,7 +1869,6 @@ function PullRequestsRouteView() { return (
- {pullRequestsSupported && rightPanelPresent ? openPanelControls : null} {rightPanelPresent && renderedPullRequestSurface && panelEnvironmentId !== null ? ( @@ -1955,6 +1939,10 @@ function PullRequestsRouteView() { /> ) : null} + {/* Native drag regions follow layout-tree order, not z-index. Keep the + actual control's no-drag rectangle after both titlebars, including + while the panel closes, without putting it in the clipped panel. */} + {pullRequestsSupported && rightPanelPresent ? openPanelControls : null}
); @@ -2213,19 +2201,14 @@ function PullRequestsColumn({ // Painted flat like the chat column: the inset underneath carries the chrome grain, and a // content surface that lets it show reads as a different background than every thread.
- {/* A closed right panel leaves this column full-width, so the shared header - reserves native window controls and hosts the controls strip itself: on - desktop the header is a drag-region, and only a no-drag descendant wins - clicks from it - a floating sibling loses to app-region hit-testing no - matter its z-index. While the panel is open, the strip mounts back at - the route level, whose box spans the panel too, so the toggle keeps one - fixed top-right anchor. */} + {/* Keep the closed-panel controls inside this titlebar. The open-panel + controls mount after both columns at the route level, preserving the + same top-right anchor while excluding both native drag regions. */} - {titlebarControls} {condensed ? ( {/* An expanded search owns the scarce horizontal space. The page title stays @@ -2282,6 +2265,7 @@ function PullRequestsColumn({
) : null} {rightPanelControl} + {titlebarControls}
Date: Mon, 7 Sep 2026 22:11:56 -0700 Subject: [PATCH 4/4] fix(web): preserve window dragging when resetting app regions --- apps/web/src/index.css | 10 +++--- apps/web/src/routes/_chat.pull-requests.tsx | 34 +++++++++++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 1640bfcc5092..1d7975d24677 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1603,13 +1603,13 @@ code { -webkit-app-region: drag; } -/* Electron 44 inherits app-region. A later header child can otherwise add a - drag rectangle over fixed controls that already opted out. `none` emits no - rectangle, preserving the parent's drag area; `no-drag` would subtract it. - Use the base layer so explicit drag/no-drag utilities still take precedence. */ +/* Electron 44 inherits app-region. Reset children to the initial value so they + do not add drag rectangles over fixed controls. Explicit `none` is treated + as `no-drag` and breaks titlebar dragging; `initial` emits no rectangle. + The base layer lets explicit drag/no-drag utilities take precedence. */ @layer base { .drag-region > * { - -webkit-app-region: none; + -webkit-app-region: initial; } } diff --git a/apps/web/src/routes/_chat.pull-requests.tsx b/apps/web/src/routes/_chat.pull-requests.tsx index b0ac463ebeb1..99986567cbfa 100644 --- a/apps/web/src/routes/_chat.pull-requests.tsx +++ b/apps/web/src/routes/_chat.pull-requests.tsx @@ -1786,7 +1786,22 @@ function PullRequestsRouteView() { } /> ), - titlebarControls: pullRequestsSupported && !rightPanelPresent ? openPanelControls : null, + titlebarControls: + // While the panel is closed the strip lives inside the header: a no-drag + // descendant beats the header's desktop drag-region, where a floating + // sibling loses (app-region hit-testing ignores z-index). While the + // floating strip crosses the header during motion, the narrow extension + // keeps that overlap non-draggable without moving the toggle. + pullRequestsSupported ? ( + rightPanelPresent ? ( + + ) : ( + openPanelControls + ) + ) : null, rightPanelOpen: rightPanelState.isOpen, listBody, scrollRef, @@ -1869,6 +1884,7 @@ function PullRequestsRouteView() { return (
+ {pullRequestsSupported && rightPanelPresent ? openPanelControls : null} {rightPanelPresent && renderedPullRequestSurface && panelEnvironmentId !== null ? ( @@ -1939,10 +1955,6 @@ function PullRequestsRouteView() { /> ) : null} - {/* Native drag regions follow layout-tree order, not z-index. Keep the - actual control's no-drag rectangle after both titlebars, including - while the panel closes, without putting it in the clipped panel. */} - {pullRequestsSupported && rightPanelPresent ? openPanelControls : null}
); @@ -2201,14 +2213,19 @@ function PullRequestsColumn({ // Painted flat like the chat column: the inset underneath carries the chrome grain, and a // content surface that lets it show reads as a different background than every thread.
- {/* Keep the closed-panel controls inside this titlebar. The open-panel - controls mount after both columns at the route level, preserving the - same top-right anchor while excluding both native drag regions. */} + {/* A closed right panel leaves this column full-width, so the shared header + reserves native window controls and hosts the controls strip itself: on + desktop the header is a drag-region, and only a no-drag descendant wins + clicks from it - a floating sibling loses to app-region hit-testing no + matter its z-index. While the panel is open, the strip mounts back at + the route level, whose box spans the panel too, so the toggle keeps one + fixed top-right anchor. */} + {titlebarControls} {condensed ? ( {/* An expanded search owns the scarce horizontal space. The page title stays @@ -2265,7 +2282,6 @@ function PullRequestsColumn({
) : null} {rightPanelControl} - {titlebarControls}