Skip to content

Commit de284aa

Browse files
hristoterezovsaghul
authored andcommitted
feat(api): replace always-on-top with native picture-in-picture
BREAKING CHANGE: Removed setupAlwaysOnTopMain, setupAlwaysOnTopRender, and cleanupAlwaysOnTopMain exports. Applications using these APIs must migrate to setupPictureInPictureMain and setupPictureInPictureRender. Replace custom always-on-top window implementation with browser's native picture-in-picture API to provide a lighter-weight solution with better OS integration. The native PiP eliminates the need for custom window management code, reduces maintenance overhead, and provides users with a familiar, OS-native experience for keeping the active speaker visible while multitasking. The new implementation: - Uses Electron's userGesture privileges to bypass transient activation requirements - Communicates between renderer and main process via IPC - Requires minimal setup compared to the previous custom window approach - Leverages browser's built-in PiP capabilities for better performance Version bumped to 8.0.0 due to breaking API changes.
1 parent 711671c commit de284aa

File tree

18 files changed

+202
-1197
lines changed

18 files changed

+202
-1197
lines changed

CLAUDE.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ The SDK is organized into feature-based modules that expose both **main process*
3838
index.js (main export)
3939
├── remotecontrol/ # Remote desktop control via robotjs
4040
├── screensharing/ # Screen sharing with desktop picker and tracker
41-
├── alwaysontop/ # Floating active speaker window
41+
├── pip/ # Picture-in-picture for active speaker video
4242
├── powermonitor/ # System idle and power events
4343
├── popupsconfig/ # Popup window configuration registry
4444
├── node_addons/ # Native C++ addons (Windows only)
@@ -69,11 +69,12 @@ Custom screen/window picker and sharing tracker:
6969
- Special handling for Wayland (uses native picker) and macOS (permission checks)
7070
- `screenSharingTracker.js`: Small always-visible window showing "X is sharing your screen"
7171

72-
#### Always On Top (`alwaysontop/`)
73-
Floating window showing active speaker when main window loses focus:
74-
- Uses Chrome's window.open implementation (requires `nativeWindowOpen: true`)
75-
- Window identified by `frameName: 'AlwaysOnTop'`
76-
- EventEmitter API with `dismissed` and `will-close` events
72+
#### Picture in Picture (`pip/`)
73+
Browser native picture-in-picture functionality for active speaker video:
74+
- `setupPictureInPictureMain`: Runs in main process, handles IPC requests and executes PiP with userGesture privileges
75+
- `setupPictureInPictureRender`: Runs in renderer, listens for `_pipRequested` events from Jitsi Meet iframe API
76+
- Uses IPC channel `jitsi-pip-channel` for communication between processes
77+
- Bypasses transient activation requirements by executing PiP from main process
7778

7879
#### Power Monitor (`powermonitor/`)
7980
Queries system idle state and power events:

README.md

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -81,47 +81,39 @@ const {
8181
setupScreenSharingMain(mainWindow, appName, osxBundleId);
8282
```
8383

84+
#### Picture in Picture
8485

85-
#### Always On Top
86-
Displays a small window with the current active speaker video when the main Jitsi Meet window is not focused.
86+
Enables the browser's native picture-in-picture functionality for the active speaker video. This allows users to keep the active speaker video visible in a floating window while using other applications.
8787

8888
**Requirements**:
89-
1. Jitsi Meet should be initialized through our [iframe API](https://github.com/jitsi/jitsi-meet/blob/master/doc/api.md)
90-
2. The `BrowserWindow` instance where Jitsi Meet is displayed should use the [Chrome's window.open implementation](https://github.com/electron/electron/blob/master/docs/api/window-open.md#using-chromes-windowopen-implementation) (set `nativeWindowOpen` option of `BrowserWindow`'s constructor to `true`).
91-
3. If you have a custom handler for opening windows you have to filter the always on top window. You can do this by its `frameName` argument which will be set to `AlwaysOnTop`.
89+
1. Jitsi Meet should be initialized through the [iframe API](https://github.com/jitsi/jitsi-meet/blob/master/doc/api.md)
90+
2. The feature requires Electron's main process to execute the PiP request with userGesture privileges to bypass browser security restrictions
9291

93-
**Enable the aways on top:**
92+
**Enable picture in picture:**
9493

9594
In the **main** electron process:
95+
9696
```Javascript
9797
const {
98-
setupAlwaysOnTopMain
98+
setupPictureInPictureMain
9999
} = require("@jitsi/electron-sdk");
100100

101-
// jitsiMeetWindow - The BrowserWindow instance
102-
// of the window where Jitsi Meet is loaded.
103-
setupAlwaysOnTopMain(jitsiMeetWindow);
101+
// jitsiMeetWindow - The BrowserWindow instance where Jitsi Meet is loaded.
102+
// loggerTransports - Optional array of logger transports for configuring the logger.
103+
const pipMain = setupPictureInPictureMain(jitsiMeetWindow, loggerTransports);
104104
```
105105

106106
In the **render** electron process of the window where Jitsi Meet is displayed:
107+
107108
```Javascript
108109
const {
109-
setupAlwaysOnTopRender
110+
setupPictureInPictureRender
110111
} = require("@jitsi/electron-sdk");
111112

112113
const api = new JitsiMeetExternalAPI(...);
113-
const alwaysOnTop = setupAlwaysOnTopRender(api);
114-
115-
alwaysOnTop.on('will-close', handleAlwaysOnTopClose);
114+
const pipRender = setupPictureInPictureRender(api);
116115
```
117116

118-
`setupAlwaysOnTopRender` return an instance of EventEmitter with the following events:
119-
120-
* _dismissed_ - emitted when the always on top window is explicitly dismissed via its close button
121-
122-
* _will-close_ - emitted right before the always on top window is going to close
123-
124-
125117
#### Power Monitor
126118

127119
Provides a way to query electron for system idle and receive power monitor events.
@@ -148,12 +140,6 @@ const api = new JitsiMeetExternalAPI(...);
148140
setupPowerMonitorRender(api);
149141
```
150142

151-
### NOTE:
152-
You'll need to add 'disable-site-isolation-trials' switch because of [https://github.com/electron/electron/issues/18214](https://github.com/electron/electron/issues/18214):
153-
```
154-
app.commandLine.appendSwitch('disable-site-isolation-trials')
155-
```
156-
157143
## Example
158144

159145
For examples of installation and usage checkout the [Jitsi Meet Electron](https://github.com/jitsi/jitsi-meet-electron) project.

alwaysontop/constants.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

alwaysontop/index.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

alwaysontop/main/config.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)