Repository navigation
fix: add an exit control to fullscreen cell output - #10769
Conversation
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
There was a problem hiding this comment.
🟡 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
Escapekey 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.fullscreenElementanddocument.exitFullscreenviaObject.defineProperty(...)but never restores them, which can leak mocked behavior into other test files (the global test setup only callsvi.clearAllMocks(), which won’t revert property descriptors). Capture the original descriptors and restore them inafterAll.
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.
State why the output carries its own exit control without naming a specific embedded browser.
There was a problem hiding this comment.
All reported issues were addressed
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Delete the fullscreen property stubs in afterEach so that later tests in the file see the real document.
Coverage Report for ./frontend
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||
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.
| const isFullscreen = useIsFullScreen(containerRef); | ||
|
|
||
| // Not every host exits fullscreen on Escape by itself. | ||
| useEffect(() => { |
There was a problem hiding this comment.
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.
📝 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