diff options
author | jamescook <jamescook@chromium.org> | 2016-03-25 11:11:53 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-25 18:13:27 +0000 |
commit | cac8709a0d06fee9d9f048b9e779ce59902673a5 (patch) | |
tree | f43374d99bd8f0310b9f26d39487b20354849678 /mash | |
parent | 260528431247b958483c9f7f2e1c6525aba077d7 (diff) | |
download | chromium_src-cac8709a0d06fee9d9f048b9e779ce59902673a5.zip chromium_src-cac8709a0d06fee9d9f048b9e779ce59902673a5.tar.gz chromium_src-cac8709a0d06fee9d9f048b9e779ce59902673a5.tar.bz2 |
Mash: Show app icons in shelf based on the Widget's app icon
* Use the large icon from WidgetDelegate::GetWindowAppIcon().
* In the mojo app's NativeWidgetMus, serialize the icon's SkBitmap as a vector of bytes and set it as a shared window property.
* In the window manager, pass the serialized icon to any UserWindowObservers.
* In the system UI, deserialize the icon and use it on the shelf.
* Set an icon in task_viewer as a demonstration.
The window property serialization is handled by a custom TypeConverter for vector<uint8>, SkBitmap. In the future it would be nice to use the serialized form of the Skia Mojom struct skia.Bitmap, but that will require Mojo to generate a public API to read the serialized bytes.
Also fixed an issue where the app's primary widget and the window manager's non-client-frame widget would fight over window titles.
A screenshot of the shelf is attached to the bug.
BUG=595850
TEST=launch mash, run mojo:task_viewer, note QuickLaunch shelf icon is default but TaskViewer icon is a gear
Review URL: https://codereview.chromium.org/1824183002
Cr-Commit-Position: refs/heads/master@{#383312}
Diffstat (limited to 'mash')
-rw-r--r-- | mash/task_viewer/BUILD.gn | 1 | ||||
-rw-r--r-- | mash/task_viewer/task_viewer.cc | 9 | ||||
-rw-r--r-- | mash/wm/non_client_frame_controller.cc | 8 | ||||
-rw-r--r-- | mash/wm/public/interfaces/user_window_controller.mojom | 4 | ||||
-rw-r--r-- | mash/wm/user_window_controller_impl.cc | 45 | ||||
-rw-r--r-- | mash/wm/user_window_controller_impl.h | 4 | ||||
-rw-r--r-- | mash/wm/window_manager.cc | 1 |
7 files changed, 57 insertions, 15 deletions
diff --git a/mash/task_viewer/BUILD.gn b/mash/task_viewer/BUILD.gn index 1d20b22..1ea8cbc 100644 --- a/mash/task_viewer/BUILD.gn +++ b/mash/task_viewer/BUILD.gn @@ -21,6 +21,7 @@ source_set("lib") { "//mojo/shell/public/cpp", "//mojo/shell/public/cpp:sources", "//mojo/shell/public/interfaces", + "//ui/resources", "//ui/views", "//ui/views/mus:for_mojo_application", ] diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc index 0e01a00..fb5cb1f 100644 --- a/mash/task_viewer/task_viewer.cc +++ b/mash/task_viewer/task_viewer.cc @@ -19,6 +19,8 @@ #include "mojo/shell/public/cpp/connector.h" #include "mojo/shell/public/interfaces/shell.mojom.h" #include "ui/base/models/table_model.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/resources/grit/ui_resources.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/controls/table/table_view.h" @@ -87,6 +89,13 @@ class TaskViewerContents : public views::WidgetDelegateView, return base::ASCIIToUTF16("Tasks"); } + gfx::ImageSkia GetWindowAppIcon() override { + // TODO(jamescook): Create a new .pak file for this app and make a custom + // icon, perhaps one that looks like the Chrome OS task viewer icon. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_SETTINGS); + } + // Overridden from views::View: void Layout() override { gfx::Rect bounds = GetLocalBounds(); diff --git a/mash/wm/non_client_frame_controller.cc b/mash/wm/non_client_frame_controller.cc index ed6ad3a..774329a 100644 --- a/mash/wm/non_client_frame_controller.cc +++ b/mash/wm/non_client_frame_controller.cc @@ -125,6 +125,14 @@ class WmNativeWidgetMus : public views::NativeWidgetMus { void CenterWindow(const gfx::Size& size) override { // Do nothing. The client controls the size, not us. } + bool SetWindowTitle(const base::string16& title) override { + // Do nothing. The client controls the window title, not us. + return false; + } + void SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) override { + // Do nothing. The client controls window icons, not us. + } void UpdateClientArea() override { // This pushes the client area to the WS. We don't want to do that as // the client area should come from the client, not us. diff --git a/mash/wm/public/interfaces/user_window_controller.mojom b/mash/wm/public/interfaces/user_window_controller.mojom index c1d61d8..3d84fb1 100644 --- a/mash/wm/public/interfaces/user_window_controller.mojom +++ b/mash/wm/public/interfaces/user_window_controller.mojom @@ -8,6 +8,7 @@ struct UserWindow { uint32 window_id; string window_title; bool window_has_focus; + array<uint8> window_app_icon; // Serialized SkBitmap. }; // An observer of user windows within mojom::Container::USER_WINDOWS. @@ -20,6 +21,9 @@ interface UserWindowObserver { OnUserWindowRemoved(uint32 window_id); OnUserWindowTitleChanged(uint32 window_id, string window_title); + + // |app_icon| is a serialized SkBitmap. + OnUserWindowAppIconChanged(uint32 window_id, array<uint8> app_icon); OnUserWindowFocusChanged(uint32 window_id, bool has_focus); }; diff --git a/mash/wm/user_window_controller_impl.cc b/mash/wm/user_window_controller_impl.cc index be2f24e..3e81da94 100644 --- a/mash/wm/user_window_controller_impl.cc +++ b/mash/wm/user_window_controller_impl.cc @@ -11,6 +11,7 @@ #include "mash/wm/public/interfaces/container.mojom.h" #include "mash/wm/root_window_controller.h" #include "mojo/common/common_type_converters.h" +#include "ui/resources/grit/ui_resources.h" namespace mash { namespace wm { @@ -26,6 +27,17 @@ mojo::String GetWindowTitle(mus::Window* window) { return mojo::String(std::string()); } +// Get the serialized app icon bitmap from a mus::Window. +mojo::Array<uint8_t> GetWindowAppIcon(mus::Window* window) { + if (window->HasSharedProperty( + mus::mojom::WindowManager::kWindowAppIcon_Property)) { + return mojo::Array<uint8_t>::From( + window->GetSharedProperty<const std::vector<uint8_t>>( + mus::mojom::WindowManager::kWindowAppIcon_Property)); + } + return mojo::Array<uint8_t>(); +} + // Returns |window|, or an ancestor thereof, parented to |container|, or null. mus::Window* GetTopLevelWindow(mus::Window* window, mus::Window* container) { while (window && window->parent() != container) @@ -38,6 +50,7 @@ mojom::UserWindowPtr GetUserWindow(mus::Window* window) { mojom::UserWindowPtr user_window(mojom::UserWindow::New()); user_window->window_id = window->id(); user_window->window_title = GetWindowTitle(window); + user_window->window_app_icon = GetWindowAppIcon(window); mus::Window* focused = window->connection()->GetFocusedWindow(); focused = GetTopLevelWindow(focused, window->parent()); user_window->window_has_focus = focused == window; @@ -46,13 +59,14 @@ mojom::UserWindowPtr GetUserWindow(mus::Window* window) { } // namespace -// Observes title changes on user windows. UserWindowControllerImpl uses this -// separate observer to avoid observing duplicate tree change notifications. -class WindowTitleObserver : public mus::WindowObserver { +// Observes property changes on user windows. UserWindowControllerImpl uses +// this separate observer to avoid observing duplicate tree change +// notifications. +class WindowPropertyObserver : public mus::WindowObserver { public: - explicit WindowTitleObserver(UserWindowControllerImpl* controller) + explicit WindowPropertyObserver(UserWindowControllerImpl* controller) : controller_(controller) {} - ~WindowTitleObserver() override {} + ~WindowPropertyObserver() override {} private: // mus::WindowObserver: @@ -61,15 +75,20 @@ class WindowTitleObserver : public mus::WindowObserver { const std::string& name, const std::vector<uint8_t>* old_data, const std::vector<uint8_t>* new_data) override { - if (controller_->user_window_observer() && - name == mus::mojom::WindowManager::kWindowTitle_Property) { + if (!controller_->user_window_observer()) + return; + if (name == mus::mojom::WindowManager::kWindowTitle_Property) { controller_->user_window_observer()->OnUserWindowTitleChanged( window->id(), GetWindowTitle(window)); + } else if (name == mus::mojom::WindowManager::kWindowAppIcon_Property) { + controller_->user_window_observer()->OnUserWindowAppIconChanged( + window->id(), new_data ? mojo::Array<uint8_t>::From(*new_data) + : mojo::Array<uint8_t>()); } } UserWindowControllerImpl* controller_; - DISALLOW_COPY_AND_ASSIGN(WindowTitleObserver); + DISALLOW_COPY_AND_ASSIGN(WindowPropertyObserver); }; UserWindowControllerImpl::UserWindowControllerImpl() @@ -87,7 +106,7 @@ UserWindowControllerImpl::~UserWindowControllerImpl() { user_container->RemoveObserver(this); for (auto iter : user_container->children()) - iter->RemoveObserver(window_title_observer_.get()); + iter->RemoveObserver(window_property_observer_.get()); } void UserWindowControllerImpl::Initialize( @@ -97,9 +116,9 @@ void UserWindowControllerImpl::Initialize( root_controller_ = root_controller; GetUserWindowContainer()->AddObserver(this); GetUserWindowContainer()->connection()->AddObserver(this); - window_title_observer_.reset(new WindowTitleObserver(this)); + window_property_observer_.reset(new WindowPropertyObserver(this)); for (auto iter : GetUserWindowContainer()->children()) - iter->AddObserver(window_title_observer_.get()); + iter->AddObserver(window_property_observer_.get()); } mus::Window* UserWindowControllerImpl::GetUserWindowContainer() const { @@ -110,11 +129,11 @@ mus::Window* UserWindowControllerImpl::GetUserWindowContainer() const { void UserWindowControllerImpl::OnTreeChanging(const TreeChangeParams& params) { DCHECK(root_controller_); if (params.new_parent == GetUserWindowContainer()) { - params.target->AddObserver(window_title_observer_.get()); + params.target->AddObserver(window_property_observer_.get()); if (user_window_observer_) user_window_observer_->OnUserWindowAdded(GetUserWindow(params.target)); } else if (params.old_parent == GetUserWindowContainer()) { - params.target->RemoveObserver(window_title_observer_.get()); + params.target->RemoveObserver(window_property_observer_.get()); if (user_window_observer_) user_window_observer_->OnUserWindowRemoved(params.target->id()); } diff --git a/mash/wm/user_window_controller_impl.h b/mash/wm/user_window_controller_impl.h index 3b6f9c4..c974f6f 100644 --- a/mash/wm/user_window_controller_impl.h +++ b/mash/wm/user_window_controller_impl.h @@ -17,7 +17,7 @@ namespace mash { namespace wm { class RootWindowController; -class WindowTitleObserver; +class WindowPropertyObserver; class UserWindowControllerImpl : public mojom::UserWindowController, public mus::WindowObserver, @@ -49,7 +49,7 @@ class UserWindowControllerImpl : public mojom::UserWindowController, RootWindowController* root_controller_; mojom::UserWindowObserverPtr user_window_observer_; - scoped_ptr<WindowTitleObserver> window_title_observer_; + scoped_ptr<WindowPropertyObserver> window_property_observer_; DISALLOW_COPY_AND_ASSIGN(UserWindowControllerImpl); }; diff --git a/mash/wm/window_manager.cc b/mash/wm/window_manager.cc index 5905469f..4ebeb9a 100644 --- a/mash/wm/window_manager.cc +++ b/mash/wm/window_manager.cc @@ -153,6 +153,7 @@ bool WindowManager::OnWmSetProperty( return name == mus::mojom::WindowManager::kShowState_Property || name == mus::mojom::WindowManager::kPreferredSize_Property || name == mus::mojom::WindowManager::kResizeBehavior_Property || + name == mus::mojom::WindowManager::kWindowAppIcon_Property || name == mus::mojom::WindowManager::kWindowTitle_Property; } |