Skip to content

fix(desktop): fullscreen header bar + always-visible close controls#8033

Merged
aharvard merged 12 commits intomainfrom
fix/fullscreen-close-button-always-visible
Mar 20, 2026
Merged

fix(desktop): fullscreen header bar + always-visible close controls#8033
aharvard merged 12 commits intomainfrom
fix/fullscreen-close-button-always-visible

Conversation

@aharvard
Copy link
Copy Markdown
Collaborator

@aharvard aharvard commented Mar 20, 2026

Closes #7142

Summary

Adds a dedicated fullscreen header bar for MCP Apps and ensures close/exit controls are always accessible in fullscreen and PiP modes — even when the app didn't declare display mode support.

Changes

useDisplayMode.ts

  • Added appTitle state, extracted from appCapabilities.title during ui/initialize
  • Exposed appTitle in the hook's return value
  • Added debug logging for ui/initialize and ui/request-display-mode messages

McpAppRenderer.tsx

  • Fullscreen header bar — new dedicated 48px header that sits outside the iframe
    • Three-column flexbox: spacer | center-aligned title | controls (PiP + close)
    • Uses theme-aware colors (text-text-secondary, bg-background-primary, border-border-primary)
    • Draggable region for Electron window movement; buttons retain individual no-drag
    • Close button always visible — no hover/opacity gating
  • Title fallback chain: appTitle (from ui/initialize) → humanizeExtensionName(extensionName)"App"
  • Container restructured for fullscreenflex flex-col so header + content stack vertically, content area gets flex-1 min-h-0
  • contentRef — ResizeObserver moved from containerRefcontentRef so apps get accurate containerDimensions excluding the header height
  • showControls — added || isFullscreen || isPip so controls render even when the app didn't declare display mode support
  • Fullscreen controls moved from floating overlay to the header bar; renderDisplayModeControls() no longer renders in fullscreen mode

Testing

  • Tested with MCP App Bench inspectors (all display mode variants)
  • Verified title displays correctly from appCapabilities.title
  • Verified fallback to humanized extension name when no title provided
  • Verified close button is always accessible in both fullscreen and PiP
  • Verified PiP close works when app sends ui/request-display-mode without declaring modes

aharvard and others added 4 commits March 20, 2026 10:11
- Add dedicated 48px fullscreen header with centered title, PiP + close controls
- Title fallback: appTitle (from ui/initialize) → humanizeExtensionName → 'App'
- Extract appTitle from appCapabilities.title in ui/initialize
- Restructure fullscreen container with flex-col layout (header + content)
- Move ResizeObserver to contentRef so apps get dimensions excluding header
- showControls renders even when app didn't declare fullscreen (|| isFullscreen)
- Header uses no-drag class, theme-aware colors, always-visible close button
- Add debug logging for ui/initialize and ui/request-display-mode

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
…re display modes

showControls now includes || isPip so the close button renders when in
PiP mode, matching the existing || isFullscreen pattern.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
Remove no-drag from the header container so the title bar area acts as
a window drag handle. Buttons retain their individual no-drag classes.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
…eExtensionName

Replace the duplicate humanizeExtensionName function with the existing
formatExtensionName from ExtensionList.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
@aharvard aharvard marked this pull request as ready for review March 20, 2026 14:32
@aharvard
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1a0bf9df9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good — just removed the two debug console.log statements from useDisplayMode.ts.

In PiP mode, contentRef does not get flex-1 so it sizes to its
scroll-content height rather than the visible 400x300 viewport.
This caused containerDimensions.height to report the wrong value
for MCP apps making layout decisions based on available space.

Revert to observing containerRef so the ResizeObserver reports the
actual visible viewport dimensions in all display modes.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fdf34b3a86

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

In fullscreen mode, the 48px header is inside containerRef, so the
ResizeObserver reports the full viewport height. Subtract
FULLSCREEN_HEADER_HEIGHT so containerDimensions.height reflects the
actual space available for app content, preventing apps from rendering
too tall and clipping behind the header.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
@aharvard aharvard enabled auto-merge March 20, 2026 15:04
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b5f7783803

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@aharvard aharvard disabled auto-merge March 20, 2026 15:12
aharvard and others added 2 commits March 20, 2026 11:24
The ui/initialize request carries the app's identity in
params.clientInfo.name, not caps.title or params.title which don't
exist in the spec. This was causing appTitle to never be set,
so the fullscreen header always fell back to the extension name.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
isFillsViewport is true for both fullscreen and standalone, but the
48px header is only rendered in fullscreen mode. Using isFullscreen
instead so standalone apps get the correct containerDimensions.height.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
@aharvard aharvard enabled auto-merge March 20, 2026 15:29
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8ad3f5ad7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Remove non-spec appInfo and capabilities fields from the handshake.
The spec defines clientInfo and appCapabilities as the correct fields.

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be84106345

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Signed-off-by: Andrew Harvard <[email protected]>
Co-authored-by: Goose <[email protected]>
Ai-assisted: true
@aharvard aharvard added this pull request to the merge queue Mar 20, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33204b02dc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Merged via the queue into main with commit 80f3e50 Mar 20, 2026
21 checks passed
@aharvard aharvard deleted the fix/fullscreen-close-button-always-visible branch March 20, 2026 16:21
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
…lock#8033)

Signed-off-by: Andrew Harvard <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Goose <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
…lock#8033)

Signed-off-by: Andrew Harvard <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Goose <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
* origin/main: (62 commits)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  docs: add Claude Code approve mode permission routing documentation (#7949)
  chatgpt_codex: Support reasoning and gpt-5.4 (#7941)
  refactor(anthropic): fix N+1 thinking message storage issue (#7958)
  fix: handle mid-stream error events in OpenAI SSE streaming (#8031)
  Fix apps extension: coerce string arguments from inner LLM responses (#8030)
  feat: ability to expand sidebar to see chats names  (#7816)
  Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940)
  set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947)
  ...
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
…pstream

* wpfleger/socket-support: (62 commits)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  docs: add Claude Code approve mode permission routing documentation (#7949)
  chatgpt_codex: Support reasoning and gpt-5.4 (#7941)
  refactor(anthropic): fix N+1 thinking message storage issue (#7958)
  fix: handle mid-stream error events in OpenAI SSE streaming (#8031)
  Fix apps extension: coerce string arguments from inner LLM responses (#8030)
  feat: ability to expand sidebar to see chats names  (#7816)
  Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940)
  set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947)
  ...
lifeizhou-ap added a commit that referenced this pull request Mar 24, 2026
* main: (37 commits)
  fix: handle reasoning content blocks in OpenAI-compat streaming parser (#8078)
  chore(acp): build native packages on latest mac (#8075)
  Display delegate sub agents logs in UI (#7519)
  Update tar version to avoid CVE-2026-33056 (#8073)
  refactor: consolidate duplicated dependencies into workspace (#8041)
  tui: set up for publishing via github actions (#8020)
  feat: feature-gate local inference dependencies (#7976)
  feat: ability to manage sub recipes in desktop ui (#6360)
  Tweak the release process: no more merge to main (#7994)
  fix: gemini models via databricks (#8042)
  feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506)
  fix: remove configured marker when deleting oauth provider configuration (#7887)
  docs: add vmware-aiops MCP extension documentation (#8055)
  Show setup instructions for ACP providers in settings modal (#8065)
  deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064)
  feat(acp): add session/set_config and stabilize list, delete and close (#7984)
  docs: Correct `gosoe` typo to `goose` (#8062)
  fix: use default provider and model when provider in session no longer exists (#8035)
  feat: add GOOSE_SHELL env var to configure preferred shell (#7909)
  fix(desktop): fullscreen header bar + always-visible close controls (#8033)
  ...
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.

MCP App iframe does not support fullscreen display mode (e.g. Excalidraw)

2 participants