(OS X)检测前端应用何时进入全屏模式 [英] (OS X) Detecting when front app goes into fullscreen mode

查看:153
本文介绍了(OS X)检测前端应用何时进入全屏模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个"UIElement"应用程序,该应用程序在屏幕的侧面显示一个状态窗口,类似于Dock.

I'm writing a "UIElement" app that shows a status window on the side of the screen, similar to the Dock.

现在,当程序占据整个屏幕时,就像Dock一样,我需要隐藏状态窗口.

Now, when a program takes over the entire screen, I need to hide my status window, just like the Dock does.

检测此事件和逆事件有哪些选择?

What are my options to detect this and the inverse event?

我想避免通过定时事件进行轮询,并且也不能使用未记录的技巧(例如建议的此处)

I like to avoid polling via a timed event and also cannot use undocumented tricks (such as suggested here)

  • kEventAppSystemUIModeChanged事件注册Carbon事件处理程序还不够-它可以检测VLC的全屏模式,但不适用于使用其右上角新的全屏小部件的现代Cocoa应用程序Windows.

  • Registering a Carbon Event Handler for the kEventAppSystemUIModeChanged event isn't sufficient - it works to detect VLC's full screen mode, but not for modern Cocoa apps that use the new fullscreen widget at the top right corner of their windows.

类似地,按照Apple关于

Similarly, following Apple's instructions about the NSApplication presentationOptions API by observing changes to the currentSystemPresentationOptions property does not help, either - again, it only informs about VLC's fullscreen mode, but not about apps using the window' top right fullscreen widget.

使用CGDisplayRegisterReconfigurationCallback监视屏幕配置的更改不起作用,因为这些全屏模式没有任何回调.

Monitoring changes to the screen configuration using CGDisplayRegisterReconfigurationCallback is not working because there aren't any callbacks for these fullscreen modes.

推荐答案

基于@Chuck的建议,我提出了一个可行的解决方案,但可能并非万无一失.

Based on @Chuck's suggestion, I've come up with a solution that works somewhat, but may not be foolproof.

该解决方案基于以下假设:10.7的

The solution is based on the assumption that 10.7's new fullscreen mode for windows moves these windows to a new Screen Space. Therefore, we subscribe to notifications for changes to the active space. In that notification handler, we check the window list to detect whether the menubar is included. If it is not, it probably means that we're in a fullscreen space.

根据Chuck的想法,检查菜单栏"窗口的存在是我能想到的最好的测试.不过,我不太喜欢它,因为它对内部管理的窗口的命名和存在进行了假设.

Checking for the presence of the "Menubar" window is the best test I could come up with based on Chuck's idea. I don't like it too much, though, because it makes assumptions on the naming and presence of internally managed windows.

这是AppDelegate.m内的测试代码,其中还包括针对其他应用范围的全屏模式的测试:

Here's the test code that goes inside AppDelegate.m, which also includes the test for the other app-wide fullscreen mode:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSApplication *app = [NSApplication sharedApplication];

    // Observe full screen mode from apps setting SystemUIMode
    // or invoking 'setPresentationOptions'
    [app addObserver:self
          forKeyPath:@"currentSystemPresentationOptions"
             options:NSKeyValueObservingOptionNew
             context:NULL];

    // Observe full screen mode from apps using a separate space
    // (i.e. those providing the fullscreen widget at the right
    // of their window title bar).
    [[[NSWorkspace sharedWorkspace] notificationCenter]
        addObserverForName:NSWorkspaceActiveSpaceDidChangeNotification
        object:NULL queue:NULL
        usingBlock:^(NSNotification *note)
        {
            // The active space changed.
            // Now we need to detect if this is a fullscreen space.
            // Let's look at the windows...
            NSArray *windows = CFBridgingRelease(CGWindowListCopyWindowInfo
                        (kCGWindowListOptionOnScreenOnly, kCGNullWindowID));
            //NSLog(@"active space change: %@", windows);

            // We detect full screen spaces by checking if there's a menubar
            // in the window list.
            // If not, we assume it's in fullscreen mode.
            BOOL hasMenubar = NO;
            for (NSDictionary *d in windows) {
                if ([d[@"kCGWindowOwnerName"] isEqualToString:@"Window Server"]
                 && [d[@"kCGWindowName"] isEqualToString:@"Menubar"]) {
                    hasMenubar = YES;
                    break;
                }
            }
            NSLog(@"fullscreen: %@", hasMenubar ? @"No" : @"Yes");
        }
     ];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqual:@"currentSystemPresentationOptions"]) {
        NSLog(@"currentSystemPresentationOptions: %@", [change objectForKey:NSKeyValueChangeNewKey]); // a value of 4 indicates fullscreen mode
    }
}

这篇关于(OS X)检测前端应用何时进入全屏模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆