Chromium Code Reviews| Index: chrome/browser/shell_integration_linux.cc |
| diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc |
| index 9c287ed2aa65bca503e28f3de9487da72deb0e20..113bba63399ceff2fe0bb58f072aa48b3f1e2091 100644 |
| --- a/chrome/browser/shell_integration_linux.cc |
| +++ b/chrome/browser/shell_integration_linux.cc |
| @@ -394,6 +394,32 @@ ShellIntegration::DefaultWebClientState GetIsDefaultWebClient( |
| #endif |
| } |
| +// Get the value of NoDisplay from the [Desktop Entry] section of a .desktop |
| +// file, given in |shortcut_contents|. If the key is not found, returns false. |
| +bool GetNoDisplayFromDesktopFile(const std::string& shortcut_contents) { |
| + GKeyFile* key_file = g_key_file_new(); |
| + GError* err = NULL; |
| + if (!g_key_file_load_from_data(key_file, shortcut_contents.c_str(), |
| + shortcut_contents.size(), G_KEY_FILE_NONE, |
| + &err)) { |
| + LOG(WARNING) << "Unable to read desktop file template: " << err->message; |
| + g_error_free(err); |
| + return false; |
| + } |
| + |
| + bool nodisplay = false; |
| + char* nodisplay_c_string = g_key_file_get_string(key_file, kDesktopEntry, |
| + "NoDisplay", &err); |
| + if (nodisplay_c_string) { |
| + if (!g_strcmp0(nodisplay_c_string, "true")) |
| + nodisplay = true; |
| + g_free(nodisplay_c_string); |
| + } |
| + |
| + g_key_file_free(key_file); |
| + return nodisplay; |
| +} |
| + |
| } // namespace |
| // static |
| @@ -457,8 +483,9 @@ std::string GetDesktopName(base::Environment* env) { |
| #endif |
| } |
| -bool GetDesktopShortcutTemplate(base::Environment* env, |
| - std::string* output) { |
| +bool GetExistingDesktopShortcutContents(base::Environment* env, |
| + const base::FilePath& desktop_filename, |
| + std::string* output) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| std::vector<base::FilePath> search_paths; |
| @@ -488,21 +515,31 @@ bool GetDesktopShortcutTemplate(base::Environment* env, |
| search_paths.push_back(base::FilePath("/usr/local/share")); |
| } |
| - std::string template_filename(GetDesktopName(env)); |
| for (std::vector<base::FilePath>::const_iterator i = search_paths.begin(); |
| i != search_paths.end(); ++i) { |
| - base::FilePath path = i->Append("applications").Append(template_filename); |
| - VLOG(1) << "Looking for desktop file template in " << path.value(); |
| + base::FilePath path = i->Append("applications").Append(desktop_filename); |
| + VLOG(1) << "Looking for desktop file in " << path.value(); |
| if (file_util::PathExists(path)) { |
| - VLOG(1) << "Found desktop file template at " << path.value(); |
| + VLOG(1) << "Found desktop file at " << path.value(); |
| return file_util::ReadFileToString(path, output); |
| } |
| } |
| - LOG(ERROR) << "Could not find desktop file template."; |
| return false; |
| } |
| +bool GetDesktopShortcutTemplate(base::Environment* env, |
| + std::string* output) { |
| + base::FilePath template_filename(GetDesktopName(env)); |
| + if (GetExistingDesktopShortcutContents(env, template_filename, output)) { |
| + return true; |
| + } else { |
| + LOG(ERROR) << "Could not find desktop file " << template_filename.value() |
| + << "."; |
| + return false; |
| + } |
| +} |
| + |
| base::FilePath GetWebShortcutFilename(const GURL& url) { |
| // Use a prefix, because xdg-desktop-menu requires it. |
| std::string filename = |
| @@ -549,7 +586,8 @@ std::string GetDesktopFileContents( |
| const base::FilePath& extension_path, |
| const string16& title, |
| const std::string& icon_name, |
| - const base::FilePath& profile_path) { |
| + const base::FilePath& profile_path, |
| + bool no_display) { |
| // 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"; |
| @@ -650,6 +688,10 @@ std::string GetDesktopFileContents( |
| if (!icon_name.empty()) |
| g_key_file_set_string(key_file, kDesktopEntry, "Icon", icon_name.c_str()); |
| + // Set the "NoDisplay" key. |
| + if (no_display) |
| + g_key_file_set_string(key_file, kDesktopEntry, "NoDisplay", "true"); |
| + |
| #if defined(TOOLKIT_GTK) |
| std::string wmclass = web_app::GetWMClassFromAppName(app_name); |
| g_key_file_set_string(key_file, kDesktopEntry, "StartupWMClass", |
| @@ -698,6 +740,12 @@ bool CreateDesktopShortcut( |
| std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename); |
| + // If we are to create the shortcut in neither the desktop nor applications |
| + // menu, we still want to register the app, so we create a shortcut with |
| + // NoDisplay=true. |
| + bool no_display = (!creation_locations.on_desktop && |
|
benwells
2013/03/05 04:32:38
Note for later: this feels a bit strange. It would
Matt Giuca
2013/03/05 05:25:44
Well it wouldn't necessarily need to be platform-s
|
| + !creation_locations.in_applications_menu); |
| + |
| std::string app_name = |
| web_app::GenerateApplicationNameFromInfo(shortcut_info); |
| std::string contents = ShellIntegrationLinux::GetDesktopFileContents( |
| @@ -708,14 +756,17 @@ bool CreateDesktopShortcut( |
| shortcut_info.extension_path, |
| shortcut_info.title, |
| icon_name, |
| - shortcut_info.profile_path); |
| + shortcut_info.profile_path, |
| + no_display); |
| bool success = true; |
| if (creation_locations.on_desktop) |
| success = CreateShortcutOnDesktop(shortcut_filename, contents); |
| - if (creation_locations.in_applications_menu) |
| + // If no_display is true, CreateShortcutInApplicationsMenu will install the |
| + // shortcut, but it will not appear in menus or be searchable by users. |
| + if (creation_locations.in_applications_menu || no_display) |
| success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) && |
| success; |
| @@ -734,4 +785,42 @@ void DeleteDesktopShortcuts(const base::FilePath& profile_path, |
| DeleteShortcutInApplicationsMenu(shortcut_filename); |
| } |
| +ShellIntegration::ShortcutLocations DesktopShortcutLocations( |
| + base::Environment* env, const base::FilePath& profile_path, |
| + const std::string& extension_id) { |
|
benwells
2013/03/05 04:32:38
Nit: one parameter per line.
Matt Giuca
2013/03/06 06:29:51
Done.
|
| + base::FilePath desktop_path; |
| + // If Get returns false, just leave desktop_path empty. |
| + PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); |
| + return DesktopShortcutLocations(env, profile_path, extension_id, |
| + desktop_path); |
| +} |
| + |
| +ShellIntegration::ShortcutLocations DesktopShortcutLocations( |
| + base::Environment* env, const base::FilePath& profile_path, |
| + const std::string& extension_id, const base::FilePath& desktop_path) { |
|
benwells
2013/03/05 04:32:38
Nit: one parameter per line.
Matt Giuca
2013/03/06 06:29:51
Done.
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + base::FilePath shortcut_filename = GetExtensionShortcutFilename( |
| + profile_path, extension_id); |
| + DCHECK(!shortcut_filename.empty()); |
| + ShellIntegration::ShortcutLocations locations; |
| + |
| + // Determine whether there is a shortcut on desktop. |
| + if (!desktop_path.empty()) { |
| + locations.on_desktop = |
| + file_util::PathExists(desktop_path.Append(shortcut_filename)); |
| + } |
| + |
| + // Determine whether there is a shortcut in applications menu that *does not* |
| + // have NoDisplay=true. |
| + std::string shortcut_contents; |
| + if (GetExistingDesktopShortcutContents(env, shortcut_filename, |
| + &shortcut_contents)) { |
| + locations.in_applications_menu = |
| + !GetNoDisplayFromDesktopFile(shortcut_contents); |
| + } |
| + |
| + return locations; |
| +} |
| + |
| } // namespace ShellIntegrationLinux |