mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added winemenubuilder-associations patchset
This commit is contained in:
parent
a7a75d0d06
commit
95679a2f40
@ -0,0 +1,266 @@
|
||||
From 88814d059f53ba2575568d252f4da7539ee50c01 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Henrie <alexhenrie24@gmail.com>
|
||||
Date: Sun, 7 May 2023 22:34:15 -0600
|
||||
Subject: [PATCH] winemenubuilder: Create .desktop files for programs that open
|
||||
URIs.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22904
|
||||
---
|
||||
programs/winemenubuilder/winemenubuilder.c | 164 ++++++++++++---------
|
||||
1 file changed, 96 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
|
||||
index c16d22e2a57..b06eae422ff 100644
|
||||
--- a/programs/winemenubuilder/winemenubuilder.c
|
||||
+++ b/programs/winemenubuilder/winemenubuilder.c
|
||||
@@ -1831,10 +1831,13 @@ static BOOL has_association_changed(LPCWSTR extensionW, const WCHAR *mimeType, c
|
||||
ret = TRUE;
|
||||
heap_free(value);
|
||||
|
||||
- value = reg_get_valW(assocKey, extensionW, L"ProgID");
|
||||
- if (!value || wcscmp(value, progId))
|
||||
- ret = TRUE;
|
||||
- heap_free(value);
|
||||
+ if (progId)
|
||||
+ {
|
||||
+ value = reg_get_valW(assocKey, extensionW, L"ProgID");
|
||||
+ if (!value || wcscmp(value, progId))
|
||||
+ ret = TRUE;
|
||||
+ heap_free(value);
|
||||
+ }
|
||||
|
||||
value = reg_get_valW(assocKey, extensionW, L"AppName");
|
||||
if (!value || wcscmp(value, appName))
|
||||
@@ -1878,7 +1881,7 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
|
||||
}
|
||||
|
||||
RegSetValueExW(subkey, L"MimeType", 0, REG_SZ, (const BYTE*) mimeType, (lstrlenW(mimeType) + 1) * sizeof(WCHAR));
|
||||
- RegSetValueExW(subkey, L"ProgID", 0, REG_SZ, (const BYTE*) progId, (lstrlenW(progId) + 1) * sizeof(WCHAR));
|
||||
+ if (progId) RegSetValueExW(subkey, L"ProgID", 0, REG_SZ, (const BYTE*) progId, (lstrlenW(progId) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, L"AppName", 0, REG_SZ, (const BYTE*) appName, (lstrlenW(appName) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, L"DesktopFile", 0, REG_SZ, (const BYTE*) desktopFile, (lstrlenW(desktopFile) + 1) * sizeof(WCHAR));
|
||||
if (openWithIcon)
|
||||
@@ -1962,12 +1965,16 @@ static BOOL write_freedesktop_mime_type_entry(const WCHAR *packages_dir, const W
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static BOOL is_extension_banned(LPCWSTR extension)
|
||||
+static BOOL is_type_banned(const WCHAR *win_type)
|
||||
{
|
||||
/* These are managed through external tools like wine.desktop, to evade malware created file type associations */
|
||||
- if (!wcsicmp(extension, L".com") ||
|
||||
- !wcsicmp(extension, L".exe") ||
|
||||
- !wcsicmp(extension, L".msi"))
|
||||
+ if (!wcsicmp(win_type, L".com") ||
|
||||
+ !wcsicmp(win_type, L".exe") ||
|
||||
+ !wcsicmp(win_type, L".msi"))
|
||||
+ return TRUE;
|
||||
+ /* Associating a program with the file URI scheme is like associating it with all file types, which is not allowed
|
||||
+ * for the same reasons */
|
||||
+ if (!wcsicmp(win_type, L"file"))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2041,11 +2048,15 @@ static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const
|
||||
if (prefix)
|
||||
{
|
||||
char *path = wine_get_unix_file_name( prefix );
|
||||
- fprintf(desktop, "Exec=env WINEPREFIX=\"%s\" wine start /ProgIDOpen %s %%f\n", path, escape(progId));
|
||||
+ fprintf(desktop, "Exec=env WINEPREFIX=\"%s\" wine start ", path);
|
||||
heap_free( path );
|
||||
}
|
||||
else
|
||||
- fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", escape(progId));
|
||||
+ fprintf(desktop, "Exec=wine start ");
|
||||
+ if (progId) /* file association */
|
||||
+ fprintf(desktop, "/ProgIDOpen %s %%f\n", escape(progId));
|
||||
+ else /* protocol association */
|
||||
+ fprintf(desktop, "%%u\n");
|
||||
fprintf(desktop, "NoDisplay=true\n");
|
||||
fprintf(desktop, "StartupNotify=true\n");
|
||||
if (openWithIcon)
|
||||
@@ -2073,12 +2084,19 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
- WCHAR *extensionW;
|
||||
+ WCHAR *winTypeW;
|
||||
+ BOOL isProtocolType = FALSE;
|
||||
|
||||
- if (!(extensionW = reg_enum_keyW(HKEY_CLASSES_ROOT, i)))
|
||||
+ if (!(winTypeW = reg_enum_keyW(HKEY_CLASSES_ROOT, i)))
|
||||
break;
|
||||
|
||||
- if (extensionW[0] == '.' && !is_extension_banned(extensionW))
|
||||
+ if (winTypeW[0] != '.')
|
||||
+ {
|
||||
+ if (RegGetValueW(HKEY_CLASSES_ROOT, winTypeW, L"URL Protocol", RRF_RT_ANY, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||
+ isProtocolType = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ if ((winTypeW[0] == '.' || isProtocolType) && !is_type_banned(winTypeW))
|
||||
{
|
||||
WCHAR *commandW = NULL;
|
||||
WCHAR *executableW = NULL;
|
||||
@@ -2092,7 +2110,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
|
||||
WCHAR *mimeProgId = NULL;
|
||||
struct rb_string_entry *entry;
|
||||
|
||||
- commandW = assoc_query(ASSOCSTR_COMMAND, extensionW, L"open");
|
||||
+ commandW = assoc_query(ASSOCSTR_COMMAND, winTypeW, L"open");
|
||||
if (commandW == NULL)
|
||||
/* no command => no application is associated */
|
||||
goto end;
|
||||
@@ -2101,78 +2119,88 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
|
||||
/* command is on the exclude list => desktop integration is not desirable */
|
||||
goto end;
|
||||
|
||||
- wcslwr(extensionW);
|
||||
- friendlyDocNameW = assoc_query(ASSOCSTR_FRIENDLYDOCNAME, extensionW, NULL);
|
||||
+ iconW = assoc_query(ASSOCSTR_DEFAULTICON, winTypeW, NULL);
|
||||
|
||||
- iconW = assoc_query(ASSOCSTR_DEFAULTICON, extensionW, NULL);
|
||||
+ if (isProtocolType)
|
||||
+ {
|
||||
+ mimeType = heap_wprintf(L"x-scheme-handler/%s", winTypeW);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ wcslwr(winTypeW);
|
||||
+ friendlyDocNameW = assoc_query(ASSOCSTR_FRIENDLYDOCNAME, winTypeW, NULL);
|
||||
|
||||
- contentTypeW = assoc_query(ASSOCSTR_CONTENTTYPE, extensionW, NULL);
|
||||
- if (contentTypeW)
|
||||
- wcslwr(contentTypeW);
|
||||
+ contentTypeW = assoc_query(ASSOCSTR_CONTENTTYPE, winTypeW, NULL);
|
||||
+ if (contentTypeW)
|
||||
+ wcslwr(contentTypeW);
|
||||
|
||||
- mimeType = freedesktop_mime_type_for_extension(&nativeMimeTypes, extensionW);
|
||||
+ mimeType = freedesktop_mime_type_for_extension(&nativeMimeTypes, winTypeW);
|
||||
|
||||
- if (mimeType == NULL)
|
||||
- {
|
||||
- if (contentTypeW != NULL && wcschr(contentTypeW, '/'))
|
||||
- mimeType = xwcsdup(contentTypeW);
|
||||
- else if (!(mimeType = get_special_mime_type(extensionW)))
|
||||
- mimeType = heap_wprintf(L"application/x-wine-extension-%s", &extensionW[1]);
|
||||
-
|
||||
- /* GNOME seems to ignore the <icon> tag in MIME packages,
|
||||
- * and the default name is more intuitive anyway.
|
||||
- */
|
||||
- if (iconW)
|
||||
+ if (mimeType == NULL)
|
||||
{
|
||||
- WCHAR *flattened_mime = slashes_to_minuses(mimeType);
|
||||
- int index = 0;
|
||||
- WCHAR *comma = wcsrchr(iconW, ',');
|
||||
- if (comma)
|
||||
+ if (contentTypeW != NULL && wcschr(contentTypeW, '/'))
|
||||
+ mimeType = xwcsdup(contentTypeW);
|
||||
+ else if (!(mimeType = get_special_mime_type(winTypeW)))
|
||||
+ mimeType = heap_wprintf(L"application/x-wine-extension-%s", &winTypeW[1]);
|
||||
+
|
||||
+ /* GNOME seems to ignore the <icon> tag in MIME packages,
|
||||
+ * and the default name is more intuitive anyway.
|
||||
+ */
|
||||
+ if (iconW)
|
||||
{
|
||||
- *comma = 0;
|
||||
- index = wcstol(comma + 1, NULL, 10);
|
||||
+ WCHAR *flattened_mime = slashes_to_minuses(mimeType);
|
||||
+ int index = 0;
|
||||
+ WCHAR *comma = wcsrchr(iconW, ',');
|
||||
+ if (comma)
|
||||
+ {
|
||||
+ *comma = 0;
|
||||
+ index = wcstol(comma + 1, NULL, 10);
|
||||
+ }
|
||||
+ extract_icon(iconW, index, flattened_mime, FALSE);
|
||||
+ heap_free(flattened_mime);
|
||||
}
|
||||
- extract_icon(iconW, index, flattened_mime, FALSE);
|
||||
- heap_free(flattened_mime);
|
||||
+
|
||||
+ write_freedesktop_mime_type_entry(packages_dir, winTypeW, mimeType, friendlyDocNameW);
|
||||
+ hasChanged = TRUE;
|
||||
}
|
||||
|
||||
- write_freedesktop_mime_type_entry(packages_dir, extensionW, mimeType, friendlyDocNameW);
|
||||
- hasChanged = TRUE;
|
||||
+ progIdW = reg_get_valW(HKEY_CLASSES_ROOT, winTypeW, NULL);
|
||||
+ if (!progIdW) goto end; /* no progID => not a file type association */
|
||||
+
|
||||
+ /* Do not allow duplicate ProgIDs for a MIME type, it causes unnecessary duplication in Open dialogs */
|
||||
+ mimeProgId = heap_wprintf(L"%s=>%s", mimeType, progIdW);
|
||||
+ if (wine_rb_get(&mimeProgidTree, mimeProgId))
|
||||
+ {
|
||||
+ heap_free(mimeProgId);
|
||||
+ goto end;
|
||||
+ }
|
||||
+ entry = xmalloc(sizeof(struct rb_string_entry));
|
||||
+ entry->string = mimeProgId;
|
||||
+ if (wine_rb_put(&mimeProgidTree, mimeProgId, &entry->entry))
|
||||
+ {
|
||||
+ WINE_ERR("error updating rb tree\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
}
|
||||
|
||||
- executableW = assoc_query(ASSOCSTR_EXECUTABLE, extensionW, L"open");
|
||||
+ executableW = assoc_query(ASSOCSTR_EXECUTABLE, winTypeW, L"open");
|
||||
if (executableW)
|
||||
openWithIcon = compute_native_identifier(0, executableW, NULL);
|
||||
|
||||
- friendlyAppName = assoc_query(ASSOCSTR_FRIENDLYAPPNAME, extensionW, L"open");
|
||||
+ friendlyAppName = assoc_query(ASSOCSTR_FRIENDLYAPPNAME, winTypeW, L"open");
|
||||
if (!friendlyAppName) friendlyAppName = L"A Wine application";
|
||||
|
||||
- progIdW = reg_get_valW(HKEY_CLASSES_ROOT, extensionW, NULL);
|
||||
- if (!progIdW) goto end; /* no progID => not a file type association */
|
||||
-
|
||||
- /* Do not allow duplicate ProgIDs for a MIME type, it causes unnecessary duplication in Open dialogs */
|
||||
- mimeProgId = heap_wprintf(L"%s=>%s", mimeType, progIdW);
|
||||
- if (wine_rb_get(&mimeProgidTree, mimeProgId))
|
||||
+ if (has_association_changed(winTypeW, mimeType, progIdW, friendlyAppName, openWithIcon))
|
||||
{
|
||||
- heap_free(mimeProgId);
|
||||
- goto end;
|
||||
- }
|
||||
- entry = xmalloc(sizeof(struct rb_string_entry));
|
||||
- entry->string = mimeProgId;
|
||||
- if (wine_rb_put(&mimeProgidTree, mimeProgId, &entry->entry))
|
||||
- {
|
||||
- WINE_ERR("error updating rb tree\n");
|
||||
- goto end;
|
||||
- }
|
||||
-
|
||||
- if (has_association_changed(extensionW, mimeType, progIdW, friendlyAppName, openWithIcon))
|
||||
- {
|
||||
- WCHAR *desktopPath = heap_wprintf(L"%s\\wine-extension-%s.desktop",
|
||||
- applications_dir, extensionW + 1 );
|
||||
+ WCHAR *desktopPath;
|
||||
+ if (isProtocolType)
|
||||
+ desktopPath = heap_wprintf(L"%s\\wine-protocol-%s.desktop", applications_dir, winTypeW);
|
||||
+ else
|
||||
+ desktopPath = heap_wprintf(L"%s\\wine-extension-%s.desktop", applications_dir, winTypeW + 1);
|
||||
if (write_freedesktop_association_entry(desktopPath, friendlyAppName, mimeType, progIdW, openWithIcon))
|
||||
{
|
||||
hasChanged = TRUE;
|
||||
- update_association(extensionW, mimeType, progIdW, friendlyAppName, desktopPath, openWithIcon);
|
||||
+ update_association(winTypeW, mimeType, progIdW, friendlyAppName, desktopPath, openWithIcon);
|
||||
}
|
||||
heap_free(desktopPath);
|
||||
}
|
||||
@@ -2189,7 +2217,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
|
||||
heap_free(mimeType);
|
||||
heap_free(progIdW);
|
||||
}
|
||||
- heap_free(extensionW);
|
||||
+ heap_free(winTypeW);
|
||||
}
|
||||
|
||||
wine_rb_destroy(&mimeProgidTree, winemenubuilder_rb_destroy, NULL);
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 1d91d62e04e11defa69177084e3b4d5e55e0eae8 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Henrie <alexhenrie24@gmail.com>
|
||||
Date: Sun, 7 May 2023 22:34:15 -0600
|
||||
Subject: [PATCH] winecfg: Mention protocol associations.
|
||||
|
||||
---
|
||||
programs/winecfg/winecfg.rc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc
|
||||
index 3f18020e8a8..7e58f1553ce 100644
|
||||
--- a/programs/winecfg/winecfg.rc
|
||||
+++ b/programs/winecfg/winecfg.rc
|
||||
@@ -313,7 +313,7 @@ BEGIN
|
||||
CONTROL "",IDC_SYSPARAM_SIZE_UD,UPDOWN_CLASSA,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | WS_DISABLED, 185,75,15,13
|
||||
|
||||
GROUPBOX "MIME types",IDC_STATIC,8,95,244,23
|
||||
- CONTROL "Manage file &associations",IDC_ENABLE_FILE_ASSOCIATIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,230,10
|
||||
+ CONTROL "Manage file and protocol &associations",IDC_ENABLE_FILE_ASSOCIATIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,230,10
|
||||
|
||||
PUSHBUTTON "&Font...",IDC_SYSPARAM_FONT,190,75,55,13,WS_DISABLED
|
||||
GROUPBOX "Folders",IDC_STATIC,8,120,244,94
|
||||
--
|
||||
2.40.1
|
||||
|
2
patches/winemenubuilder-associations/definition
Normal file
2
patches/winemenubuilder-associations/definition
Normal file
@ -0,0 +1,2 @@
|
||||
# PR 2740
|
||||
Fixes: [22904] Register URL protocol handlers under linux.
|
Loading…
Reference in New Issue
Block a user