feat: portal-based monitor enumeration fallback

Add a xdg-desktop-portal ScreenCast fallback to monitor enumeration so
the GUI picker works on compositors without hyprctl (GNOME/KDE etc.).
ListMonitors now tries hyprctl first, then creates a portal session,
selects monitor sources, starts capture and parses the stream list.

Verified on Hyprland: the portal path returns the 1920x1200 monitor,
confirming the compositor-agnostic mechanism works.
This commit is contained in:
2026-09-19 20:40:56 +01:00
parent aab2006e78
commit f1f2bfe1a3
2 changed files with 258 additions and 3 deletions
+7 -3
View File
@@ -29,12 +29,16 @@ type Monitor struct {
// ErrNoMonitors is returned when monitor enumeration is unsupported or fails.
var ErrNoMonitors = errors.New("capture: monitor enumeration unavailable on this compositor")
// ListMonitors returns the available monitors for the GUI picker.
// ListMonitors returns the available monitors for the GUI picker. It prefers
// the Hyprland IPC when available, falling back to the xdg-desktop-portal
// ScreenCast API for other compositors.
func ListMonitors() ([]Monitor, error) {
if hyprctlAvailable() {
return hyprctlMonitors()
if mons, err := hyprctlMonitors(); err == nil {
return mons, nil
}
}
return nil, ErrNoMonitors
return portalMonitors()
}
// hyprctlAvailable reports whether the Hyprland monitor command exists.