This fixes various problems I've run into while trying to use Fusion 360 in wine. - stacking issues in unmanaged mode - I also attempted to apply the same fix for managed mode, but it looks difficult to do this in a way that plays well with window managers; I think it's best left up to them to keep override_redirect windows at the top of the stack) - when the window manager sets our state to withdrawn, tell the window that it's been minimized, since the semantics are very similar - the last one is a hack because I don't really know what to do about it, when clicking on the floating popups, they gain focus, which causes wine to incorrectly make them managed and that breaks everything
-- v3: winex11: don't let captionless popups be managed winex11: pass ICCCM withdrawn state as minimized winex11: restack a window's owned popups above it
From: novenary streetwalkermc@gmail.com
This fixes Z ordering issues in the virtual desktop. For example, Fusion 360's floating menus tend to disappear behind the main window. --- dlls/winex11.drv/event.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 1ae39eb9edf..19126cecaf8 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -539,6 +539,34 @@ static inline BOOL can_activate_window( HWND hwnd ) }
+/*********************************************************************** + * restack_owned_popups + * + * Restack a window's owned popups above it. + */ +static void restack_owned_popups( struct x11drv_win_data *data ) +{ + HWND *list; + UINT i; + struct x11drv_win_data *owned_data; + XWindowChanges changes = {.stack_mode = Above, .sibling = data->whole_window}; + + if (!(list = build_hwnd_list())) return; + + for (i = 0; list[i] != HWND_BOTTOM; i++) + { + if (NtUserGetWindowRelative( list[i], GW_OWNER ) != data->hwnd) continue; + owned_data = get_win_data( list[i] ); + if (owned_data && !owned_data->managed) + XConfigureWindow( data->display, owned_data->whole_window, CWSibling | CWStackMode, &changes ); + release_win_data( owned_data ); + } + + free( list ); + return; +} + + /********************************************************************** * set_input_focus * @@ -561,6 +589,7 @@ static void set_input_focus( struct x11drv_win_data *data ) /* Set X focus and install colormap */ changes.stack_mode = Above; XConfigureWindow( data->display, data->whole_window, CWStackMode, &changes ); + restack_owned_popups( data );
if (data->embedder) xembed_request_focus( data->display, data->embedder, timestamp );
From: novenary streetwalkermc@gmail.com
A window is withdrawn when neither it nor its "taskbar" icon is visible, e.g. when switching workspaces.
This fixes issues with unmanaged popups showing on all workspaces. --- dlls/winex11.drv/event.c | 5 +---- dlls/winex11.drv/window.c | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 19126cecaf8..e05e45a4c12 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1301,9 +1301,6 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat TRACE( "%p/%lx: new WM_STATE %d from %d\n", data->hwnd, data->whole_window, new_state, old_state ); data->wm_state = new_state; - /* ignore the initial state transition out of withdrawn state */ - /* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */ - if (!old_state) goto done; } } break; @@ -1342,7 +1339,7 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style ); } } - else if (!data->iconic && data->wm_state == IconicState) + else if (!data->iconic && (data->wm_state == IconicState || data->wm_state == WithdrawnState)) { data->iconic = TRUE; if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED)) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index cb9e07599c4..fcbdad97d16 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2721,7 +2721,10 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, data->iconic = (new_style & WS_MINIMIZE) != 0; TRACE( "changing win %p iconic state to %u\n", data->hwnd, data->iconic ); if (data->iconic) - XIconifyWindow( data->display, data->whole_window, data->vis.screen ); + { + if (data->wm_state != WithdrawnState) + XIconifyWindow( data->display, data->whole_window, data->vis.screen ); + } else if (is_window_rect_mapped( rectWindow )) XMapWindow( data->display, data->whole_window ); update_net_wm_states( data );
From: novenary streetwalkermc@gmail.com
Popups without a title bar are expected to be self-managed.
This fixes Fusion 360's popups becoming activated and therefore managed when clicked, which breaks them in several ways. --- dlls/winex11.drv/window.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index fcbdad97d16..c1fe1ed85e1 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -248,6 +248,8 @@ static BOOL is_window_managed( HWND hwnd, UINT swp_flags, const RECT *window_rec /* child windows are not managed */ style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD) return FALSE; + /* captionless popups are not managed */ + if ((style & (WS_CAPTION|WS_POPUP)) == WS_POPUP) return FALSE; /* activated windows are managed */ if (!(swp_flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW))) return TRUE; if (hwnd == get_active_window()) return TRUE;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130823
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:9304: Test succeeded inside todo block: Expected (0,0)-(1025,737), got (0,0)-(1025,737). winstation.c:988: Test succeeded inside todo block: unexpected foreground window 00000000
I finally took the time to figure out how to fix the floating popup management issue.
However, I ran into a regression (new crash) with Wine 8.4, so I'll have to investigate that. Patches work as expected on 8.3.
On Fri Dec 8 11:44:40 2023 +0000, novenary * wrote:
I finally took the time to figure out how to fix the floating popup management issue. ~~However, I ran into a regression (new crash) with Wine 8.4, so I'll have to investigate that.~~ I can't reproduce the crash anymore. Patches work as expected on 8.3.
It looks that the "most controversial" commit was cleaned up quite some time ago.
I wonder if @rbernon may have some time free to look into this. (Sorry to bother). Whatever, this really looks to be a nice improvement for **winex11** in general and not only in conjunction with Autodesk Fusion 360. :thumbsup: