| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/shell_integration_linux.h" | 5 #include "chrome/browser/shell_integration_linux.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <glib.h> | 8 #include <glib.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" |
| 44 #include "grit/chrome_unscaled_resources.h" | 44 #include "grit/chrome_unscaled_resources.h" |
| 45 #include "ui/base/resource/resource_bundle.h" | 45 #include "ui/base/resource/resource_bundle.h" |
| 46 #include "ui/gfx/image/image_family.h" | 46 #include "ui/gfx/image/image_family.h" |
| 47 #include "url/gurl.h" | 47 #include "url/gurl.h" |
| 48 | 48 |
| 49 using content::BrowserThread; | 49 using content::BrowserThread; |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 | 52 |
| 53 // The Categories for the App Launcher desktop shortcut. Should be the same as |
| 54 // the Chrome desktop shortcut, so they are in the same sub-menu. |
| 55 const char kAppListCategories[] = "Network;WebBrowser;"; |
| 56 |
| 53 // Helper to launch xdg scripts. We don't want them to ask any questions on the | 57 // Helper to launch xdg scripts. We don't want them to ask any questions on the |
| 54 // terminal etc. The function returns true if the utility launches and exits | 58 // terminal etc. The function returns true if the utility launches and exits |
| 55 // cleanly, in which case |exit_code| returns the utility's exit code. | 59 // cleanly, in which case |exit_code| returns the utility's exit code. |
| 56 bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) { | 60 bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) { |
| 57 // xdg-settings internally runs xdg-mime, which uses mv to move newly-created | 61 // xdg-settings internally runs xdg-mime, which uses mv to move newly-created |
| 58 // files on top of originals after making changes to them. In the event that | 62 // files on top of originals after making changes to them. In the event that |
| 59 // the original files are owned by another user (e.g. root, which can happen | 63 // the original files are owned by another user (e.g. root, which can happen |
| 60 // if they are updated within sudo), mv will prompt the user to confirm if | 64 // if they are updated within sudo), mv will prompt the user to confirm if |
| 61 // standard input is a terminal (otherwise it just does it). So make sure it's | 65 // standard input is a terminal (otherwise it just does it). So make sure it's |
| 62 // not, to avoid locking everything up waiting for mv. | 66 // not, to avoid locking everything up waiting for mv. |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 } | 754 } |
| 751 | 755 |
| 752 std::string GetDesktopFileContents( | 756 std::string GetDesktopFileContents( |
| 753 const base::FilePath& chrome_exe_path, | 757 const base::FilePath& chrome_exe_path, |
| 754 const std::string& app_name, | 758 const std::string& app_name, |
| 755 const GURL& url, | 759 const GURL& url, |
| 756 const std::string& extension_id, | 760 const std::string& extension_id, |
| 757 const base::string16& title, | 761 const base::string16& title, |
| 758 const std::string& icon_name, | 762 const std::string& icon_name, |
| 759 const base::FilePath& profile_path, | 763 const base::FilePath& profile_path, |
| 764 const std::string& categories, |
| 760 bool no_display) { | 765 bool no_display) { |
| 761 CommandLine cmd_line = ShellIntegration::CommandLineArgsForLauncher( | 766 CommandLine cmd_line = ShellIntegration::CommandLineArgsForLauncher( |
| 762 url, extension_id, profile_path); | 767 url, extension_id, profile_path); |
| 763 cmd_line.SetProgram(chrome_exe_path); | 768 cmd_line.SetProgram(chrome_exe_path); |
| 764 return GetDesktopFileContentsForCommand(cmd_line, app_name, url, title, | 769 return GetDesktopFileContentsForCommand(cmd_line, app_name, url, title, |
| 765 icon_name, no_display); | 770 icon_name, categories, no_display); |
| 766 } | 771 } |
| 767 | 772 |
| 768 std::string GetDesktopFileContentsForCommand( | 773 std::string GetDesktopFileContentsForCommand( |
| 769 const CommandLine& command_line, | 774 const CommandLine& command_line, |
| 770 const std::string& app_name, | 775 const std::string& app_name, |
| 771 const GURL& url, | 776 const GURL& url, |
| 772 const base::string16& title, | 777 const base::string16& title, |
| 773 const std::string& icon_name, | 778 const std::string& icon_name, |
| 779 const std::string& categories, |
| 774 bool no_display) { | 780 bool no_display) { |
| 775 // Although not required by the spec, Nautilus on Ubuntu Karmic creates its | 781 // Although not required by the spec, Nautilus on Ubuntu Karmic creates its |
| 776 // launchers with an xdg-open shebang. Follow that convention. | 782 // launchers with an xdg-open shebang. Follow that convention. |
| 777 std::string output_buffer = std::string(kXdgOpenShebang) + "\n"; | 783 std::string output_buffer = std::string(kXdgOpenShebang) + "\n"; |
| 778 | 784 |
| 779 // See http://standards.freedesktop.org/desktop-entry-spec/latest/ | 785 // See http://standards.freedesktop.org/desktop-entry-spec/latest/ |
| 780 GKeyFile* key_file = g_key_file_new(); | 786 GKeyFile* key_file = g_key_file_new(); |
| 781 | 787 |
| 782 // Set keys with fixed values. | 788 // Set keys with fixed values. |
| 783 g_key_file_set_string(key_file, kDesktopEntry, "Version", "1.0"); | 789 g_key_file_set_string(key_file, kDesktopEntry, "Version", "1.0"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 801 g_key_file_set_string(key_file, kDesktopEntry, "Exec", final_path.c_str()); | 807 g_key_file_set_string(key_file, kDesktopEntry, "Exec", final_path.c_str()); |
| 802 | 808 |
| 803 // Set the "Icon" key. | 809 // Set the "Icon" key. |
| 804 if (!icon_name.empty()) { | 810 if (!icon_name.empty()) { |
| 805 g_key_file_set_string(key_file, kDesktopEntry, "Icon", icon_name.c_str()); | 811 g_key_file_set_string(key_file, kDesktopEntry, "Icon", icon_name.c_str()); |
| 806 } else { | 812 } else { |
| 807 g_key_file_set_string(key_file, kDesktopEntry, "Icon", | 813 g_key_file_set_string(key_file, kDesktopEntry, "Icon", |
| 808 GetIconName().c_str()); | 814 GetIconName().c_str()); |
| 809 } | 815 } |
| 810 | 816 |
| 817 // Set the "Categories" key. |
| 818 if (!categories.empty()) { |
| 819 g_key_file_set_string( |
| 820 key_file, kDesktopEntry, "Categories", categories.c_str()); |
| 821 } |
| 822 |
| 811 // Set the "NoDisplay" key. | 823 // Set the "NoDisplay" key. |
| 812 if (no_display) | 824 if (no_display) |
| 813 g_key_file_set_string(key_file, kDesktopEntry, "NoDisplay", "true"); | 825 g_key_file_set_string(key_file, kDesktopEntry, "NoDisplay", "true"); |
| 814 | 826 |
| 815 std::string wmclass = web_app::GetWMClassFromAppName(app_name); | 827 std::string wmclass = web_app::GetWMClassFromAppName(app_name); |
| 816 g_key_file_set_string(key_file, kDesktopEntry, "StartupWMClass", | 828 g_key_file_set_string(key_file, kDesktopEntry, "StartupWMClass", |
| 817 wmclass.c_str()); | 829 wmclass.c_str()); |
| 818 | 830 |
| 819 gsize length = 0; | 831 gsize length = 0; |
| 820 gchar* data_dump = g_key_file_to_data(key_file, &length, NULL); | 832 gchar* data_dump = g_key_file_to_data(key_file, &length, NULL); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 | 922 |
| 911 if (creation_locations.on_desktop) { | 923 if (creation_locations.on_desktop) { |
| 912 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( | 924 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( |
| 913 chrome_exe_path, | 925 chrome_exe_path, |
| 914 app_name, | 926 app_name, |
| 915 shortcut_info.url, | 927 shortcut_info.url, |
| 916 shortcut_info.extension_id, | 928 shortcut_info.extension_id, |
| 917 shortcut_info.title, | 929 shortcut_info.title, |
| 918 icon_name, | 930 icon_name, |
| 919 shortcut_info.profile_path, | 931 shortcut_info.profile_path, |
| 932 "", |
| 920 false); | 933 false); |
| 921 success = CreateShortcutOnDesktop(shortcut_filename, contents); | 934 success = CreateShortcutOnDesktop(shortcut_filename, contents); |
| 922 } | 935 } |
| 923 | 936 |
| 924 if (creation_locations.applications_menu_location != | 937 if (creation_locations.applications_menu_location != |
| 925 web_app::APP_MENU_LOCATION_NONE || | 938 web_app::APP_MENU_LOCATION_NONE || |
| 926 creation_locations.hidden) { | 939 creation_locations.hidden) { |
| 927 base::FilePath directory_filename; | 940 base::FilePath directory_filename; |
| 928 std::string directory_contents; | 941 std::string directory_contents; |
| 929 switch (creation_locations.applications_menu_location) { | 942 switch (creation_locations.applications_menu_location) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 942 // Set NoDisplay=true if hidden but not in the applications menu. This will | 955 // Set NoDisplay=true if hidden but not in the applications menu. This will |
| 943 // hide the application from user-facing menus. | 956 // hide the application from user-facing menus. |
| 944 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( | 957 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( |
| 945 chrome_exe_path, | 958 chrome_exe_path, |
| 946 app_name, | 959 app_name, |
| 947 shortcut_info.url, | 960 shortcut_info.url, |
| 948 shortcut_info.extension_id, | 961 shortcut_info.extension_id, |
| 949 shortcut_info.title, | 962 shortcut_info.title, |
| 950 icon_name, | 963 icon_name, |
| 951 shortcut_info.profile_path, | 964 shortcut_info.profile_path, |
| 965 "", |
| 952 creation_locations.applications_menu_location == | 966 creation_locations.applications_menu_location == |
| 953 web_app::APP_MENU_LOCATION_NONE); | 967 web_app::APP_MENU_LOCATION_NONE); |
| 954 success = CreateShortcutInApplicationsMenu( | 968 success = CreateShortcutInApplicationsMenu( |
| 955 shortcut_filename, contents, directory_filename, directory_contents) && | 969 shortcut_filename, contents, directory_filename, directory_contents) && |
| 956 success; | 970 success; |
| 957 } | 971 } |
| 958 | 972 |
| 959 return success; | 973 return success; |
| 960 } | 974 } |
| 961 | 975 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 980 gfx::ImageFamily icon_images; | 994 gfx::ImageFamily icon_images; |
| 981 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); | 995 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); |
| 982 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_16)); | 996 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_16)); |
| 983 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_32)); | 997 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_32)); |
| 984 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_48)); | 998 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_48)); |
| 985 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_256)); | 999 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_256)); |
| 986 std::string icon_name = CreateShortcutIcon(icon_images, desktop_name); | 1000 std::string icon_name = CreateShortcutIcon(icon_images, desktop_name); |
| 987 | 1001 |
| 988 CommandLine command_line(chrome_exe_path); | 1002 CommandLine command_line(chrome_exe_path); |
| 989 command_line.AppendSwitch(switches::kShowAppList); | 1003 command_line.AppendSwitch(switches::kShowAppList); |
| 990 std::string contents = GetDesktopFileContentsForCommand( | 1004 std::string contents = |
| 991 command_line, wm_class, GURL(), base::UTF8ToUTF16(title), icon_name, | 1005 GetDesktopFileContentsForCommand(command_line, |
| 992 false); | 1006 wm_class, |
| 1007 GURL(), |
| 1008 base::UTF8ToUTF16(title), |
| 1009 icon_name, |
| 1010 kAppListCategories, |
| 1011 false); |
| 993 return CreateShortcutInApplicationsMenu( | 1012 return CreateShortcutInApplicationsMenu( |
| 994 shortcut_filename, contents, base::FilePath(), ""); | 1013 shortcut_filename, contents, base::FilePath(), ""); |
| 995 } | 1014 } |
| 996 | 1015 |
| 997 void DeleteDesktopShortcuts(const base::FilePath& profile_path, | 1016 void DeleteDesktopShortcuts(const base::FilePath& profile_path, |
| 998 const std::string& extension_id) { | 1017 const std::string& extension_id) { |
| 999 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1018 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 1000 | 1019 |
| 1001 base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 1020 base::FilePath shortcut_filename = GetExtensionShortcutFilename( |
| 1002 profile_path, extension_id); | 1021 profile_path, extension_id); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 for (std::vector<base::FilePath>::const_iterator it = | 1056 for (std::vector<base::FilePath>::const_iterator it = |
| 1038 shortcut_filenames_app_menu.begin(); | 1057 shortcut_filenames_app_menu.begin(); |
| 1039 it != shortcut_filenames_app_menu.end(); ++it) { | 1058 it != shortcut_filenames_app_menu.end(); ++it) { |
| 1040 DeleteShortcutInApplicationsMenu(*it, | 1059 DeleteShortcutInApplicationsMenu(*it, |
| 1041 base::FilePath(kDirectoryFilename)); | 1060 base::FilePath(kDirectoryFilename)); |
| 1042 } | 1061 } |
| 1043 } | 1062 } |
| 1044 } | 1063 } |
| 1045 | 1064 |
| 1046 } // namespace ShellIntegrationLinux | 1065 } // namespace ShellIntegrationLinux |
| OLD | NEW |