OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #include "ui/base/cocoa/focus_window_set.h" | 7 #include "ui/base/cocoa/focus_window_set.h" |
8 | 8 |
9 namespace ui { | 9 namespace ui { |
10 | 10 |
11 void FocusWindowSet(const std::set<NSWindow*>& windows) { | 11 // This attempts to match OS X's native behavior, namely that a window |
12 // is only ever deminiaturized if ALL windows on ALL workspaces are | |
13 // miniaturized. (This callback runs before AppKit picks its own | |
14 // window to deminiaturize, so we get to pick one from the right set.) | |
15 // | |
16 // In addition, limit to the windows on the current | |
17 // workspace. Otherwise we jump spaces haphazardly. | |
18 // | |
19 // NOTE: This is not perfect. If clicking the dock icon resulted in | |
20 // switching spaces, isOnActiveSpace gives the answer for the PREVIOUS | |
21 // space. This means that we actually raise the wrong space's | |
22 // windows. This seems to still work okay. | |
23 // | |
24 // However, if we decide to deminiaturize a window instead, that | |
25 // results in switching spaces and switching back. Fortunately, this | |
26 // only happens if, say, space 1 contains an app, space 2 contains a | |
27 // miniaturized browser. We click the icon, OS X switches to space 1, | |
28 // we deminiaturize the browser, and that triggers switching back. | |
Nico
2013/09/04 15:50:09
Would using the private api CGSGetWindowWorkspace(
davidben
2013/09/04 16:05:58
Probably not? Is there a way to figure out where O
davidben
2013/09/04 16:19:16
Thinking about that some more, another explanation
| |
29 void FocusWindowSet(const std::set<NSWindow*>& windows, | |
30 bool allow_workspace_switch) { | |
12 NSArray* ordered_windows = [NSApp orderedWindows]; | 31 NSArray* ordered_windows = [NSApp orderedWindows]; |
13 NSWindow* frontmost_window = nil; | 32 NSWindow* frontmost_window = nil; |
33 NSWindow* frontmost_window_all_spaces = nil; | |
14 NSWindow* frontmost_miniaturized_window = nil; | 34 NSWindow* frontmost_miniaturized_window = nil; |
35 bool all_miniaturized = true; | |
15 for (int i = [ordered_windows count] - 1; i >= 0; i--) { | 36 for (int i = [ordered_windows count] - 1; i >= 0; i--) { |
16 NSWindow* win = [ordered_windows objectAtIndex:i]; | 37 NSWindow* win = [ordered_windows objectAtIndex:i]; |
17 if (windows.find(win) != windows.end()) { | 38 if (windows.find(win) != windows.end()) { |
18 if ([win isVisible]) { | 39 if ([win isMiniaturized]) { |
19 [win orderFront:nil]; | |
20 frontmost_window = win; | |
21 } else if ([win isMiniaturized]) { | |
22 frontmost_miniaturized_window = win; | 40 frontmost_miniaturized_window = win; |
41 } else if ([win isVisible]) { | |
42 all_miniaturized = false; | |
43 frontmost_window_all_spaces = win; | |
44 if ([win isOnActiveSpace]) { | |
45 [win orderFront:nil]; | |
46 frontmost_window = win; | |
47 } | |
23 } | 48 } |
24 } | 49 } |
25 } | 50 } |
26 if (!frontmost_window && frontmost_miniaturized_window) { | 51 if (all_miniaturized && frontmost_miniaturized_window) { |
27 [frontmost_miniaturized_window deminiaturize:nil]; | 52 [frontmost_miniaturized_window deminiaturize:nil]; |
28 frontmost_window = frontmost_miniaturized_window; | 53 frontmost_window = frontmost_miniaturized_window; |
29 } | 54 } |
55 // If we couldn't find one on this window, consider all spaces. | |
56 if (allow_workspace_switch && | |
57 !frontmost_window && frontmost_window_all_spaces) { | |
58 frontmost_window = frontmost_window_all_spaces; | |
59 [frontmost_window orderFront:nil]; | |
60 } | |
30 if (frontmost_window) { | 61 if (frontmost_window) { |
31 [NSApp activateIgnoringOtherApps:YES]; | 62 [NSApp activateIgnoringOtherApps:YES]; |
32 [frontmost_window makeMainWindow]; | 63 [frontmost_window makeMainWindow]; |
33 [frontmost_window makeKeyWindow]; | 64 [frontmost_window makeKeyWindow]; |
34 } | 65 } |
35 } | 66 } |
36 | 67 |
37 } // namespace ui | 68 } // namespace ui |
OLD | NEW |