From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 2 -- dlls/winex11.drv/keyboard.c | 7 +++++- dlls/winex11.drv/mouse.c | 8 +++++- dlls/winex11.drv/window.c | 50 +++++++++++-------------------------- dlls/winex11.drv/x11drv.h | 3 ++- 5 files changed, 30 insertions(+), 40 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 4f0e9dd4b1f..f88d4993d68 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -701,8 +701,6 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
if (protocol == x11drv_atom(WM_DELETE_WINDOW)) { - update_user_time( event_time ); - if (hwnd == NtUserGetDesktopWindow()) { /* The desktop window does not have a close button that we can diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 7b7371ed696..8a5ef62f57d 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1335,12 +1335,17 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) int ascii_chars; XIC xic = X11DRV_get_ic( hwnd ); DWORD event_time = EVENT_x11_time_to_win32_time(event->time); + struct x11drv_win_data *data; Status status = 0;
TRACE_(key)("type %d, window %lx, state 0x%04x, keycode %u\n", event->type, event->window, event->state, event->keycode);
- if (event->type == KeyPress) update_user_time( event->time ); + if (event->type == KeyPress && (data = get_win_data( hwnd ))) + { + window_set_user_time( data, event->time ); + release_win_data( data ); + }
/* Clients should pass only KeyPress events to XmbLookupString */ if (xic && event->type == KeyPress) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 9d25b71c992..b4693c1fb82 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -1534,6 +1534,7 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) { XButtonEvent *event = &xev->xbutton; int buttonNum = event->button - 1; + struct x11drv_win_data *data; INPUT input;
if (buttonNum >= NB_BUTTONS) return FALSE; @@ -1547,7 +1548,12 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) input.mi.time = EVENT_x11_time_to_win32_time( event->time ); input.mi.dwExtraInfo = 0;
- update_user_time( event->time ); + if ((data = get_win_data( hwnd ))) + { + window_set_user_time( data, event->time ); + release_win_data( data ); + } + map_event_coords( hwnd, event->window, event->root, event->x_root, event->y_root, &input ); send_mouse_input( hwnd, event->window, event->state, &input ); return TRUE; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 3927ffaf0c4..4d425343cc9 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -100,10 +100,6 @@ XContext winContext = 0; static XContext win_data_context = 0; static XContext host_window_context = 0;
-/* time of last user event and window where it's stored */ -static Time last_user_time; -static Window user_time_window; - static const WCHAR whole_window_prop[] = {'_','_','w','i','n','e','_','x','1','1','_','w','h','o','l','e','_','w','i','n','d','o','w',0}; static const WCHAR clip_window_prop[] = @@ -253,7 +249,7 @@ void host_window_set_parent( struct host_window *win, Window parent ) /*********************************************************************** * http://standards.freedesktop.org/startup-notification-spec */ -static void remove_startup_notification(Display *display, Window window) +static void remove_startup_notification( struct x11drv_win_data *data ) { static LONG startup_notification_removed = 0; char message[1024]; @@ -268,8 +264,7 @@ static void remove_startup_notification(Display *display, Window window) return;
if (!(id = getenv( "DESKTOP_STARTUP_ID" )) || !id[0]) return; - - if ((src = strstr( id, "_TIME" ))) update_user_time( atol( src + 5 )); + if ((src = strstr( id, "_TIME" ))) window_set_user_time( data, atol( src + 5 ) );
pos = snprintf(message, sizeof(message), "remove: ID="); message[pos++] = '"'; @@ -285,8 +280,8 @@ static void remove_startup_notification(Display *display, Window window)
xevent.xclient.type = ClientMessage; xevent.xclient.message_type = x11drv_atom(_NET_STARTUP_INFO_BEGIN); - xevent.xclient.display = display; - xevent.xclient.window = window; + xevent.xclient.display = data->display; + xevent.xclient.window = data->whole_window; xevent.xclient.format = 8;
src = message; @@ -302,7 +297,7 @@ static void remove_startup_notification(Display *display, Window window) src += msglen; srclen -= msglen;
- XSendEvent( display, DefaultRootWindow( display ), False, PropertyChangeMask, &xevent ); + XSendEvent( data->display, DefaultRootWindow( data->display ), False, PropertyChangeMask, &xevent ); xevent.xclient.message_type = x11drv_atom(_NET_STARTUP_INFO); } } @@ -385,6 +380,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) data->display = display; data->vis = default_visual; data->hwnd = hwnd; + data->user_time = -1; pthread_mutex_lock( &win_data_mutex ); XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data ); } @@ -1048,11 +1044,6 @@ static void set_initial_wm_hints( Display *display, Window window )
XChangeProperty( display, window, x11drv_atom(XdndAware), XA_ATOM, 32, PropModeReplace, (unsigned char*)&dndVersion, 1 ); - - update_user_time( 0 ); /* make sure that the user time window exists */ - if (user_time_window) - XChangeProperty( display, window, x11drv_atom(_NET_WM_USER_TIME_WINDOW), - XA_WINDOW, 32, PropModeReplace, (unsigned char *)&user_time_window, 1 ); }
@@ -1119,28 +1110,17 @@ Window init_clip_window(void)
/*********************************************************************** - * update_user_time + * window_set_user_time */ -void update_user_time( Time time ) +void window_set_user_time( struct x11drv_win_data *data, Time time ) { - if (!user_time_window) - { - Window win = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, CopyFromParent, - InputOnly, CopyFromParent, 0, NULL ); - if (InterlockedCompareExchangePointer( (void **)&user_time_window, (void *)win, 0 )) - XDestroyWindow( gdi_display, win ); - TRACE( "user time window %lx\n", user_time_window ); - } + if (data->user_time == time) return; + data->user_time = time;
- if (!time) return; - XLockDisplay( gdi_display ); - if (!last_user_time || (long)(time - last_user_time) > 0) - { - last_user_time = time; - XChangeProperty( gdi_display, user_time_window, x11drv_atom(_NET_WM_USER_TIME), - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&time, 1 ); - } - XUnlockDisplay( gdi_display ); + TRACE( "window %p/%lx, requesting _NET_WM_USER_TIME %ld serial %lu\n", data->hwnd, data->whole_window, + data->user_time, NextRequest( data->display ) ); + XChangeProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_USER_TIME), XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&time, 1 ); }
/* Update _NET_WM_FULLSCREEN_MONITORS when _NET_WM_STATE_FULLSCREEN is set to support fullscreen @@ -1439,7 +1419,7 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state ) { case MAKELONG(WithdrawnState, IconicState): case MAKELONG(WithdrawnState, NormalState): - remove_startup_notification( data->display, data->whole_window ); + remove_startup_notification( data ); set_wm_hints( data ); update_net_wm_states( data ); sync_window_style( data ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a1a226f876c..6880898d48c 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -652,6 +652,7 @@ struct x11drv_win_data Pixmap icon_mask; unsigned long *icon_bits; unsigned int icon_size; + Time user_time;
struct window_state desired_state; /* window state tracking the desired / win32 state */ struct window_state pending_state; /* window state tracking the pending / requested state */ @@ -683,7 +684,7 @@ extern void net_active_window_init( struct x11drv_thread_data *data ); extern void net_supported_init( struct x11drv_thread_data *data );
extern Window init_clip_window(void); -extern void update_user_time( Time time ); +extern void window_set_user_time( struct x11drv_win_data *data, Time time ); extern UINT get_window_net_wm_state( Display *display, Window window ); extern void make_window_embedded( struct x11drv_win_data *data ); extern Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colormap );