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

Unified Diff: chrome/browser/shell_integration_linux.cc

Issue 12208085: On Linux, automatically create app shortcuts on install or update. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Diff against Issue 12386077. Created 7 years, 10 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
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

Powered by Google App Engine
This is Rietveld 408576698