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

Unified Diff: chrome/browser/shell_integration_linux.cc

Issue 14383003: Application shortcuts in Linux are now installed into a "Chrome Apps" folder. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: GetDirectoryFileContents needs the same \n hack as GetDesktopFileContents. Created 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/shell_integration_linux.h ('k') | chrome/browser/shell_integration_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/shell_integration_linux.cc
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index be33d73f790e4683e71d5de118f071c7f644d617..7b2088dd7ac65096cabf5f365468c245c9b97f47 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -173,12 +173,30 @@ void DeleteShortcutOnDesktop(const base::FilePath& shortcut_filename) {
file_util::Delete(desktop_path.Append(shortcut_filename), false);
}
+// Creates a shortcut with |shortcut_filename| and |contents| in the system
+// applications menu. If |directory_filename| is non-empty, creates a sub-menu
+// with |directory_filename| and |directory_contents|, and stores the shortcut
+// under the sub-menu.
bool CreateShortcutInApplicationsMenu(const base::FilePath& shortcut_filename,
- const std::string& contents) {
+ const std::string& contents,
+ const base::FilePath& directory_filename,
+ const std::string& directory_contents) {
base::ScopedTempDir temp_dir;
if (!temp_dir.CreateUniqueTempDir())
return false;
+ base::FilePath temp_directory_path;
+ if (!directory_filename.empty()) {
+ temp_directory_path = temp_dir.path().Append(directory_filename);
+
+ int bytes_written = file_util::WriteFile(temp_directory_path,
+ directory_contents.data(),
+ directory_contents.length());
+
+ if (bytes_written != static_cast<int>(directory_contents.length()))
+ return false;
+ }
+
base::FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);
int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
@@ -196,13 +214,18 @@ bool CreateShortcutInApplicationsMenu(const base::FilePath& shortcut_filename,
argv.push_back("--mode");
argv.push_back("user");
+ // If provided, install the shortcut file inside the given directory.
+ if (!directory_filename.empty())
+ argv.push_back(temp_directory_path.value());
argv.push_back(temp_file_path.value());
int exit_code;
LaunchXdgUtility(argv, &exit_code);
return exit_code == 0;
}
-void DeleteShortcutInApplicationsMenu(const base::FilePath& shortcut_filename) {
+void DeleteShortcutInApplicationsMenu(
+ const base::FilePath& shortcut_filename,
+ const base::FilePath& directory_filename) {
std::vector<std::string> argv;
argv.push_back("xdg-desktop-menu");
argv.push_back("uninstall");
@@ -213,6 +236,10 @@ void DeleteShortcutInApplicationsMenu(const base::FilePath& shortcut_filename) {
// The file does not need to exist anywhere - xdg-desktop-menu will uninstall
// items from the menu with a matching name.
+ // If |directory_filename| is supplied, this will also remove the item from
+ // the directory, and remove the directory if it is empty.
+ if (!directory_filename.empty())
+ argv.push_back(directory_filename.value());
argv.push_back(shortcut_filename.value());
int exit_code;
LaunchXdgUtility(argv, &exit_code);
@@ -254,6 +281,8 @@ const char kXdgSettings[] = "xdg-settings";
const char kXdgSettingsDefaultBrowser[] = "default-web-browser";
const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
+const char kDirectoryFilename[] = "chrome-apps.directory";
+
} // namespace
namespace {
@@ -694,6 +723,41 @@ std::string GetDesktopFileContents(
return output_buffer;
}
+std::string GetDirectoryFileContents(const string16& title,
+ const std::string& icon_name) {
+ // See http://standards.freedesktop.org/desktop-entry-spec/latest/
+ GKeyFile* key_file = g_key_file_new();
+
+ g_key_file_set_string(key_file, kDesktopEntry, "Version", "1.0");
+ g_key_file_set_string(key_file, kDesktopEntry, "Type", "Directory");
+ std::string final_title = UTF16ToUTF8(title);
+ g_key_file_set_string(key_file, kDesktopEntry, "Name", final_title.c_str());
+ if (!icon_name.empty()) {
+ g_key_file_set_string(key_file, kDesktopEntry, "Icon", icon_name.c_str());
+ } else {
+ g_key_file_set_string(key_file, kDesktopEntry, "Icon",
+ GetIconName().c_str());
+ }
+
+ gsize length = 0;
+ gchar* data_dump = g_key_file_to_data(key_file, &length, NULL);
+ std::string output_buffer;
+ if (data_dump) {
+ // If strlen(data_dump[0]) == 0, this check will fail.
+ if (data_dump[0] == '\n') {
+ // Older versions of glib produce a leading newline. If this is the case,
+ // remove it to avoid double-newline after the shebang.
+ output_buffer += (data_dump + 1);
+ } else {
+ output_buffer += data_dump;
+ }
+ g_free(data_dump);
+ }
+
+ g_key_file_free(key_file);
+ return output_buffer;
+}
+
bool CreateDesktopShortcut(
const ShellIntegration::ShortcutInfo& shortcut_info,
const ShellIntegration::ShortcutLocations& creation_locations) {
@@ -708,7 +772,7 @@ bool CreateDesktopShortcut(
if (creation_locations.on_desktop)
DeleteShortcutOnDesktop(shortcut_filename);
if (creation_locations.in_applications_menu || creation_locations.hidden)
- DeleteShortcutInApplicationsMenu(shortcut_filename);
+ DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath());
} else {
shortcut_filename = GetWebShortcutFilename(shortcut_info.url);
}
@@ -746,6 +810,13 @@ bool CreateDesktopShortcut(
// The 'in_applications_menu' and 'hidden' locations are actually the same
// place ('applications').
if (creation_locations.in_applications_menu || creation_locations.hidden) {
+ base::FilePath directory_filename;
+ std::string directory_contents;
+ if (!creation_locations.applications_menu_subdir.empty()) {
+ directory_filename = base::FilePath(kDirectoryFilename);
+ directory_contents = ShellIntegrationLinux::GetDirectoryFileContents(
+ creation_locations.applications_menu_subdir, "");
+ }
// Set NoDisplay=true if hidden but not in_applications_menu. This will hide
// the application from user-facing menus.
std::string contents = ShellIntegrationLinux::GetDesktopFileContents(
@@ -758,8 +829,9 @@ bool CreateDesktopShortcut(
icon_name,
shortcut_info.profile_path,
!creation_locations.in_applications_menu);
- success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) &&
- success;
+ success = CreateShortcutInApplicationsMenu(
+ shortcut_filename, contents, directory_filename, directory_contents) &&
+ success;
}
return success;
@@ -774,7 +846,13 @@ void DeleteDesktopShortcuts(const base::FilePath& profile_path,
DCHECK(!shortcut_filename.empty());
DeleteShortcutOnDesktop(shortcut_filename);
- DeleteShortcutInApplicationsMenu(shortcut_filename);
+ // Delete shortcuts from |kDirectoryFilename|.
+ // Note that it is possible that shortcuts were not created in the Chrome Apps
+ // directory (depending on the value of |applications_menu_subdir| when they
+ // were created). It doesn't matter: this will still delete the shortcut even
+ // if it isn't in the directory.
+ DeleteShortcutInApplicationsMenu(shortcut_filename,
+ base::FilePath(kDirectoryFilename));
}
} // namespace ShellIntegrationLinux
« no previous file with comments | « chrome/browser/shell_integration_linux.h ('k') | chrome/browser/shell_integration_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698