Определить - отображается ли поле поиска Spotlight или нет

Я пытаюсь определить из приложения MacOS (Swift) - отображается ли поле поиска Spotlight или нет?

Я сделал простой отдельный эскиз проекта - приложение Cocoa с именем "MyTestApp" - один ViewController с одной кнопкой.

// the code of the button pressing processing
@IBAction func buttonClick(_ sender: NSButton) {
        print("The Detect button was pressed - it's time to press Command+Space!")
        let timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) {_ in
            print("The delay time is over!")
            let runningApps = NSWorkspace.shared.runningApplications
            for runningApp in runningApps {
                // Print current active app name
                if runningApp.isActive {
                    print("localizedName: \(runningApp.localizedName)")
                    print("bundleIdentifier: \(runningApp.bundleIdentifier)")
                    print("processIdentifier: \(runningApp.processIdentifier)")
                    print("isActive: \(runningApp.isActive)")
                    print("isHidden: \(runningApp.isHidden)")
                    print("***")
                }
                // Print Spotlight state
                if let localizedName = runningApp.localizedName {
                    if localizedName == "Spotlight" {
                        print("bundleIdentifier: \(runningApp.bundleIdentifier)")
                        print("processIdentifier: \(runningApp.processIdentifier)")
                        print("isActive: \(runningApp.isActive)")
                        print("isHidden: \(runningApp.isHidden)")
                        print("***")                        
                    }
                }
            }
    }
}

После нажатия кнопки в этом приложении я нажимаю Ctrl +Space на клавиатуре, чтобы запустить Spotlight, и он запускается, поэтому я вижу и использую поле поиска Spotlight. Благодаря задержке в этом коде я проверяю состояние запущенных приложений, когда Spotlight находится на переднем крае, однако вывод в выводе журнала Xcode не такой:

The Detect button was pressed - it's time to press Command+Space!
The delay time is over!
bundleIdentifier: Optional("com.apple.Spotlight")
processIdentifier: 275
isActive: false
isHidden: false
***
localizedName: Optional("MyTestApp")
bundleIdentifier: Optional("noname.MyTestApp")
processIdentifier: 1560
isActive: true
isHidden: false
***    

Итак, как мне определить, отображается ли поле поиска Spotlight? Или в Spotlight есть клавиатура? Или какое приложение набирается сейчас? Или какое приложение теперь имеет фокус клавиатуры?

1 ответ

Ответ за заголовок:

1 КВО на работающем приложении:

NSArray<NSRunningApplication *> *runningApplications = [[NSWorkspace sharedWorkspace] runningApplications];
for (NSRunningApplication *app in runningApplications) {
    NSURL *URL = [app bundleURL];
    NSBundle *bundle = [NSBundle bundleWithURL:URL];
    if ([[app bundleIdentifier] isEqualToString:@"com.apple.Spotlight"]) {
        [app addObserver:self forKeyPath:@"active" options:NSKeyValueObservingOptionNew context:nil];
        _app = app;
    }
}



- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    //WARNING: LAZY CODE USE PROPER OBSERVATION WITH CONTEXT AND CALLING SUPER!
    NSLog(@"%@", keyPath);
    NSLog(@"%@", object);
    NSLog(@"isActive: %d", [_app isActive]);
}

- (void)dealloc
{
  if (_app) {
    [_app removeObserver:self]
  }
}

2. Получить список окон на экране.

CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);

PS: не забудьте выпустить. Полный исходный код приведен в примере приложения Apple: "Сын Граба"

{
    kCGWindowAlpha = 1;
    kCGWindowBounds =     {
        Height = 56;
        Width = 680;
        X = 387;
        Y = 377;
    };
    kCGWindowIsOnscreen = 1;
    kCGWindowLayer = 23;
    kCGWindowMemoryUsage = 1248;
    kCGWindowName = Spotlight;
    kCGWindowNumber = 101;
    kCGWindowOwnerName = Spotlight;
    kCGWindowOwnerPID = 316;
    kCGWindowSharingState = 1;
    kCGWindowStoreType = 1;
},

В случае, если вам нужно больше (читая, что было напечатано и т. Д.), Вам понадобится Accessibility API и разрешение от пользователя (песочница)

Другие вопросы по тегам