Closed IncubusRK closed 3 years ago
We don't use the System.Windows.Forms library from mono, so that shouldn't make any difference.
Maybe fix must be here https://github.com/madewokherd/winforms/blob/2ccd830395e52bebf300e8a676e4f26db93c4b69/src/System.Windows.Forms/src/System/Windows/Forms/ToolTip.cs#L242
Fix on application side look like this https://sourceforge.net/p/autowikibrowser/code/11270/tree//AWB/WikiFunctions/Controls/AWBToolTip.cs
Could be. Does this work on .NET Framework?
Not that it matters, we should be able to do better than .NET Framework, but ideally we should do it in a way that's not visible to the application. We probably need winex11.drv's heuristic to treat the windows as unmanaged here: https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/winex11.drv/window.c#l227
Unfortunately, that seems to only account for window styles, so our options are limited.
It's not clear to me why that particular set of styles fixes it. This could use some more investigation to figure out why this doesn't work, and if it can be fixed without doing that.
Since this appears to be using the builtin tooltip class, I feel like winex11's heuristic should account for that, which would allow us to keep the styles the same and also fix this bug for .NET. (Or, if it works in .NET, I'd like to know why.)
My guess is that the builtin tooltip class should use ShowWindow or SetWindowPos flags that do not focus the window (SW_SHOWNA or SWP_NOACTIVATE), so that is_window_managed sees that in swp_flags and doesn't treat it as managed. This should be possible to test without involving wine-mono at all.
I made a quick test case
diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c
index 639d51f7c28..7be7b2fdf82 100644
--- a/dlls/comctl32/tests/tooltips.c
+++ b/dlls/comctl32/tests/tooltips.c
@@ -1228,6 +1228,9 @@ static void test_TTN_SHOW(void)
ok_sequence(sequences, PARENT_SEQ_INDEX, ttn_show_parent_seq, "TTN_SHOW parent seq", FALSE);
+ ok(GetForegroundWindow() != hwndTip, "got wrong foreground window\n");
+ ok(GetActiveWindow() != hwndTip, "got wrong active window\n");
+
DestroyWindow(hwndTip);
DestroyWindow(hwnd);
}
This passes on Windows but fails on Wine. However, my theory on why it fails is incorrect, as SWP_NOACTIVATE is already correctly being passed to SetWindowPos when showing the tooltip. It seems WS_CAPTION gets implicitly set in the window style somehow during creation, and that causes Wine's heuristic to treat it as managed.
I'm going to move this over to the Wine Bugzilla as it does not appear to be specific to Wine Mono.
It seems there are already a few bugs filed that may have the same cause, so I'm not going to file a new one: https://bugs.winehq.org/show_bug.cgi?id=39547 https://bugs.winehq.org/show_bug.cgi?id=41062
I'll add the new information to bug 41062 for now.
Closing the issue here, we can track it on the Winehq bug.
Ok, but native C++ MFC application haven't issues with tooltips
I went ahead and pushed a work-around anyway: https://github.com/madewokherd/wine-mono/commit/ac9e8ba1fe1c97d2ff35d7819c10e70917f7ecff
The Wine bug depends on the styles passed to CreateWindow, if MFC passes in WS_POPUP then it won't encounter this bug. On Windows, passing in WS_POPUP is not needed.
The work-around is in Wine Mono 6.4.0 which will be in Wine 6.18.
In Windows Forms application tooltips steal focus from main window. It happens only in Wine-Mono. (It also can depend of windows manager version in Linux distro) To check error you can create any simple WinForms application with tooltip
Workarroud to prevent this is override function "CreateParams" and add WS_EX_NOACTIVATE style
Suggested fix: https://github.com/madewokherd/mono/blob/e51d7a840c2d998e28928dbbf6f37b59e3b9e799/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolTip.cs#L117
cp.ExStyle = (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST | WindowExStyles.WS_EX_NOACTIVATE);