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

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: . 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
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_delegate.h"
8 #include "components/mus/ws/server_window.h" 8 #include "components/mus/ws/server_window.h"
9 #include "components/mus/ws/server_window_drawn_tracker.h" 9 #include "components/mus/ws/server_window_drawn_tracker.h"
10 10
11 namespace mus { 11 namespace mus {
12 12
13 namespace ws { 13 namespace ws {
14 14
15 FocusController::FocusController(FocusControllerDelegate* delegate) 15 FocusController::FocusController(FocusControllerDelegate* delegate)
16 : delegate_(delegate) {} 16 : delegate_(delegate), focused_window_(nullptr), active_window_(nullptr) {}
17 17
18 FocusController::~FocusController() {} 18 FocusController::~FocusController() {}
19 19
20 void FocusController::SetFocusedWindow(ServerWindow* window) { 20 void FocusController::SetFocusedWindow(ServerWindow* window) {
21 if (GetFocusedWindow() == window) 21 if (GetFocusedWindow() == window)
22 return; 22 return;
23 23
24 SetFocusedWindowImpl(window, CHANGE_SOURCE_EXPLICIT); 24 SetFocusedWindowImpl(window, CHANGE_SOURCE_EXPLICIT);
25 } 25 }
26 26
27 ServerWindow* FocusController::GetFocusedWindow() { 27 ServerWindow* FocusController::GetFocusedWindow() {
28 return drawn_tracker_ ? drawn_tracker_->window() : nullptr; 28 return focused_window_;
29 } 29 }
30 30
31 bool FocusController::CanBeFocused(ServerWindow* window) const { 31 bool FocusController::CanBeFocused(ServerWindow* window) const {
32 // All ancestors of |window| must be drawn, and be focusable. 32 // All ancestors of |window| must be drawn, and be focusable.
33 for (ServerWindow* w = window; w; w = w->parent()) { 33 for (ServerWindow* w = window; w; w = w->parent()) {
34 if (!w->IsDrawn()) 34 if (!w->IsDrawn())
35 return false; 35 return false;
36 if (!w->can_focus()) 36 if (!w->can_focus())
37 return false; 37 return false;
38 } 38 }
39 39
40 // |window| must be a descendent of an activatable window. 40 // |window| must be a descendent of an activatable window.
41 for (ServerWindow* w = window; w; w = w->parent()) { 41 return GetActivatableAncestorOf(window) != nullptr;
42 if (CanBeActivated(w))
43 return true;
44 }
45
46 return false;
47 } 42 }
48 43
49 bool FocusController::CanBeActivated(ServerWindow* window) const { 44 bool FocusController::CanBeActivated(ServerWindow* window) const {
45 DCHECK(window);
46 // The parent window must be allowed to have active children.
47 if (!delegate_->CanHaveActiveChildren(window->parent()))
48 return false;
49
50 // TODO(sad): Implement this. 50 // TODO(sad): Implement this.
51 return true; 51 return true;
52 } 52 }
53 53
54 ServerWindow* FocusController::GetActivatableAncestorOf(
55 ServerWindow* window) const {
56 for (ServerWindow* w = window; w; w = w->parent()) {
57 if (CanBeActivated(w))
58 return w;
59 }
60 return nullptr;
61 }
62
54 void FocusController::SetFocusedWindowImpl(ServerWindow* window, 63 void FocusController::SetFocusedWindowImpl(ServerWindow* window,
55 ChangeSource change_source) { 64 ChangeSource change_source) {
56 if (window && !CanBeFocused(window)) 65 if (window && !CanBeFocused(window)) {
57 return; 66 // Allow the old focused window to lose focus even if |window| cannot be
58 ServerWindow* old = GetFocusedWindow(); 67 // focused.
Ben Goodger (Google) 2015/11/19 07:26:24 what's the reason for this policy?
sadrul 2015/11/19 19:33:34 Hm, I thought this is what we wanted to do. But I
Ben Goodger (Google) 2015/11/23 22:29:45 Yeah I was concerned you'd be left in a bad state
68 window = nullptr;
69 }
70 ServerWindow* old_focused = GetFocusedWindow();
59 71
60 DCHECK(!window || window->IsDrawn()); 72 DCHECK(!window || window->IsDrawn());
61 73
62 // TODO(sad): Activate the closest activatable ancestor window. 74 // Activate the closest activatable ancestor window.
63 if (window) 75 // TODO(sad): The window to activate doesn't necessarily have to be a direct
64 drawn_tracker_.reset(new ServerWindowDrawnTracker(window, this)); 76 // ancestor (e.g. could be a transient parent).
77 ServerWindow* old_active = active_window_;
78 active_window_ = GetActivatableAncestorOf(window);
79 if (old_active != active_window_)
80 delegate_->OnActivationChanged(old_active, active_window_);
81
82 focused_window_ = window;
83 if (change_source == CHANGE_SOURCE_DRAWN_STATE_CHANGED)
84 delegate_->OnFocusChanged(old_focused, focused_window_);
85
86 // We can currently use only a single ServerWindowDrawnTracker since focused
87 // window is expected to be a direct descendant of the active window.
88 if (focused_window_ && active_window_) {
89 DCHECK(active_window_->Contains(focused_window_));
90 }
91 ServerWindow* track_window = focused_window_;
92 if (!track_window)
93 track_window = active_window_;
94 if (track_window)
95 drawn_tracker_.reset(new ServerWindowDrawnTracker(track_window, this));
65 else 96 else
66 drawn_tracker_.reset(); 97 drawn_tracker_.reset();
67
68 if (change_source == CHANGE_SOURCE_DRAWN_STATE_CHANGED)
69 delegate_->OnFocusChanged(old, window);
70 } 98 }
71 99
72 void FocusController::OnDrawnStateChanged(ServerWindow* ancestor, 100 void FocusController::OnDrawnStateChanged(ServerWindow* ancestor,
73 ServerWindow* window, 101 ServerWindow* window,
74 bool is_drawn) { 102 bool is_drawn) {
75 DCHECK(!is_drawn); // We only observe when drawn. 103 DCHECK(!is_drawn); // We only observe when drawn.
104 // TODO(sad): If |window| is |focused_window_|, then move focus to the next
105 // focusable window in |active_window_|, if |active_window_| is still visible.
106 // If |active_window_| is invisible, or if |window| is |active_window_|, then
107 // activate the next window that can be activated.
76 SetFocusedWindowImpl(ancestor, CHANGE_SOURCE_DRAWN_STATE_CHANGED); 108 SetFocusedWindowImpl(ancestor, CHANGE_SOURCE_DRAWN_STATE_CHANGED);
77 } 109 }
78 110
79 } // namespace ws 111 } // namespace ws
80 112
81 } // namespace mus 113 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698