-
Notifications
You must be signed in to change notification settings - Fork 0
Remove programmatic fullscreen requests that violate browser security policies #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Remove programmatic fullscreen requests that violate browser security policies. Child windows can no longer enter fullscreen automatically via BroadcastChannel as this is not considered a user gesture. Users must double-click each window to enter fullscreen mode. Co-authored-by: ap0ught <41078+ap0ught@users.noreply.github.com>
Add detailed documentation about browser security policies that prevent programmatic fullscreen requests. Clarify that users must manually double-click each child window to enter fullscreen mode. Co-authored-by: ap0ught <41078+ap0ught@users.noreply.github.com>
🎬 PR Preview Deployed!Your changes are now available for testing: Preview URL: https://ap0ught.github.io/matrix/pr-79/ Test Links:The preview will be updated automatically when you push new commits. Preview deployed from commit 7f8d332 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR resolves browser security policy violations by removing programmatic fullscreen requests that are not triggered by direct user gestures. The main issue was that child windows in multi-monitor mode were attempting to enter fullscreen via BroadcastChannel message passing, which breaks the user gesture chain and causes "TypeError: Permissions check failed" errors.
Key Changes:
- Removed programmatic
requestFullscreen()call in child windows triggered by broadcast messages - Added comprehensive error handling with try-catch blocks and promise rejection handlers for all fullscreen requests
- Updated documentation to explain browser security restrictions and clarify that users must manually double-click each child window
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
js/multi-monitor.js |
Removed programmatic fullscreen request from handleChildFullscreenRequest() and replaced with console guidance; added documentation explaining browser security restrictions |
js/fullscreen.js |
Wrapped all three fullscreen request locations with try-catch blocks and promise rejection handlers to prevent uncaught errors |
MULTI_MONITOR.md |
Added comprehensive "Browser Security Restrictions" section documenting user gesture requirements; updated usage instructions throughout to clarify manual double-click requirement for child windows |
| try { | ||
| const result = requestFullscreen(element); | ||
| if (result && result.catch) { | ||
| result.catch((error) => { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| } | ||
| } else { | ||
| // Fall back to single-screen fullscreen | ||
| console.warn("Multi-monitor fullscreen failed, falling back to single screen"); | ||
| requestFullscreen(element); | ||
| try { | ||
| const result = requestFullscreen(element); | ||
| if (result && result.catch) { | ||
| result.catch((error) => { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| } | ||
| } | ||
| } else { | ||
| // Normal single-screen fullscreen | ||
| requestFullscreen(element); | ||
| try { | ||
| const result = requestFullscreen(element); | ||
| if (result && result.catch) { | ||
| result.catch((error) => { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| console.error("Fullscreen request failed:", error.message); | ||
| } |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error handling pattern for fullscreen requests is duplicated three times with identical code blocks. This violates the DRY (Don't Repeat Yourself) principle and makes the code harder to maintain.
Consider extracting this into a helper function within the setupFullscreenToggle scope:
const safeRequestFullscreen = (element) => {
try {
const result = requestFullscreen(element);
if (result && result.catch) {
result.catch((error) => {
console.error("Fullscreen request failed:", error.message);
});
}
} catch (error) {
console.error("Fullscreen request failed:", error.message);
}
};Then replace all three occurrences (lines 191-200, 204-213, 217-226) with calls to this helper function.
There was a problem hiding this 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.
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Request fullscreen on main window | ||
| try { | ||
| const result = requestFullscreen(element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid requesting fullscreen after an awaited spawn
This requestFullscreen runs only after await multiMonitorManager.spawnWindows(...) earlier in the same double‑click handler. The updated docs in MULTI_MONITOR.md explicitly note that user gestures don’t survive async operations/promises, so the browser will reject this call (Permissions check failed) and the main window never enters fullscreen in multi‑monitor mode. Users then can’t fullscreen the main window without re-triggering the flow (which re-spawns windows). Consider issuing the fullscreen request before the awaited work or requiring a second, dedicated user gesture for the main window.
Useful? React with 👍 / 👎.
Browser security policies require
requestFullscreen()to be invoked in direct response to user gestures. The multi-monitor implementation was attempting to trigger fullscreen via BroadcastChannel message passing, breaking the user gesture chain and causingTypeError: Permissions check failed.Changes
js/multi-monitor.jscanvas.requestFullscreen()call inhandleChildFullscreenRequest()that was triggered by broadcast messagejs/fullscreen.jsMULTI_MONITOR.mdTechnical Context
User gestures do not "transfer" across:
postMessage,BroadcastChannel)Main window can enter fullscreen on double-click (direct user gesture), but child windows cannot via broadcast message (not a user gesture in their context).
Original prompt
This section details on the original issue you should resolve
<issue_title>issue with fullscreen</issue_title>
<issue_description>Matrix screensaver mode started
holoplaycore.module.js:492 WebSocket connection to 'ws://localhost:11222/driver' failed:
openWebsocket @ holoplaycore.module.js:492
Client @ holoplaycore.module.js:466
device @ lkgHelper.js:80
default @ lkgHelper.js:78Understand this error
matrix/?version=holoplay&effect=stripes:1 Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.Understand this warningExplanationUnderstanding the problemThe error message "Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture" indicates that your code is attempting to put an element into fullscreen mode without direct user interaction. Modern web browsers prevent requestFullscreen() from being called programmatically (e.g., on page load, after a timer) to protect users from malicious or intrusive websites that might force them into an unwanted fullscreen experience.How to verifyTo verify this, you can check your code for calls to element.requestFullscreen() that are not directly nested within event handlers for user interactions like click, keydown, touchend, etc. For example, if requestFullscreen() is called immediately after a page loads or as part of an asynchronous operation not triggered by a user, it will fail.Suggested fixEnsure that the requestFullscreen() method is called only in response to a direct user action. Wrap the call to requestFullscreen() within an event listener for a user-initiated event.Example of incorrect usage (will cause the error):jsUse code snippets with cautionExample of correct usage:jsUse code snippets with cautionExplanation for the fix:
In the corrected example, the requestFullscreen() call is placed inside a click event listener for a button. This ensures that the fullscreen request is initiated by a user gesture, satisfying the browser's security requirements. It's also good practice to include a .catch() block to handle potential errors during the fullscreen request, as well as vendor prefixes for broader browser compatibility.SummaryThe "API can only be initiated by a user gesture" error for requestFullscreen() means you're trying to activate fullscreen without a direct user action. The fix is to ensure requestFullscreen() is called within an event handler triggered by an explicit user interaction (e.g., a click).Data used to understand this messageConsole messageUse search insteadAI tools may generate inaccurate info that doesn't represent Google's views. Data sent to Google may be seen by human reviewers to improve this feature. Open settings or learn more
matrix/?version=holo…ay&effect=stripes:1 Uncaught (in promise) TypeError: Permissions check failedUnderstand this errorExplanationThe error message Uncaught (in promise) TypeError: Permissions check failed indicates that a JavaScript operation that requires specific user or system permissions was attempted but failed because those permissions were not granted or available. This error is "uncaught in promise" because the operation was likely asynchronous (returned a Promise) and the rejection of that Promise was not handled by a catch block.Understanding the problemThis error typically occurs when your web application tries to access a "powerful feature" of the browser or operating system without the necessary authorization. Modern web browsers prioritize user security and privacy, requiring explicit user consent before certain functionalities can be used.Common scenarios that trigger this error include:Accessing Sensitive APIs: APIs like Geolocation, Camera, Microphone, Notifications, Clipboard, or Fullscreen often require user permission. If the user denies permission, or if the permission hasn't been explicitly granted, attempts to use these APIs will result in a permissions check failure.Missing User Gesture: Some operations, especially those that might be intrusive (like entering fullscreen mode or opening pop-up windows), can only be initiated by a direct user action (a "user gesture" like a click or keypress). If your code tries to trigger such an action programmatically without a preceding user gesture, the browser will block it and a permissions check might fail.Permissions Policy / Feature Policy Restrictions: Web servers can send Permissions-Policy (formerly Feature-Policy) HTTP headers that restrict what features are available to the document and its embedded iframes. If a feature is disallowed by this policy, attempts to use it will fail with a TypeError.Sandbox Restrictions: If your code is running within a sandboxed iframe, it might have limited permissions, preventing certain operations.Browser/OS-level Restrictions: In some cases, the browser itself or the underlying operating system might have settings or policies that prevent certain permissions from being granted to web content. For example, enterprise po...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.