Skip to content

Conversation

Copy link

Copilot AI commented Dec 25, 2025

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 causing TypeError: Permissions check failed.

Changes

js/multi-monitor.js

  • Removed canvas.requestFullscreen() call in handleChildFullscreenRequest() that was triggered by broadcast message
  • Replaced with console guidance prompting users to double-click each window
  • Added documentation explaining browser security restrictions

js/fullscreen.js

  • Wrapped all fullscreen requests in try-catch with promise rejection handlers
  • Added user guidance for multi-monitor setups requiring manual fullscreen activation per window

MULTI_MONITOR.md

  • Added "Browser Security Restrictions" section documenting user gesture requirements
  • Updated usage instructions to clarify manual double-click needed for each child window

Technical Context

User gestures do not "transfer" across:

  • Asynchronous operations (timers, promises)
  • Message passing (postMessage, BroadcastChannel)
  • Network responses

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).

// Before: Violates security policy
channel.addEventListener("message", (event) => {
  if (event.data.type === "requestFullscreen") {
    canvas.requestFullscreen(); // ❌ Not a user gesture
  }
});

// After: Respects security policy
channel.addEventListener("message", (event) => {
  if (event.data.type === "requestFullscreen") {
    console.log("Double-click the window to enter fullscreen mode."); // ✅
  }
});

Matrix rendering correctly without fullscreen errors

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.

Copilot AI and others added 2 commits December 25, 2025 20:32
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>
Copilot AI changed the title [WIP] Fix fullscreen issue caused by lack of user gesture Remove programmatic fullscreen requests that violate browser security policies Dec 25, 2025
Copilot AI requested a review from ap0ught December 25, 2025 20:36
@ap0ught ap0ught marked this pull request as ready for review December 25, 2025 20:49
Copilot AI review requested due to automatic review settings December 25, 2025 20:49
@github-actions
Copy link

🎬 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

@ap0ught ap0ught merged commit ae9f914 into master Dec 25, 2025
9 checks passed
@ap0ught ap0ught deleted the copilot/fix-fullscreen-issue branch December 25, 2025 20:52
Copy link

Copilot AI left a 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

Comment on lines +191 to +226
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);
}
Copy link

Copilot AI Dec 25, 2025

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.

Copilot uses AI. Check for mistakes.
Copy link

@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.

ℹ️ 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".

Comment on lines +190 to +192
// Request fullscreen on main window
try {
const result = requestFullscreen(element);

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

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.

issue with fullscreen

2 participants