How to set an external application always being frontmost on OS X?
Asked Answered
B

0

1

I am trying to launch the built-in calculator.app on my Mac(which means it is external to my application) within my application and force the calculator to stay frontmost permanently on screen.

Here is my process. Firstly, I launch the calculator and place it frontmost temporarily.

if ([[NSWorkspace sharedWorkspace] respondsToSelector:@selector(launchApplicationAtURL:options:configuration:error:)])
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:@"/Applications/Calculator.app/Contents/MacOS/Calculator" isDirectory:NO]
                                              options:NSWorkspaceLaunchDefault
                                        configuration:nil
                                                error:NULL];

After that, I recognize the Calculator by it's owner name and try to pin Calculator.app frontmost. I was stuck here. What I would like to do is either these two ways:

1.Set an attribute to place it always frontmost. (Can't find suitable attribute, only found attributes to resize or position)

2.Get the NSWindow of Calculator and set the level to frontmost. (Seems to be non-viable: How to convert a Carbon AXUIElementRef to Cocoa NSWindow)

But seems that both of them are not available.

CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
NSArray *arr = CFBridgingRelease(windowList);
    for (NSMutableDictionary *entry in arr){
        NSString *ownerName = [entry objectForKey:(id)kCGWindowOwnerName];
        if([ownerName isEqualToString:@"Calculator"]){
            pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
            AXUIElementRef appRef = AXUIElementCreateApplication(pid);
            CFArrayRef windowList;
            AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
            AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList, 0);
            CFTypeRef role;
            AXUIElementCopyAttributeValue(windowRef, kAXRoleAttribute, (CFTypeRef *)&role);

            /*Would like to get the window of the application or assign some attribute to set Calculator frontmost*/
        }

Are there any ways to achieve the two aspects I've mentioned above? Or are there any suggestions for setting an external application always being frontmost?

Barlow answered 16/11, 2016 at 10:55 Comment(1)
@jimwan Have you made it on this frontmost feature?Barlow

© 2022 - 2024 — McMap. All rights reserved.