From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 13 +++++++++ dlls/winex11.drv/window.c | 50 +++++++++++++++++++++++++++++++--- dlls/winex11.drv/x11drv.h | 4 +++ dlls/winex11.drv/x11drv_main.c | 1 + 4 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 94e178fd9f0..acf0c3dccfb 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1285,6 +1285,18 @@ static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event ) NtUserPostMessage( hwnd, WM_WINE_WINDOW_STATE_CHANGED, 0, 0 ); }
+static void handle_wm_hints_notify( HWND hwnd, XPropertyEvent *event ) +{ + struct x11drv_win_data *data; + XWMHints empty = {0}, *hints; + + if (!(data = get_win_data( hwnd ))) return; + hints = event->state == PropertyNewValue ? XGetWMHints( event->display, event->window ) : ∅ + window_wm_hints_notify( data, event->serial, hints ); + if (hints != &empty) XFree( hints ); + release_win_data( data ); +} + static void handle_mwm_hints_notify( HWND hwnd, XPropertyEvent *event ) { struct x11drv_win_data *data; @@ -1347,6 +1359,7 @@ static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *xev ) if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, event ); if (event->atom == x11drv_atom(_XEMBED_INFO)) handle_xembed_info_notify( hwnd, event ); if (event->atom == x11drv_atom(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event ); + if (event->atom == x11drv_atom(WM_HINTS)) handle_wm_hints_notify( hwnd, event ); if (event->atom == x11drv_atom(_MOTIF_WM_HINTS)) handle_mwm_hints_notify( hwnd, event ); if (event->atom == x11drv_atom(WM_NORMAL_HINTS)) handle_wm_normal_hints_notify( hwnd, event ); if (event->atom == x11drv_atom(_NET_SUPPORTED)) handle_net_supported_notify( event ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 78e95b55808..96062faa505 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, "{" ); + 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] ); @@ -1039,6 +1055,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, 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; + data->wm_hints_serial = NextRequest( data->display ); + TRACE( "window %p/%lx, requesting WM_HINTS %s serial %lu\n", data->hwnd, data->whole_window, + debugstr_wm_hints(&data->pending_state.wm_hints), data->wm_hints_serial ); + XSetWMHints( data->display, data->whole_window, new_hints ); +} + /*********************************************************************** * set_style_hints */ @@ -1088,10 +1119,7 @@ static void set_style_hints( struct x11drv_win_data *data, DWORD style, DWORD ex 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 ); + window_set_wm_hints( data, wm_hints ); XFree( wm_hints ); }
@@ -1852,6 +1880,20 @@ void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long ser window_set_config( data, data->desired_state.rect, FALSE ); }
+void window_wm_hints_notify( struct x11drv_win_data *data, unsigned long serial, const XWMHints *value ) +{ + XWMHints *desired = &data->desired_state.wm_hints, *pending = &data->pending_state.wm_hints, *current = &data->current_state.wm_hints; + unsigned long *expect_serial = &data->wm_hints_serial; + const char *expected, *received, *prefix; + + prefix = wine_dbg_sprintf( "window %p/%lx ", data->hwnd, data->whole_window ); + received = wine_dbg_sprintf( "WM_HINTS %s/%lu", debugstr_wm_hints(value), serial ); + expected = *expect_serial ? wine_dbg_sprintf( ", expected %s/%lu", debugstr_wm_hints(pending), *expect_serial ) : ""; + + handle_state_change( serial, expect_serial, sizeof(*value), value, desired, pending, + current, expected, prefix, received, NULL ); +} + void window_mwm_hints_notify( struct x11drv_win_data *data, unsigned long serial, const MwmHints *value ) { MwmHints *desired = &data->desired_state.mwm_hints, *pending = &data->pending_state.mwm_hints, *current = &data->current_state.mwm_hints; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 39be211c018..4d0ce851e8e 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_PROTOCOLS, XATOM_WM_DELETE_WINDOW, + XATOM_WM_HINTS, XATOM_WM_NORMAL_HINTS, XATOM_WM_STATE, XATOM_WM_TAKE_FOCUS, @@ -642,6 +643,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; @@ -685,6 +687,7 @@ struct x11drv_win_data struct window_state current_state; /* window state tracking the current X11 state */ unsigned long wm_state_serial; /* serial of last pending WM_STATE request */ unsigned long net_wm_state_serial; /* serial of last pending _NET_WM_STATE request */ + unsigned long wm_hints_serial; /* serial of last pending WM_HINTS request */ unsigned long mwm_hints_serial; /* serial of last pending _MOTIF_WM_HINTS request */ unsigned long wm_normal_hints_serial;/* serial of last pending WM_NORMAL_HINTS request */ unsigned long configure_serial; /* serial of last pending configure request */ @@ -701,6 +704,7 @@ extern BOOL window_should_take_focus( HWND hwnd, Time time ); extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state ); extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value, Time time ); extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); +extern void window_wm_hints_notify( struct x11drv_win_data *data, unsigned long serial, const XWMHints *hints ); extern void window_mwm_hints_notify( struct x11drv_win_data *data, unsigned long serial, const MwmHints *hints ); extern void window_wm_normal_hints_notify( struct x11drv_win_data *data, unsigned long serial, const XSizeHints *hints ); extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect ); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 9dfb8347cf4..e02c4cfdd9a 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -120,6 +120,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "RAW_CAP_HEIGHT", "WM_PROTOCOLS", "WM_DELETE_WINDOW", + "WM_HINTS", "WM_NORMAL_HINTS", "WM_STATE", "WM_TAKE_FOCUS",