From 0583f87814239e08fddae43be41ba07cccdd5680 Mon Sep 17 00:00:00 2001 From: NelloKudo Date: Fri, 20 Dec 2024 02:26:52 +0100 Subject: [PATCH] bump proton-osu-9-12! - fixed issues with high polling rate devices: https://bugs.winehq.org/show_bug.cgi?id=57442 - fixed osu's hardcoded explorer path to the Screenshots folder when hiding Wine --- ...u-Check-for-driver-events-more-often.patch | 83 ++++++++ ...lace-osu-s-explorer.exe-calls-with-t.patch | 189 ++++++++++++++++++ setup.sh | 2 +- 3 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 patches/wine/0005-osu/0001-win32u-Check-for-driver-events-more-often.patch create mode 100644 patches/wine/0005-osu/HACK-proton-shell32-replace-osu-s-explorer.exe-calls-with-t.patch diff --git a/patches/wine/0005-osu/0001-win32u-Check-for-driver-events-more-often.patch b/patches/wine/0005-osu/0001-win32u-Check-for-driver-events-more-often.patch new file mode 100644 index 0000000..de3307d --- /dev/null +++ b/patches/wine/0005-osu/0001-win32u-Check-for-driver-events-more-often.patch @@ -0,0 +1,83 @@ +From 074d1def1d497d071f2e4bfdd0837b0cde494357 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Thu, 12 Dec 2024 03:37:59 -0800 +Subject: [PATCH] win32u: Check for driver events more often. + +Use a QPC wrapper to avoid NtGetTickCount, which is coupled to +the 16 millisecond user_shared_data_timeout in server/fd.c. This +lowers the throttling period to 0.25ms (8khz), which is quick +enough to consume driver events from high polling rate devices. + +Fixes: 54ca1ab607d3ff22a1f57a9561430f64c75f0916 +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57442 + +(cherry picked from commit b5a4c2f64ad07b0aaeddc2d8245bc79ddb33b1f5) +--- + dlls/win32u/message.c | 16 ++++++++++++---- + dlls/win32u/ntuser_private.h | 2 +- + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c +index aec44a03e65..dbfbe157a97 100644 +--- a/dlls/win32u/message.c ++++ b/dlls/win32u/message.c +@@ -3159,6 +3159,14 @@ static HANDLE get_server_queue_handle(void) + return ret; + } + ++/* monotonic timer tick for throttling driver event checks */ ++static inline LONGLONG get_driver_check_time(void) ++{ ++ LARGE_INTEGER counter, freq; ++ NtQueryPerformanceCounter( &counter, &freq ); ++ return counter.QuadPart * 8000 / freq.QuadPart; /* 8kHz */ ++} ++ + /* check for driver events if we detect that the app is not properly consuming messages */ + static inline void check_for_driver_events( UINT msg ) + { +@@ -3358,7 +3366,7 @@ BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, U + int ret; + + user_check_not_lock(); +- if (thread_info->last_driver_time != NtGetTickCount()) ++ if (thread_info->last_driver_time != get_driver_check_time()) + check_for_driver_events( 0 ); + + ret = peek_message( &msg, hwnd, first, last, flags, 0, FALSE ); +@@ -3366,8 +3374,8 @@ BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, U + + if (!ret) + { +- if (thread_info->last_driver_time == NtGetTickCount()) return FALSE; +- thread_info->last_driver_time = NtGetTickCount(); ++ if (thread_info->last_driver_time == get_driver_check_time()) return FALSE; ++ thread_info->last_driver_time = get_driver_check_time(); + flush_window_surfaces( TRUE ); + ret = wait_message( 0, NULL, 0, QS_ALLINPUT, 0 ); + /* if we received driver events, check again for a pending message */ +@@ -3375,7 +3383,7 @@ BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, U + } + + check_for_driver_events( msg.message ); +- thread_info->last_driver_time = NtGetTickCount() - 1; ++ thread_info->last_driver_time = get_driver_check_time() - 1; + + /* copy back our internal safe copy of message data to msg_out. + * msg_out is a variable from the *program*, so it can't be used +diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h +index 4221c25d65f..4d24c7dd9ef 100644 +--- a/dlls/win32u/ntuser_private.h ++++ b/dlls/win32u/ntuser_private.h +@@ -131,7 +131,7 @@ struct user_thread_info + HANDLE server_queue; /* Handle to server-side queue */ + DWORD wake_mask; /* Current queue wake mask */ + DWORD changed_mask; /* Current queue changed mask */ +- DWORD last_driver_time; /* Get/PeekMessage driver event time */ ++ LONGLONG last_driver_time; /* Get/PeekMessage driver event time */ + DWORD last_getmsg_time; /* Get/PeekMessage last request time */ + WORD message_count; /* Get/PeekMessage loop counter */ + WORD hook_call_depth; /* Number of recursively called hook procs */ +-- +2.47.1 + diff --git a/patches/wine/0005-osu/HACK-proton-shell32-replace-osu-s-explorer.exe-calls-with-t.patch b/patches/wine/0005-osu/HACK-proton-shell32-replace-osu-s-explorer.exe-calls-with-t.patch new file mode 100644 index 0000000..08189f2 --- /dev/null +++ b/patches/wine/0005-osu/HACK-proton-shell32-replace-osu-s-explorer.exe-calls-with-t.patch @@ -0,0 +1,189 @@ +From 5299d1b07a9738999093478afd3723efaac89e2f Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Sun, 15 Dec 2024 17:22:38 -0800 +Subject: [PATCH 1/2] HACK: shell32: replace osu!'s explorer.exe calls with the + folder of the file it's trying to open. + +This allows osu! to open the screenshot folder by clicking +the popup ingame, when WINE_BLOCK_GET_VERSION=1 is used. + +That's under the assumption that the Folder\\shell\\open\\command +registry key is set up correctly with xdg-open and all that +machinery that osu-winello sets up automatically. +--- + dlls/shell32/shlexec.c | 61 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c +index b9fb6285f39..bde391c4433 100644 +--- a/dlls/shell32/shlexec.c ++++ b/dlls/shell32/shlexec.c +@@ -32,6 +32,7 @@ + #include "winbase.h" + #include "winerror.h" + #include "winreg.h" ++#include "winternl.h" + #include "winuser.h" + #include "shlwapi.h" + #include "ddeml.h" +@@ -1629,6 +1630,23 @@ static WCHAR *expand_environment( const WCHAR *str ) + return buf; + } + ++static BOOL is_osu(void) ++{ ++ static volatile char cache = -1; ++ BOOL ret = cache; ++ if (ret == -1) ++ { ++ const WCHAR *p, *name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; ++ if ((p = wcsrchr(name, '/'))) ++ name = p + 1; ++ if ((p = wcsrchr(name, '\\'))) ++ name = p + 1; ++ ret = !wcsicmp(name, L"osu!.exe"); ++ cache = ret; ++ } ++ return ret; ++} ++ + /************************************************************************* + * SHELL_execute [Internal] + */ +@@ -1654,6 +1672,49 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) + /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */ + sei_tmp = *sei; + ++ /* HACK: open screenshot folder directly */ ++ if (is_osu() && !wcscmp(sei_tmp.lpFile, L"explorer.exe") && sei_tmp.lpParameters) ++ { ++ static const WCHAR select_prefix[] = L"/select,"; ++ LPCWSTR path = sei_tmp.lpParameters; ++ ++ if (!wcsncmp(path, select_prefix, ARRAY_SIZE(select_prefix) - 1)) ++ { ++ path += ARRAY_SIZE(select_prefix) - 1; ++ ++ BOOL has_quotes = (*path == '\"'); ++ if (has_quotes) ++ path++; ++ ++ size_t path_len = wcslen(path); ++ if (has_quotes && path_len > 0 && path[path_len - 1] == '\"') ++ path_len--; ++ ++ LPWSTR dir_path = malloc((path_len + 2) * sizeof(WCHAR)); ++ if (!dir_path) ++ return FALSE; ++ ++ memcpy(dir_path, path, path_len); ++ dir_path[path_len] = '\0'; ++ ++ if (!PathRemoveFileSpecW(dir_path)) ++ { ++ free(dir_path); ++ return FALSE; ++ } ++ ++ if (wcslen(dir_path) + 2 <= path_len + 2) ++ PathAddBackslashW(dir_path); ++ ++ sei_tmp.lpFile = dir_path; ++ sei_tmp.lpParameters = sei_tmp.lpVerb = NULL; ++ ++ BOOL ret = SHELL_execute(&sei_tmp, execfunc); ++ free(dir_path); ++ return ret; ++ } ++ } ++ + TRACE("mask=0x%08lx hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n", + sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb), + debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters), +-- +2.47.1 + +From ae7fe9133126aafdf5d4669f776a8c35831a9ee7 Mon Sep 17 00:00:00 2001 +From: William Horvath +Date: Sun, 15 Dec 2024 17:23:53 -0800 +Subject: [PATCH 2/2] wine.inf.in: Remove default folder/ddeexec handler. + +--- + loader/wine.inf.in | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/loader/wine.inf.in b/loader/wine.inf.in +index ad1987a..b449b78 100644 +--- a/loader/wine.inf.in ++++ b/loader/wine.inf.in +@@ -73,6 +73,7 @@ AddReg=\ + Tapi,\ + ThemeManager,\ + LicenseInformation ++DelReg=RemoveClasses + + [DefaultInstall.NT] + RegisterDlls=RegisterDllsSection +@@ -102,6 +103,7 @@ AddReg=\ + NVIDIANGX, \ + ProtonOverrides,\ + SteamClient ++DelReg=RemoveClasses + + [DefaultInstall.ntamd64] + RegisterDlls=RegisterDllsSection +@@ -133,6 +135,7 @@ AddReg=\ + TTS, \ + ProtonOverrides,\ + SteamClient.ntamd64 ++DelReg=RemoveClasses + + [DefaultInstall.ntarm64] + RegisterDlls=RegisterDllsSection +@@ -159,6 +162,7 @@ AddReg=\ + ThemeManager,\ + VersionInfo,\ + LicenseInformation ++DelReg=RemoveClasses + + [Wow64Install.ntx86] + RegisterDlls=RegisterDllsSection +@@ -179,6 +183,7 @@ AddReg=\ + NVIDIANGX, \ + ProtonOverrides,\ + SteamClient.ntamd64 ++DelReg=RemoveClasses + + [Wow64Install.ntarm] + RegisterDlls=RegisterDllsSection +@@ -194,6 +199,7 @@ AddReg=\ + Tapi,\ + VersionInfo,\ + LicenseInformation ++DelReg=RemoveClasses + + [DefaultInstall.Services] + AddService=BITS,0,BITSService +@@ -314,9 +320,6 @@ HKCR,exefile,,2,"Application" + HKCR,exefile\DefaultIcon,,2,"%1" + HKCR,exefile\shell\open\command,,2,"""%1"" %*" + HKCR,exefile\shell\runas\command,,2,"""%1"" %*" +-HKCR,folder\shell\open\ddeexec,,2,"[ViewFolder("%l", %I, %S)]" +-HKCR,folder\shell\open\ddeexec,"NoActivateHandler",2,"" +-HKCR,folder\shell\open\ddeexec\application,,2,"Folders" + HKCR,folder\shellex\ContextMenuHandlers,,16 + HKCR,hlpfile,,2,"Help File" + HKCR,hlpfile\shell\open\command,,2,"""%11%\winhlp32.exe"" ""%1""" +@@ -359,6 +362,9 @@ HKCR,https\shell\open\command,,2,"""%11%\winebrowser.exe"" ""%1""" + HKCR,mailto\shell\open\command,,2,"""%11%\winebrowser.exe"" ""%1""" + HKCR,steam\shell\open\command,,,"""%16426%\Steam\Steam.exe"" -- ""%1""" + ++[RemoveClasses] ++HKCR,folder\shell\open\ddeexec ++ + [ContentIndex] + HKLM,System\CurrentControlSet\Control\ContentIndex\Language\Neutral,"WBreakerClass",,"{369647e0-17b0-11ce-9950-00aa004bbb1f}" + HKLM,System\CurrentControlSet\Control\ContentIndex\Language\Neutral,"StemmerClass",,"" +-- +2.47.1 + diff --git a/setup.sh b/setup.sh index 50024f8..04dbb81 100755 --- a/setup.sh +++ b/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash -pkgver=9-11 +pkgver=9-12 buildname="proton-osu" pkgname="${buildname}-${pkgver}"