OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/ui/views/apps/native_app_window_views_win.h" | 5 #include "chrome/browser/ui/views/apps/native_app_window_views_win.h" |
6 | 6 |
7 #include "apps/shell_window.h" | 7 #include "apps/shell_window.h" |
8 #include "apps/shell_window_registry.h" | 8 #include "apps/shell_window_registry.h" |
9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 10 #include "base/command_line.h" |
| 11 #include "base/file_util.h" |
| 12 #include "base/path_service.h" |
| 13 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/browser/apps/per_app_settings_service.h" | 14 #include "chrome/browser/apps/per_app_settings_service.h" |
11 #include "chrome/browser/apps/per_app_settings_service_factory.h" | 15 #include "chrome/browser/apps/per_app_settings_service_factory.h" |
12 #include "chrome/browser/metro_utils/metro_chrome_win.h" | 16 #include "chrome/browser/metro_utils/metro_chrome_win.h" |
| 17 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/web_applications/web_app_ui.h" |
| 19 #include "chrome/browser/web_applications/web_app.h" |
| 20 #include "chrome/browser/web_applications/web_app_win.h" |
| 21 #include "chrome/common/chrome_switches.h" |
| 22 #include "content/public/browser/browser_thread.h" |
13 #include "extensions/common/extension.h" | 23 #include "extensions/common/extension.h" |
14 #include "ui/aura/remote_root_window_host_win.h" | 24 #include "ui/aura/remote_root_window_host_win.h" |
| 25 #include "ui/base/win/shell.h" |
15 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" | 26 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
| 27 #include "ui/views/win/hwnd_util.h" |
16 | 28 |
17 NativeAppWindowViewsWin::NativeAppWindowViewsWin() { | 29 namespace { |
| 30 |
| 31 void CreateIconAndSetRelaunchDetails( |
| 32 const base::FilePath& web_app_path, |
| 33 const base::FilePath& icon_file, |
| 34 const ShellIntegration::ShortcutInfo& shortcut_info, |
| 35 const HWND hwnd) { |
| 36 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 37 |
| 38 // Set the relaunch data so "Pin this program to taskbar" has the app's |
| 39 // information. |
| 40 CommandLine command_line = ShellIntegration::CommandLineArgsForLauncher( |
| 41 shortcut_info.url, |
| 42 shortcut_info.extension_id, |
| 43 shortcut_info.profile_path); |
| 44 |
| 45 base::FilePath chrome_exe; |
| 46 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
| 47 NOTREACHED(); |
| 48 return; |
| 49 } |
| 50 command_line.SetProgram(chrome_exe); |
| 51 ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(), |
| 52 shortcut_info.title, hwnd); |
| 53 |
| 54 if (!base::PathExists(web_app_path) && |
| 55 !base::CreateDirectory(web_app_path)) { |
| 56 return; |
| 57 } |
| 58 |
| 59 ui::win::SetAppIconForWindow(icon_file.value(), hwnd); |
| 60 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon); |
| 61 } |
| 62 |
| 63 } // namespace |
| 64 |
| 65 NativeAppWindowViewsWin::NativeAppWindowViewsWin() |
| 66 : weak_ptr_factory_(this) { |
18 } | 67 } |
19 | 68 |
20 void NativeAppWindowViewsWin::ActivateParentDesktopIfNecessary() { | 69 void NativeAppWindowViewsWin::ActivateParentDesktopIfNecessary() { |
21 if (!ash::Shell::HasInstance()) | 70 if (!ash::Shell::HasInstance()) |
22 return; | 71 return; |
23 | 72 |
24 views::Widget* widget = | 73 views::Widget* widget = |
25 implicit_cast<views::WidgetDelegate*>(this)->GetWidget(); | 74 implicit_cast<views::WidgetDelegate*>(this)->GetWidget(); |
26 chrome::HostDesktopType host_desktop_type = | 75 chrome::HostDesktopType host_desktop_type = |
27 chrome::GetHostDesktopTypeForNativeWindow(widget->GetNativeWindow()); | 76 chrome::GetHostDesktopTypeForNativeWindow(widget->GetNativeWindow()); |
28 // Only switching into Ash from Native is supported. Tearing the user out of | 77 // Only switching into Ash from Native is supported. Tearing the user out of |
29 // Metro mode can only be done by launching a process from Metro mode itself. | 78 // Metro mode can only be done by launching a process from Metro mode itself. |
30 // This is done for launching apps, but not regular activations. | 79 // This is done for launching apps, but not regular activations. |
31 if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH && | 80 if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH && |
32 chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_NATIVE) { | 81 chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_NATIVE) { |
33 chrome::ActivateMetroChrome(); | 82 chrome::ActivateMetroChrome(); |
34 } | 83 } |
35 } | 84 } |
36 | 85 |
| 86 void NativeAppWindowViewsWin::OnShortcutInfoLoaded( |
| 87 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 88 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 89 |
| 90 HWND hwnd = GetNativeAppWindowHWND(); |
| 91 |
| 92 // Set window's icon to the one we're about to create/update in the web app |
| 93 // path. The icon cache will refresh on icon creation. |
| 94 base::FilePath web_app_path = web_app::GetWebAppDataDirectory( |
| 95 shortcut_info.profile_path, shortcut_info.extension_id, |
| 96 shortcut_info.url); |
| 97 base::FilePath icon_file = web_app_path |
| 98 .Append(web_app::internals::GetSanitizedFileName(shortcut_info.title)) |
| 99 .ReplaceExtension(FILE_PATH_LITERAL(".ico")); |
| 100 |
| 101 content::BrowserThread::PostBlockingPoolTask( |
| 102 FROM_HERE, |
| 103 base::Bind(&CreateIconAndSetRelaunchDetails, |
| 104 web_app_path, icon_file, shortcut_info, hwnd)); |
| 105 } |
| 106 |
| 107 HWND NativeAppWindowViewsWin::GetNativeAppWindowHWND() const { |
| 108 return views::HWNDForWidget(window()->GetTopLevelWidget()); |
| 109 } |
| 110 |
37 void NativeAppWindowViewsWin::OnBeforeWidgetInit( | 111 void NativeAppWindowViewsWin::OnBeforeWidgetInit( |
38 views::Widget::InitParams* init_params, views::Widget* widget) { | 112 views::Widget::InitParams* init_params, views::Widget* widget) { |
39 // If an app has any existing windows, ensure new ones are created on the | 113 // If an app has any existing windows, ensure new ones are created on the |
40 // same desktop. | 114 // same desktop. |
41 apps::ShellWindow* any_existing_window = | 115 apps::ShellWindow* any_existing_window = |
42 apps::ShellWindowRegistry::Get(browser_context()) | 116 apps::ShellWindowRegistry::Get(browser_context()) |
43 ->GetCurrentShellWindowForApp(extension()->id()); | 117 ->GetCurrentShellWindowForApp(extension()->id()); |
44 chrome::HostDesktopType desktop_type; | 118 chrome::HostDesktopType desktop_type; |
45 if (any_existing_window) { | 119 if (any_existing_window) { |
46 desktop_type = chrome::GetHostDesktopTypeForNativeWindow( | 120 desktop_type = chrome::GetHostDesktopTypeForNativeWindow( |
47 any_existing_window->GetNativeWindow()); | 121 any_existing_window->GetNativeWindow()); |
48 } else { | 122 } else { |
49 PerAppSettingsService* settings = | 123 PerAppSettingsService* settings = |
50 PerAppSettingsServiceFactory::GetForBrowserContext(browser_context()); | 124 PerAppSettingsServiceFactory::GetForBrowserContext(browser_context()); |
51 if (settings->HasDesktopLastLaunchedFrom(extension()->id())) { | 125 if (settings->HasDesktopLastLaunchedFrom(extension()->id())) { |
52 desktop_type = settings->GetDesktopLastLaunchedFrom(extension()->id()); | 126 desktop_type = settings->GetDesktopLastLaunchedFrom(extension()->id()); |
53 } else { | 127 } else { |
54 // We don't know what desktop this app was last launched from, so take our | 128 // We don't know what desktop this app was last launched from, so take our |
55 // best guess as to what desktop the user is on. | 129 // best guess as to what desktop the user is on. |
56 desktop_type = chrome::GetActiveDesktop(); | 130 desktop_type = chrome::GetActiveDesktop(); |
57 } | 131 } |
58 } | 132 } |
59 if (desktop_type == chrome::HOST_DESKTOP_TYPE_ASH) | 133 if (desktop_type == chrome::HOST_DESKTOP_TYPE_ASH) |
60 init_params->context = ash::Shell::GetPrimaryRootWindow(); | 134 init_params->context = ash::Shell::GetPrimaryRootWindow(); |
61 else | 135 else |
62 init_params->native_widget = new views::DesktopNativeWidgetAura(widget); | 136 init_params->native_widget = new views::DesktopNativeWidgetAura(widget); |
63 } | 137 } |
64 | 138 |
| 139 void NativeAppWindowViewsWin::InitializeDefaultWindow( |
| 140 const apps::ShellWindow::CreateParams& create_params) { |
| 141 NativeAppWindowViews::InitializeDefaultWindow(create_params); |
| 142 |
| 143 std::string app_name = |
| 144 web_app::GenerateApplicationNameFromExtensionId(extension()->id()); |
| 145 base::string16 app_name_wide = base::UTF8ToWide(app_name); |
| 146 HWND hwnd = GetNativeAppWindowHWND(); |
| 147 ui::win::SetAppIdForWindow( |
| 148 ShellIntegration::GetAppModelIdForProfile( |
| 149 app_name_wide, |
| 150 Profile::FromBrowserContext(browser_context())->GetPath()), |
| 151 hwnd); |
| 152 |
| 153 web_app::UpdateShortcutInfoAndIconForApp( |
| 154 *extension(), |
| 155 Profile::FromBrowserContext(browser_context()), |
| 156 base::Bind(&NativeAppWindowViewsWin::OnShortcutInfoLoaded, |
| 157 weak_ptr_factory_.GetWeakPtr())); |
| 158 } |
| 159 |
65 void NativeAppWindowViewsWin::Show() { | 160 void NativeAppWindowViewsWin::Show() { |
66 ActivateParentDesktopIfNecessary(); | 161 ActivateParentDesktopIfNecessary(); |
67 NativeAppWindowViews::Show(); | 162 NativeAppWindowViews::Show(); |
68 } | 163 } |
69 | 164 |
70 void NativeAppWindowViewsWin::Activate() { | 165 void NativeAppWindowViewsWin::Activate() { |
71 ActivateParentDesktopIfNecessary(); | 166 ActivateParentDesktopIfNecessary(); |
72 NativeAppWindowViews::Activate(); | 167 NativeAppWindowViews::Activate(); |
73 } | 168 } |
OLD | NEW |