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

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