summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormgiuca@chromium.org <mgiuca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-20 04:06:21 +0000
committermgiuca@chromium.org <mgiuca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-20 04:06:21 +0000
commit7199367d14a8a1257c78416ff5bb5fc705acedc1 (patch)
tree70f24b8ce21abd90da8f5d44737ed6d44f1ec570
parent56347e22959f040135baab89bea1aa622d3c3e10 (diff)
downloadchromium_src-7199367d14a8a1257c78416ff5bb5fc705acedc1.zip
chromium_src-7199367d14a8a1257c78416ff5bb5fc705acedc1.tar.gz
chromium_src-7199367d14a8a1257c78416ff5bb5fc705acedc1.tar.bz2
Create App Launcher shortcuts and icons on Linux with --enable-app-list.
The shortcuts are only created if they have not been in the past. This adds Linux-suitable icons to chrome/app/theme/chromium/linux, which are PNG versions of the images in app_list.ico. The existing PNG images are designed exclusively for Mac and are unsuitable on Linux. Also made --enable-app-list and --reset-app-list-install-state available on Linux in about://flags. BUG=299250 Review URL: https://codereview.chromium.org/111853006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245855 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc14
-rw-r--r--chrome/browser/shell_integration_linux.cc79
-rw-r--r--chrome/browser/shell_integration_linux.h11
-rw-r--r--chrome/browser/shell_integration_linux_unittest.cc28
-rw-r--r--chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc21
-rw-r--r--ui/app_list/app_list_constants.cc8
-rw-r--r--ui/app_list/app_list_constants.h5
-rw-r--r--ui/app_list/views/app_list_view.cc9
9 files changed, 157 insertions, 24 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6ad1c7f..646719b 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6705,6 +6705,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
Reset the app launcher install state on every restart. While this flag is set, Chrome will forget the launcher has been installed each time it starts. This is used for testing the app launcher install flow.
</message>
<if expr="pp_ifdef('enable_app_list')">
+ <message name="IDS_FLAGS_ENABLE_APP_LIST_NAME" desc="Name of the flag to enable the app launcher.">
+ Enable the app launcher.
+ </message>
+ <message name="IDS_FLAGS_ENABLE_APP_LIST_DESCRIPTION" desc="Description of the flag to enable app launcher.">
+ Enable the app launcher. Upon enabling, creates operating system shortcuts to the app launcher.
+ </message>
<message name="IDS_FLAGS_ENABLE_APP_LIST_START_PAGE_NAME" desc="Name of the flag to enable the start page of app launcher.">
Enable the app launcher start page.
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c74285f..b41c3af 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1723,7 +1723,7 @@ const Experiment kExperiments[] = {
"reset-app-list-install-state",
IDS_FLAGS_RESET_APP_LIST_INSTALL_STATE_NAME,
IDS_FLAGS_RESET_APP_LIST_INSTALL_STATE_DESCRIPTION,
- kOsMac | kOsWin,
+ kOsMac | kOsWin | kOsLinux,
SINGLE_VALUE_TYPE(switches::kResetAppListInstallState)
},
#if defined(ENABLE_APP_LIST)
@@ -1734,6 +1734,18 @@ const Experiment kExperiments[] = {
kOsWin | kOsCrOS,
SINGLE_VALUE_TYPE(switches::kShowAppListStartPage)
},
+#if defined(OS_LINUX)
+ {
+ // This is compiled out on non-Linux platforms because otherwise it would be
+ // visible on Win/Mac/CrOS but not on Linux GTK, which would be confusing.
+ // TODO(mgiuca): Remove the #if when Aura is the default on Linux.
+ "enable-app-list",
+ IDS_FLAGS_ENABLE_APP_LIST_NAME,
+ IDS_FLAGS_ENABLE_APP_LIST_DESCRIPTION,
+ kOsLinux,
+ SINGLE_VALUE_TYPE(switches::kEnableAppList)
+ },
+#endif
{
"enable-app-list-folder",
IDS_FLAGS_ENABLE_APP_LIST_FOLDER,
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index 519b10d..923a30d 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -38,8 +38,11 @@
#include "build/build_config.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/browser/browser_thread.h"
+#include "grit/chrome_unscaled_resources.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_family.h"
#include "url/gurl.h"
@@ -76,10 +79,9 @@ bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) {
return base::WaitForExitCode(handle, exit_code);
}
-std::string CreateShortcutIcon(
- const ShellIntegration::ShortcutInfo& shortcut_info,
- const base::FilePath& shortcut_filename) {
- if (shortcut_info.favicon.empty())
+std::string CreateShortcutIcon(const gfx::ImageFamily& icon_images,
+ const base::FilePath& shortcut_filename) {
+ if (icon_images.empty())
return std::string();
// TODO(phajdan.jr): Report errors from this function, possibly as infobars.
@@ -91,8 +93,8 @@ std::string CreateShortcutIcon(
shortcut_filename.ReplaceExtension("png"));
std::string icon_name = temp_file_path.BaseName().RemoveExtension().value();
- for (gfx::ImageFamily::const_iterator it = shortcut_info.favicon.begin();
- it != shortcut_info.favicon.end(); ++it) {
+ for (gfx::ImageFamily::const_iterator it = icon_images.begin();
+ it != icon_images.end(); ++it) {
int width = it->Width();
scoped_refptr<base::RefCountedMemory> png_data = it->As1xPNGBytes();
if (png_data->size() == 0) {
@@ -287,6 +289,12 @@ const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
const char kDirectoryFilename[] = "chrome-apps.directory";
+#if defined(GOOGLE_CHROME_BUILD)
+const char kAppListDesktopName[] = "chrome-app-list";
+#else // CHROMIUM_BUILD
+const char kAppListDesktopName[] = "chromium-app-list";
+#endif
+
} // namespace
namespace {
@@ -720,7 +728,8 @@ std::string GetDesktopFileContents(
const base::string16& title,
const std::string& icon_name,
const base::FilePath& profile_path,
- bool no_display) {
+ bool no_display,
+ bool show_app_list) {
// Although not required by the spec, Nautilus on Ubuntu Karmic creates its
// launchers with an xdg-open shebang. Follow that convention.
std::string output_buffer = std::string(kXdgOpenShebang) + "\n";
@@ -748,8 +757,12 @@ std::string GetDesktopFileContents(
// Set the "Exec" key.
std::string final_path = chrome_exe_path.value();
CommandLine cmd_line(CommandLine::NO_PROGRAM);
- cmd_line = ShellIntegration::CommandLineArgsForLauncher(
- url, extension_id, profile_path);
+ if (show_app_list) {
+ cmd_line.AppendSwitch(switches::kShowAppList);
+ } else {
+ cmd_line = ShellIntegration::CommandLineArgsForLauncher(
+ url, extension_id, profile_path);
+ }
const CommandLine::SwitchMap& switch_map = cmd_line.GetSwitches();
for (CommandLine::SwitchMap::const_iterator i = switch_map.begin();
i != switch_map.end(); ++i) {
@@ -857,7 +870,8 @@ bool CreateDesktopShortcut(
if (shortcut_filename.empty())
return false;
- std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename);
+ std::string icon_name =
+ CreateShortcutIcon(shortcut_info.favicon, shortcut_filename);
std::string app_name =
web_app::GenerateApplicationNameFromInfo(shortcut_info);
@@ -880,6 +894,7 @@ bool CreateDesktopShortcut(
shortcut_info.title,
icon_name,
shortcut_info.profile_path,
+ false,
false);
success = CreateShortcutOnDesktop(shortcut_filename, contents);
}
@@ -914,7 +929,8 @@ bool CreateDesktopShortcut(
icon_name,
shortcut_info.profile_path,
creation_locations.applications_menu_location ==
- ShellIntegration::APP_MENU_LOCATION_NONE);
+ ShellIntegration::APP_MENU_LOCATION_NONE,
+ false);
success = CreateShortcutInApplicationsMenu(
shortcut_filename, contents, directory_filename, directory_contents) &&
success;
@@ -923,6 +939,47 @@ bool CreateDesktopShortcut(
return success;
}
+bool CreateAppListDesktopShortcut(
+ const std::string& wm_class,
+ const std::string& title) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ base::FilePath desktop_name(kAppListDesktopName);
+ base::FilePath shortcut_filename = desktop_name.AddExtension("desktop");
+
+ // We do not want duplicate shortcuts. Delete any that already exist and
+ // replace them.
+ DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath());
+
+ base::FilePath chrome_exe_path = GetChromeExePath();
+ if (chrome_exe_path.empty()) {
+ LOG(WARNING) << "Could not get executable path.";
+ return false;
+ }
+
+ gfx::ImageFamily icon_images;
+ ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
+ icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_16));
+ icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_32));
+ icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_48));
+ icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_256));
+ std::string icon_name = CreateShortcutIcon(icon_images, desktop_name);
+
+ std::string contents = ShellIntegrationLinux::GetDesktopFileContents(
+ chrome_exe_path,
+ wm_class,
+ GURL(),
+ "",
+ base::FilePath(),
+ base::UTF8ToUTF16(title),
+ icon_name,
+ base::FilePath(),
+ false,
+ true);
+ return CreateShortcutInApplicationsMenu(
+ shortcut_filename, contents, base::FilePath(), "");
+}
+
void DeleteDesktopShortcuts(const base::FilePath& profile_path,
const std::string& extension_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
diff --git a/chrome/browser/shell_integration_linux.h b/chrome/browser/shell_integration_linux.h
index 0e9350f..32f3195 100644
--- a/chrome/browser/shell_integration_linux.h
+++ b/chrome/browser/shell_integration_linux.h
@@ -85,6 +85,8 @@ std::vector<base::FilePath> GetExistingProfileShortcutFilenames(
// Returns contents for .desktop file based on |url| and |title|. If
// |no_display| is true, the shortcut will not be visible to the user in menus.
+// If |show_app_list| is true, creates a shortcut to the app list, and ignores
+// |url|, |extension_id| and |profile_path|.
std::string GetDesktopFileContents(const base::FilePath& chrome_exe_path,
const std::string& app_name,
const GURL& url,
@@ -93,7 +95,8 @@ std::string GetDesktopFileContents(const base::FilePath& chrome_exe_path,
const base::string16& title,
const std::string& icon_name,
const base::FilePath& profile_path,
- bool no_display);
+ bool no_display,
+ bool show_app_list);
// Returns contents for .directory file named |title| with icon |icon_name|. If
// |icon_name| is empty, will use the Chrome icon.
@@ -108,6 +111,12 @@ bool CreateDesktopShortcut(
const ShellIntegration::ShortcutInfo& shortcut_info,
const ShellIntegration::ShortcutLocations& creation_locations);
+// Create shortcuts in the application menu for the app launcher. Duplicate
+// shortcuts are avoided, so if a requested shortcut already exists it is
+// deleted first. Also creates the icon required by the shortcut.
+bool CreateAppListDesktopShortcut(const std::string& wm_class,
+ const std::string& title);
+
// Delete any desktop shortcuts on desktop or in the application menu that have
// been added for the extension with |extension_id| in |profile_path|.
void DeleteDesktopShortcuts(const base::FilePath& profile_path,
diff --git a/chrome/browser/shell_integration_linux_unittest.cc b/chrome/browser/shell_integration_linux_unittest.cc
index 3bb6ba4..39ecd62 100644
--- a/chrome/browser/shell_integration_linux_unittest.cc
+++ b/chrome/browser/shell_integration_linux_unittest.cc
@@ -576,10 +576,36 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
base::ASCIIToUTF16(test_cases[i].title),
test_cases[i].icon_name,
base::FilePath(),
- test_cases[i].nodisplay));
+ test_cases[i].nodisplay,
+ false));
}
}
+TEST(ShellIntegrationTest, GetDesktopFileContentsAppList) {
+ const base::FilePath kChromeExePath("/opt/google/chrome/google-chrome");
+ EXPECT_EQ(
+ "#!/usr/bin/env xdg-open\n"
+ "[Desktop Entry]\n"
+ "Version=1.0\n"
+ "Terminal=false\n"
+ "Type=Application\n"
+ "Name=Chrome App Launcher\n"
+ "Exec=/opt/google/chrome/google-chrome --show-app-list\n"
+ "Icon=chrome_app_list\n"
+ "StartupWMClass=chrome-app-list\n",
+ ShellIntegrationLinux::GetDesktopFileContents(
+ kChromeExePath,
+ "chrome-app-list",
+ GURL(),
+ std::string(),
+ base::FilePath(),
+ base::ASCIIToUTF16("Chrome App Launcher"),
+ "chrome_app_list",
+ base::FilePath(),
+ false,
+ true));
+}
+
TEST(ShellIntegrationTest, GetDirectoryFileContents) {
const struct {
const char* title;
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
index c018eab..caee3bee6 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
@@ -5,6 +5,8 @@
#include "chrome/browser/ui/views/app_list/linux/app_list_service_linux.h"
#include "base/memory/singleton.h"
+#include "chrome/browser/shell_integration.h"
+#include "chrome/browser/shell_integration_linux.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/app_list_factory.h"
#include "chrome/browser/ui/app_list/app_list_shower.h"
@@ -12,7 +14,12 @@
#include "chrome/browser/ui/app_list/keep_alive_service_impl.h"
#include "chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h"
#include "chrome/browser/ui/views/app_list/linux/app_list_linux.h"
+#include "content/public/browser/browser_thread.h"
+#include "grit/chromium_strings.h"
+#include "grit/google_chrome_strings.h"
+#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/views/app_list_view.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/screen.h"
namespace {
@@ -49,6 +56,17 @@ class AppListFactoryLinux : public AppListFactory {
DISALLOW_COPY_AND_ASSIGN(AppListFactoryLinux);
};
+void CreateShortcuts() {
+ std::string app_list_title =
+ l10n_util::GetStringUTF8(IDS_APP_LIST_SHORTCUT_NAME);
+
+ if (!ShellIntegrationLinux::CreateAppListDesktopShortcut(
+ app_list::kAppListWMClass,
+ app_list_title)) {
+ LOG(WARNING) << "Unable to create App Launcher shortcut.";
+ }
+}
+
} // namespace
AppListServiceLinux::~AppListServiceLinux() {}
@@ -111,7 +129,8 @@ AppListControllerDelegate* AppListServiceLinux::GetControllerDelegate() {
}
void AppListServiceLinux::CreateShortcut() {
- NOTIMPLEMENTED();
+ content::BrowserThread::PostTask(
+ content::BrowserThread::FILE, FROM_HERE, base::Bind(&CreateShortcuts));
}
AppListServiceLinux::AppListServiceLinux()
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc
index 5f45dec..c770460 100644
--- a/ui/app_list/app_list_constants.cc
+++ b/ui/app_list/app_list_constants.cc
@@ -57,4 +57,12 @@ const size_t kNumFolderTopItems = 4;
const ui::ResourceBundle::FontStyle kItemTextFontStyle =
ui::ResourceBundle::SmallBoldFont;
+#if defined(OS_LINUX)
+#if defined(GOOGLE_CHROME_BUILD)
+const char kAppListWMClass[] = "chrome_app_list";
+#else // CHROMIUM_BUILD
+const char kAppListWMClass[] = "chromium_app_list";
+#endif
+#endif
+
} // namespace app_list
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h
index 7f5940e..c23ed1a 100644
--- a/ui/app_list/app_list_constants.h
+++ b/ui/app_list/app_list_constants.h
@@ -45,6 +45,11 @@ APP_LIST_EXPORT extern const size_t kNumFolderTopItems;
APP_LIST_EXPORT extern const ui::ResourceBundle::FontStyle kItemTextFontStyle;
+#if defined(OS_LINUX)
+// The WM_CLASS name for the app launcher window on Linux.
+APP_LIST_EXPORT extern const char kAppListWMClass[];
+#endif
+
} // namespace app_list
#endif // UI_APP_LIST_APP_LIST_CONSTANTS_H_
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index b023847..c38c107 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -58,15 +58,6 @@ const float kSpeechUIAppearingPosition = 12;
// The distance between the arrow tip and edge of the anchor view.
const int kArrowOffset = 10;
-#if defined(OS_LINUX)
-// The WM_CLASS name for the app launcher window on Linux.
-#if defined(GOOGLE_CHROME_BUILD)
-const char kAppListWMClass[] = "chrome_app_list";
-#else // CHROMIUM_BUILD
-const char kAppListWMClass[] = "chromium_app_list";
-#endif
-#endif
-
// Determines whether the current environment supports shadows bubble borders.
bool SupportsShadow() {
#if defined(USE_AURA) && defined(OS_WIN)