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

Side by Side Diff: components/mus/ws/focus_controller.cc

Issue 1459463004: mus: Allow the WM to specify the windows that can have active children. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tot-merge Created 5 years, 1 month 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
« no previous file with comments | « components/mus/ws/focus_controller.h ('k') | components/mus/ws/focus_controller_delegate.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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/mus/ws/focus_controller.h" 5 #include "components/mus/ws/focus_controller.h"
6 6
7 #include "components/mus/ws/focus_controller_delegate.h"
7 #include "components/mus/ws/focus_controller_observer.h" 8 #include "components/mus/ws/focus_controller_observer.h"
8 #include "components/mus/ws/server_window.h" 9 #include "components/mus/ws/server_window.h"
9 #include "components/mus/ws/server_window_drawn_tracker.h" 10 #include "components/mus/ws/server_window_drawn_tracker.h"
10 11
11 namespace mus { 12 namespace mus {
12 namespace ws { 13 namespace ws {
13 14
14 FocusController::FocusController() {} 15 FocusController::FocusController(FocusControllerDelegate* delegate)
16 : delegate_(delegate), focused_window_(nullptr), active_window_(nullptr) {}
15 17
16 FocusController::~FocusController() {} 18 FocusController::~FocusController() {}
17 19
18 void FocusController::SetFocusedWindow(ServerWindow* window) { 20 void FocusController::SetFocusedWindow(ServerWindow* window) {
19 if (GetFocusedWindow() == window) 21 if (GetFocusedWindow() == window)
20 return; 22 return;
21 23
22 SetFocusedWindowImpl(FocusControllerChangeSource::EXPLICIT, window); 24 SetFocusedWindowImpl(FocusControllerChangeSource::EXPLICIT, window);
23 } 25 }
24 26
25 ServerWindow* FocusController::GetFocusedWindow() { 27 ServerWindow* FocusController::GetFocusedWindow() {
26 return drawn_tracker_ ? drawn_tracker_->window() : nullptr; 28 return focused_window_;
27 } 29 }
28 30
29 void FocusController::AddObserver(FocusControllerObserver* observer) { 31 void FocusController::AddObserver(FocusControllerObserver* observer) {
30 observers_.AddObserver(observer); 32 observers_.AddObserver(observer);
31 } 33 }
32 34
33 void FocusController::RemoveObserver(FocusControllerObserver* observer) { 35 void FocusController::RemoveObserver(FocusControllerObserver* observer) {
34 observers_.RemoveObserver(observer); 36 observers_.RemoveObserver(observer);
35 } 37 }
36 38
37 bool FocusController::CanBeFocused(ServerWindow* window) const { 39 bool FocusController::CanBeFocused(ServerWindow* window) const {
38 // All ancestors of |window| must be drawn, and be focusable. 40 // All ancestors of |window| must be drawn, and be focusable.
39 for (ServerWindow* w = window; w; w = w->parent()) { 41 for (ServerWindow* w = window; w; w = w->parent()) {
40 if (!w->IsDrawn()) 42 if (!w->IsDrawn())
41 return false; 43 return false;
42 if (!w->can_focus()) 44 if (!w->can_focus())
43 return false; 45 return false;
44 } 46 }
45 47
46 // |window| must be a descendent of an activatable window. 48 // |window| must be a descendent of an activatable window.
47 for (ServerWindow* w = window; w; w = w->parent()) { 49 return GetActivatableAncestorOf(window) != nullptr;
48 if (CanBeActivated(w))
49 return true;
50 }
51
52 return false;
53 } 50 }
54 51
55 bool FocusController::CanBeActivated(ServerWindow* window) const { 52 bool FocusController::CanBeActivated(ServerWindow* window) const {
53 DCHECK(window);
54 // The parent window must be allowed to have active children.
55 if (!delegate_->CanHaveActiveChildren(window->parent()))
56 return false;
57
56 // TODO(sad): Implement this. 58 // TODO(sad): Implement this.
57 return true; 59 return true;
58 } 60 }
59 61
62 ServerWindow* FocusController::GetActivatableAncestorOf(
63 ServerWindow* window) const {
64 for (ServerWindow* w = window; w; w = w->parent()) {
65 if (CanBeActivated(w))
66 return w;
67 }
68 return nullptr;
69 }
70
60 void FocusController::SetFocusedWindowImpl( 71 void FocusController::SetFocusedWindowImpl(
61 FocusControllerChangeSource change_source, 72 FocusControllerChangeSource change_source,
62 ServerWindow* window) { 73 ServerWindow* window) {
63 if (window && !CanBeFocused(window)) 74 if (window && !CanBeFocused(window))
64 return; 75 return;
65 ServerWindow* old = GetFocusedWindow(); 76 ServerWindow* old_focused = GetFocusedWindow();
66 77
67 DCHECK(!window || window->IsDrawn()); 78 DCHECK(!window || window->IsDrawn());
68 79
69 // TODO(sad): Activate the closest activatable ancestor window. 80 // Activate the closest activatable ancestor window.
70 if (window) 81 // TODO(sad): The window to activate doesn't necessarily have to be a direct
71 drawn_tracker_.reset(new ServerWindowDrawnTracker(window, this)); 82 // ancestor (e.g. could be a transient parent).
83 ServerWindow* old_active = active_window_;
84 active_window_ = GetActivatableAncestorOf(window);
85 if (old_active != active_window_) {
86 FOR_EACH_OBSERVER(FocusControllerObserver, observers_,
87 OnActivationChanged(old_active, active_window_));
88 }
89
90 FOR_EACH_OBSERVER(FocusControllerObserver, observers_,
91 OnFocusChanged(change_source, old_focused, window));
92
93 focused_window_ = window;
94 // We can currently use only a single ServerWindowDrawnTracker since focused
95 // window is expected to be a direct descendant of the active window.
96 if (focused_window_ && active_window_) {
97 DCHECK(active_window_->Contains(focused_window_));
98 }
99 ServerWindow* track_window = focused_window_;
100 if (!track_window)
101 track_window = active_window_;
102 if (track_window)
103 drawn_tracker_.reset(new ServerWindowDrawnTracker(track_window, this));
72 else 104 else
73 drawn_tracker_.reset(); 105 drawn_tracker_.reset();
74
75 FOR_EACH_OBSERVER(FocusControllerObserver, observers_,
76 OnFocusChanged(change_source, old, window));
77 } 106 }
78 107
79 void FocusController::OnDrawnStateChanged(ServerWindow* ancestor, 108 void FocusController::OnDrawnStateChanged(ServerWindow* ancestor,
80 ServerWindow* window, 109 ServerWindow* window,
81 bool is_drawn) { 110 bool is_drawn) {
82 DCHECK(!is_drawn); // We only observe when drawn. 111 DCHECK(!is_drawn); // We only observe when drawn.
112 // TODO(sad): If |window| is |focused_window_|, then move focus to the next
113 // focusable window in |active_window_|, if |active_window_| is still visible.
114 // If |active_window_| is invisible, or if |window| is |active_window_|, then
115 // activate the next window that can be activated.
83 SetFocusedWindowImpl(FocusControllerChangeSource::DRAWN_STATE_CHANGED, 116 SetFocusedWindowImpl(FocusControllerChangeSource::DRAWN_STATE_CHANGED,
84 ancestor); 117 ancestor);
85 } 118 }
86 119
87 } // namespace ws 120 } // namespace ws
88 } // namespace mus 121 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/ws/focus_controller.h ('k') | components/mus/ws/focus_controller_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698