Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: ash/wm/activation_controller.cc

Issue 10830365: Initial crack at new workspace behavior. Each workspace now has its (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/shell_window_ids.h ('k') | ash/wm/always_on_top_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "ash/wm/activation_controller.h" 5 #include "ash/wm/activation_controller.h"
6 6
7 #include "ash/root_window_controller.h"
7 #include "ash/shell.h" 8 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h" 9 #include "ash/shell_window_ids.h"
10 #include "ash/wm/property_util.h"
9 #include "ash/wm/window_modality_controller.h" 11 #include "ash/wm/window_modality_controller.h"
10 #include "ash/wm/window_util.h" 12 #include "ash/wm/window_util.h"
13 #include "ash/wm/workspace_controller.h"
11 #include "base/auto_reset.h" 14 #include "base/auto_reset.h"
12 #include "ui/aura/client/activation_change_observer.h" 15 #include "ui/aura/client/activation_change_observer.h"
13 #include "ui/aura/client/activation_delegate.h" 16 #include "ui/aura/client/activation_delegate.h"
14 #include "ui/aura/client/aura_constants.h" 17 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/env.h" 18 #include "ui/aura/env.h"
16 #include "ui/aura/focus_manager.h" 19 #include "ui/aura/focus_manager.h"
17 #include "ui/aura/root_window.h" 20 #include "ui/aura/root_window.h"
18 #include "ui/aura/window.h" 21 #include "ui/aura/window.h"
19 #include "ui/aura/window_delegate.h" 22 #include "ui/aura/window_delegate.h"
20 #include "ui/base/ui_base_types.h" 23 #include "ui/base/ui_base_types.h"
21 #include "ui/compositor/layer.h" 24 #include "ui/compositor/layer.h"
22 25
23 namespace ash { 26 namespace ash {
24 namespace internal { 27 namespace internal {
25 namespace { 28 namespace {
26 29
27 // These are the list of container ids of containers which may contain windows 30 // These are the list of container ids of containers which may contain windows
28 // that need to be activated in the order that they should be activated. 31 // that need to be activated in the order that they should be activated.
29 const int kWindowContainerIds[] = { 32 const int kWindowContainerIds[] = {
30 kShellWindowId_LockSystemModalContainer, 33 kShellWindowId_LockSystemModalContainer,
31 kShellWindowId_SettingBubbleContainer, 34 kShellWindowId_SettingBubbleContainer,
32 kShellWindowId_LockScreenContainer, 35 kShellWindowId_LockScreenContainer,
33 kShellWindowId_SystemModalContainer, 36 kShellWindowId_SystemModalContainer,
34 kShellWindowId_AlwaysOnTopContainer, 37 kShellWindowId_AlwaysOnTopContainer,
35 kShellWindowId_AppListContainer, 38 kShellWindowId_AppListContainer,
39 // TODO(sky): defaultcontainer shouldn't be in the list with workspace2.
36 kShellWindowId_DefaultContainer, 40 kShellWindowId_DefaultContainer,
37 41
38 // Panel, launcher and status are intentionally checked after other 42 // Panel, launcher and status are intentionally checked after other
39 // containers even though these layers are higher. The user expects their 43 // containers even though these layers are higher. The user expects their
40 // windows to be focused before these elements. 44 // windows to be focused before these elements.
41 kShellWindowId_PanelContainer, 45 kShellWindowId_PanelContainer,
42 kShellWindowId_LauncherContainer, 46 kShellWindowId_LauncherContainer,
43 kShellWindowId_StatusContainer, 47 kShellWindowId_StatusContainer,
44 }; 48 };
45 49
46 // Returns true if children of |window| can be activated. 50 // Returns true if children of |window| can be activated.
47 // These are the only containers in which windows can receive focus. 51 // These are the only containers in which windows can receive focus.
48 bool SupportsChildActivation(aura::Window* window) { 52 bool SupportsChildActivation(aura::Window* window) {
53 // TODO(sky): straighten this out when workspace2 is the default.
54 // kShellWindowId_WorkspaceContainer isn't in |kWindowContainerIds| since it
55 // needs to be special cased in GetTopmostWindowToActivate().
56 if (window->id() == kShellWindowId_WorkspaceContainer)
57 return true;
58
49 for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { 59 for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) {
50 if (window->id() == kWindowContainerIds[i]) 60 if (window->id() == kWindowContainerIds[i] &&
61 (window->id() != kShellWindowId_DefaultContainer ||
62 !WorkspaceController::IsWorkspace2Enabled())) {
51 return true; 63 return true;
64 }
52 } 65 }
53 return false; 66 return false;
54 } 67 }
55 68
56 bool HasModalTransientChild(aura::Window* window) { 69 bool HasModalTransientChild(aura::Window* window) {
57 aura::Window::Windows::const_iterator it; 70 aura::Window::Windows::const_iterator it;
58 for (it = window->transient_children().begin(); 71 for (it = window->transient_children().begin();
59 it != window->transient_children().end(); 72 it != window->transient_children().end();
60 ++it) { 73 ++it) {
61 if ((*it)->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_WINDOW) 74 if ((*it)->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_WINDOW)
62 return true; 75 return true;
63 } 76 }
64 return false; 77 return false;
65 } 78 }
66 79
67 // See description in VisibilityMatches. 80 // See description in VisibilityMatches.
68 enum ActivateVisibilityType { 81 enum ActivateVisibilityType {
69 TARGET_VISIBILITY, 82 TARGET_VISIBILITY,
70 CURRENT_VISIBILITY, 83 CURRENT_VISIBILITY,
71 }; 84 };
72 85
73 // Used by CanActivateWindowWithEvent() to test the visibility of a window. 86 // Used by CanActivateWindowWithEvent() to test the visibility of a window.
74 // This is used by two distinct code paths: 87 // This is used by two distinct code paths:
75 // . when activating from an event we only care about the actual visibility. 88 // . when activating from an event we only care about the actual visibility.
76 // . when activating because of a keyboard accelerator, in which case we 89 // . when activating because of a keyboard accelerator, in which case we
77 // care about the TargetVisibility. 90 // care about the TargetVisibility.
78 bool VisibilityMatches(aura::Window* window, ActivateVisibilityType type) { 91 bool VisibilityMatches(aura::Window* window, ActivateVisibilityType type) {
79 bool visible = (type == CURRENT_VISIBILITY) ? window->IsVisible() : 92 bool visible = (type == CURRENT_VISIBILITY) ? window->IsVisible() :
80 window->TargetVisibility(); 93 window->TargetVisibility();
81 return visible || wm::IsWindowMinimized(window); 94 return visible || wm::IsWindowMinimized(window) ||
95 (window->TargetVisibility() &&
96 window->parent()->id() == kShellWindowId_WorkspaceContainer);
82 } 97 }
83 98
84 // Returns true if |window| can be activated or deactivated. 99 // Returns true if |window| can be activated or deactivated.
85 // A window manager typically defines some notion of "top level window" that 100 // A window manager typically defines some notion of "top level window" that
86 // supports activation/deactivation. 101 // supports activation/deactivation.
87 bool CanActivateWindowWithEvent(aura::Window* window, 102 bool CanActivateWindowWithEvent(aura::Window* window,
88 const ui::Event* event, 103 const ui::Event* event,
89 ActivateVisibilityType visibility_type) { 104 ActivateVisibilityType visibility_type) {
90 return window && 105 return window &&
91 VisibilityMatches(window, visibility_type) && 106 VisibilityMatches(window, visibility_type) &&
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 258
244 AutoReset<bool> in_activate_window(&updating_activation_, true); 259 AutoReset<bool> in_activate_window(&updating_activation_, true);
245 // Nothing may actually have changed. 260 // Nothing may actually have changed.
246 if (active_window_ == window) 261 if (active_window_ == window)
247 return; 262 return;
248 // The stacking client may impose rules on what window configurations can be 263 // The stacking client may impose rules on what window configurations can be
249 // activated or deactivated. 264 // activated or deactivated.
250 if (window && !CanActivateWindowWithEvent(window, event, CURRENT_VISIBILITY)) 265 if (window && !CanActivateWindowWithEvent(window, event, CURRENT_VISIBILITY))
251 return; 266 return;
252 267
268 // Make sure the workspace manager switches to the workspace for window.
269 // Without this CanReceiveEvents() below returns false and activation never
270 // changes. CanReceiveEvents() returns false if |window| isn't in the active
271 // workspace, in which case its parent is not visible.
272 // TODO(sky): if I instead change the opacity of the parent this isn't an
273 // issue, but will make animations trickier... Consider which one is better.
274 if (window) {
275 internal::RootWindowController* root_window_controller =
276 GetRootWindowController(window->GetRootWindow());
277 root_window_controller->workspace_controller()->
278 SetActiveWorkspaceByWindow(window);
279 }
280
253 // Restore minimized window. This needs to be done before CanReceiveEvents() 281 // Restore minimized window. This needs to be done before CanReceiveEvents()
254 // is called as that function checks window visibility. 282 // is called as that function checks window visibility.
255 if (window && wm::IsWindowMinimized(window)) 283 if (window && wm::IsWindowMinimized(window))
256 window->Show(); 284 window->Show();
257 285
258 // If the screen is locked, just bring the window to top so that 286 // If the screen is locked, just bring the window to top so that
259 // it will be activated when the lock window is destroyed. 287 // it will be activated when the lock window is destroyed.
260 if (window && !window->CanReceiveEvents()) { 288 if (window && !window->CanReceiveEvents()) {
261 StackTransientParentsBelowModalWindow(window); 289 StackTransientParentsBelowModalWindow(window);
262 window->parent()->StackChildAtTop(window); 290 window->parent()->StackChildAtTop(window);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 if (container && container->Contains(ignore)) { 342 if (container && container->Contains(ignore)) {
315 current_container_index = i; 343 current_container_index = i;
316 break; 344 break;
317 } 345 }
318 } 346 }
319 347
320 // Look for windows to focus in that container and below. 348 // Look for windows to focus in that container and below.
321 aura::Window* window = NULL; 349 aura::Window* window = NULL;
322 for (; !window && current_container_index < arraysize(kWindowContainerIds); 350 for (; !window && current_container_index < arraysize(kWindowContainerIds);
323 current_container_index++) { 351 current_container_index++) {
324
325 aura::Window::Windows containers = 352 aura::Window::Windows containers =
326 Shell::GetAllContainers(kWindowContainerIds[current_container_index]); 353 Shell::GetAllContainers(kWindowContainerIds[current_container_index]);
327 for (aura::Window::Windows::const_iterator iter = containers.begin(); 354 for (aura::Window::Windows::const_iterator iter = containers.begin();
328 iter != containers.end(); 355 iter != containers.end() && !window; ++iter) {
329 ++iter) {
330 window = GetTopmostWindowToActivateInContainer((*iter), ignore); 356 window = GetTopmostWindowToActivateInContainer((*iter), ignore);
331 } 357 }
332 } 358 }
333 return window; 359 return window;
334 } 360 }
335 361
336 aura::Window* ActivationController::GetTopmostWindowToActivateInContainer( 362 aura::Window* ActivationController::GetTopmostWindowToActivateInContainer(
337 aura::Window* container, 363 aura::Window* container,
338 aura::Window* ignore) const { 364 aura::Window* ignore) const {
365 // Workspace2 has an extra level of windows that needs to be special cased.
366 if (container->id() == kShellWindowId_DefaultContainer &&
367 WorkspaceController::IsWorkspace2Enabled()) {
368 for (aura::Window::Windows::const_reverse_iterator i =
369 container->children().rbegin();
370 i != container->children().rend(); ++i) {
371 if ((*i)->IsVisible()) {
372 aura::Window* window = GetTopmostWindowToActivateInContainer(
373 *i, ignore);
374 if (window)
375 return window;
376 }
377 }
378 return NULL;
379 }
339 for (aura::Window::Windows::const_reverse_iterator i = 380 for (aura::Window::Windows::const_reverse_iterator i =
340 container->children().rbegin(); 381 container->children().rbegin();
341 i != container->children().rend(); 382 i != container->children().rend();
342 ++i) { 383 ++i) {
343 if (*i != ignore && 384 if (*i != ignore &&
344 CanActivateWindowWithEvent(*i, NULL, CURRENT_VISIBILITY) && 385 CanActivateWindowWithEvent(*i, NULL, CURRENT_VISIBILITY) &&
345 !wm::IsWindowMinimized(*i)) 386 !wm::IsWindowMinimized(*i))
346 return *i; 387 return *i;
347 } 388 }
348 return NULL; 389 return NULL;
349 } 390 }
350 391
351 } // namespace internal 392 } // namespace internal
352 } // namespace ash 393 } // namespace ash
OLDNEW
« no previous file with comments | « ash/shell_window_ids.h ('k') | ash/wm/always_on_top_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698