Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 在前景化后立即将键盘事件注入NSRunningApplication_Macos_Nswindow_Nsevent_Nsrunningapplication_Foregroundnotification - Fatal编程技术网

Macos 在前景化后立即将键盘事件注入NSRunningApplication

Macos 在前景化后立即将键盘事件注入NSRunningApplication,macos,nswindow,nsevent,nsrunningapplication,foregroundnotification,Macos,Nswindow,Nsevent,Nsrunningapplication,Foregroundnotification,我正在尝试将NSRunningApplication*实例带到前台,并插入一个键盘事件 NSRunningApplication* app = ...; [app activateWithOptions: 0]; inject_keystrokes(); 。。。无法注入键盘事件,但: NSRunningApplication* app = ...; [app activateWithOptions: 0]; dispatch_time_t _100ms = dispatch_time( DIS

我正在尝试将
NSRunningApplication*
实例带到前台,并插入一个键盘事件

NSRunningApplication* app = ...;
[app activateWithOptions: 0];
inject_keystrokes();
。。。无法注入键盘事件,但:

NSRunningApplication* app = ...;
[app activateWithOptions: 0];
dispatch_time_t _100ms = dispatch_time( DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC) );
dispatch_after(
               _100ms,
               dispatch_get_main_queue(),
               ^{ inject_keystrokes(); }
               );
。。。成功

我想窗口在前景中渲染需要一定的时间,这可能发生在一个单独的线程上,这就解释了注入失败的原因

然而,这是一个非常丑陋的解决方案。它依赖于任意的时间间隔

以某种方式等待窗口完成前景化会更干净

有没有办法做到这一点

PS
inject_keystrokes()
使用
CGEventPost(kCGHIDEventTap,someCGEvent)

PPS参考文献:
-
-

-

NSRunningApplication
上为KVO属性添加一个观察者
isActive

for (NSRunningApplication* ra in [[NSWorkspace sharedWorkspace] runningApplications])
{
    if ([ra.bundleIdentifier isEqualToString:@"com.apple.TextEdit"])
    {
        [ra addObserver:self forKeyPath:@"isActive" options:0 context:ra];
        [ra retain];
        [ra activateWithOptions:0];
    }
}

// ...

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
    if ([keyPath isEqualToString:@"isActive"])
    {
        NSRunningApplication* ra = (NSRunningApplication*) context;
        [ra removeObserver:self forKeyPath:@"isActive"];
        [ra release];
        inject_keystrokes();
    }
}

请注意,我手动保留然后释放
NSRunningApplication
,以保持其引用处于活动状态,因为我没有将其保留在属性或ivar中。您必须小心,不要在观察者仍然连接的情况下删除引用。

NSRunningApplication
上为KVO属性添加观察者
isActive

for (NSRunningApplication* ra in [[NSWorkspace sharedWorkspace] runningApplications])
{
    if ([ra.bundleIdentifier isEqualToString:@"com.apple.TextEdit"])
    {
        [ra addObserver:self forKeyPath:@"isActive" options:0 context:ra];
        [ra retain];
        [ra activateWithOptions:0];
    }
}

// ...

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
    if ([keyPath isEqualToString:@"isActive"])
    {
        NSRunningApplication* ra = (NSRunningApplication*) context;
        [ra removeObserver:self forKeyPath:@"isActive"];
        [ra release];
        inject_keystrokes();
    }
}

请注意,我手动保留然后释放
NSRunningApplication
,以保持其引用处于活动状态,因为我没有将其保留在属性或ivar中。你必须小心,不要在观察者仍然连接的情况下删除引用。

你是否尝试使用
CGEventPostToPid
将事件发布到应用程序?我刚刚尝试,不幸的是它不起作用。你是否尝试使用
CGEventPostToPid
将事件发布到应用程序?我刚刚尝试,不幸的是它不起作用。