浏览代码

Merge pull request #2656 from dbieber/z2020-04-05-mac-capture

mac-capture: Use window id to identify windows on MacOS
Colin Edwards 5 年之前
父节点
当前提交
8b1b6b1e75
共有 2 个文件被更改,包括 40 次插入1 次删除
  1. 1 0
      plugins/mac-capture/window-utils.h
  2. 39 1
      plugins/mac-capture/window-utils.m

+ 1 - 0
plugins/mac-capture/window-utils.h

@@ -6,6 +6,7 @@
 
 struct cocoa_window {
 	CGWindowID window_id;
+	int owner_pid;
 
 	pthread_mutex_t name_lock;
 	NSString *owner_name;

+ 39 - 1
plugins/mac-capture/window-utils.m

@@ -60,8 +60,11 @@ bool find_window(cocoa_window_t cw, obs_data_t *settings, bool force)
 
 		NSNumber *window_id = (NSNumber *)dict[WINDOW_NUMBER];
 		cw->window_id = window_id.intValue;
+		NSNumber *owner_pid = (NSNumber *)dict[OWNER_PID];
+		cw->owner_pid = owner_pid.intValue;
 
 		obs_data_set_int(settings, "window", cw->window_id);
+		obs_data_set_int(settings, "owner_pid", cw->owner_pid);
 		return true;
 	}
 
@@ -78,7 +81,41 @@ void init_window(cocoa_window_t cw, obs_data_t *settings)
 	cw->window_name = @(obs_data_get_string(settings, "window_name"));
 	[cw->owner_name retain];
 	[cw->window_name retain];
-	find_window(cw, settings, true);
+
+	// Find initial window.
+	pthread_mutex_lock(&cw->name_lock);
+
+	if (!cw->window_name.length && !cw->owner_name.length)
+		goto invalid_name;
+
+	NSNumber *owner_pid = @(obs_data_get_int(settings, "owner_pid"));
+	NSNumber *window_id = @(obs_data_get_int(settings, "window"));
+	for (NSDictionary *dict in enumerate_windows()) {
+		bool owner_names_match =
+			[cw->owner_name isEqualToString:dict[OWNER_NAME]];
+		bool ids_match =
+			[owner_pid isEqualToNumber:dict[OWNER_PID]] &&
+			[window_id isEqualToNumber:dict[WINDOW_NUMBER]];
+		bool window_names_match =
+			[cw->window_name isEqualToString:dict[WINDOW_NAME]];
+
+		if (owner_names_match && (ids_match || window_names_match)) {
+			pthread_mutex_unlock(&cw->name_lock);
+
+			NSNumber *window_id = (NSNumber *)dict[WINDOW_NUMBER];
+			cw->window_id = window_id.intValue;
+			NSNumber *owner_pid = (NSNumber *)dict[OWNER_PID];
+			cw->owner_pid = owner_pid.intValue;
+
+			obs_data_set_int(settings, "window", cw->window_id);
+			obs_data_set_int(settings, "owner_pid", cw->owner_pid);
+			return;
+		}
+	}
+
+invalid_name:
+	pthread_mutex_unlock(&cw->name_lock);
+	return;
 }
 
 void destroy_window(cocoa_window_t cw)
@@ -99,6 +136,7 @@ void update_window(cocoa_window_t cw, obs_data_t *settings)
 	[cw->window_name retain];
 	pthread_mutex_unlock(&cw->name_lock);
 
+	cw->owner_pid = obs_data_get_int(settings, "owner_pid");
 	cw->window_id = obs_data_get_int(settings, "window");
 }