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

Side by Side Diff: ui/aura/mus/focus_synchronizer.cc

Issue 2714763002: Change FocusSynchronizer to maintain active focus client and window. (Closed)
Patch Set: fix crash in aura_test_helper tear down Created 3 years, 9 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "ui/aura/mus/focus_synchronizer.h" 5 #include "ui/aura/mus/focus_synchronizer.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "services/ui/public/interfaces/window_tree.mojom.h" 8 #include "services/ui/public/interfaces/window_tree.mojom.h"
9 #include "ui/aura/client/aura_constants.h"
9 #include "ui/aura/client/focus_client.h" 10 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/env.h"
11 #include "ui/aura/mus/focus_synchronizer_delegate.h" 11 #include "ui/aura/mus/focus_synchronizer_delegate.h"
12 #include "ui/aura/mus/window_mus.h"
13 #include "ui/aura/window.h" 12 #include "ui/aura/window.h"
14 13
15 namespace aura { 14 namespace aura {
16 15
17 FocusSynchronizer::FocusSynchronizer(FocusSynchronizerDelegate* delegate, 16 FocusSynchronizer::FocusSynchronizer(FocusSynchronizerDelegate* delegate,
18 ui::mojom::WindowTree* window_tree) 17 ui::mojom::WindowTree* window_tree)
19 : delegate_(delegate), window_tree_(window_tree) { 18 : delegate_(delegate), window_tree_(window_tree) {}
20 Env::GetInstance()->AddObserver(this);
21 }
22 19
23 FocusSynchronizer::~FocusSynchronizer() { 20 FocusSynchronizer::~FocusSynchronizer() {
24 SetActiveFocusClient(nullptr); 21 SetActiveFocusClient(nullptr);
25 Env::GetInstance()->RemoveObserver(this); 22 }
23
24 void FocusSynchronizer::AddObserver(FocusSynchronizerObserver* observer) {
25 observers_.AddObserver(observer);
26 }
27
28 void FocusSynchronizer::RemoveObserver(FocusSynchronizerObserver* observer) {
29 observers_.RemoveObserver(observer);
26 } 30 }
27 31
28 void FocusSynchronizer::SetFocusFromServer(WindowMus* window) { 32 void FocusSynchronizer::SetFocusFromServer(WindowMus* window) {
29 if (focused_window_ == window) 33 if (focused_window_ == window)
30 return; 34 return;
31 35
32 DCHECK(!setting_focus_); 36 DCHECK(!setting_focus_);
33 base::AutoReset<bool> focus_reset(&setting_focus_, true); 37 base::AutoReset<bool> focus_reset(&setting_focus_, true);
34 base::AutoReset<WindowMus*> window_setting_focus_to_reset( 38 base::AutoReset<WindowMus*> window_setting_focus_to_reset(
35 &window_setting_focus_to_, window); 39 &window_setting_focus_to_, window);
36 Env* env = Env::GetInstance(); 40
37 if (window) { 41 if (window) {
38 Window* root = window->GetWindow()->GetRootWindow(); 42 Window* root = window->GetWindow()->GetRootWindow();
39 // The client should provide a focus client for all roots. 43 // The client should provide a focus client for all roots.
40 DCHECK(client::GetFocusClient(root)); 44 DCHECK(client::GetFocusClient(root));
41 if (env->active_focus_client_root() != root) 45 if (focused_window() != root)
42 env->SetActiveFocusClient(client::GetFocusClient(root), root); 46 OnActiveFocusClientChanged(client::GetFocusClient(root), root);
43 window->GetWindow()->Focus(); 47 window->GetWindow()->Focus();
44 } else if (env->active_focus_client()) { 48 } else if (active_focus_client_) {
45 env->active_focus_client()->FocusWindow(nullptr); 49 active_focus_client_->FocusWindow(nullptr);
46 } 50 }
47 } 51 }
48 52
49 void FocusSynchronizer::OnFocusedWindowDestroyed() { 53 void FocusSynchronizer::OnFocusedWindowDestroyed() {
54 UpdateFocusedWindowObserver(nullptr);
50 focused_window_ = nullptr; 55 focused_window_ = nullptr;
51 } 56 }
52 57
58 void FocusSynchronizer::AttachToFocusClient(client::FocusClient* focus_client,
59 Window* focus_client_root) {
60 OnActiveFocusClientChanged(focus_client, focus_client_root);
61 }
62
63 void FocusSynchronizer::DetachFromFocusClient(
64 client::FocusClient* focus_client) {
65 if (focus_client == active_focus_client_)
66 OnActiveFocusClientChanged(nullptr, nullptr);
67 else
68 focus_client->RemoveObserver(this);
69 }
70
53 void FocusSynchronizer::SetActiveFocusClient( 71 void FocusSynchronizer::SetActiveFocusClient(
54 client::FocusClient* focus_client) { 72 client::FocusClient* focus_client) {
55 if (focus_client == active_focus_client_) 73 if (focus_client == active_focus_client_)
56 return; 74 return;
57 75
58 if (active_focus_client_) 76 if (active_focus_client_)
59 active_focus_client_->RemoveObserver(this); 77 active_focus_client_->RemoveObserver(this);
60 active_focus_client_ = focus_client; 78 active_focus_client_ = focus_client;
61 if (active_focus_client_) 79 if (active_focus_client_)
62 active_focus_client_->AddObserver(this); 80 active_focus_client_->AddObserver(this);
63 } 81 }
64 82
83 void FocusSynchronizer::UpdateFocusedWindowObserver(Window* window) {
84 if (focused_window())
85 focused_window()->RemoveObserver(this);
86 if (window)
87 window->AddObserver(this);
88 }
89
65 void FocusSynchronizer::SetFocusedWindow(WindowMus* window) { 90 void FocusSynchronizer::SetFocusedWindow(WindowMus* window) {
66 const uint32_t change_id = delegate_->CreateChangeIdForFocus(focused_window_); 91 const uint32_t change_id = delegate_->CreateChangeIdForFocus(focused_window_);
67 focused_window_ = window; 92 focused_window_ = window;
68 window_tree_->SetFocus(change_id, 93 window_tree_->SetFocus(change_id,
69 window ? window->server_id() : kInvalidServerId); 94 window ? window->server_id() : kInvalidServerId);
70 } 95 }
71 96
97 void FocusSynchronizer::OnActiveFocusClientChanged(
98 client::FocusClient* focus_client,
99 Window* window) {
100 if (focus_client == active_focus_client_ && window == focused_window())
101 return;
102
103 SetActiveFocusClient(focus_client);
104 if (setting_focus_)
105 return;
106
107 if (focus_client) {
108 Window* focused_window = focus_client->GetFocusedWindow();
109 UpdateFocusedWindowObserver(focused_window ? focused_window : window);
110 SetFocusedWindow(focused_window ? WindowMus::Get(focused_window)
111 : WindowMus::Get(window));
112 } else {
113 UpdateFocusedWindowObserver(nullptr);
114 SetFocusedWindow(nullptr);
115 }
116
117 for (FocusSynchronizerObserver& observer : observers_)
118 observer.OnActiveFocusClientChanged(focus_client, window);
119 }
120
121 void FocusSynchronizer::OnWindowDestroying(Window* window) {
122 OnActiveFocusClientChanged(nullptr, nullptr);
123 }
124
125 void FocusSynchronizer::OnWindowPropertyChanged(Window* window,
126 const void* key,
127 intptr_t old) {
128 if (key != client::kFocusClientKey)
129 return;
130
131 // Assume if the focus client changes the window is being destroyed.
132 OnActiveFocusClientChanged(nullptr, nullptr);
133 }
134
72 void FocusSynchronizer::OnWindowFocused(Window* gained_focus, 135 void FocusSynchronizer::OnWindowFocused(Window* gained_focus,
73 Window* lost_focus) { 136 Window* lost_focus) {
74 WindowMus* gained_focus_mus = WindowMus::Get(gained_focus); 137 WindowMus* gained_focus_mus = WindowMus::Get(gained_focus);
138 UpdateFocusedWindowObserver(gained_focus);
75 if (setting_focus_ && gained_focus_mus == window_setting_focus_to_) { 139 if (setting_focus_ && gained_focus_mus == window_setting_focus_to_) {
76 focused_window_ = gained_focus_mus; 140 focused_window_ = gained_focus_mus;
77 return; 141 return;
78 } 142 }
79 SetFocusedWindow(gained_focus_mus); 143 SetFocusedWindow(gained_focus_mus);
80 } 144 }
81 145
82 void FocusSynchronizer::OnWindowInitialized(Window* window) {}
83
84 void FocusSynchronizer::OnActiveFocusClientChanged(
85 client::FocusClient* focus_client,
86 Window* window) {
87 SetActiveFocusClient(focus_client);
88 if (setting_focus_)
89 return;
90
91 if (focus_client) {
92 Window* focused_window = focus_client->GetFocusedWindow();
93 SetFocusedWindow(focused_window ? WindowMus::Get(focused_window)
94 : WindowMus::Get(window));
95 } else {
96 SetFocusedWindow(nullptr);
97 }
98 }
99
100 } // namespace aura 146 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698