Cocoa windowNumbersWithOptions:on Yosemite无法返回我的应用程序的NSPanel窗口
我有一个基于文档的应用程序,有一个主文档窗口和几个显示相关信息的“卫星”NSPanel窗口。它们不是浮动的,它们可以(而且确实)成为关键点,并且似乎与主窗口位于同一层 我尝试实现这样的显示/隐藏操作:如果面板不可见,则显示它。如果它是可见的,但不在前面-使它在前面。如果它是可见的和正面-隐藏它 为此,我需要知道NSPanel是否为“最前端”。遗憾的是,不存在用于此目的的NSWindowAPI。我尝试使用Cocoa windowNumbersWithOptions:on Yosemite无法返回我的应用程序的NSPanel窗口,cocoa,nswindow,z-order,nspanel,Cocoa,Nswindow,Z Order,Nspanel,我有一个基于文档的应用程序,有一个主文档窗口和几个显示相关信息的“卫星”NSPanel窗口。它们不是浮动的,它们可以(而且确实)成为关键点,并且似乎与主窗口位于同一层 我尝试实现这样的显示/隐藏操作:如果面板不可见,则显示它。如果它是可见的,但不在前面-使它在前面。如果它是可见的和正面-隐藏它 为此,我需要知道NSPanel是否为“最前端”。遗憾的是,不存在用于此目的的NSWindowAPI。我尝试使用windowNumbersWithOptions来比较我的面板的z顺序 -(void) tog
windowNumbersWithOptions
来比较我的面板的z顺序
-(void) togglePanelVisibility:(PMXPanelController *)panelController {
NSPanel *panel = [panelController window];
if ([panel isVisible]) {
NSArray *windowNumbers = [NSWindow windowNumbersWithOptions:0];
if ([panel windowNumber] == [[windowNumbers firstObject] integerValue]) {
[panel orderOut:self];
}
else {
[panel makeKeyAndOrderFront:self];
}
} else
[panelController showWindow:self];
}
唉,我收到的数组只包含一个数字——用于我的主文档窗口。我可以在“窗口”菜单中看到我的面板,我可以单击它们将它们带到前面,我可以关闭它们并使用它们-但我无法通过WindowNumbers和选项获取它们的编号:
有人吗 它没有在任何地方说明这一点,但从使用
nswindownumberinstallapplications
返回的少量窗口来看,windowNumbersWithOptions
似乎只从正常级别返回窗口,或者应用某种不包括其他窗口的过滤。最好的选择是NSApplication
实例的属性,但既然您提到了面板,请注意:
阵列中仅包括通常可编写脚本的窗口。例如,不包括面板
请记住,这两种方法都依赖于Quartz API,并且可能会使用–在最坏的情况下,您可以转到较低的级别并使用它。根据给出的建议,我最终得出了以下结论,这似乎对我来说是合理的
/* Here is the logic: If panel of panelController is frontMost - hide it.
If it is visible, but not frontMost - bring it to front.
If it is not visible - Show it, and bring it to front. */
-(void) togglePanelVisibility:(PMXPanelController *)panelController
{
NSWindow *panel = [panelController window];
if ([panel isVisible]) {
BOOL panelIsFront = [self isPanelFront:panel];
if (panelIsFront)
[panel orderOut:self];
else
[panel makeKeyAndOrderFront:self];
} else
[panelController showWindow:self];
}
// Attempt to determine if a given panel (window) is front window
-(BOOL) isPanelFront:(NSWindow *)panel
{
BOOL panelIsFront = NO;
#if 0
// This simple implementation won't work because orderedWindows don't contain panels.
panelIsFront = [panel isEqualTo:[[NSApp orderedWindows] firstObject]];
// This used to work, but broke on OS X 10.10 Yosemite. I only receive my main window.
panelIsFront = ([panel windowNumber] == [[[NSWindow windowNumbersWithOptions:0] firstObject] integerValue]);
#endif
// Last resort, - using CoreGraphics window list. Seems to work on all systems up to 10.10.4
NSMutableArray *windowNumbers = [NSMutableArray arrayWithCapacity:32]; // I rely on window numbers to determine "frontness".
CFArrayRef windowInfoArray = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
for (NSDictionary* nswindowsdescription in (__bridge NSArray*)windowInfoArray) {
NSNumber *windowLayer = (NSNumber*)[nswindowsdescription objectForKey:(NSString *)kCGWindowLayer];
if (windowLayer.integerValue != 0) // filter out windows not in our normal window layer.
continue;
NSNumber* windowid = (NSNumber*)[nswindowsdescription objectForKey:(NSString *)kCGWindowNumber];
if(windowid)
[windowNumbers addObject:windowid];
}
CFRelease(windowInfoArray);
panelIsFront = ([panel windowNumber] == [[windowNumbers firstObject] integerValue]);
return panelIsFront;
}
非常感谢你。我会尝试两种方法,但我的心倾向于CG。B.T.W,你不觉得没有简单的API告诉我哪个窗口在前面很遗憾吗?毕竟它隐藏了另一个窗口,我可能会感兴趣。。。