web_app.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/file_util_icu.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Predicator for sorting images from largest to smallest. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconPrecedes(const WebApplicationInfo::IconInfo& left, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebApplicationInfo::IconInfo& right) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left.width < right.width; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteShortcutsOnFileThread( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ShellIntegration::ShortcutInfo& shortcut_info) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory( 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.profile_path, shortcut_info.extension_id, GURL()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return web_app::internals::DeletePlatformShortcuts( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_data_dir, shortcut_info); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateShortcutsOnFileThread( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ShellIntegration::ShortcutInfo& shortcut_info) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.profile_path, shortcut_info.extension_id, GURL()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return web_app::internals::UpdatePlatformShortcuts( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_data_dir, shortcut_info); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_app { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following string is used to build the directory name for 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shortcuts to chrome applications (the kind which are installed 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from a CRX). Application shortcuts to URLs use the {host}_{path} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the name of this directory. Hosts can't include an underscore. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// By starting this string with an underscore, we ensure that there 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are no naming conflicts. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kCrxAppPrefix = "_crx_"; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internals { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetSanitizedFileName(const string16& name) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 file_name = name; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_name = UTF16ToUTF8(name); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(file_name); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internals 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetWebAppDataDirectory(const FilePath& profile_path, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile_path.empty()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id.empty()) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_data_dir.AppendASCII( 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateApplicationNameFromExtensionId(extension_id)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host(url.host()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme(url.has_scheme() ? url.scheme() : "http"); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string port(url.has_port() ? url.port() : "80"); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme_port(scheme + "_" + port); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath::StringType host_path(UTF8ToUTF16(host)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath::StringType scheme_port_path(UTF8ToUTF16(scheme_port)); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath::StringType host_path(host); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath::StringType scheme_port_path(scheme_port); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_data_dir.Append(host_path).Append(scheme_port_path); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetWebAppDataDirectory(const FilePath& profile_path, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension& extension) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWebAppDataDirectory( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_path, extension.id(), GURL(extension.launch_web_url())); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromInfo( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ShellIntegration::ShortcutInfo& shortcut_info) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shortcut_info.extension_id.empty()) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return web_app::GenerateApplicationNameFromExtensionId( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.extension_id); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return web_app::GenerateApplicationNameFromURL( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.url); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromURL(const GURL& url) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string t; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(url.host()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append("_"); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(url.path()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return t; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromExtensionId(const std::string& id) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string t(web_app::kCrxAppPrefix); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(id); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return t; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionIdFromApplicationName(const std::string& app_name) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string prefix(kCrxAppPrefix); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_name.substr(0, prefix.length()) != prefix) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_name.substr(prefix.length()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(base::IgnoreResult(&CreateShortcutsOnFileThread), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteAllShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DeleteShortcutsOnFileThread, shortcut_info)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateAllShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&UpdateShortcutsOnFileThread, shortcut_info)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateShortcutsOnFileThread( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ShellIntegration::ShortcutInfo& shortcut_info) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath shortcut_data_dir = GetWebAppDataDirectory( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.profile_path, shortcut_info.extension_id, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_info.url); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return internals::CreatePlatformShortcuts(shortcut_data_dir, shortcut_info); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrl(const GURL& url) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* const kValidUrlSchemes[] = { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kFileScheme, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kFileSystemScheme, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kFtpScheme, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kHttpScheme, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kHttpsScheme, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::kExtensionScheme, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kValidUrlSchemes); ++i) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.SchemeIs(kValidUrlSchemes[i])) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIconsInfo(const WebApplicationInfo& app_info, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IconInfoList* icons) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(icons); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icons->clear(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < app_info.icons.size(); ++i) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only take square shaped icons (i.e. width == height). 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_info.icons[i].width == app_info.icons[i].height) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icons->push_back(app_info.icons[i]); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(icons->begin(), icons->end(), &IconPrecedes); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetWMClassFromAppName(std::string app_name) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimString(app_name, "_", &app_name); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_name; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace web_app 224