Troy Rollo wrote:
The attached C sample demonstrates two problems with using ShowWindow(hwnd,SW_SHOWMINIMIZED) to minimise a top level window. The tests were done in KDE, but the second problem has been confirmed in Gnome and I suspect the first also occurs there.
The problem is that we should ask the Window manager to minimize us. There's a hack in CrossOver that "fixes" it, which I've attached. If you're in a good mood, try getting it accepted into Wine. :)
I haven't tested that this patch works as is... however it should be complete, and at least compiles.
Mike
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c index 5fdde83..33370df 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -923,12 +923,42 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT return swpFlags; }
+/*********************************************************************** + * X11DRV_WMMinimizeWindow + * + * See the ICCCM section 4.1.4. Changing Window State for more details. + * http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4 + */ +static BOOL X11DRV_WMMinimizeWindow(HWND hwnd) +{ + XEvent xev; + + TRACE("%p\n", hwnd); + + wine_tsx11_lock(); + + xev.xclient.type = ClientMessage; + xev.xclient.window = X11DRV_get_whole_window( hwnd ); + xev.xclient.message_type = x11drv_atom(WM_CHANGE_STATE); + xev.xclient.serial = 0; + xev.xclient.display = thread_display(); + xev.xclient.send_event = True; + xev.xclient.format = 32; + xev.xclient.data.l[0] = IconicState; + xev.xclient.data.l[2] = 0; + XSendEvent(thread_display(), root_window, False, SubstructureNotifyMask, &xev); + + wine_tsx11_unlock(); + + return TRUE; +}
/*********************************************************************** * ShowWindow (X11DRV.@) */ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) { + Display *display = thread_display(); WND *wndPtr; HWND parent; LONG style = GetWindowLongW( hwnd, GWL_STYLE ); @@ -957,6 +987,19 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c swp |= SWP_SHOWWINDOW; /* fall through */ case SW_MINIMIZE: + + /* handle minimize a different way */ + if ((root_window == DefaultRootWindow(display)) && + GetAncestor(hwnd,GA_PARENT) == GetDesktopWindow()) + { + if( !(style & WS_MINIMIZE) ) + { + X11DRV_WMMinimizeWindow( hwnd ); + WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE ); + } + return wasVisible; + } + swp |= SWP_FRAMECHANGED; if( !(style & WS_MINIMIZE) ) swp |= WINPOS_MinMaximize( hwnd, SW_MINIMIZE, &newPos ); diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h index d259c86..9e8c3d9 100644 --- a/dlls/x11drv/x11drv.h +++ b/dlls/x11drv/x11drv.h @@ -561,6 +561,7 @@ enum x11drv_atoms XATOM_WM_PROTOCOLS, XATOM_WM_DELETE_WINDOW, XATOM_WM_TAKE_FOCUS, + XATOM_WM_CHANGE_STATE, XATOM_KWM_DOCKWINDOW, XATOM_DndProtocol, XATOM_DndSelection, diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c index f0269a9..322ffd7 100644 --- a/dlls/x11drv/x11drv_main.c +++ b/dlls/x11drv/x11drv_main.c @@ -123,6 +123,7 @@ static const char * const atom_names[NB_ "WM_PROTOCOLS", "WM_DELETE_WINDOW", "WM_TAKE_FOCUS", + "WM_CHANGE_STATE", "KWM_DOCKWINDOW", "DndProtocol", "DndSelection",