首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在前景化后立即将键盘事件注入NSRunningApplication

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

Stack Overflow用户
提问于 2019-07-12 11:41:43
回答 1查看 180关注 0票数 0

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

代码语言:javascript
复制
NSRunningApplication* app = ...;
[app activateWithOptions: 0];
inject_keystrokes();

..。无法注入键盘事件,但是:

代码语言:javascript
复制
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参考文献:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-13 20:10:09

isActive上为KVO属性添加一个观察者对我来说是有效的。

代码语言:javascript
复制
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中。你必须小心,不要在观察者还在的情况下放弃引用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57006309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档