From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 66 +++++++++++++++++++++++----------- dlls/winex11.drv/x11drv.h | 5 ++- dlls/winex11.drv/x11drv_main.c | 4 ++- 3 files changed, 53 insertions(+), 22 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0eddc40da0c..8f52313e20b 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -111,6 +111,22 @@ static const char *debugstr_mwm_hints( const MwmHints *hints ) return wine_dbg_sprintf( "%lx,%lx", hints->functions, hints->decorations ); }
+static const char *debugstr_size_hints( const XSizeHints *hints ) +{ + char buffer[1024], *buf = buffer; + buf += sprintf( buf, "%p {", hints ); + if (hints->flags & PPosition) buf += sprintf( buf, " pos %d,%d", hints->x, hints->y ); + if (hints->flags & PSize) buf += sprintf( buf, " size %d,%d", hints->width, hints->height ); + if (hints->flags & PMinSize) buf += sprintf( buf, " min %d,%d", hints->min_width, hints->min_height ); + if (hints->flags & PMaxSize) buf += sprintf( buf, " max %d,%d", hints->max_width, hints->max_height ); + if (hints->flags & PResizeInc) buf += sprintf( buf, " inc %d,%d", hints->width_inc, hints->height_inc ); + if (hints->flags & PAspect) buf += sprintf( buf, " a/r min %d:%d max %d:%d", hints->min_aspect.x, hints->min_aspect.y, hints->max_aspect.x, hints->max_aspect.y ); + if (hints->flags & PBaseSize) buf += sprintf( buf, " base %d,%d", hints->base_width, hints->base_height ); + if (hints->flags & PWinGravity) buf += sprintf( buf, " grav %d", hints->win_gravity ); + 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] ); @@ -862,6 +878,21 @@ static void set_window_icon_data( struct x11drv_win_data *data, HICON icon, cons data->icon_size = size; }
+static void window_set_wm_normal_hints( struct x11drv_win_data *data, const XSizeHints *new_hints ) +{ + const XSizeHints *old_hints = &data->pending_state.wm_normal_hints; + + data->desired_state.wm_normal_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_normal_hints = *new_hints; + TRACE( "window %p/%lx, requesting WM_NORMAL_HINTS %s serial %lu\n", data->hwnd, data->whole_window, + debugstr_size_hints(&data->pending_state.wm_normal_hints), NextRequest( data->display ) ); + XChangeProperty( data->display, data->whole_window, x11drv_atom(WM_NORMAL_HINTS), x11drv_atom(WM_SIZE_HINTS), + 32, PropModeReplace, (unsigned char *)new_hints, sizeof(*new_hints) / sizeof(long) ); +} +
/*********************************************************************** * set_size_hints @@ -870,12 +901,10 @@ static void set_window_icon_data( struct x11drv_win_data *data, HICON icon, cons */ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) { - XSizeHints* size_hints; - - if (!(size_hints = XAllocSizeHints())) return; + XSizeHints size_hints = {0};
- size_hints->win_gravity = StaticGravity; - size_hints->flags |= PWinGravity; + size_hints.win_gravity = StaticGravity; + size_hints.flags |= PWinGravity;
/* don't update size hints if window is not in normal state */ if (!(style & (WS_MINIMIZE | WS_MAXIMIZE))) @@ -883,28 +912,25 @@ static void set_size_hints( struct x11drv_win_data *data, DWORD style ) if (data->hwnd != NtUserGetDesktopWindow()) /* don't force position of desktop */ { POINT pt = virtual_screen_to_root( data->rects.visible.left, data->rects.visible.top ); - size_hints->x = pt.x; - size_hints->y = pt.y; - size_hints->flags |= PPosition; + size_hints.x = pt.x; + size_hints.y = pt.y; + size_hints.flags |= PPosition; } - else size_hints->win_gravity = NorthWestGravity; + else size_hints.win_gravity = NorthWestGravity;
if (!is_window_resizable( data, style )) { - size_hints->max_width = data->rects.visible.right - data->rects.visible.left; - size_hints->max_height = data->rects.visible.bottom - data->rects.visible.top; - if (size_hints->max_width <= 0 ||size_hints->max_height <= 0) - size_hints->max_width = size_hints->max_height = 1; - size_hints->min_width = size_hints->max_width; - size_hints->min_height = size_hints->max_height; - size_hints->flags |= PMinSize | PMaxSize; + size_hints.max_width = data->rects.visible.right - data->rects.visible.left; + size_hints.max_height = data->rects.visible.bottom - data->rects.visible.top; + if (size_hints.max_width <= 0 ||size_hints.max_height <= 0) + size_hints.max_width = size_hints.max_height = 1; + size_hints.min_width = size_hints.max_width; + size_hints.min_height = size_hints.max_height; + size_hints.flags |= PMinSize | PMaxSize; } }
- TRACE( "window %p/%lx requesting WM_NORMAL_HINTS flags %#lx, serial %lu\n", data->hwnd, - data->whole_window, size_hints->flags, NextRequest( data->display ) ); - XSetWMNormalHints( data->display, data->whole_window, size_hints ); - XFree( size_hints ); + window_set_wm_normal_hints( data, &size_hints ); }
/* bits that can trigger spurious ConfigureNotify events */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e597b956e67..792526d02bd 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -498,8 +498,10 @@ enum x11drv_atoms XATOM_RAW_ASCENT, XATOM_RAW_DESCENT, XATOM_RAW_CAP_HEIGHT, - XATOM_WM_PROTOCOLS, XATOM_WM_DELETE_WINDOW, + XATOM_WM_NORMAL_HINTS, + XATOM_WM_PROTOCOLS, + XATOM_WM_SIZE_HINTS, XATOM_WM_STATE, XATOM_WM_TAKE_FOCUS, XATOM_DndProtocol, @@ -642,6 +644,7 @@ struct window_state BOOL activate; UINT net_wm_state; MwmHints mwm_hints; + XSizeHints wm_normal_hints; struct monitor_indices monitors; RECT rect; BOOL above; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 6616f9fb7d0..14b75443656 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -118,8 +118,10 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "RAW_ASCENT", "RAW_DESCENT", "RAW_CAP_HEIGHT", - "WM_PROTOCOLS", "WM_DELETE_WINDOW", + "WM_NORMAL_HINTS", + "WM_PROTOCOLS", + "WM_SIZE_HINTS", "WM_STATE", "WM_TAKE_FOCUS", "DndProtocol",