Skip to content

fix: add an exit control to fullscreen cell output - #10769

Merged
kirangadhave merged 7 commits into
mainfrom
kg/fullscreen-exit-button
Sep 9, 2026
Merged

kirangadhave merged 7 commits into
mainfrom
kg/fullscreen-exit-button

Conversation

@kirangadhave

@kirangadhave kirangadhave commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

📝 Summary

Fullscreen paints the output element only, and the fullscreen and expand buttons sit outside it in the cell gutter. A fullscreen output therefore shows no control at all. Browsers hide this with their own exit overlay and Escape handling, but embedded hosts do not. In JCEF, which backs the JetBrains plugin, no overlay appears and Escape does nothing, so the only way back to the notebook is to clear the cell output.

Render an exit button inside the fullscreen element, and exit on Escape while an output is fullscreen. A local build in PyCharm confirms that the Escape handler works, so JCEF delivers the key and simply never acts on it. This removes the need for a keyboard handler on the plugin side.

Closes marimo-team/jetbrains-marimo#108
Closes MO-7561

Fullscreen paints the output element only, and the action buttons sit outside it. Hosts that draw no exit overlay, for example JCEF in JetBrains IDEs, left no path back to the notebook.
Embedded hosts such as JCEF in JetBrains IDEs deliver the Escape keydown but never exit fullscreen themselves. Handle the key while an output is fullscreen.
Add tests for the exit button and the Escape handler. Fix the fullscreen check, which treated a null fullscreen element as a match while the container ref was still unset.
@vercel

vercel Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
marimo-docs Ready Ready Preview Sep 9, 2026 7:17pm UTC

Request Review

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@kirangadhave
kirangadhave marked this pull request as ready for review September 9, 2026 00:06
Copilot AI lite review requested due to automatic review settings September 9, 2026 00:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new tests override document fullscreen properties without restoring them, which can leak mocked behavior into other test files and cause flaky failures.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds an in-output “Exit fullscreen” control for cell outputs and handles Escape to exit fullscreen, addressing embedded hosts (e.g., JCEF in JetBrains IDEs) that don’t provide browser-native fullscreen exit UI/behavior.

Changes:

  • Add an Escape key handler while an output element is fullscreen and render an exit button inside the fullscreen-painted output element.
  • Introduce an exitFullscreen() helper that logs a warning if exiting fullscreen fails.
  • Add unit tests covering button visibility and exiting fullscreen via click/Escape.
File summaries
File Description
frontend/src/components/editor/Output.tsx Adds a fullscreen “exit” button inside the output element and a scoped Escape handler to exit fullscreen.
frontend/src/components/editor/tests/Output.test.tsx Adds tests verifying the exit button appears only in fullscreen and that click/Escape trigger document.exitFullscreen().
Review details

Suppressed comments (1)

frontend/src/components/editor/tests/Output.test.tsx:177

  • This suite overrides document.fullscreenElement and document.exitFullscreen via Object.defineProperty(...) but never restores them, which can leak mocked behavior into other test files (the global test setup only calls vi.clearAllMocks(), which won’t revert property descriptors). Capture the original descriptors and restore them in afterAll.
describe("OutputArea fullscreen exit control", () => {
  let fullscreenElement: Element | null = null;
  const exitFullscreen = vi.fn(() => Promise.resolve());

  beforeEach(() => {
    fullscreenElement = null;
    exitFullscreen.mockClear();
    Object.defineProperty(document, "fullscreenElement", {
      configurable: true,
      get: () => fullscreenElement,
    });
    Object.defineProperty(document, "exitFullscreen", {
      configurable: true,
      value: exitFullscreen,
    });
  });
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread frontend/src/components/editor/__tests__/Output.test.tsx Outdated
@kirangadhave kirangadhave added the enhancement New feature or request label Sep 9, 2026
State why the output carries its own exit control without naming a specific embedded browser.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread frontend/src/components/editor/Output.tsx Outdated
Comment thread frontend/src/components/editor/__tests__/Output.test.tsx
Delete the fullscreen property stubs in afterEach so that later tests in the file see the real document.
@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Report for ./frontend

Status Category Percentage Covered / Total
🔵 Lines 57.01% 21527 / 37760
🔵 Statements 56.94% 21904 / 38465
🔵 Functions 50.14% 4858 / 9688
🔵 Branches 50.09% 11074 / 22108
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
frontend/src/components/editor/Output.tsx 59.3% 52.22% 46.66% 59.3% 96, 105, 135-136, 167-171, 178-244, 266-337, 378, 417, 444, 460-481
frontend/src/components/ui/fullscreen.tsx 54.68% 45.83% 62.5% 54.68% 25, 82-101, 111, 135-154, 162, 179-196
frontend/src/hooks/useEventListener.ts 100% 100% 100% 100%
Generated in workflow #21223 for commit b625d05 by the Vitest Coverage Report Action

Track the fullscreen element in a single document listener and give each caller a boolean, so a fullscreen transition no longer scales with the number of cell outputs.
mscolnick
mscolnick previously approved these changes Sep 9, 2026
const isFullscreen = useIsFullScreen(containerRef);

// Not every host exits fullscreen on Escape by itself.
useEffect(() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we should have a useEventListener(document, () …) that may DRY this up only slightly

Widen the Document overload to accept null so that the hook can take a conditional target, then replace the hand-written effect with it.
@kirangadhave
kirangadhave merged commit f596e6b into main Sep 9, 2026
29 checks passed
@kirangadhave
kirangadhave deleted the kg/fullscreen-exit-button branch September 9, 2026 19:26

This branch was successfully deployed

1 active deployment
Preview — b625d055 Deployed Sep 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No UI option to return when in full screen on a cell output

3 participants