| Index: chrome/browser/ui/views/app_list/app_list_controller_win.cc
|
| ===================================================================
|
| --- chrome/browser/ui/views/app_list/app_list_controller_win.cc (revision 181966)
|
| +++ chrome/browser/ui/views/app_list/app_list_controller_win.cc (working copy)
|
| @@ -49,6 +49,12 @@
|
| #include "ui/views/bubble/bubble_border.h"
|
| #include "ui/views/widget/widget.h"
|
|
|
| +#if defined(USE_ASH)
|
| +#include "ash/shell.h"
|
| +#include "ui/aura/root_window.h"
|
| +#include "ui/aura/window.h"
|
| +#endif
|
| +
|
| namespace {
|
|
|
| // Offset from the cursor to the point of the bubble arrow. It looks weird
|
| @@ -156,11 +162,11 @@
|
| class AppListController : public ProfileInfoCacheObserver {
|
| public:
|
| AppListController();
|
| + virtual ~AppListController();
|
|
|
| void set_can_close(bool can_close) { can_close_app_list_ = can_close; }
|
| bool can_close() { return can_close_app_list_; }
|
| Profile* profile() const { return profile_; }
|
| - bool app_list_is_showing() const { return app_list_is_showing_; }
|
|
|
| // Creates the app list view and populates it from |profile|, but doesn't
|
| // show it. Does nothing if the view already exists.
|
| @@ -168,13 +174,26 @@
|
|
|
| // Activates the app list at the current mouse cursor location, creating the
|
| // app list if necessary.
|
| - void ShowAppList(Profile* profile);
|
| + virtual void ShowAppList(Profile* profile);
|
|
|
| + // Hides the app list.
|
| + virtual void DismissAppList();
|
| +
|
| + virtual void OnBeginExtensionInstall(Profile* profile,
|
| + const std::string& extension_id,
|
| + const std::string& extension_name,
|
| + const gfx::ImageSkia& installing_icon);
|
| + virtual void OnDownloadProgress(Profile* profile,
|
| + const std::string& extension_id,
|
| + int percent_downloaded);
|
| + virtual bool IsAppListVisible() const;
|
| + virtual void OnInstallFailure(Profile* profile,
|
| + const std::string& extension_id);
|
| +
|
| // Update the profile path stored in local prefs, load it (if not already
|
| // loaded), and show the app list.
|
| void SetProfilePath(const base::FilePath& profile_file_path);
|
|
|
| - void DismissAppList();
|
| void AppListClosing();
|
| void AppListActivationChanged(bool active);
|
| app_list::AppListView* GetView() { return current_view_; }
|
| @@ -191,15 +210,6 @@
|
| const string16& profile_name) OVERRIDE {}
|
| void OnProfileAvatarChanged(const base::FilePath& profile_path) OVERRIDE {}
|
|
|
| - void OnBeginExtensionInstall(Profile* profile,
|
| - const std::string& extension_id,
|
| - const std::string& extension_name,
|
| - const gfx::ImageSkia& installing_icon);
|
| - void OnDownloadProgress(Profile* profile,
|
| - const std::string& extension_id,
|
| - int percent_downloaded);
|
| - void OnInstallFailure(Profile* profile, const std::string& extension_id);
|
| -
|
| private:
|
| // Loads a profile asynchronously and calls OnProfileLoaded() when done.
|
| void LoadProfileAsync(const base::FilePath& profile_file_path);
|
| @@ -236,6 +246,9 @@
|
| // periodically whenever the app list does not have focus.
|
| void CheckTaskbarOrViewHasFocus();
|
|
|
| + // Returns the underlying HWND for the AppList.
|
| + HWND GetAppListHWND() const;
|
| +
|
| // Weak pointer. The view manages its own lifetime.
|
| app_list::AppListView* current_view_;
|
|
|
| @@ -381,6 +394,9 @@
|
| profile_manager->GetProfileInfoCache().AddObserver(this);
|
| }
|
|
|
| +AppListController::~AppListController() {
|
| +}
|
| +
|
| void AppListController::OnProfileWillBeRemoved(
|
| const base::FilePath& profile_path) {
|
| // If the profile the app list uses just got deleted, reset it to the last
|
| @@ -499,24 +515,28 @@
|
| }
|
|
|
| void AppListController::PopulateViewFromProfile(Profile* profile) {
|
| -#if !defined(USE_AURA)
|
| if (profile == profile_)
|
| return;
|
| profile_ = profile;
|
| +
|
| + gfx::NativeWindow parent = NULL;
|
| +
|
| +#if !defined(USE_AURA)
|
| + parent = ::GetDesktopWindow();
|
| +#endif
|
| // The controller will be owned by the view delegate, and the delegate is
|
| // owned by the app list view. The app list view manages it's own lifetime.
|
| view_delegate_ = new AppListViewDelegate(new AppListControllerDelegateWin(),
|
| profile_);
|
| current_view_ = new app_list::AppListView(view_delegate_);
|
| gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
|
| - current_view_->InitAsBubble(GetDesktopWindow(),
|
| + current_view_->InitAsBubble(parent,
|
| &pagination_model_,
|
| NULL,
|
| cursor,
|
| views::BubbleBorder::BOTTOM_LEFT);
|
| + HWND hwnd = GetAppListHWND();
|
|
|
| - HWND hwnd =
|
| - current_view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow();
|
| ui::win::SetAppIdForWindow(GetAppModelId(), hwnd);
|
| CommandLine relaunch = GetAppListCommandLine();
|
| string16 app_name(l10n_util::GetStringUTF16(IDS_APP_LIST_SHORTCUT_NAME));
|
| @@ -525,7 +545,6 @@
|
| ::SetWindowText(hwnd, app_name.c_str());
|
| string16 icon_path = GetAppListIconPath();
|
| ui::win::SetAppIconForWindow(icon_path, hwnd);
|
| -#endif
|
| }
|
|
|
| void AppListController::DismissAppList() {
|
| @@ -537,24 +556,6 @@
|
| }
|
| }
|
|
|
| -void AppListController::AppListClosing() {
|
| - current_view_ = NULL;
|
| - view_delegate_ = NULL;
|
| - timer_.Stop();
|
| -}
|
| -
|
| -void AppListController::AppListActivationChanged(bool active) {
|
| - const int kFocusCheckIntervalMS = 250;
|
| - if (active) {
|
| - timer_.Stop();
|
| - return;
|
| - }
|
| -
|
| - timer_.Start(FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(kFocusCheckIntervalMS), this,
|
| - &AppListController::CheckTaskbarOrViewHasFocus);
|
| -}
|
| -
|
| void AppListController::OnBeginExtensionInstall(
|
| Profile* profile,
|
| const std::string& extension_id,
|
| @@ -577,6 +578,10 @@
|
| view_delegate_->OnDownloadProgress(extension_id, percent_downloaded);
|
| }
|
|
|
| +bool AppListController::IsAppListVisible() const {
|
| + return app_list_is_showing_;
|
| +}
|
| +
|
| void AppListController::OnInstallFailure(Profile* profile,
|
| const std::string& extension_id) {
|
| // We only have a model for the current profile, so ignore events about
|
| @@ -589,12 +594,29 @@
|
| view_delegate_->OnInstallFailure(extension_id);
|
| }
|
|
|
| +void AppListController::AppListClosing() {
|
| + current_view_ = NULL;
|
| + view_delegate_ = NULL;
|
| + timer_.Stop();
|
| +}
|
| +
|
| +void AppListController::AppListActivationChanged(bool active) {
|
| + const int kFocusCheckIntervalMS = 250;
|
| + if (active) {
|
| + timer_.Stop();
|
| + return;
|
| + }
|
| +
|
| + timer_.Start(FROM_HERE,
|
| + base::TimeDelta::FromMilliseconds(kFocusCheckIntervalMS), this,
|
| + &AppListController::CheckTaskbarOrViewHasFocus);
|
| +}
|
| +
|
| // Attempts to find the bounds of the Windows taskbar. Returns true on success.
|
| // |rect| is in screen coordinates. If the taskbar is in autohide mode and is
|
| // not visible, |rect| will be outside the current monitor's bounds, except for
|
| // one pixel of overlap where the edge of the taskbar is shown.
|
| bool GetTaskbarRect(gfx::Rect* rect) {
|
| -#if !defined(USE_AURA)
|
| HWND taskbar_hwnd = FindWindow(kTrayClassName, NULL);
|
| if (!taskbar_hwnd)
|
| return false;
|
| @@ -605,9 +627,6 @@
|
|
|
| *rect = gfx::Rect(win_rect);
|
| return true;
|
| -#else
|
| - return false;
|
| -#endif
|
| }
|
|
|
| // Used to position the view in a corner, which requires |anchor| to be in
|
| @@ -750,7 +769,6 @@
|
| }
|
|
|
| void AppListController::CheckTaskbarOrViewHasFocus() {
|
| -#if !defined(USE_AURA)
|
| // Don't bother checking if the view has been closed.
|
| if (!current_view_)
|
| return;
|
| @@ -759,9 +777,9 @@
|
| // context menu which the taskbar uses).
|
| HWND jump_list_hwnd = FindWindow(L"DV2ControlHost", NULL);
|
| HWND taskbar_hwnd = FindWindow(kTrayClassName, NULL);
|
| - HWND app_list_hwnd =
|
| - current_view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow();
|
|
|
| + HWND app_list_hwnd = GetAppListHWND();
|
| +
|
| // Get the focused window, and check if it is one of these windows. Keep
|
| // checking it's parent until either we find one of these windows, or there
|
| // is no parent left.
|
| @@ -778,6 +796,15 @@
|
| // If we get here, the focused window is not the taskbar, it's context menu,
|
| // or the app list, so close the app list.
|
| DismissAppList();
|
| +}
|
| +
|
| +HWND AppListController::GetAppListHWND() const {
|
| +#if defined(USE_AURA)
|
| + gfx::NativeWindow window =
|
| + current_view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow();
|
| + return window->GetRootWindow()->GetAcceleratedWidget();
|
| +#else
|
| + return current_view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow();
|
| #endif
|
| }
|
|
|
| @@ -839,6 +866,72 @@
|
| g_app_list_controller.Get().InitView(profile);
|
| }
|
|
|
| +#if defined(USE_ASH)
|
| +// The AppListControllerAsh class provides the functionality for
|
| +// displaying/hiding the App list for Windows 8 Chrome ASH.
|
| +class AppListControllerAsh : public AppListController {
|
| + public:
|
| + AppListControllerAsh() {}
|
| + virtual ~AppListControllerAsh() {}
|
| +
|
| + // AppListController overrides.
|
| + virtual void ShowAppList(Profile* profile) OVERRIDE;
|
| +
|
| + virtual void DismissAppList() OVERRIDE;
|
| +
|
| + // The OnBeginExtensionInstall/OnDownloadProgress/OnInstallFalure overrides
|
| + // are not necessary for ASH as these are handled by the ash Shell.
|
| + virtual void OnBeginExtensionInstall(Profile* profile,
|
| + const std::string& extension_id,
|
| + const std::string& extension_name,
|
| + const gfx::ImageSkia& installing_icon)
|
| + OVERRIDE {}
|
| +
|
| + virtual void OnDownloadProgress(Profile* profile,
|
| + const std::string& extension_id,
|
| + int percent_downloaded) OVERRIDE {}
|
| +
|
| + virtual bool IsAppListVisible() const OVERRIDE;
|
| +
|
| + virtual void OnInstallFailure(
|
| + Profile* profile,
|
| + const std::string& extension_id) OVERRIDE {}
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(AppListControllerAsh);
|
| +};
|
| +
|
| +base::LazyInstance<AppListControllerAsh>::Leaky g_app_list_controller_ash =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| +void AppListControllerAsh::ShowAppList(Profile* profile) {
|
| + // This may not work correctly if the profile passed in is different from the
|
| + // one the ash Shell is currently using.
|
| + // TODO(ananta): Handle profile changes correctly.
|
| + if (!IsAppListVisible())
|
| + ash::Shell::GetInstance()->ToggleAppList(NULL);
|
| +}
|
| +
|
| +void AppListControllerAsh::DismissAppList() {
|
| + if (AppListControllerAsh::IsAppListVisible())
|
| + ash::Shell::GetInstance()->ToggleAppList(NULL);
|
| +}
|
| +
|
| +bool AppListControllerAsh::IsAppListVisible() const {
|
| + return ash::Shell::GetInstance()->GetAppListWindow() != NULL;
|
| +}
|
| +
|
| +#endif
|
| +
|
| +// Returns the AppListController instance for the current environment.
|
| +AppListController* GetCurrentAppListController() {
|
| +#if defined(USE_ASH)
|
| + if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
|
| + return &g_app_list_controller_ash.Get();
|
| +#endif
|
| + return &g_app_list_controller.Get();
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace chrome {
|
| @@ -872,25 +965,24 @@
|
| base::TimeDelta::FromSeconds(kInitWindowDelay));
|
| }
|
|
|
| -#if !defined(USE_ASH)
|
| void ShowAppList(Profile* profile) {
|
| - g_app_list_controller.Get().ShowAppList(profile);
|
| + GetCurrentAppListController()->ShowAppList(profile);
|
| }
|
|
|
| void SetAppListProfile(const base::FilePath& profile_file_path) {
|
| - g_app_list_controller.Get().SetProfilePath(profile_file_path);
|
| + GetCurrentAppListController()->SetProfilePath(profile_file_path);
|
| }
|
|
|
| void DismissAppList() {
|
| - g_app_list_controller.Get().DismissAppList();
|
| + GetCurrentAppListController()->DismissAppList();
|
| }
|
|
|
| Profile* GetCurrentAppListProfile() {
|
| - return g_app_list_controller.Get().profile();
|
| + return GetCurrentAppListController()->profile();
|
| }
|
|
|
| bool IsAppListVisible() {
|
| - return g_app_list_controller.Get().app_list_is_showing();
|
| + return GetCurrentAppListController()->IsAppListVisible();
|
| }
|
|
|
| void NotifyAppListOfBeginExtensionInstall(
|
| @@ -898,26 +990,24 @@
|
| const std::string& extension_id,
|
| const std::string& extension_name,
|
| const gfx::ImageSkia& installing_icon) {
|
| - g_app_list_controller.Get().OnBeginExtensionInstall(profile,
|
| - extension_id,
|
| - extension_name,
|
| - installing_icon);
|
| + GetCurrentAppListController()->OnBeginExtensionInstall(profile,
|
| + extension_id,
|
| + extension_name,
|
| + installing_icon);
|
| }
|
|
|
| void NotifyAppListOfDownloadProgress(
|
| Profile* profile,
|
| const std::string& extension_id,
|
| int percent_downloaded) {
|
| - g_app_list_controller.Get().OnDownloadProgress(profile, extension_id,
|
| - percent_downloaded);
|
| + GetCurrentAppListController()->OnDownloadProgress(profile, extension_id,
|
| + percent_downloaded);
|
| }
|
|
|
| void NotifyAppListOfExtensionInstallFailure(
|
| Profile* profile,
|
| const std::string& extension_id) {
|
| - g_app_list_controller.Get().OnInstallFailure(profile, extension_id);
|
| + GetCurrentAppListController()->OnInstallFailure(profile, extension_id);
|
| }
|
|
|
| -#endif // !defined(USE_ASH)
|
| -
|
| } // namespace chrome
|
|
|