Skip to content

Comments

Better Picture in Picture Functionality#22

Merged
iamEvanYT merged 5 commits intomainfrom
evan/auto-picture-in-picture
Apr 17, 2025
Merged

Better Picture in Picture Functionality#22
iamEvanYT merged 5 commits intomainfrom
evan/auto-picture-in-picture

Conversation

@iamEvanYT
Copy link
Member

@iamEvanYT iamEvanYT commented Apr 17, 2025

Summary by CodeRabbit

  • New Features

    • Added automatic Picture-in-Picture (PiP) mode for video content when a tab becomes invisible, and automatic exit from PiP when the tab becomes visible again.
    • Introduced the ability to manually disable Picture-in-Picture mode for individual tabs.
    • Tabs now display their current Picture-in-Picture status.
  • Enhancements

    • The application window now opens maximized by default.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 17, 2025

Walkthrough

A Picture-in-Picture (PiP) mode feature has been introduced and integrated into the tab management system. The Tab class now tracks PiP state with a new boolean property and manages entering or exiting PiP mode based on tab visibility. The TabManager class provides a method to programmatically disable PiP mode for a given tab. IPC mechanisms and API interfaces have been updated to expose this functionality across process boundaries, and the tab data structures now include the PiP state. Additionally, the browser window is set to maximize by default upon creation.

Changes

File(s) Change Summary
electron/browser/tabs/tab.ts Added isPictureInPicture property and logic to enter/exit PiP mode based on tab visibility.
electron/browser/tabs/tab-manager.ts Added disablePictureInPicture(tabId) and getTabByWebContents(webContents) methods to manage PiP state.
electron/ipc/browser/tabs.ts Extended getTabData to include isPictureInPicture; added IPC handler for disabling PiP mode.
electron/preload.ts Added disablePictureInPicture() method to tabsAPI, allowing tabs to request PiP mode disable via IPC.
shared/types/tabs.ts Extended TabData type with isPictureInPicture property.
vite/src/lib/flow/interfaces/browser/tabs.ts Added disablePictureInPicture() method to FlowTabsAPI interface.
electron/browser/window.ts Modified window initialization to maximize by default and made minor import/formatting adjustments.

Sequence Diagram(s)

sequenceDiagram
    participant Renderer
    participant Preload
    participant MainProcess
    participant TabManager
    participant Tab

    Renderer->>Preload: tabsAPI.disablePictureInPicture()
    Preload->>MainProcess: IPC "tabs:disable-picture-in-picture"
    MainProcess->>TabManager: disablePictureInPicture(tabId)
    TabManager->>Tab: (if PiP) set isPictureInPicture = false, emit "updated", set active
    TabManager->>MainProcess: Return true/false
    MainProcess->>Preload: Return result
    Preload->>Renderer: Return result
Loading
sequenceDiagram
    participant Tab
    participant WebContents

    Note over Tab: On visibility change
    Tab->>WebContents: executeJavaScript (enter/exit PiP)
    WebContents-->>Tab: Result (success/failure)
    Tab->>Tab: Update isPictureInPicture, emit "updated"
Loading

Poem

In a warren of tabs, a new trick appears,
Picture-in-Picture now hops with our peers!
With a flick of a paw, you can pop out the view,
Or tuck it back in—just a click will do.
From window to tab, the features expand,
This bunny’s PiP magic is now close at hand!
🐇✨

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bed23b4 and ab9255e.

📒 Files selected for processing (3)
  • electron/browser/tabs/tab-manager.ts (3 hunks)
  • electron/browser/tabs/tab.ts (2 hunks)
  • electron/ipc/browser/tabs.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • electron/ipc/browser/tabs.ts
  • electron/browser/tabs/tab.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
electron/browser/tabs/tab-manager.ts (1)
electron/browser/tabs/tab.ts (1)
  • Tab (83-713)
🪛 Biome (1.9.4)
electron/browser/tabs/tab-manager.ts

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (3)
electron/browser/tabs/tab-manager.ts (3)

9-9: Clean import of WebContents from Electron

The WebContents import is correctly added to support the new tab lookup functionality.


194-208: Well-implemented PiP disabling functionality

This method successfully handles disabling Picture-in-Picture mode and activating the tab when needed. The implementation follows the class's patterns and includes proper documentation.

Note that the static analysis suggestion to use an optional chain here is a false positive - the current implementation correctly checks both tab existence and PiP state.

🧰 Tools
🪛 Biome (1.9.4)

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


442-452: Good implementation of tab lookup by WebContents

This helper method provides a clean way to find tabs based on their WebContents instance, which is essential for the Picture-in-Picture functionality. The iteration through all tabs is appropriate since there's no direct mapping from WebContents to tabs.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@iamEvanYT iamEvanYT marked this pull request as ready for review April 17, 2025 23:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
electron/browser/window.ts (1)

76-77: User experience change: Windows now open maximized by default

This change makes all browser windows maximize immediately upon creation, which changes the default user experience. While this may enhance the Picture-in-Picture functionality, consider:

  1. Is this behavior desirable for all users and scenarios?
  2. Should this be a configurable setting rather than a hard-coded behavior?
  3. Should the window size/state be persisted between sessions?

Consider making window maximization behavior configurable:

+ import { getSettings } from "@/saving/settings";

  constructor(browser: Browser, type: BrowserWindowType, options: BrowserWindowCreationOptions = {}) {
    // ...existing code...
    
    this.window = new BrowserWindow({
      // ...existing options...
    });

-   this.window.maximize();
+   // Maximize window based on settings or default behavior
+   getSettings().then(settings => {
+     if (settings.window?.startMaximized !== false) {
+       this.window.maximize();
+     }
+   }).catch(() => {
+     // Fall back to maximized if settings can't be loaded
+     this.window.maximize();
+   });

    // ...rest of constructor...
  }
electron/browser/tabs/tab-manager.ts (1)

193-207: Use optional‑chaining & minimal guard logic

The null‑check on tab can be simplified with optional‑chaining, which also satisfies the Biome useOptionalChain lint error flagged at this location.

-    const tab = this.getTabById(tabId);
-    if (tab && tab.isPictureInPicture) {
+    const tab = this.getTabById(tabId);
+    if (tab?.isPictureInPicture) {
       tab.isPictureInPicture = false;
       tab.emit("updated");

       this.setActiveTab(tab);

       return true;
     }
     return false;

Besides tidier code, this avoids accidentally dereferencing undefined if the method is called after the tab has been removed.

🧰 Tools
🪛 Biome (1.9.4)

[error] 198-198: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

electron/ipc/browser/tabs.ts (1)

170-173: browser?.tabs may still be undefined – add an extra optional‑chain

If, for any reason, the Browser instance exists but its tabs manager has not been initialised, the current code will attempt to read disablePictureInPicture on undefined and throw. A single character fixes the edge‑case:

-  const disabled = browser?.tabs.disablePictureInPicture(tabId);
+  const disabled = browser?.tabs?.disablePictureInPicture(tabId);

Returning false on failure (as you already do) is then guaranteed.

electron/browser/tabs/tab.ts (2)

100-104: Public flag added — consider initial sync on construction

isPictureInPicture defaults to false, but if the tab happens to load a page that is already in PiP before the first layout pass, the flag could be out‑of‑sync.
Not critical, yet initialising by interrogating document.pictureInPictureElement once after did-finish-load would make the state authoritative.


512-537: Exiting PiP: race‑condition & leakage of inline function

  1. exitPiP is re‑created on every visibility change; extracting it to a const outside updateLayout (or to a private static) avoids needless re‑allocations.
  2. Because executeJavaScript is asynchronous, the tab could flip visibility again before the promise settles, leaving isPictureInPicture briefly incorrect. Awaiting it (or storing a local visibleAtCallTime flag) would prevent the mismatch.

No functional bug today, but the above would make the state handling more robust.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8685875 and 2668f49.

📒 Files selected for processing (7)
  • electron/browser/tabs/tab-manager.ts (1 hunks)
  • electron/browser/tabs/tab.ts (2 hunks)
  • electron/browser/window.ts (3 hunks)
  • electron/ipc/browser/tabs.ts (2 hunks)
  • electron/preload.ts (1 hunks)
  • shared/types/tabs.ts (1 hunks)
  • vite/src/lib/flow/interfaces/browser/tabs.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
electron/ipc/browser/tabs.ts (1)
electron/index.ts (1)
  • browser (9-9)
🪛 Biome (1.9.4)
electron/browser/tabs/tab-manager.ts

[error] 198-198: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (5)
shared/types/tabs.ts (1)

13-13: Appropriate type addition for PiP state tracking

The addition of the isPictureInPicture boolean property to the TabData type is well-placed and properly typed. This follows the existing pattern of using boolean flags with the is prefix to track tab states.

vite/src/lib/flow/interfaces/browser/tabs.ts (1)

37-41: Well-documented API method for disabling PiP mode

The disablePictureInPicture method is appropriately added to the interface with proper typing and comprehensive JSDoc documentation. It correctly follows the pattern of other API methods, taking a tab ID and returning a Promise with a boolean result.

electron/browser/window.ts (2)

10-10: Minor syntactic improvement

Adding a semicolon to the import statement follows JavaScript/TypeScript best practices.


54-54: Removed trailing comma

Removal of the trailing comma in the object literal is a minor syntactic improvement.

electron/ipc/browser/tabs.ts (1)

20-22: 👍 Property forwarded correctly

isPictureInPicture is now included in the serialized TabData. No issues spotted.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2668f49 and bed23b4.

📒 Files selected for processing (3)
  • electron/ipc/browser/tabs.ts (2 hunks)
  • electron/preload.ts (1 hunks)
  • vite/src/lib/flow/interfaces/browser/tabs.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • vite/src/lib/flow/interfaces/browser/tabs.ts
  • electron/preload.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
electron/ipc/browser/tabs.ts (1)
electron/index.ts (1)
  • browser (9-9)
🪛 Biome (1.9.4)
electron/ipc/browser/tabs.ts

[error] 175-175: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🔇 Additional comments (1)
electron/ipc/browser/tabs.ts (1)

20-20: LGTM: Properly exposing PiP state in the tab data structure

The addition of the isPictureInPicture property to the tab data structure is a clean implementation that correctly exposes the Picture-in-Picture state from the Tab object to the renderer process.

@iamEvanYT iamEvanYT merged commit bdff9ad into main Apr 17, 2025
1 check passed
@iamEvanYT iamEvanYT deleted the evan/auto-picture-in-picture branch April 17, 2025 23:37
@coderabbitai coderabbitai bot mentioned this pull request May 13, 2025
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.

1 participant