Alexandre Julliard : winex11: Set the user time property on top-level windows.

Alexandre Julliard julliard at winehq.org
Tue Jun 29 10:25:19 CDT 2010


Module: wine
Branch: master
Commit: f2f508856ba9f3e5439f7123efd70ccc7599fc3f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f2f508856ba9f3e5439f7123efd70ccc7599fc3f

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jun 29 11:08:51 2010 +0200

winex11: Set the user time property on top-level windows.

Helps convince some broken window managers to put new windows on top
of the z-order.

---

 dlls/winex11.drv/event.c       |    4 +++-
 dlls/winex11.drv/keyboard.c    |    2 ++
 dlls/winex11.drv/mouse.c       |    1 +
 dlls/winex11.drv/window.c      |   32 ++++++++++++++++++++++++++++++++
 dlls/winex11.drv/x11drv.h      |    3 +++
 dlls/winex11.drv/x11drv_main.c |    2 ++
 6 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 0e8d60c..8fc955a 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -503,11 +503,14 @@ static void set_focus( Display *display, HWND hwnd, Time time )
 static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
 {
     Atom protocol = (Atom)event->data.l[0];
+    Time event_time = (Time)event->data.l[1];
 
     if (!protocol) return;
 
     if (protocol == x11drv_atom(WM_DELETE_WINDOW))
     {
+        update_user_time( event_time );
+
         if (hwnd == GetDesktopWindow())
         {
             /* The desktop window does not have a close button that we can
@@ -559,7 +562,6 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
     }
     else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
     {
-        Time event_time = (Time)event->data.l[1];
         HWND last_focus = x11drv_thread_data()->last_focus;
 
         TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 893796f..d9da4d2 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1376,6 +1376,8 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
     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 );
+
     wine_tsx11_lock();
     /* 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 e8c84dc..cf988c9 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -921,6 +921,7 @@ void X11DRV_ButtonPress( HWND hwnd, XEvent *xev )
         break;
     }
 
+    update_user_time( event->time );
     update_mouse_state( hwnd, event->window, event->x, event->y, event->state, &pt );
 
     X11DRV_send_mouse_input( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 7bdf4e1..eb6432e 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -74,6 +74,10 @@ XContext winContext = 0;
 /* X context to associate a struct x11drv_win_data to an hwnd */
 static XContext win_data_context;
 
+/* time of last user event and window where it's stored */
+static Time last_user_time;
+static Window user_time_window;
+
 static const char whole_window_prop[] = "__wine_x11_whole_window";
 static const char client_window_prop[]= "__wine_x11_client_window";
 static const char icon_window_prop[]  = "__wine_x11_icon_window";
@@ -104,6 +108,8 @@ static void remove_startup_notification(Display *display, Window window)
         return;
     SetEnvironmentVariableA("DESKTOP_STARTUP_ID", NULL);
 
+    if ((src = strstr( id, "_TIME" ))) update_user_time( atol( src + 5 ));
+
     pos = snprintf(message, sizeof(message), "remove: ID=");
     message[pos++] = '"';
     for (i = 0; id[i] && pos < sizeof(message) - 2; i++)
@@ -1100,6 +1106,11 @@ static void set_initial_wm_hints( Display *display, struct x11drv_win_data *data
     XChangeProperty( display, data->whole_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, data->whole_window, x11drv_atom(_NET_WM_USER_TIME_WINDOW),
+                         XA_WINDOW, 32, PropModeReplace, (unsigned char *)&user_time_window, 1 );
+
     data->wm_hints = XAllocWMHints();
     wine_tsx11_unlock();
 
@@ -1219,6 +1230,27 @@ static void set_wm_hints( Display *display, struct x11drv_win_data *data )
 
 
 /***********************************************************************
+ *     update_user_time
+ */
+void update_user_time( Time time )
+{
+    wine_tsx11_lock();
+    if (!user_time_window)
+    {
+        user_time_window = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, 0, InputOnly,
+                                          DefaultVisual(gdi_display,DefaultScreen(gdi_display)), 0, NULL );
+        TRACE( "user time window %lx\n", user_time_window );
+    }
+    if (time && (!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 );
+    }
+    wine_tsx11_unlock();
+}
+
+/***********************************************************************
  *     update_net_wm_states
  */
 void update_net_wm_states( Display *display, struct x11drv_win_data *data )
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 944669e..1cd610d 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -649,6 +649,8 @@ enum x11drv_atoms
     XATOM__NET_WM_STATE_MAXIMIZED_VERT,
     XATOM__NET_WM_STATE_SKIP_PAGER,
     XATOM__NET_WM_STATE_SKIP_TASKBAR,
+    XATOM__NET_WM_USER_TIME,
+    XATOM__NET_WM_USER_TIME_WINDOW,
     XATOM__NET_WM_WINDOW_OPACITY,
     XATOM__NET_WM_WINDOW_TYPE,
     XATOM__NET_WM_WINDOW_TYPE_DIALOG,
@@ -770,6 +772,7 @@ extern Drawable create_glxpixmap( Display *display, XVisualInfo *vis, Pixmap par
 extern void flush_gl_drawable( X11DRV_PDEVICE *physDev );
 
 extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set );
+extern void update_user_time( Time time );
 extern void update_net_wm_states( Display *display, struct x11drv_win_data *data );
 extern void make_window_embedded( Display *display, struct x11drv_win_data *data );
 
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 3a1fa3f..b07061c 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -150,6 +150,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
     "_NET_WM_STATE_MAXIMIZED_VERT",
     "_NET_WM_STATE_SKIP_PAGER",
     "_NET_WM_STATE_SKIP_TASKBAR",
+    "_NET_WM_USER_TIME",
+    "_NET_WM_USER_TIME_WINDOW",
     "_NET_WM_WINDOW_OPACITY",
     "_NET_WM_WINDOW_TYPE",
     "_NET_WM_WINDOW_TYPE_DIALOG",




More information about the wine-cvs mailing list