From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 58 ++++++++++++++++++++++++---------- dlls/winex11.drv/x11drv.h | 2 ++ dlls/winex11.drv/x11drv_main.c | 1 + 3 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 8f52313e20b..99580d47623 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -127,6 +127,22 @@ static const char *debugstr_size_hints( const XSizeHints *hints ) return __wine_dbg_strdup( buffer ); }
+static const char *debugstr_wm_hints( const XWMHints *hints ) +{ + char buffer[1024], *buf = buffer; + buf += sprintf( buf, "%p {", hints ); + if (hints->flags & InputHint) buf += sprintf( buf, " input %u", hints->input ); + if (hints->flags & StateHint) buf += sprintf( buf, " state %u", hints->initial_state ); + if (hints->flags & IconPixmapHint) buf += sprintf( buf, " icon pix %lx", hints->icon_pixmap ); + if (hints->flags & IconWindowHint) buf += sprintf( buf, " icon win %lx", hints->icon_window ); + if (hints->flags & IconPositionHint) buf += sprintf( buf, " icon pos %d,%d", hints->icon_x, hints->icon_y ); + if (hints->flags & IconMaskHint) buf += sprintf( buf, " icon mask %lx", hints->icon_mask ); + if (hints->flags & WindowGroupHint) buf += sprintf( buf, " group %lx", hints->window_group ); + if (hints->flags & XUrgencyHint) buf += sprintf( buf, " urgent" ); + buf += sprintf( buf, " }" ); + return __wine_dbg_strdup( buffer ); +} + static const char *debugstr_monitor_indices( const struct monitor_indices *monitors ) { return wine_dbg_sprintf( "%ld,%ld,%ld,%ld", monitors->indices[0], monitors->indices[1], monitors->indices[2], monitors->indices[3] ); @@ -1036,6 +1052,21 @@ static void set_mwm_hints( struct x11drv_win_data *data, UINT style, UINT ex_sty }
+static void window_set_wm_hints( struct x11drv_win_data *data, const XWMHints *new_hints ) +{ + const XWMHints *old_hints = &data->pending_state.wm_hints; + + data->desired_state.wm_hints = *new_hints; + if (!data->whole_window) return; /* no window or not managed, nothing to update */ + if (!memcmp( old_hints, new_hints, sizeof(*new_hints) )) return; /* hints are the same, nothing to update */ + + data->pending_state.wm_hints = *new_hints; + TRACE( "window %p/%lx, requesting WM_HINTS %s serial %lu\n", data->hwnd, data->whole_window, + debugstr_wm_hints(&data->pending_state.wm_hints), NextRequest( data->display ) ); + XChangeProperty( data->display, data->whole_window, x11drv_atom(WM_HINTS), x11drv_atom(WM_HINTS), + 32, PropModeReplace, (unsigned char *)new_hints, sizeof(*new_hints) / sizeof(long) ); +} + /*********************************************************************** * set_style_hints */ @@ -1044,7 +1075,7 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex Window group_leader = data->whole_window; HWND owner = NtUserGetWindowRelative( data->hwnd, GW_OWNER ); Window owner_win = 0; - XWMHints *wm_hints; + XWMHints wm_hints = {0}; Atom window_type;
if (owner) @@ -1073,24 +1104,17 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex XChangeProperty(data->display, data->whole_window, x11drv_atom(_NET_WM_WINDOW_TYPE), XA_ATOM, 32, PropModeReplace, (unsigned char*)&window_type, 1);
- if ((wm_hints = XAllocWMHints())) + wm_hints.flags = InputHint | StateHint | WindowGroupHint; + wm_hints.input = !use_take_focus && !(style & WS_DISABLED); + wm_hints.initial_state = (style & WS_MINIMIZE) ? IconicState : NormalState; + wm_hints.window_group = group_leader; + if (data->icon_pixmap) { - wm_hints->flags = InputHint | StateHint | WindowGroupHint; - wm_hints->input = !use_take_focus && !(style & WS_DISABLED); - wm_hints->initial_state = (style & WS_MINIMIZE) ? IconicState : NormalState; - wm_hints->window_group = group_leader; - if (data->icon_pixmap) - { - wm_hints->icon_pixmap = data->icon_pixmap; - wm_hints->icon_mask = data->icon_mask; - wm_hints->flags |= IconPixmapHint | IconMaskHint; - } - - TRACE( "window %p/%lx requesting WM_HINTS flags %#lx, serial %lu\n", data->hwnd, - data->whole_window, wm_hints->flags, NextRequest( data->display ) ); - XSetWMHints( data->display, data->whole_window, wm_hints ); - XFree( wm_hints ); + wm_hints.icon_pixmap = data->icon_pixmap; + wm_hints.icon_mask = data->icon_mask; + wm_hints.flags |= IconPixmapHint | IconMaskHint; } + window_set_wm_hints( data, &wm_hints );
if (data->icon_bits) { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 792526d02bd..1a68a17119c 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -500,6 +500,7 @@ enum x11drv_atoms XATOM_RAW_CAP_HEIGHT, XATOM_WM_DELETE_WINDOW, XATOM_WM_NORMAL_HINTS, + XATOM_WM_HINTS, XATOM_WM_PROTOCOLS, XATOM_WM_SIZE_HINTS, XATOM_WM_STATE, @@ -643,6 +644,7 @@ struct window_state UINT wm_state; BOOL activate; UINT net_wm_state; + XWMHints wm_hints; MwmHints mwm_hints; XSizeHints wm_normal_hints; struct monitor_indices monitors; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 14b75443656..1cbf7451c4d 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -119,6 +119,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "RAW_DESCENT", "RAW_CAP_HEIGHT", "WM_DELETE_WINDOW", + "WM_HINTS", "WM_NORMAL_HINTS", "WM_PROTOCOLS", "WM_SIZE_HINTS",