diff --git a/ChangeLog b/ChangeLog index 3d49835dd4..357fd27408 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Sun Apr 18 16:15:15 2004 Soeren Sandmann + + Support for _NET_WM_USER_TIME (bug 115650). Patch by Elijah + Newren. + + * gdk/x11/gdkwindow-x11.[ch]: Add new internal function + _gdk_x11_set_user_time() to set the _NET_WM_USER_TIME property. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add user_time field + + * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_USER_TIME to list of + precached atoms. + + * gdk/x11/gdkinput-x11.c, gdk/x11/gdkevents-x11.c: Set the + property on user interaction. + 2004-04-15 Federico Mena Quintero * gtk/gtkfilesel.c (open_new_dir): Tell the user to use diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 3d49835dd4..357fd27408 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,19 @@ +Sun Apr 18 16:15:15 2004 Soeren Sandmann + + Support for _NET_WM_USER_TIME (bug 115650). Patch by Elijah + Newren. + + * gdk/x11/gdkwindow-x11.[ch]: Add new internal function + _gdk_x11_set_user_time() to set the _NET_WM_USER_TIME property. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add user_time field + + * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_USER_TIME to list of + precached atoms. + + * gdk/x11/gdkinput-x11.c, gdk/x11/gdkevents-x11.c: Set the + property on user interaction. + 2004-04-15 Federico Mena Quintero * gtk/gtkfilesel.c (open_new_dir): Tell the user to use diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 3d49835dd4..357fd27408 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,19 @@ +Sun Apr 18 16:15:15 2004 Soeren Sandmann + + Support for _NET_WM_USER_TIME (bug 115650). Patch by Elijah + Newren. + + * gdk/x11/gdkwindow-x11.[ch]: Add new internal function + _gdk_x11_set_user_time() to set the _NET_WM_USER_TIME property. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add user_time field + + * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_USER_TIME to list of + precached atoms. + + * gdk/x11/gdkinput-x11.c, gdk/x11/gdkevents-x11.c: Set the + property on user interaction. + 2004-04-15 Federico Mena Quintero * gtk/gtkfilesel.c (open_new_dir): Tell the user to use diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 3d49835dd4..357fd27408 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,19 @@ +Sun Apr 18 16:15:15 2004 Soeren Sandmann + + Support for _NET_WM_USER_TIME (bug 115650). Patch by Elijah + Newren. + + * gdk/x11/gdkwindow-x11.[ch]: Add new internal function + _gdk_x11_set_user_time() to set the _NET_WM_USER_TIME property. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add user_time field + + * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_USER_TIME to list of + precached atoms. + + * gdk/x11/gdkinput-x11.c, gdk/x11/gdkevents-x11.c: Set the + property on user interaction. + 2004-04-15 Federico Mena Quintero * gtk/gtkfilesel.c (open_new_dir): Tell the user to use diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 3d49835dd4..357fd27408 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,19 @@ +Sun Apr 18 16:15:15 2004 Soeren Sandmann + + Support for _NET_WM_USER_TIME (bug 115650). Patch by Elijah + Newren. + + * gdk/x11/gdkwindow-x11.[ch]: Add new internal function + _gdk_x11_set_user_time() to set the _NET_WM_USER_TIME property. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add user_time field + + * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_USER_TIME to list of + precached atoms. + + * gdk/x11/gdkinput-x11.c, gdk/x11/gdkevents-x11.c: Set the + property on user interaction. + 2004-04-15 Federico Mena Quintero * gtk/gtkfilesel.c (open_new_dir): Tell the user to use diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 0c1c772f75..8a4d3c61dc 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -81,6 +81,7 @@ static const char *const precache_atoms[] = { "_NET_WM_STATE_FULLSCREEN", "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_NORMAL", + "_NET_WM_USER_TIME", }; GType @@ -217,6 +218,9 @@ gdk_display_open (const gchar *display_name) display_x11->leader_window, gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"), XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1); + + /* We don't yet know a valid time. */ + display_x11->user_time = 0; #ifdef HAVE_XKB { diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 40dec9e56d..0d3d6838f7 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -138,6 +138,9 @@ struct _GdkDisplayX11 /* Startup notification */ gchar *startup_notification_id; + /* Time of most recent user interaction. */ + gulong user_time; + /* Sets of atoms for DND */ guint base_dnd_atoms_precached : 1; guint xdnd_atoms_precached : 1; diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index 294dd1f805..cfcb734bd0 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -802,6 +802,23 @@ static const char notify_details[][22] = { }; #endif +void +set_user_time (GdkWindow *window, + GdkEvent *event) +{ + g_return_if_fail (event != NULL); + + window = gdk_window_get_toplevel (event->client.window); + g_return_if_fail (GDK_IS_WINDOW (window)); + + /* If an event doesn't have a valid timestamp, we shouldn't use it + * to update the latest user interaction time. + */ + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + _gdk_x11_window_set_user_time (gdk_window_get_toplevel (window), + gdk_event_get_time (event)); +} + static gboolean gdk_event_translate (GdkDisplay *display, GdkEvent *event, @@ -995,6 +1012,7 @@ gdk_event_translate (GdkDisplay *display, break; } translate_key_event (display, event, xevent); + set_user_time (window, event); break; case KeyRelease: @@ -1093,6 +1111,7 @@ gdk_event_translate (GdkDisplay *display, break; } + set_user_time (window, event); break; case ButtonRelease: diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c index 1f294e79f4..a920c27df5 100644 --- a/gdk/x11/gdkinput-x11.c +++ b/gdk/x11/gdkinput-x11.c @@ -584,6 +584,12 @@ _gdk_input_common_other_event (GdkEvent *event, event->button.x, event->button.y, xdbe->button)); + /* Update the timestamp of the latest user interaction, if the event has + * a valid timestamp. + */ + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), + gdk_event_get_time (event)); return TRUE; } @@ -644,6 +650,12 @@ _gdk_input_common_other_event (GdkEvent *event, event->key.keyval, event->key.state)); + /* Update the timestamp of the latest user interaction, if the event has + * a valid timestamp. + */ + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), + gdk_event_get_time (event)); return TRUE; } @@ -674,6 +686,12 @@ _gdk_input_common_other_event (GdkEvent *event, (xdme->is_hint) ? "true" : "false")); + /* Update the timestamp of the latest user interaction, if the event has + * a valid timestamp. + */ + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), + gdk_event_get_time (event)); return TRUE; } @@ -688,6 +706,12 @@ _gdk_input_common_other_event (GdkEvent *event, event->proximity.window = input_window->window; event->proximity.time = xpne->time; + /* Update the timestamp of the latest user interaction, if the event has + * a valid timestamp. + */ + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), + gdk_event_get_time (event)); return TRUE; } diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index c594444845..da96795477 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -457,6 +457,9 @@ setup_toplevel_window (GdkWindow *window, GdkWindow *parent) gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"), XA_WINDOW, 32, PropModeReplace, (guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1); + + if (GDK_DISPLAY_X11 (screen_x11->display)->user_time != 0) + _gdk_x11_window_set_user_time (window, GDK_DISPLAY_X11 (screen_x11->display)->user_time); } /** @@ -3308,6 +3311,48 @@ gdk_window_set_accept_focus (GdkWindow *window, } } +/** + * _gdk_x11_window_set_user_time: + * @window: A toplevel #GdkWindow + * @timestamp: An XServer timestamp to which the property should be set + * + * The application can use this call to update the _NET_WM_USER_TIME + * property on a toplevel window. This property stores an Xserver + * time which represents the time of the last user input event + * received for this window. This property may be used by the window + * manager to alter the focus, stacking, and/or placement behavior of + * windows when they are mapped depending on whether the new window + * was created by a user action or is a "pop-up" window activated by a + * timer or some other event. + * + * Note that this property is automatically updated by GDK, so this + * function should only be used by applications which handle input + * events bypassing GDK. + **/ +void +_gdk_x11_window_set_user_time (GdkWindow *window, + guint32 timestamp) +{ + GdkDisplay *display; + GdkDisplayX11 *display_x11; + + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + display = gdk_drawable_get_display (window); + display_x11 = GDK_DISPLAY_X11 (display); + + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"), + XA_CARDINAL, 32, PropModeReplace, + (guchar *)×tamp, 1); + + if (timestamp != GDK_CURRENT_TIME) + display_x11->user_time = timestamp; +} /** * gdk_window_set_icon_list: diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index 109e726a38..8dd75ea709 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -123,7 +123,9 @@ struct _GdkToplevelX11 GType gdk_window_impl_x11_get_type (void); -GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window); +GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window); +void _gdk_x11_window_set_user_time (GdkWindow *window, + guint32 timestamp); G_END_DECLS