From dfef65c30fac557db6ba016112aad006fadac0db Mon Sep 17 00:00:00 2001 From: tytan652 Date: Thu, 18 Apr 2024 13:41:34 +0200 Subject: [PATCH] linux-pipewire: Unify ScreenCast sources as Screen Capture Allow to select both main type of ScreenCast (monitor, window) with only one source type rather than adding a source type per ScreenCast type. This change is made as a new Screen Capture source type which obsoletes the use of the previous Screen Capture (monitor-only) and Window Capture. --- plugins/linux-pipewire/data/locale/en-US.ini | 1 + plugins/linux-pipewire/screencast-portal.c | 87 +++++++++++++++----- 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/plugins/linux-pipewire/data/locale/en-US.ini b/plugins/linux-pipewire/data/locale/en-US.ini index d73ce8f61..f7482bc54 100644 --- a/plugins/linux-pipewire/data/locale/en-US.ini +++ b/plugins/linux-pipewire/data/locale/en-US.ini @@ -6,6 +6,7 @@ PipeWireDesktopCapture="Screen Capture (PipeWire)" PipeWireSelectMonitor="Select Monitor" PipeWireSelectWindow="Select Window" PipeWireWindowCapture="Window Capture (PipeWire)" +PipeWireSelectScreenCast="Open Selector" Resolution="Resolution" ShowCursor="Show Cursor" VideoFormat="Video Format" diff --git a/plugins/linux-pipewire/screencast-portal.c b/plugins/linux-pipewire/screencast-portal.c index 0a1ff2118..a5cdec726 100644 --- a/plugins/linux-pipewire/screencast-portal.c +++ b/plugins/linux-pipewire/screencast-portal.c @@ -35,8 +35,15 @@ enum portal_cursor_mode { PORTAL_CURSOR_MODE_METADATA = 1 << 2, }; +enum obs_portal_capture_type { + OBS_PORTAL_CAPTURE_TYPE_MONITOR = PORTAL_CAPTURE_TYPE_MONITOR, + OBS_PORTAL_CAPTURE_TYPE_WINDOW = PORTAL_CAPTURE_TYPE_WINDOW, + OBS_PORTAL_CAPTURE_TYPE_UNIFIED = PORTAL_CAPTURE_TYPE_MONITOR | + PORTAL_CAPTURE_TYPE_WINDOW, +}; + struct screencast_portal_capture { - enum portal_capture_type capture_type; + enum obs_portal_capture_type capture_type; GCancellable *cancellable; @@ -139,18 +146,19 @@ static uint32_t get_screencast_version(void) /* ------------------------------------------------- */ -static const char *capture_type_to_string(enum portal_capture_type capture_type) +static const char * +capture_type_to_string(enum obs_portal_capture_type capture_type) { switch (capture_type) { - case PORTAL_CAPTURE_TYPE_MONITOR: - return "desktop"; - case PORTAL_CAPTURE_TYPE_WINDOW: + case OBS_PORTAL_CAPTURE_TYPE_MONITOR: + return "monitor"; + case OBS_PORTAL_CAPTURE_TYPE_WINDOW: return "window"; - case PORTAL_CAPTURE_TYPE_VIRTUAL: + case OBS_PORTAL_CAPTURE_TYPE_UNIFIED: + return "monitor and window"; default: return "unknown"; } - return "unknown"; } /* ------------------------------------------------- */ @@ -285,8 +293,7 @@ static void on_start_response_received_cb(GVariant *parameters, void *user_data) obs_source_save(capture->source); } - blog(LOG_INFO, "[pipewire] %s selected, setting up screencast", - capture_type_to_string(capture->capture_type)); + blog(LOG_INFO, "[pipewire] source selected, setting up screencast"); open_pipewire_remote(capture); } @@ -582,7 +589,7 @@ static void *screencast_portal_desktop_capture_create(obs_data_t *settings, struct screencast_portal_capture *capture; capture = bzalloc(sizeof(struct screencast_portal_capture)); - capture->capture_type = PORTAL_CAPTURE_TYPE_MONITOR; + capture->capture_type = OBS_PORTAL_CAPTURE_TYPE_MONITOR; capture->cursor_visible = obs_data_get_bool(settings, "ShowCursor"); capture->restore_token = bstrdup(obs_data_get_string(settings, "RestoreToken")); @@ -598,7 +605,24 @@ static void *screencast_portal_window_capture_create(obs_data_t *settings, struct screencast_portal_capture *capture; capture = bzalloc(sizeof(struct screencast_portal_capture)); - capture->capture_type = PORTAL_CAPTURE_TYPE_WINDOW; + capture->capture_type = OBS_PORTAL_CAPTURE_TYPE_WINDOW; + capture->cursor_visible = obs_data_get_bool(settings, "ShowCursor"); + capture->restore_token = + bstrdup(obs_data_get_string(settings, "RestoreToken")); + capture->source = source; + + init_screencast_capture(capture); + + return capture; +} + +static void *screencast_portal_capture_create(obs_data_t *settings, + obs_source_t *source) +{ + struct screencast_portal_capture *capture; + + capture = bzalloc(sizeof(struct screencast_portal_capture)); + capture->capture_type = OBS_PORTAL_CAPTURE_TYPE_UNIFIED; capture->cursor_visible = obs_data_get_bool(settings, "ShowCursor"); capture->restore_token = bstrdup(obs_data_get_string(settings, "RestoreToken")); @@ -657,13 +681,15 @@ static obs_properties_t *screencast_portal_capture_get_properties(void *data) obs_properties_t *properties; switch (capture->capture_type) { - case PORTAL_CAPTURE_TYPE_MONITOR: + case OBS_PORTAL_CAPTURE_TYPE_MONITOR: reload_string_id = "PipeWireSelectMonitor"; break; - case PORTAL_CAPTURE_TYPE_WINDOW: + case OBS_PORTAL_CAPTURE_TYPE_WINDOW: reload_string_id = "PipeWireSelectWindow"; break; - case PORTAL_CAPTURE_TYPE_VIRTUAL: + case OBS_PORTAL_CAPTURE_TYPE_UNIFIED: + reload_string_id = "PipeWireSelectScreenCast"; + break; default: return NULL; } @@ -744,21 +770,21 @@ void screencast_portal_load(void) (available_capture_types & PORTAL_CAPTURE_TYPE_WINDOW) != 0; if (available_capture_types == 0) { - blog(LOG_INFO, "[pipewire] No captures available"); + blog(LOG_INFO, "[pipewire] No capture sources available"); return; } - blog(LOG_INFO, "[pipewire] Available captures:"); + blog(LOG_INFO, "[pipewire] Available capture sources:"); if (desktop_capture_available) - blog(LOG_INFO, "[pipewire] - Desktop capture"); + blog(LOG_INFO, "[pipewire] - Monitor source"); if (window_capture_available) - blog(LOG_INFO, "[pipewire] - Window capture"); + blog(LOG_INFO, "[pipewire] - Window source"); // Desktop capture const struct obs_source_info screencast_portal_desktop_capture_info = { .id = "pipewire-desktop-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE, .get_name = screencast_portal_desktop_capture_get_name, .create = screencast_portal_desktop_capture_create, .destroy = screencast_portal_capture_destroy, @@ -780,7 +806,7 @@ void screencast_portal_load(void) const struct obs_source_info screencast_portal_window_capture_info = { .id = "pipewire-window-capture-source", .type = OBS_SOURCE_TYPE_INPUT, - .output_flags = OBS_SOURCE_VIDEO, + .output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE, .get_name = screencast_portal_window_capture_get_name, .create = screencast_portal_window_capture_create, .destroy = screencast_portal_capture_destroy, @@ -797,6 +823,27 @@ void screencast_portal_load(void) }; if (window_capture_available) obs_register_source(&screencast_portal_window_capture_info); + + // Screen capture (monitor and window) + const struct obs_source_info screencast_portal_capture_info = { + .id = "pipewire-screen-capture-source", + .type = OBS_SOURCE_TYPE_INPUT, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = screencast_portal_desktop_capture_get_name, + .create = screencast_portal_capture_create, + .destroy = screencast_portal_capture_destroy, + .save = screencast_portal_capture_save, + .get_defaults = screencast_portal_capture_get_defaults, + .get_properties = screencast_portal_capture_get_properties, + .update = screencast_portal_capture_update, + .show = screencast_portal_capture_show, + .hide = screencast_portal_capture_hide, + .get_width = screencast_portal_capture_get_width, + .get_height = screencast_portal_capture_get_height, + .video_render = screencast_portal_capture_video_render, + .icon_type = OBS_ICON_TYPE_DESKTOP_CAPTURE, + }; + obs_register_source(&screencast_portal_capture_info); } void screencast_portal_unload(void)