winemenubuilder: manage desktop shortcuts better
Damjan Jovanovic
damjan.jov at gmail.com
Wed May 19 14:49:01 CDT 2010
Changelog:
* winemenubuilder: manage desktop shortcuts better
Details:
* When we write a .lnk to ~/Desktop, do not generate a .desktop file.
Patches committed in the last round ensured .lnk will still start
through a double-click, and future patches could thumbnail an icon for
the .lnk. Deletion of the .lnk on uninstall fully cleans up
everything.
* When we write a .lnk to the "public desktop", which isn't ~/Desktop,
then generate a .desktop file in ~/Desktop and link the 2 together in
the registry, so when the .lnk is deleted on uninstall the .desktop is
also deleted later.
* The .desktop file, when we generate it, now also runs start.exe with
the path to the .lnk instead of the escaped/quoted command in the
.lnk.
* Simplify the InvokeShellLinker function.
Except for the cosmetic details like the icon, this essentially closes #3548.
Damjan Jovanovic
-------------- next part --------------
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 9f10fdb..b0dc7c5 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -2222,12 +2222,37 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
return hasChanged;
}
-static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
+static char* escape_unix_link_arg(LPCSTR unix_link)
+{
+ char *ret = NULL;
+ WCHAR *unix_linkW = utf8_chars_to_wchars(unix_link);
+ if (unix_linkW)
+ {
+ char *escaped_lnk = escape(unix_linkW);
+ if (escaped_lnk)
+ {
+ ret = heap_printf("/Unix %s", escaped_lnk);
+ HeapFree(GetProcessHeap(), 0, escaped_lnk);
+ }
+ HeapFree(GetProcessHeap(), 0, unix_linkW);
+ }
+ return ret;
+}
+
+static char *get_start_exe_path(void)
{
static const WCHAR startW[] = {'\\','c','o','m','m','a','n','d',
'\\','s','t','a','r','t','.','e','x','e',0};
+ WCHAR start_path[MAX_PATH];
+ GetWindowsDirectoryW(start_path, MAX_PATH);
+ lstrcatW(start_path, startW);
+ return escape(start_path);
+}
+
+static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
+{
char *link_name = NULL, *icon_name = NULL, *work_dir = NULL;
- char *escaped_path = NULL, *escaped_args = NULL, *description = NULL;
+ char *description = NULL;
WCHAR szTmp[INFOTIPSIZE];
WCHAR szDescription[INFOTIPSIZE], szPath[MAX_PATH], szWorkDir[MAX_PATH];
WCHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH];
@@ -2235,6 +2260,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
DWORD csidl = -1;
HANDLE hsem = NULL;
char *unix_link = NULL;
+ char *start_path = NULL;
if ( !link )
{
@@ -2310,52 +2336,22 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
/* check the path */
if( szPath[0] )
{
- static const WCHAR exeW[] = {'.','e','x','e',0};
- WCHAR *p;
-
- /* check for .exe extension */
- if (!(p = strrchrW( szPath, '.' )) ||
- strchrW( p, '\\' ) || strchrW( p, '/' ) ||
- lstrcmpiW( p, exeW ))
- {
- /* Not .exe - use 'start.exe' to launch this file */
- p = szArgs + lstrlenW(szPath) + 2;
- if (szArgs[0])
- {
- p[0] = ' ';
- memmove( p+1, szArgs, min( (lstrlenW(szArgs) + 1) * sizeof(szArgs[0]),
- sizeof(szArgs) - (p + 1 - szArgs) * sizeof(szArgs[0]) ) );
- }
- else
- p[0] = 0;
-
- szArgs[0] = '"';
- lstrcpyW(szArgs + 1, szPath);
- p[-1] = '"';
-
- GetWindowsDirectoryW(szPath, MAX_PATH);
- lstrcatW(szPath, startW);
- }
-
/* convert app working dir */
if (szWorkDir[0])
work_dir = wine_get_unix_file_name( szWorkDir );
}
- else
+
+ description = wchars_to_utf8_chars(szDescription);
+ if (description == NULL)
{
- /* if there's no path... try run the link itself */
- lstrcpynW(szArgs, link, MAX_PATH);
- GetWindowsDirectoryW(szPath, MAX_PATH);
- lstrcatW(szPath, startW);
+ WINE_ERR("out of memory allocating description\n");
+ goto cleanup;
}
- /* escape the path and parameters */
- escaped_path = escape(szPath);
- escaped_args = escape(szArgs);
- description = wchars_to_utf8_chars(szDescription);
- if (escaped_path == NULL || escaped_args == NULL || description == NULL)
+ start_path = get_start_exe_path();
+ if (start_path == NULL)
{
- WINE_ERR("out of memory allocating/escaping parameters\n");
+ WINE_ERR("out of memory\n");
goto cleanup;
}
@@ -2369,39 +2365,40 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
if (in_desktop_dir(csidl))
{
- char *location;
- const char *lastEntry;
- lastEntry = strrchr(link_name, '/');
- if (lastEntry == NULL)
- lastEntry = link_name;
- else
- ++lastEntry;
- location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
- if (location)
+ if (csidl == CSIDL_COMMON_DESKTOPDIRECTORY)
{
- r = !write_desktop_entry(NULL, location, lastEntry, escaped_path, escaped_args, description, work_dir, icon_name);
- if (r == 0)
- chmod(location, 0755);
- HeapFree(GetProcessHeap(), 0, location);
+ char *location;
+ const char *lastEntry;
+ lastEntry = strrchr(link_name, '/');
+ if (lastEntry == NULL)
+ lastEntry = link_name;
+ else
+ ++lastEntry;
+ location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
+ if (location)
+ {
+ char *link_arg = escape_unix_link_arg(unix_link);
+ if (link_arg)
+ {
+ r = !write_desktop_entry(unix_link, location, lastEntry,
+ start_path, link_arg, description, work_dir, icon_name);
+ if (r == 0)
+ chmod(location, 0755);
+ HeapFree(GetProcessHeap(), 0, link_arg);
+ }
+ HeapFree(GetProcessHeap(), 0, location);
+ }
}
+ else
+ WINE_TRACE("not generating .desktop file for %s, it is already on the desktop\n", unix_link);
}
else
{
- WCHAR *unix_linkW = utf8_chars_to_wchars(unix_link);
- if (unix_linkW)
+ char *link_arg = escape_unix_link_arg(unix_link);
+ if (link_arg)
{
- char *escaped_lnk = escape(unix_linkW);
- if (escaped_lnk)
- {
- char *menuarg = heap_printf("/Unix %s", escaped_lnk);
- if (menuarg)
- {
- r = !write_menu_entry(unix_link, link_name, "start", menuarg, description, work_dir, icon_name);
- HeapFree(GetProcessHeap(), 0, menuarg);
- }
- HeapFree(GetProcessHeap(), 0, escaped_lnk);
- }
- HeapFree(GetProcessHeap(), 0, unix_linkW);
+ r = !write_menu_entry(unix_link, link_name, start_path, link_arg, description, work_dir, icon_name);
+ HeapFree(GetProcessHeap(), 0, link_arg);
}
}
@@ -2412,10 +2409,9 @@ cleanup:
HeapFree( GetProcessHeap(), 0, icon_name );
HeapFree( GetProcessHeap(), 0, work_dir );
HeapFree( GetProcessHeap(), 0, link_name );
- HeapFree( GetProcessHeap(), 0, escaped_args );
- HeapFree( GetProcessHeap(), 0, escaped_path );
HeapFree( GetProcessHeap(), 0, description );
- HeapFree( GetProcessHeap(), 0, unix_link);
+ HeapFree( GetProcessHeap(), 0, unix_link );
+ HeapFree( GetProcessHeap(), 0, start_path );
if (r && !bWait)
WINE_ERR("failed to build the menu\n" );
More information about the wine-patches
mailing list