Escape75
Escape75

Reputation: 310

Trouble minimizing Finder windows using objc on OS X

I am trying to minimize all windows programmatically in OS X ...

I have this sample code, it works great with most open windows, however finder as well as settings windows do some strange things:

NSMutableArray *array = [NSMutableArray array];

NSMutableArray *windows = (NSMutableArray *)CFBridgingRelease(CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID));
for (NSDictionary *window in windows)
{
    NSNumber *name = [window objectForKey:@"kCGWindowOwnerName" ];
    NSNumber *number = [window objectForKey:@"kCGWindowOwnerPID" ];
    NSNumber *level = [window objectForKey:@"kCGWindowLayer" ];

    if ([level isEqual:@0])
    {
        NSLog(@"Adding %@", name);
        [array addObject:number];
    }
}

NSArray *apps = [NSArray arrayWithArray:[[NSWorkspace sharedWorkspace] runningApplications]];
for (NSRunningApplication *app in apps )
{
    if (app.activationPolicy == NSApplicationActivationPolicyRegular)
    {
        if ([array containsObject:[NSNumber numberWithInteger:app.processIdentifier]])
        {
            NSLog(@"Minimizing %@", app.bundleIdentifier);
            [app hide];
        }
    }
}

For example, if you have Xcode and safari open they will minimize fine, most of the time, but with Finder open viewing a folder, it will leave it maximized. Quite strange behaviour ...

If we only have Safari open, it works fine:

2016-09-18 18:51:36.842425 Show Desktop[1149:46155] Adding Safari
2016-09-18 18:51:36.852206 Show Desktop[1149:46155] Minimizing com.apple.Safari

If we have both Safari and Xcode (on top), it works fine:

2016-09-18 18:52:10.371454 Show Desktop[1149:46155] Adding Xcode
2016-09-18 18:52:10.371510 Show Desktop[1149:46155] Adding Safari
2016-09-18 18:52:10.381079 Show Desktop[1149:46155] Minimizing com.apple.dt.Xcode
2016-09-18 18:52:10.382259 Show Desktop[1149:46155] Minimizing com.apple.Safari

If we have both Safari (on top) and Xcode, sometimes it fails, and we end up with Xcode visible, but Safari hidden:

2016-09-18 18:53:45.387255 Show Desktop[1149:46155] Adding Safari
2016-09-18 18:53:45.387312 Show Desktop[1149:46155] Adding Xcode
2016-09-18 18:53:45.397135 Show Desktop[1149:46155] Minimizing com.apple.dt.Xcode
2016-09-18 18:53:45.398143 Show Desktop[1149:46155] Minimizing com.apple.Safari

Also, whenever we have Finder open (on some files, etc), it will pretty much never work, Finder will always remain visible:

2016-09-18 18:54:49.889837 Show Desktop[1149:46155] Adding Xcode
2016-09-18 18:54:49.889894 Show Desktop[1149:46155] Adding Safari
2016-09-18 18:54:49.889914 Show Desktop[1149:46155] Adding Finder
2016-09-18 18:54:49.891700 Show Desktop[1149:46155] Minimizing com.apple.finder
2016-09-18 18:54:49.900926 Show Desktop[1149:46155] Minimizing com.apple.dt.Xcode
2016-09-18 18:54:49.901736 Show Desktop[1149:46155] Minimizing com.apple.Safari

Upvotes: 1

Views: 120

Answers (1)

l'L'l
l'L'l

Reputation: 47274

Actually the behavior isn't all that strange once you figure out what is happening. Since your [app hide] hides everything (including your own app) the focus goes back to Finder, in-turn it becomes active and it's windows become visible.

If you want focus to remain with your app and hide everything else this might work:

[[NSWorkspace sharedWorkspace] hideOtherApplications];

These are a few functions that might help when dealing with the app window:

[_window performMiniaturize:self]; 
// miniaturizes app _window

[_window setIsVisible:false];
 // makes the app _window not visible

[_window orderOut:self];
// removes app _window from screen

All of these functions should hide/remove the calling app's window after hideOtherApplications is invoked, while at the same time keeping it the active. There may be better ways to do this of course, although this might at least give you some idea of the what's going on with the windows.

Upvotes: 1

Related Questions