| OLD | NEW |
| 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 Loading... |
| 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 | |
| OLD | NEW |