可可窗口拖动

The*_*ler 2 macos cocoa objective-c

我正在使用 addGlobalMonitorForEventsMatchingMask 来监听 Co​​coa 中的事件:

[NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask 
                                       handler:^(NSEvent *event) {
    NSLog(@"Dragged...");
}];
Run Code Online (Sandbox Code Playgroud)

虽然我想知道我是否正在拖动/移动窗口(以及哪个窗口,但我可以找到聚焦的窗口,尽管在按住命令并拖动窗口时,据我所知,它没有获得焦点。)

那么,我可以检测我是否在拖动窗口吗?

更新:

我现在有一个类:“ SATest : NSObject <NSWindowDelegate>”,我在其中实现了 windowDidMove 方法(后来可能也是 windowWillMove。)不过,现在下一步是将它附加到窗口,对吗?所以我现在的问题是:如何将委托附加到所有应用程序的所有窗口?

更新 2:

我现在可以在屏幕上找到所有打开的窗口的列表:

AXUIElementRef _systemWideElement;
_systemWideElement = AXUIElementCreateSystemWide();

CFArrayRef _windows;
AXUIElementCopyAttributeValues(_systemWideElement, kAXWindowsAttribute, 0, 100, &_windows);
Run Code Online (Sandbox Code Playgroud)

现在我必须遍历窗口,并且每次都得到它的 NSWindow 以便我可以将我的委托添加到它: [window setDelegate:self];

更新 3:要清楚,这个问题是关于检测所有应用程序的所有窗口的拖动。不仅是我自己的应用程序的窗口。

另外,我对这个事件和窗口管理的东西很陌生,所以不需要让你的回答简短,我很高兴阅读很多:P

谢谢!-P

Ben*_*ale 5

要确定窗口是否正在被拖动,您需要通过响应NSWindowDelegate协议的以下消息来拥有一个充当窗口委托的对象:

  1. windowWillMove - 这告诉委托窗口即将移动。
  2. windowDidMove - 这告诉委托窗口已经移动。

您可以通过将对象发送到发送给这些方法的通知参数来检索有问题的 NSWindow 对象:

例如

NSWindow draggedWindow = [notification object];
Run Code Online (Sandbox Code Playgroud)

可以在此处找到更多信息。

更新:

为了响应您关于获取所有窗口的此信息的请求,NSApplication类提供了一个方法,该方法返回应用程序拥有的所有窗口的数组。获取此信息的典型方法是使用NSApplicationDelegate方法之一来获取对应用程序对象的引用。

例如,在您的应用委托(伪代码)中:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSApplication * app = [aNotification object];
    // you now have a reference to your application.
    // and can iterate over the collection of windows and call
    // [window setDelegate:self]; for each window.
}
Run Code Online (Sandbox Code Playgroud)

请注意,随着窗口的添加和删除,您需要添加/删除您的委托。执行此操作的最佳方法是– applicationDidUpdate:

这应该足以让您开始解决您的问题。