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

Side by Side Diff: ash/mus/shelf_delegate_mus.cc

Issue 1899323002: Add mash shelf application id support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync and rebase. Created 4 years, 8 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 "ash/mus/shelf_delegate_mus.h" 5 #include "ash/mus/shelf_delegate_mus.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "ash/shelf/shelf.h" 9 #include "ash/shelf/shelf.h"
10 #include "ash/shelf/shelf_item_delegate.h" 10 #include "ash/shelf/shelf_item_delegate.h"
11 #include "ash/shelf/shelf_item_delegate_manager.h" 11 #include "ash/shelf/shelf_item_delegate_manager.h"
12 #include "ash/shelf/shelf_layout_manager.h" 12 #include "ash/shelf/shelf_layout_manager.h"
13 #include "ash/shelf/shelf_menu_model.h"
13 #include "ash/shelf/shelf_model.h" 14 #include "ash/shelf/shelf_model.h"
14 #include "ash/shelf/shelf_types.h" 15 #include "ash/shelf/shelf_types.h"
15 #include "ash/shelf/shelf_widget.h" 16 #include "ash/shelf/shelf_widget.h"
16 #include "ash/shell.h" 17 #include "ash/shell.h"
17 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
18 #include "components/mus/public/cpp/property_type_converters.h" 19 #include "components/mus/public/cpp/property_type_converters.h"
19 #include "components/mus/public/cpp/window.h" 20 #include "components/mus/public/cpp/window.h"
20 #include "components/mus/public/cpp/window_property.h" 21 #include "components/mus/public/cpp/window_property.h"
21 #include "mojo/common/common_type_converters.h" 22 #include "mojo/common/common_type_converters.h"
22 #include "services/shell/public/cpp/connector.h" 23 #include "services/shell/public/cpp/connector.h"
23 #include "skia/public/type_converters.h" 24 #include "skia/public/type_converters.h"
24 #include "ui/aura/mus/mus_util.h" 25 #include "ui/aura/mus/mus_util.h"
25 #include "ui/base/resource/resource_bundle.h" 26 #include "ui/base/resource/resource_bundle.h"
26 #include "ui/gfx/image/image_skia.h" 27 #include "ui/gfx/image/image_skia.h"
27 #include "ui/resources/grit/ui_resources.h" 28 #include "ui/resources/grit/ui_resources.h"
28 #include "ui/views/mus/window_manager_connection.h" 29 #include "ui/views/mus/window_manager_connection.h"
29 30
30 using mash::wm::mojom::UserWindowController; 31 using mash::wm::mojom::UserWindowController;
31 32
32 namespace ash { 33 namespace ash {
33 namespace sysui { 34 namespace sysui {
34 35
35 namespace { 36 namespace {
36 37
37 // A ShelfItemDelegate used for pinned items and open user windows. 38 // A ShelfItemDelegate used for pinned items and open user windows.
38 class ShelfItemDelegateMus : public ShelfItemDelegate { 39 class ShelfItemDelegateMus : public ShelfItemDelegate {
39 public: 40 public:
40 ShelfItemDelegateMus(uint32_t window_id, 41 explicit ShelfItemDelegateMus(UserWindowController* user_window_controller)
41 const base::string16& title, 42 : user_window_controller_(user_window_controller) {}
42 UserWindowController* user_window_controller)
43 : window_id_(window_id),
44 title_(title),
45 user_window_controller_(user_window_controller) {}
46 ~ShelfItemDelegateMus() override {} 43 ~ShelfItemDelegateMus() override {}
47 44
48 void UpdateTitle(const base::string16& new_title) { title_ = new_title; } 45 bool pinned() const { return pinned_; }
46 void set_pinned(bool pinned) { pinned_ = pinned; }
47
48 void AddWindow(uint32_t id, const base::string16& title) {
49 DCHECK(!windows_.count(id));
50 windows_.insert(std::make_pair(id, title));
51 }
52 void RemoveWindow(uint32_t id) { windows_.erase(id); }
53 void SetWindowTitle(uint32_t id, const base::string16& title) {
54 DCHECK(windows_.count(id));
55 windows_[id] = title;
56 }
57 const std::map<uint32_t, base::string16>& windows() const { return windows_; }
58
59 const base::string16& title() { return title_; }
60 void set_title(const base::string16& title) { title_ = title; }
49 61
50 private: 62 private:
63 // This application menu model for ShelfItemDelegateMus lists open windows.
64 class ShelfMenuModelMus : public ShelfMenuModel,
65 public ui::SimpleMenuModel::Delegate {
66 public:
67 explicit ShelfMenuModelMus(ShelfItemDelegateMus* item_delegate)
68 : ShelfMenuModel(this), item_delegate_(item_delegate) {
69 AddSeparator(ui::SPACING_SEPARATOR);
70 AddItem(0, item_delegate_->GetTitle());
71 AddSeparator(ui::SPACING_SEPARATOR);
72 for (auto window : item_delegate_->windows())
sky 2016/04/22 15:51:19 const auto&
msw 2016/04/22 19:02:17 Done.
73 AddItem(window.first, window.second);
74 AddSeparator(ui::SPACING_SEPARATOR);
75 }
76 ~ShelfMenuModelMus() override {}
77
78 // ShelfMenuModel:
79 bool IsCommandActive(int command_id) const override { return false; }
80
81 // ui::SimpleMenuModel::Delegate:
82 bool IsCommandIdChecked(int command_id) const override { return false; }
83 bool IsCommandIdEnabled(int command_id) const override {
84 return command_id > 0;
85 }
86 bool GetAcceleratorForCommandId(int command_id,
87 ui::Accelerator* accelerator) override {
88 return false;
89 }
90 void ExecuteCommand(int command_id, int event_flags) override {
91 item_delegate_->user_window_controller_->FocusUserWindow(command_id);
92 }
93
94 private:
95 ShelfItemDelegateMus* item_delegate_;
96
97 DISALLOW_COPY_AND_ASSIGN(ShelfMenuModelMus);
98 };
99
51 // ShelfItemDelegate: 100 // ShelfItemDelegate:
52 ShelfItemDelegate::PerformedAction ItemSelected( 101 ShelfItemDelegate::PerformedAction ItemSelected(
53 const ui::Event& event) override { 102 const ui::Event& event) override {
54 if (window_id_ != 0) { 103 if (windows_.size() == 1) {
55 user_window_controller_->FocusUserWindow(window_id_); 104 user_window_controller_->FocusUserWindow(windows_.begin()->first);
56 return kExistingWindowActivated; 105 return kExistingWindowActivated;
57 } 106 }
58 NOTIMPLEMENTED();
59 return kNoAction; 107 return kNoAction;
60 } 108 }
61 109
62 base::string16 GetTitle() override { return title_; } 110 base::string16 GetTitle() override {
111 return windows_.empty() ? title_ : windows_.begin()->second;
112 }
63 113
64 bool CanPin() const override { 114 bool CanPin() const override {
65 NOTIMPLEMENTED(); 115 NOTIMPLEMENTED();
66 return false; 116 return true;
67 } 117 }
68 118
69 ShelfMenuModel* CreateApplicationMenu(int event_flags) override { 119 ShelfMenuModel* CreateApplicationMenu(int event_flags) override {
70 NOTIMPLEMENTED(); 120 return new ShelfMenuModelMus(this);
71 return nullptr;
72 } 121 }
73 122
74 bool IsDraggable() override { 123 bool IsDraggable() override {
75 NOTIMPLEMENTED(); 124 NOTIMPLEMENTED();
76 return false; 125 return false;
77 } 126 }
78 127
79 bool ShouldShowTooltip() override { return true; } 128 bool ShouldShowTooltip() override { return true; }
80 129
81 void Close() override { NOTIMPLEMENTED(); } 130 void Close() override { NOTIMPLEMENTED(); }
82 131
83 // TODO(msw): Support multiple open windows per button. 132 bool pinned_ = false;
84 uint32_t window_id_; 133 std::map<uint32_t, base::string16> windows_;
sky 2016/04/22 15:51:19 This name is mildly confusing as as it's really wi
msw 2016/04/22 19:02:17 Renamed, clarity in identifier names is better tha
85 base::string16 title_; 134 base::string16 title_;
86 UserWindowController* user_window_controller_; 135 UserWindowController* user_window_controller_;
87 136
88 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus); 137 DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegateMus);
89 }; 138 };
90 139
140 ShelfItemDelegateMus* GetShelfItemDelegate(ShelfID shelf_id) {
141 return static_cast<ShelfItemDelegateMus*>(
142 Shell::GetInstance()->shelf_item_delegate_manager()->GetShelfItemDelegate(
143 shelf_id));
144 }
145
91 // Returns an icon image from an SkBitmap, or the default shelf icon 146 // Returns an icon image from an SkBitmap, or the default shelf icon
92 // image if the bitmap is empty. Assumes the bitmap is a 1x icon. 147 // image if the bitmap is empty. Assumes the bitmap is a 1x icon.
93 // TODO(jamescook): Support other scale factors. 148 // TODO(jamescook): Support other scale factors.
94 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) { 149 gfx::ImageSkia GetShelfIconFromBitmap(const SkBitmap& bitmap) {
95 gfx::ImageSkia icon_image; 150 gfx::ImageSkia icon_image;
96 if (!bitmap.isNull()) { 151 if (!bitmap.isNull()) {
97 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); 152 icon_image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
98 } else { 153 } else {
99 // Use default icon. 154 // Use default icon.
100 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 155 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow()); 258 Shell::GetInstance()->SetShelfAlignment(value, Shell::GetPrimaryRootWindow());
204 } 259 }
205 260
206 void ShelfDelegateMus::SetAutoHideBehavior( 261 void ShelfDelegateMus::SetAutoHideBehavior(
207 mash::shelf::mojom::AutoHideBehavior auto_hide) { 262 mash::shelf::mojom::AutoHideBehavior auto_hide) {
208 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide); 263 ShelfAutoHideBehavior value = static_cast<ShelfAutoHideBehavior>(auto_hide);
209 Shell::GetInstance()->SetShelfAutoHideBehavior(value, 264 Shell::GetInstance()->SetShelfAutoHideBehavior(value,
210 Shell::GetPrimaryRootWindow()); 265 Shell::GetPrimaryRootWindow());
211 } 266 }
212 267
213 void ShelfDelegateMus::AddItem( 268 void ShelfDelegateMus::PinItem(
214 mash::shelf::mojom::ShelfItemPtr item, 269 mash::shelf::mojom::ShelfItemPtr item,
215 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { 270 mash::shelf::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) {
271 std::string app_id(item->app_id.To<std::string>());
272 if (app_id_to_shelf_id_.count(app_id)) {
273 ShelfID shelf_id = app_id_to_shelf_id_[app_id];
274 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
275 item_delegate->set_pinned(true);
276 return;
277 }
278
279 ShelfID shelf_id = model_->next_id();
280 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
281
216 ShelfItem shelf_item; 282 ShelfItem shelf_item;
217 shelf_item.type = TYPE_APP_SHORTCUT; 283 shelf_item.type = TYPE_APP_SHORTCUT;
218 shelf_item.status = STATUS_CLOSED; 284 shelf_item.status = STATUS_CLOSED;
219 shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>()); 285 shelf_item.image = GetShelfIconFromBitmap(item->image.To<SkBitmap>());
220
221 std::string item_id(item->id.To<std::string>());
222 if (app_id_to_shelf_id_.count(item_id))
223 return;
224 ShelfID shelf_id = model_->next_id();
225 app_id_to_shelf_id_.insert(std::make_pair(item_id, shelf_id));
226 model_->Add(shelf_item); 286 model_->Add(shelf_item);
227 287
228 std::unique_ptr<ShelfItemDelegateMus> item_delegate(new ShelfItemDelegateMus( 288 std::unique_ptr<ShelfItemDelegateMus> item_delegate(
229 0, item->title.To<base::string16>(), user_window_controller_.get())); 289 new ShelfItemDelegateMus(user_window_controller_.get()));
290 item_delegate->set_pinned(true);
291 item_delegate->set_title(item->app_title.To<base::string16>());
230 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( 292 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
231 shelf_id, std::move(item_delegate)); 293 shelf_id, std::move(item_delegate));
232 } 294 }
233 295
234 void ShelfDelegateMus::RemoveItem(const mojo::String& id) { 296 void ShelfDelegateMus::UnpinItem(const mojo::String& app_id) {
235 std::string item_id(id.To<std::string>()); 297 DCHECK(app_id_to_shelf_id_.count(app_id.To<std::string>()));
sky 2016/04/22 15:51:19 Don't trust a client to do the right thing with mo
msw 2016/04/22 19:02:17 Added early return. I think this is probably okay
236 DCHECK(app_id_to_shelf_id_.count(item_id)); 298 ShelfID shelf_id = app_id_to_shelf_id_[app_id.To<std::string>()];
237 model_->RemoveItemAt(model_->ItemIndexByID(app_id_to_shelf_id_[item_id])); 299 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
300 DCHECK(item_delegate->pinned());
301 item_delegate->set_pinned(false);
302 if (item_delegate->windows().empty())
303 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
238 } 304 }
239 305
240 void ShelfDelegateMus::OnUserWindowObserverAdded( 306 void ShelfDelegateMus::OnUserWindowObserverAdded(
241 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) { 307 mojo::Array<mash::wm::mojom::UserWindowPtr> user_windows) {
242 for (size_t i = 0; i < user_windows.size(); ++i) 308 for (size_t i = 0; i < user_windows.size(); ++i)
243 OnUserWindowAdded(std::move(user_windows[i])); 309 OnUserWindowAdded(std::move(user_windows[i]));
244 } 310 }
245 311
246 void ShelfDelegateMus::OnUserWindowAdded( 312 void ShelfDelegateMus::OnUserWindowAdded(
247 mash::wm::mojom::UserWindowPtr user_window) { 313 mash::wm::mojom::UserWindowPtr user_window) {
314 DCHECK(!window_id_to_shelf_id_.count(user_window->window_id));
315
316 std::string app_id(user_window->window_app_id.To<std::string>());
317 if (app_id_to_shelf_id_.count(app_id)) {
318 ShelfID shelf_id = app_id_to_shelf_id_[app_id];
319 window_id_to_shelf_id_.insert(
320 std::make_pair(user_window->window_id, shelf_id));
321
322 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
323 item_delegate->AddWindow(user_window->window_id,
324 user_window->window_title.To<base::string16>());
325 return;
326 }
327
328 ShelfID shelf_id = model_->next_id();
329 window_id_to_shelf_id_.insert(
330 std::make_pair(user_window->window_id, shelf_id));
331 app_id_to_shelf_id_.insert(std::make_pair(app_id, shelf_id));
332
248 ShelfItem item; 333 ShelfItem item;
249 item.type = TYPE_PLATFORM_APP; 334 item.type = TYPE_PLATFORM_APP;
250 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING; 335 item.status = user_window->window_has_focus ? STATUS_ACTIVE : STATUS_RUNNING;
251 item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon); 336 item.image = GetShelfIconFromSerializedBitmap(user_window->window_app_icon);
252
253 ShelfID shelf_id = model_->next_id();
254 window_id_to_shelf_id_.insert(
255 std::make_pair(user_window->window_id, shelf_id));
256 model_->Add(item); 337 model_->Add(item);
257 338
258 std::unique_ptr<ShelfItemDelegate> item_delegate(new ShelfItemDelegateMus( 339 std::unique_ptr<ShelfItemDelegateMus> item_delegate(
259 user_window->window_id, user_window->window_title.To<base::string16>(), 340 new ShelfItemDelegateMus(user_window_controller_.get()));
260 user_window_controller_.get())); 341 item_delegate->AddWindow(user_window->window_id,
342 user_window->window_title.To<base::string16>());
261 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate( 343 Shell::GetInstance()->shelf_item_delegate_manager()->SetShelfItemDelegate(
262 shelf_id, std::move(item_delegate)); 344 shelf_id, std::move(item_delegate));
263 } 345 }
264 346
265 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) { 347 void ShelfDelegateMus::OnUserWindowRemoved(uint32_t window_id) {
266 DCHECK(window_id_to_shelf_id_.count(window_id)); 348 DCHECK(window_id_to_shelf_id_.count(window_id));
267 model_->RemoveItemAt( 349 ShelfID shelf_id = window_id_to_shelf_id_[window_id];
268 model_->ItemIndexByID(window_id_to_shelf_id_[window_id])); 350 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
351 item_delegate->RemoveWindow(window_id);
352 window_id_to_shelf_id_.erase(window_id);
353 if (item_delegate->windows().empty() && !item_delegate->pinned())
354 model_->RemoveItemAt(model_->ItemIndexByID(shelf_id));
269 } 355 }
270 356
271 void ShelfDelegateMus::OnUserWindowTitleChanged( 357 void ShelfDelegateMus::OnUserWindowTitleChanged(
272 uint32_t window_id, 358 uint32_t window_id,
273 const mojo::String& window_title) { 359 const mojo::String& window_title) {
274 DCHECK(window_id_to_shelf_id_.count(window_id)); 360 DCHECK(window_id_to_shelf_id_.count(window_id));
275 ShelfID shelf_id = window_id_to_shelf_id_[window_id]; 361 ShelfID shelf_id = window_id_to_shelf_id_[window_id];
276 ShelfItemDelegateManager* manager = 362 ShelfItemDelegateMus* item_delegate = GetShelfItemDelegate(shelf_id);
277 Shell::GetInstance()->shelf_item_delegate_manager(); 363 item_delegate->SetWindowTitle(window_id, window_title.To<base::string16>());
278 ShelfItemDelegate* delegate = manager->GetShelfItemDelegate(shelf_id);
279 DCHECK(delegate);
280 static_cast<ShelfItemDelegateMus*>(delegate)->UpdateTitle(
281 window_title.To<base::string16>());
282 364
283 // There's nothing in the ShelfItem that needs to be updated. But we still 365 // There's nothing in the ShelfItem that needs to be updated. But we still
284 // need to update the ShelfModel so that the observers can pick up any 366 // need to update the ShelfModel so that the observers can pick up any
285 // changes. 367 // changes.
286 int index = model_->ItemIndexByID(shelf_id); 368 int index = model_->ItemIndexByID(shelf_id);
287 DCHECK_GE(index, 0); 369 DCHECK_GE(index, 0);
288 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id); 370 ShelfItems::const_iterator iter = model_->ItemByID(shelf_id);
289 DCHECK(iter != model_->items().end()); 371 DCHECK(iter != model_->items().end());
290 model_->Set(index, *iter); 372 model_->Set(index, *iter);
291 } 373 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 StatusAreaWidget* status_widget = widget->status_area_widget(); 412 StatusAreaWidget* status_widget = widget->status_area_widget();
331 mus::Window* status_window = 413 mus::Window* status_window =
332 aura::GetMusWindow(status_widget->GetNativeWindow()); 414 aura::GetMusWindow(status_widget->GetNativeWindow());
333 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size(); 415 gfx::Size status_size = status_widget->GetWindowBoundsInScreen().size();
334 status_window->SetSharedProperty<gfx::Size>( 416 status_window->SetSharedProperty<gfx::Size>(
335 mus::mojom::WindowManager::kPreferredSize_Property, status_size); 417 mus::mojom::WindowManager::kPreferredSize_Property, status_size);
336 } 418 }
337 419
338 } // namespace sysui 420 } // namespace sysui
339 } // namespace ash 421 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698