mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
mac-capture: Don't crash when migrating unknown display IDs
The current code assumes that a display UUID can be created with the stored ID, but that's not always the case, e.g. when the user doesn't have the display connected. As such, we need to null check this, and fall back to the invalid ID (0) when the ID cannot be migrated. The current code also only migrates on source creation, which yields weird behaviour where if the user opens properties and then cancels it would still show the first display, but only for the session. This is why the code was factored out of the creation function and now is always used when an ID needs to be acquired from OBS Data settings, including when the source is updated.
This commit is contained in:
parent
857c42aaba
commit
23bfb625ce
@ -286,27 +286,7 @@ static void *display_capture_create(obs_data_t *settings, obs_source_t *source)
|
|||||||
init_window(&dc->window, settings);
|
init_window(&dc->window, settings);
|
||||||
load_crop(dc, settings);
|
load_crop(dc, settings);
|
||||||
|
|
||||||
bool legacy_display_id = obs_data_has_user_value(settings, "display");
|
dc->display = get_display_migrate_settings(settings);
|
||||||
if (legacy_display_id) {
|
|
||||||
CGDirectDisplayID display_id = (CGDirectDisplayID) obs_data_get_int(settings, "display");
|
|
||||||
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(display_id);
|
|
||||||
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
|
|
||||||
obs_data_set_string(settings, "display_uuid", CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
|
|
||||||
obs_data_erase(settings, "display");
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(display_uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *display_uuid = obs_data_get_string(settings, "display_uuid");
|
|
||||||
if (display_uuid) {
|
|
||||||
CFStringRef uuid_string = CFStringCreateWithCString(kCFAllocatorDefault, display_uuid, kCFStringEncodingUTF8);
|
|
||||||
CFUUIDRef uuid_ref = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
|
|
||||||
dc->display = CGDisplayGetDisplayIDFromUUID(uuid_ref);
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(uuid_ref);
|
|
||||||
} else {
|
|
||||||
dc->display = CGMainDisplayID();
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_init(&dc->mutex, NULL);
|
pthread_mutex_init(&dc->mutex, NULL);
|
||||||
|
|
||||||
@ -561,12 +541,7 @@ static void display_capture_update(void *data, obs_data_t *settings)
|
|||||||
if (requires_window(dc->crop))
|
if (requires_window(dc->crop))
|
||||||
update_window(&dc->window, settings);
|
update_window(&dc->window, settings);
|
||||||
|
|
||||||
CFStringRef uuid_string = CFStringCreateWithCString(
|
CGDirectDisplayID display = get_display_migrate_settings(settings);
|
||||||
kCFAllocatorDefault, obs_data_get_string(settings, "display_uuid"), kCFStringEncodingUTF8);
|
|
||||||
CFUUIDRef display_uuid = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
|
|
||||||
CGDirectDisplayID display = CGDisplayGetDisplayIDFromUUID(display_uuid);
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(display_uuid);
|
|
||||||
|
|
||||||
bool show_cursor = obs_data_get_bool(settings, "show_cursor");
|
bool show_cursor = obs_data_get_bool(settings, "show_cursor");
|
||||||
if (dc->display == display && dc->hide_cursor != show_cursor)
|
if (dc->display == display && dc->hide_cursor != show_cursor)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "mac-sck-common.h"
|
#include "mac-sck-common.h"
|
||||||
|
#include "window-utils.h"
|
||||||
|
|
||||||
static void destroy_screen_stream(struct screen_capture *sc)
|
static void destroy_screen_stream(struct screen_capture *sc)
|
||||||
{
|
{
|
||||||
@ -271,27 +272,7 @@ static void *sck_video_capture_create(obs_data_t *settings, obs_source_t *source
|
|||||||
if (!sc->effect)
|
if (!sc->effect)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
bool legacy_display_id = obs_data_has_user_value(settings, "display");
|
sc->display = get_display_migrate_settings(settings);
|
||||||
if (legacy_display_id) {
|
|
||||||
CGDirectDisplayID display_id = (CGDirectDisplayID) obs_data_get_int(settings, "display");
|
|
||||||
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(display_id);
|
|
||||||
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
|
|
||||||
obs_data_set_string(settings, "display_uuid", CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
|
|
||||||
obs_data_erase(settings, "display");
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(display_uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *display_uuid = obs_data_get_string(settings, "display_uuid");
|
|
||||||
if (display_uuid) {
|
|
||||||
CFStringRef uuid_string = CFStringCreateWithCString(kCFAllocatorDefault, display_uuid, kCFStringEncodingUTF8);
|
|
||||||
CFUUIDRef uuid_ref = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
|
|
||||||
sc->display = CGDisplayGetDisplayIDFromUUID(uuid_ref);
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(uuid_ref);
|
|
||||||
} else {
|
|
||||||
sc->display = CGMainDisplayID();
|
|
||||||
}
|
|
||||||
|
|
||||||
sc->application_id = [[NSString alloc] initWithUTF8String:obs_data_get_string(settings, "application")];
|
sc->application_id = [[NSString alloc] initWithUTF8String:obs_data_get_string(settings, "application")];
|
||||||
pthread_mutex_init(&sc->mutex, NULL);
|
pthread_mutex_init(&sc->mutex, NULL);
|
||||||
@ -420,12 +401,7 @@ static void sck_video_capture_update(void *data, obs_data_t *settings)
|
|||||||
|
|
||||||
ScreenCaptureStreamType capture_type = (ScreenCaptureStreamType) obs_data_get_int(settings, "type");
|
ScreenCaptureStreamType capture_type = (ScreenCaptureStreamType) obs_data_get_int(settings, "type");
|
||||||
|
|
||||||
CFStringRef uuid_string = CFStringCreateWithCString(
|
CGDirectDisplayID display = get_display_migrate_settings(settings);
|
||||||
kCFAllocatorDefault, obs_data_get_string(settings, "display_uuid"), kCFStringEncodingUTF8);
|
|
||||||
CFUUIDRef display_uuid = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
|
|
||||||
CGDirectDisplayID display = CGDisplayGetDisplayIDFromUUID(display_uuid);
|
|
||||||
CFRelease(uuid_string);
|
|
||||||
CFRelease(display_uuid);
|
|
||||||
|
|
||||||
NSString *application_id = [[NSString alloc] initWithUTF8String:obs_data_get_string(settings, "application")];
|
NSString *application_id = [[NSString alloc] initWithUTF8String:obs_data_get_string(settings, "application")];
|
||||||
bool show_cursor = obs_data_get_bool(settings, "show_cursor");
|
bool show_cursor = obs_data_get_bool(settings, "show_cursor");
|
||||||
|
@ -31,3 +31,8 @@ void window_defaults(obs_data_t *settings);
|
|||||||
void add_window_properties(obs_properties_t *props);
|
void add_window_properties(obs_properties_t *props);
|
||||||
|
|
||||||
void show_window_properties(obs_properties_t *props, bool show);
|
void show_window_properties(obs_properties_t *props, bool show);
|
||||||
|
|
||||||
|
/** Get the display ID of a display and simultaneously migrate pre-30.0 display IDs to 30.0 UUIDs.
|
||||||
|
- Parameter settings: Pointer to `obs_data_t` object containing `display` int and/or `display_uuid` string
|
||||||
|
- Returns: `CGDirectDisplayID` of the display the user selected. May be 0 if the display cannot be found. */
|
||||||
|
CGDirectDisplayID get_display_migrate_settings(obs_data_t *settings);
|
||||||
|
@ -245,3 +245,36 @@ void show_window_properties(obs_properties_t *props, bool show)
|
|||||||
obs_property_set_visible(obs_properties_get(props, "window"), show);
|
obs_property_set_visible(obs_properties_get(props, "window"), show);
|
||||||
obs_property_set_visible(obs_properties_get(props, "show_empty_names"), show);
|
obs_property_set_visible(obs_properties_get(props, "show_empty_names"), show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGDirectDisplayID get_display_migrate_settings(obs_data_t *settings)
|
||||||
|
{
|
||||||
|
bool legacy_display_id = obs_data_has_user_value(settings, "display");
|
||||||
|
bool new_display_id = obs_data_has_user_value(settings, "display_uuid");
|
||||||
|
if (legacy_display_id && !new_display_id) {
|
||||||
|
CGDirectDisplayID display_id = (CGDirectDisplayID) obs_data_get_int(settings, "display");
|
||||||
|
CFUUIDRef display_uuid = CGDisplayCreateUUIDFromDisplayID(display_id);
|
||||||
|
if (display_uuid) {
|
||||||
|
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, display_uuid);
|
||||||
|
obs_data_set_string(settings, "display_uuid", CFStringGetCStringPtr(uuid_string, kCFStringEncodingUTF8));
|
||||||
|
obs_data_erase(settings, "display");
|
||||||
|
CFRelease(uuid_string);
|
||||||
|
CFRelease(display_uuid);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (legacy_display_id && new_display_id) {
|
||||||
|
obs_data_erase(settings, "display");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *display_uuid = obs_data_get_string(settings, "display_uuid");
|
||||||
|
if (display_uuid) {
|
||||||
|
CFStringRef uuid_string = CFStringCreateWithCString(kCFAllocatorDefault, display_uuid, kCFStringEncodingUTF8);
|
||||||
|
CFUUIDRef uuid_ref = CFUUIDCreateFromString(kCFAllocatorDefault, uuid_string);
|
||||||
|
CGDirectDisplayID display = CGDisplayGetDisplayIDFromUUID(uuid_ref);
|
||||||
|
CFRelease(uuid_string);
|
||||||
|
CFRelease(uuid_ref);
|
||||||
|
return display;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user