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

Side by Side Diff: mash/simple_wm/simple_wm.cc

Issue 2571653002: Add a basic task switcher to the simple window manager. (Closed)
Patch Set: . Created 4 years 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 | « mash/simple_wm/simple_wm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "mash/simple_wm/simple_wm.h" 5 #include "mash/simple_wm/simple_wm.h"
6 6
7 #include "base/observer_list.h"
7 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
8 #include "ui/aura/client/aura_constants.h" 9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/layout_manager.h"
9 #include "ui/display/screen_base.h" 11 #include "ui/display/screen_base.h"
10 #include "ui/gfx/canvas.h" 12 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/geometry/mojo/geometry.mojom.h" 13 #include "ui/gfx/geometry/mojo/geometry.mojom.h"
14 #include "ui/views/controls/button/md_text_button.h"
12 #include "ui/views/controls/label.h" 15 #include "ui/views/controls/label.h"
13 #include "ui/views/mus/aura_init.h" 16 #include "ui/views/mus/aura_init.h"
14 #include "ui/views/mus/mus_client.h" 17 #include "ui/views/mus/mus_client.h"
15 #include "ui/views/widget/native_widget_aura.h" 18 #include "ui/views/widget/native_widget_aura.h"
16 #include "ui/views/widget/widget.h" 19 #include "ui/views/widget/widget.h"
17 #include "ui/views/widget/widget_delegate.h" 20 #include "ui/views/widget/widget_delegate.h"
18 #include "ui/wm/core/default_activation_client.h" 21 #include "ui/wm/core/default_activation_client.h"
19 22
20 namespace simple_wm { 23 namespace simple_wm {
21 24
22 namespace { 25 namespace {
23 26
24 const int kNonClientTopHeight = 24; 27 const int kNonClientTopHeight = 24;
25 const int kNonClientSize = 5; 28 const int kNonClientSize = 5;
26 29
27 } // namespace 30 } // namespace
28 31
32 class SimpleWM::WindowListModelObserver {
33 public:
34 virtual void OnWindowAddedOrRemoved() = 0;
35 virtual void OnWindowTitleChanged(size_t index,
36 const base::string16& title) = 0;
37 };
38
39 class SimpleWM::WindowListModel : public aura::WindowObserver {
40 public:
41 explicit WindowListModel(aura::Window* window_container)
42 : window_container_(window_container) {
43 window_container_->AddObserver(this);
44 }
45 ~WindowListModel() override {
46 window_container_->RemoveObserver(this);
47 for (auto window : windows_)
48 window->RemoveObserver(this);
49 }
50
51 size_t GetSize() const {
52 return windows_.size();
53 }
54 base::string16 GetTitle(size_t index) const {
55 return windows_.at(index)->GetTitle();
56 }
57 aura::Window* GetWindow(size_t index) const {
58 return windows_.at(index);
59 }
60
61 void AddObserver(WindowListModelObserver* observer) {
62 observers_.AddObserver(observer);
63 }
64 void RemoveObserver(WindowListModelObserver* observer) {
65 observers_.RemoveObserver(observer);
66 }
67
68 private:
69 // aura::WindowObserver:
70 void OnWindowAdded(aura::Window* window) override {
71 if (window->parent() == window_container_)
72 AddWindow(window);
73 for (auto& observer : observers_)
74 observer.OnWindowAddedOrRemoved();
75 }
76 void OnWillRemoveWindow(aura::Window* window) override {
77 window->RemoveObserver(this);
78 for (auto& observer : observers_)
79 observer.OnWindowAddedOrRemoved();
80 auto it = std::find(windows_.begin(), windows_.end(), window);
81 DCHECK(it != windows_.end());
82 windows_.erase(it);
83 }
84 void OnWindowTitleChanged(aura::Window* window) override {
85 auto it = std::find(windows_.begin(), windows_.end(), window);
86 size_t index = it - windows_.begin();
87 for (auto& observer : observers_)
88 observer.OnWindowTitleChanged(index, window->GetTitle());
89 }
90
91 void AddWindow(aura::Window* window) {
92 window->AddObserver(this);
93 auto it = std::find(windows_.begin(), windows_.end(), window);
94 DCHECK(it == windows_.end());
95 windows_.push_back(window);
96 }
97
98 aura::Window* window_container_;
99 std::vector<aura::Window*> windows_;
100 base::ObserverList<WindowListModelObserver> observers_;
101
102 DISALLOW_COPY_AND_ASSIGN(WindowListModel);
103 };
104
105 class SimpleWM::WindowListView : public views::WidgetDelegateView,
106 public views::ButtonListener,
107 public SimpleWM::WindowListModelObserver {
108 public:
109 using ActivateCallback = base::Callback<void(aura::Window*)>;
110
111 WindowListView(WindowListModel* model, ActivateCallback activate_callback)
112 : model_(model), activate_callback_(activate_callback) {
113 model_->AddObserver(this);
114 Rebuild();
115 }
116 ~WindowListView() override {
117 model_->RemoveObserver(this);
118 }
119
120 static const int kButtonSpacing = 5;
121
122 // views::View
123 void Layout() override {
124 int x_offset = kButtonSpacing;
125 for (int i = 0; i < child_count(); ++i) {
126 View* v = child_at(i);
127 gfx::Size ps = v->GetPreferredSize();
128 gfx::Rect bounds(x_offset, kButtonSpacing, ps.width(), ps.height());
129 v->SetBoundsRect(bounds);
130 x_offset = bounds.right() + kButtonSpacing;
131 }
132 }
133 void OnPaint(gfx::Canvas* canvas) override {
134 canvas->DrawColor(SK_ColorLTGRAY);
135 }
136 gfx::Size GetPreferredSize() const override {
137 std::unique_ptr<views::MdTextButton> measure_button(
138 views::MdTextButton::Create(nullptr, base::UTF8ToUTF16("Sample")));
139 int height =
140 measure_button->GetPreferredSize().height() + 2 * kButtonSpacing;
141 return gfx::Size(0, height);
142 }
143
144 private:
145 // views::ButtonListener:
146 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
147 activate_callback_.Run(
148 model_->GetWindow(static_cast<size_t>(sender->tag())));
149 }
150
151 // WindowListModelObserver:
152 void OnWindowAddedOrRemoved() override {
153 Rebuild();
154 }
155 void OnWindowTitleChanged(size_t index,
156 const base::string16& new_title) override {
157 views::MdTextButton* label =
158 static_cast<views::MdTextButton*>(child_at(static_cast<int>(index)));
159 label->SetText(new_title);
160 Layout();
161 }
162
163 void Rebuild() {
164 RemoveAllChildViews(true);
165
166 size_t size = model_->GetSize();
167 for (size_t i = 0; i < size; ++i) {
168 base::string16 title = model_->GetTitle(i);
169 if (title.empty())
170 title = base::UTF8ToUTF16("Untitled");
171 views::MdTextButton* button = views::MdTextButton::Create(this, title);
172 button->set_tag(static_cast<int>(i));
173 AddChildView(button);
174 }
175 Layout();
176 }
177
178 WindowListModel* model_;
179 ActivateCallback activate_callback_;
180
181 DISALLOW_COPY_AND_ASSIGN(WindowListView);
182 };
183
29 class SimpleWM::FrameView : public views::WidgetDelegateView, 184 class SimpleWM::FrameView : public views::WidgetDelegateView,
30 public aura::WindowObserver { 185 public aura::WindowObserver {
31 public: 186 public:
32 explicit FrameView(aura::Window* client_window) 187 explicit FrameView(aura::Window* client_window)
33 : client_window_(client_window) { 188 : client_window_(client_window) {
34 client_window_->AddObserver(this); 189 client_window_->AddObserver(this);
35 } 190 }
36 ~FrameView() override {} 191 ~FrameView() override {}
37 192
38 private: 193 private:
39 // views::WidgetDelegateView: 194 // views::WidgetDelegateView:
40 base::string16 GetWindowTitle() const override { 195 base::string16 GetWindowTitle() const override {
41 base::string16* title = 196 base::string16* title_from_property =
42 client_window_->GetProperty(aura::client::kTitleKey); 197 client_window_->GetProperty(aura::client::kTitleKey);
43 if (!title) 198 base::string16 title = title_from_property ? *title_from_property
44 return base::UTF8ToUTF16("(Window)"); 199 : base::UTF8ToUTF16("(Window)");
45 return *title; 200 // TODO(beng): quick hack to cause WindowObserver::OnWindowTitleChanged to
201 // fire.
202 GetWidget()->GetNativeWindow()->SetTitle(title);
203 return title;
46 } 204 }
47 void Layout() override { 205 void Layout() override {
48 // Client offsets are applied automatically by the window service. 206 // Client offsets are applied automatically by the window service.
49 gfx::Rect parent_bounds = GetWidget()->GetNativeWindow()->bounds(); 207 gfx::Rect parent_bounds = GetWidget()->GetNativeWindow()->bounds();
50 parent_bounds.set_origin(gfx::Point()); 208 parent_bounds.set_origin(gfx::Point());
51 client_window_->SetBounds(parent_bounds); 209 client_window_->SetBounds(parent_bounds);
52 } 210 }
53 211
54 // aura::WindowObserver: 212 // aura::WindowObserver:
55 void OnWindowPropertyChanged(aura::Window* window, const void* key, 213 void OnWindowPropertyChanged(aura::Window* window, const void* key,
56 intptr_t old) override { 214 intptr_t old) override {
57 if (key == aura::client::kTitleKey) 215 if (key == aura::client::kTitleKey)
58 GetWidget()->UpdateWindowTitle(); 216 GetWidget()->UpdateWindowTitle();
59 } 217 }
60 218
61 aura::Window* client_window_; 219 aura::Window* client_window_;
62 220
63 DISALLOW_COPY_AND_ASSIGN(FrameView); 221 DISALLOW_COPY_AND_ASSIGN(FrameView);
64 }; 222 };
65 223
224 class SimpleWM::DisplayLayoutManager : public aura::LayoutManager {
225 public:
226 DisplayLayoutManager(aura::Window* display_root,
227 aura::Window* window_root,
228 SimpleWM::WindowListView* window_list_view)
229 : display_root_(display_root),
230 window_root_(window_root),
231 window_list_view_(window_list_view) {}
232 ~DisplayLayoutManager() override {}
233
234 private:
235 // aura::LayoutManager:
236 void OnWindowResized() override {}
237 void OnWindowAddedToLayout(aura::Window* child) override {
238 Layout();
239 }
240 void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
241 void OnWindowRemovedFromLayout(aura::Window* child) override {}
242 void OnChildWindowVisibilityChanged(aura::Window* child,
243 bool visible) override {}
244 void SetChildBounds(aura::Window* child,
245 const gfx::Rect& requested_bounds) override {
246 SetChildBoundsDirect(child, requested_bounds);
247 }
248
249 void Layout() {
250 gfx::Size ps = window_list_view_->GetPreferredSize();
251 gfx::Rect bounds = display_root_->bounds();
252 gfx::Rect window_root_bounds = bounds;
253 window_root_bounds.set_height(window_root_bounds.height() - ps.height());
254 window_root_->SetBounds(window_root_bounds);
255 gfx::Rect window_list_view_bounds = bounds;
256 window_list_view_bounds.set_height(ps.height());
257 window_list_view_bounds.set_y(window_root_bounds.bottom());
258 window_list_view_->GetWidget()->SetBounds(window_list_view_bounds);
259 }
260
261 aura::Window* display_root_;
262 aura::Window* window_root_;
263 SimpleWM::WindowListView* window_list_view_;
264
265 DISALLOW_COPY_AND_ASSIGN(DisplayLayoutManager);
266 };
267
66 SimpleWM::SimpleWM() {} 268 SimpleWM::SimpleWM() {}
67 269
68 SimpleWM::~SimpleWM() { 270 SimpleWM::~SimpleWM() {
69 // WindowTreeHost uses state from WindowTreeClient, so destroy it first. 271 // WindowTreeHost uses state from WindowTreeClient, so destroy it first.
70 window_tree_host_.reset(); 272 window_tree_host_.reset();
71 273
72 // WindowTreeClient destruction may callback to us. 274 // WindowTreeClient destruction may callback to us.
73 window_tree_client_.reset(); 275 window_tree_client_.reset();
74 276
75 gpu_.reset(); 277 gpu_.reset();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 SetWindowType(client_window, window_type); 360 SetWindowType(client_window, window_type);
159 client_window->Init(ui::LAYER_NOT_DRAWN); 361 client_window->Init(ui::LAYER_NOT_DRAWN);
160 362
161 views::Widget* frame_widget = new views::Widget; 363 views::Widget* frame_widget = new views::Widget;
162 views::NativeWidgetAura* frame_native_widget = 364 views::NativeWidgetAura* frame_native_widget =
163 new views::NativeWidgetAura(frame_widget, true); 365 new views::NativeWidgetAura(frame_widget, true);
164 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 366 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
165 FrameView* frame_view = new FrameView(client_window); 367 FrameView* frame_view = new FrameView(client_window);
166 params.delegate = frame_view; 368 params.delegate = frame_view;
167 params.native_widget = frame_native_widget; 369 params.native_widget = frame_native_widget;
168 params.parent = root_; 370 params.parent = window_root_;
169 params.bounds = gfx::Rect(10, 10, 500, 500); 371 params.bounds = gfx::Rect(10, 10, 500, 500);
170 frame_widget->Init(params); 372 frame_widget->Init(params);
171 frame_widget->Show(); 373 frame_widget->Show();
172 374
173 frame_widget->GetNativeWindow()->AddChild(client_window); 375 frame_widget->GetNativeWindow()->AddChild(client_window);
174 376
175 client_window_to_frame_view_[client_window] = frame_view; 377 client_window_to_frame_view_[client_window] = frame_view;
176 // TODO(beng): probably need to observe client_window from now on so we can 378 // TODO(beng): probably need to observe client_window from now on so we can
177 // clean up this map. 379 // clean up this map.
178 380
179 return client_window; 381 return client_window;
180 } 382 }
181 383
182 void SimpleWM::OnWmClientJankinessChanged( 384 void SimpleWM::OnWmClientJankinessChanged(
183 const std::set<aura::Window*>& client_windows, 385 const std::set<aura::Window*>& client_windows,
184 bool janky) { 386 bool janky) {
185 // Don't care. 387 // Don't care.
186 } 388 }
187 389
188 void SimpleWM::OnWmWillCreateDisplay(const display::Display& display) { 390 void SimpleWM::OnWmWillCreateDisplay(const display::Display& display) {
189 screen_->display_list().AddDisplay(display, 391 screen_->display_list().AddDisplay(display,
190 display::DisplayList::Type::PRIMARY); 392 display::DisplayList::Type::PRIMARY);
191 } 393 }
192 394
193 void SimpleWM::OnWmNewDisplay( 395 void SimpleWM::OnWmNewDisplay(
194 std::unique_ptr<aura::WindowTreeHostMus> window_tree_host, 396 std::unique_ptr<aura::WindowTreeHostMus> window_tree_host,
195 const display::Display& display) { 397 const display::Display& display) {
196 // Only handles a single root. 398 // Only handles a single root.
197 DCHECK(!root_); 399 DCHECK(!window_root_);
198 window_tree_host_ = std::move(window_tree_host); 400 window_tree_host_ = std::move(window_tree_host);
199 root_ = window_tree_host_->window(); 401 window_tree_host_->InitHost();
402 display_root_ = window_tree_host_->window();
403 window_root_ = new aura::Window(nullptr);
404 window_root_->Init(ui::LAYER_NOT_DRAWN);
405 display_root_->AddChild(window_root_);
406 window_root_->Show();
407
408 window_list_model_ = base::MakeUnique<WindowListModel>(window_root_);
409
410 views::Widget* window_list_widget = new views::Widget;
411 views::NativeWidgetAura* window_list_widget_native_widget =
412 new views::NativeWidgetAura(window_list_widget, true);
413 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
414 WindowListView* window_list_view =
415 new WindowListView(window_list_model_.get(),
416 base::Bind(&SimpleWM::OnWindowListViewItemActivated,
417 base::Unretained(this)));
418 params.delegate = window_list_view;
419 params.native_widget = window_list_widget_native_widget;
420 params.parent = display_root_;
421 window_list_widget->Init(params);
422 window_list_widget->Show();
423
424 display_root_->SetLayoutManager(new DisplayLayoutManager(
425 display_root_, window_root_, window_list_view));
426
200 DCHECK(window_manager_client_); 427 DCHECK(window_manager_client_);
201 window_manager_client_->AddActivationParent(root_); 428 window_manager_client_->AddActivationParent(window_root_);
202 ui::mojom::FrameDecorationValuesPtr frame_decoration_values = 429 ui::mojom::FrameDecorationValuesPtr frame_decoration_values =
203 ui::mojom::FrameDecorationValues::New(); 430 ui::mojom::FrameDecorationValues::New();
204 frame_decoration_values->normal_client_area_insets.Set( 431 frame_decoration_values->normal_client_area_insets.Set(
205 kNonClientTopHeight, kNonClientSize, kNonClientSize, kNonClientSize); 432 kNonClientTopHeight, kNonClientSize, kNonClientSize, kNonClientSize);
206 frame_decoration_values->max_title_bar_button_width = 0; 433 frame_decoration_values->max_title_bar_button_width = 0;
207 window_manager_client_->SetFrameDecorationValues( 434 window_manager_client_->SetFrameDecorationValues(
208 std::move(frame_decoration_values)); 435 std::move(frame_decoration_values));
209 new wm::DefaultActivationClient(root_); 436 new wm::DefaultActivationClient(display_root_);
210 aura::client::SetFocusClient(root_, &focus_client_); 437 aura::client::SetFocusClient(display_root_, &focus_client_);
211 } 438 }
212 439
213 void SimpleWM::OnWmDisplayRemoved( 440 void SimpleWM::OnWmDisplayRemoved(
214 aura::WindowTreeHostMus* window_tree_host) { 441 aura::WindowTreeHostMus* window_tree_host) {
215 DCHECK_EQ(window_tree_host, window_tree_host_.get()); 442 DCHECK_EQ(window_tree_host, window_tree_host_.get());
216 root_ = nullptr; 443 window_root_ = nullptr;
217 window_tree_host_.reset(); 444 window_tree_host_.reset();
218 } 445 }
219 446
220 void SimpleWM::OnWmDisplayModified(const display::Display& display) {} 447 void SimpleWM::OnWmDisplayModified(const display::Display& display) {}
221 448
222 void SimpleWM::OnWmPerformMoveLoop( 449 void SimpleWM::OnWmPerformMoveLoop(
223 aura::Window* window, 450 aura::Window* window,
224 ui::mojom::MoveLoopSource source, 451 ui::mojom::MoveLoopSource source,
225 const gfx::Point& cursor_location, 452 const gfx::Point& cursor_location,
226 const base::Callback<void(bool)>& on_done) { 453 const base::Callback<void(bool)>& on_done) {
227 // Don't care. 454 // Don't care.
228 } 455 }
229 456
230 void SimpleWM::OnWmCancelMoveLoop(aura::Window* window) {} 457 void SimpleWM::OnWmCancelMoveLoop(aura::Window* window) {}
231 458
232 void SimpleWM::OnWmSetClientArea( 459 void SimpleWM::OnWmSetClientArea(
233 aura::Window* window, 460 aura::Window* window,
234 const gfx::Insets& insets, 461 const gfx::Insets& insets,
235 const std::vector<gfx::Rect>& additional_client_areas) {} 462 const std::vector<gfx::Rect>& additional_client_areas) {}
236 463
237 SimpleWM::FrameView* SimpleWM::GetFrameViewForClientWindow( 464 SimpleWM::FrameView* SimpleWM::GetFrameViewForClientWindow(
238 aura::Window* client_window) { 465 aura::Window* client_window) {
239 auto it = client_window_to_frame_view_.find(client_window); 466 auto it = client_window_to_frame_view_.find(client_window);
240 return it != client_window_to_frame_view_.end() ? it->second : nullptr; 467 return it != client_window_to_frame_view_.end() ? it->second : nullptr;
241 } 468 }
242 469
470 void SimpleWM::OnWindowListViewItemActivated(aura::Window* window) {
471 aura::client::ActivationClient* activation_client =
472 aura::client::GetActivationClient(window->GetRootWindow());
473 activation_client->ActivateWindow(window);
474 }
475
243 } // namespace simple_wm 476 } // namespace simple_wm
244
OLDNEW
« no previous file with comments | « mash/simple_wm/simple_wm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698