Skip to content

feat(screensharing): list and share minimized windows on Windows - #1825

Open
vladopol wants to merge 1 commit into
nextcloud:mainfrom
vladopol:feat/screenshare-minimized-windows
Open

feat(screensharing): list and share minimized windows on Windows#1825
vladopol wants to merge 1 commit into
nextcloud:mainfrom
vladopol:feat/screenshare-minimized-windows

Conversation

@vladopol

Copy link
Copy Markdown

On Windows, minimized (iconic) windows are missing from the "Choose what to share" picker: Chromium/WebRTC omits them from desktopCapturer.getSources() because a minimized window isn't rendered and can't produce frames (#1788). This especially hurts full-screen Remote Desktop windows, which have to be minimized to reach Talk — and then vanish from the picker.

This enumerates top-level windows natively and adds the minimized ones the capturer omits. On selection the window is restored so WebRTC can capture it, then sharing starts — the approach @ShGKme suggested in #1788 (enumerate via the Windows API, then activate the window like Zoom).

What it does

  • Native enumeration via user32 (koffi FFI): EnumWindows with the standard Alt‑Tab filter (visible, unowned, not a tool window, has a title, not DWM‑cloaked).
  • Minimized windows are added to Application windows with a Minimized badge and the window's own icon — read from the window via WM_GETICON (with a timeout so an unresponsive window can't block the picker) and converted from its HICON, matching the icon Windows shows in the taskbar and the one desktopCapturer provides for non‑minimized windows. No live preview — they have no frames until restored.
  • On Share screen, the window is restored (ShowWindowAsync(SW_RESTORE) + SetForegroundWindow) before capture. Electron encodes the HWND in the window sourceId (window:<HWND>:0), so it stays valid after restoring.
  • Windows‑only; no‑ops on macOS/Linux.

Dependency

Adds koffi (MIT, prebuilt — no node‑gyp/compilation). It is loaded lazily and only on Windows; kept out of the webpack bundle (external) and packaged for the target win32 arch only via a packageAfterCopy hook, with its .node unpacked from the asar archive. It is not shipped on macOS/Linux.

Testing

Verified on Windows 10 and 11 as a normal user: minimized windows (including Remote Desktop and non‑ASCII titles) are listed with the correct window icon, restore correctly on Share, and stream. Non‑minimized sharing is unchanged. ts:check and eslint pass.

Notes

  • Capturing a window requires it to be un‑minimized; this restores it on selection, so the shared window briefly comes to the foreground (as Zoom does).
  • When only a couple of windows are open, the dialog shows some empty space below the list — that is NcDialog's minimum content height, not specific to this change.

Closes #1788

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

On Windows, Chromium/WebRTC omits minimized (iconic) windows from
desktopCapturer.getSources() because they are not rendered and cannot
produce frames. They are therefore missing from the "Choose what to
share" picker, which is especially painful for full-screen Remote
Desktop windows that have to be minimized to reach Talk.

Enumerate top-level windows natively via user32 (koffi FFI) and add the
minimized ones that desktopCapturer omits, shown with a "Minimized"
badge, the window's own icon and no live preview. When such a window is
selected, restore it (ShowWindowAsync + SetForegroundWindow) so WebRTC
can capture it, then start sharing - the approach suggested in nextcloud#1788.

The icon is read from the window itself (WM_GETICON / class icon) and
converted from its HICON via GDI, matching the icon Windows shows in the
taskbar and the one desktopCapturer provides for non-minimized windows.

koffi is a prebuilt, MIT-licensed FFI module. It is loaded lazily and
only on Windows, kept out of the webpack bundle and packaged for win32
only via a packageAfterCopy hook, with its .node unpacked from the asar
archive.

Signed-off-by: Vladimir Poluliashenko <vladopol@gmail.com>
@vladopol
vladopol force-pushed the feat/screenshare-minimized-windows branch from 66d39d6 to 3048ddb Compare August 10, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Minimized windows not listed in screen sharing picker on Windows

1 participant