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 |