2017-06-17 136 views
0

对于很多遗留代码跨平台的项目,我的可可应用程序只使用一个NSWindow与捕获所有的鼠标事件,并提请我所有的应用程序图形细节自定义的NSView。CFRunLoopRunInMode冻结主窗口

我需要实现本地模式的行为,所以我用的主线程中:

CFRunLoopRunInMode(kCFRunLoopDefaultMode,0.01%,FALSE);

在语言环境中。如预期的那样,函数在0.01秒后返回,其值为kCFRunLoopRunTimedOut。然而,鼠标事件在那段时间内不再被自定义的NSView接收,所以我的应用程序看起来像被冻结了(颜色鼠标光标四处移动)。

定时器事件仍然到达自定义的NSView,而不是鼠标事件。

苹果指定该功能可以递归调用。还有什么我应该这样做,NSView仍然收到用户鼠标输入?

+0

在调用'CFRunLoopRunInMode'的行上放置一个断点。当命中断点时,复制堆栈跟踪。编辑您的问题并粘贴到堆栈跟踪中。 –

回答

1

事件循环是建立在一个运行循环的顶部,但它不止于此。仅仅运行运行循环不足以接收和处理事件。

你可以通过围绕-[NSWindow nextEventMatchingMask:untilDate:inMode:dequeue:]-sendEvent:建立一个循环来实现你想要做的一些事情,但是真的不清楚你的目标是什么。如果你解释一下,可能有更好的方法。

例如,如果你想提出一个模态对话框,你应该使用-[NSApplication runModalForWindow:]

+0

感谢肯,它确实工作完美,只需在我的本地循环内使用以下两行: – Dominique

+0

'event = [mainWindow nextEventMatchingMask:NSUIntegerMax untilDate:[NSDate dateWithTimeIntervalSinceNow:0.010] inMode:NSDefaultRunLoopMode dequeue:YES]; (事件) [mainWindow sendEvent:event];' – Dominique

+0

我在这个遗留代码(300,000行C++代码)中面临的主要问题是,它们的函数中包含大量“模态”循环。大多数这些功能都是特定的(但非常复杂的)一个用户操作的处理程序,从鼠标开始,处理鼠标移动的流程,并且只在鼠标移动事件中退出功能。重构整个代码以分离每个鼠标动作的处理将是一件非常大的工作,并且很可能会在运行良好的代码的一部分中引入错误,因为这些交互非常复杂。 – Dominique