Index: configure.in =================================================================== RCS file: /cvs/gnome/gtk+/configure.in,v retrieving revision 1.307 diff -u -p -u -r1.307 configure.in --- configure.in 3 Dec 2002 03:11:41 -0000 1.307 +++ configure.in 9 Dec 2002 16:44:48 -0000 @@ -1149,6 +1149,16 @@ if test "x$gdktarget" = "xx11"; then , $x_libs_for_checks) + # Check for XSync extension + + AC_CHECK_LIB(Xext, XSyncQueryExtension, + if test -z "`echo $x_extra_libs $x_libs | grep "\-lXext" 2> /dev/null`"; then + x_extra_libs="-lXext $x_extra_libs" + fi + AC_DEFINE(HAVE_XSYNC), + , + $x_libs_for_checks) + # Check for XConvertCase (X11R6 specific) AC_CHECK_LIB(X11, XConvertCase, Index: acconfig.h =================================================================== RCS file: /cvs/gnome/gtk+/acconfig.h,v retrieving revision 1.28 diff -u -p -u -r1.28 acconfig.h --- acconfig.h 12 Jun 2002 18:48:09 -0000 1.28 +++ acconfig.h 9 Dec 2002 16:44:48 -0000 @@ -48,6 +48,9 @@ #undef USE_GMODULE #undef USE_MMX +/* Xsync extension */ +#undef HAVE_XSYNC + /* Define to use XKB extension */ #undef HAVE_XKB Index: gdk/gdkgc.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkgc.c,v retrieving revision 1.39 diff -u -p -u -r1.39 gdkgc.c --- gdk/gdkgc.c 25 Sep 2002 07:23:52 -0000 1.39 +++ gdk/gdkgc.c 9 Dec 2002 16:44:48 -0000 @@ -112,7 +112,7 @@ gdk_gc_new_with_values (GdkDrawable *dra { gc->colormap = gdk_drawable_get_colormap (drawable); if (gc->colormap) - g_object_ref (gc->colormap); + g_object_ref (gc->colormap); } return gc; Index: gdk/gdkinternals.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkinternals.h,v retrieving revision 1.27 diff -u -p -u -r1.27 gdkinternals.h --- gdk/gdkinternals.h 31 Oct 2002 21:11:13 -0000 1.27 +++ gdk/gdkinternals.h 9 Dec 2002 16:44:48 -0000 @@ -308,6 +308,11 @@ void _gdk_windowing_display_set_sm_clien GType _gdk_window_impl_get_type (void) G_GNUC_CONST; GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST; +/* Called after processing updates on a window */ +void _gdk_windowing_window_notify_updated (GdkWindow *window); +/* Called when we get a configure notify on a window */ +void _gdk_window_must_notify_updated (GdkWindow *window); + /************************************ * Initialization and exit routines * ************************************/ Index: gdk/gdkwindow.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v retrieving revision 1.146 diff -u -p -u -r1.146 gdkwindow.c --- gdk/gdkwindow.c 28 Nov 2002 00:33:03 -0000 1.146 +++ gdk/gdkwindow.c 9 Dec 2002 16:44:48 -0000 @@ -2067,6 +2067,7 @@ gdk_window_copy_to_image (GdkDrawable */ static GSList *update_windows = NULL; +static GSList *update_notify_windows = NULL; static guint update_idle = 0; static gboolean debug_updates = FALSE; @@ -2133,6 +2134,18 @@ gdk_window_process_updates_internal (Gdk if (expose_region != update_area) gdk_region_destroy (expose_region); + + /* Notify windowing system of updates, X11 uses this + * to notify the window manager + */ + { + GdkWindow *top; + + top = gdk_window_get_toplevel (window); + if (top != NULL) + _gdk_window_must_notify_updated (top); + } + g_object_unref (window); } if (!save_region) @@ -2140,6 +2153,51 @@ gdk_window_process_updates_internal (Gdk } } +static void +gdk_window_notify_updates (void) +{ + GSList *tmp_list = update_notify_windows; + + while (tmp_list != NULL) + { + GSList *next = tmp_list->next; + GdkWindow *window = tmp_list->data; + + _gdk_windowing_window_notify_updated (window); + g_object_unref (G_OBJECT (window)); + + tmp_list = next; + } + + g_slist_free (update_notify_windows); + update_notify_windows = NULL; +} + +/* FIXME move this */ +static gboolean gdk_window_update_idle (gpointer data); + +void +_gdk_window_must_notify_updated (GdkWindow *window) +{ + if (GDK_WINDOW_OBJECT (window)->window_type == GDK_WINDOW_TOPLEVEL || + GDK_WINDOW_OBJECT (window)->window_type == GDK_WINDOW_DIALOG) + { + if (g_slist_find (update_notify_windows, window) == NULL) + { + update_notify_windows = g_slist_prepend (update_notify_windows, + window); + g_object_ref (window); + } + + /* be sure we process updates, even if there's not actually + * any invalid region. + */ + if (!GDK_WINDOW_OBJECT (window)->update_freeze_count && !update_idle) + update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, NULL, NULL); + } +} + /** * gdk_window_process_all_updates: * @@ -2167,10 +2225,12 @@ gdk_window_process_all_updates (void) g_object_unref (tmp_list->data); tmp_list = tmp_list->next; } - + g_slist_free (old_update_windows); - gdk_flush(); + gdk_window_notify_updates (); + + gdk_flush (); } static gboolean @@ -2222,6 +2282,8 @@ gdk_window_process_updates (GdkWindow *w tmp_list = tmp_list->next; } } + + gdk_window_notify_updates (); } /** Index: gdk/x11/gdkdisplay-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.c,v retrieving revision 1.24 diff -u -p -u -r1.24 gdkdisplay-x11.c --- gdk/x11/gdkdisplay-x11.c 28 Nov 2002 00:33:05 -0000 1.24 +++ gdk/x11/gdkdisplay-x11.c 9 Dec 2002 16:44:48 -0000 @@ -213,6 +213,20 @@ gdk_display_open (const gchar *display_n } #endif + display_x11->use_xsync = FALSE; +#ifdef HAVE_XSYNC + { + int major, minor; + int error_base, event_base; + + if (XSyncQueryExtension (display_x11->xdisplay, + &event_base, &error_base) && + XSyncInitialize (display_x11->xdisplay, + &major, &minor)) + display_x11->use_xsync = TRUE; + } +#endif + _gdk_windowing_image_init (display); _gdk_events_init (display); _gdk_input_init (display); Index: gdk/x11/gdkdisplay-x11.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.h,v retrieving revision 1.8 diff -u -p -u -r1.8 gdkdisplay-x11.h --- gdk/x11/gdkdisplay-x11.h 8 Nov 2002 22:29:32 -0000 1.8 +++ gdk/x11/gdkdisplay-x11.h 9 Dec 2002 16:44:48 -0000 @@ -24,8 +24,14 @@ #ifndef __GDK_DISPLAY_X11__ #define __GDK_DISPLAY_X11__ +#include + #include #include +#ifdef HAVE_XSYNC +#include +#endif + #include #include #include @@ -136,6 +142,9 @@ struct _GdkDisplayX11 /* Startup notification */ gchar *startup_notification_id; + + /* XSync */ + gboolean use_xsync; }; struct _GdkDisplayX11Class Index: gdk/x11/gdkevents-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v retrieving revision 1.104 diff -u -p -u -r1.104 gdkevents-x11.c --- gdk/x11/gdkevents-x11.c 9 Dec 2002 02:41:51 -0000 1.104 +++ gdk/x11/gdkevents-x11.c 9 Dec 2002 16:44:49 -0000 @@ -1627,6 +1627,9 @@ gdk_event_translate (GdkDisplay *display if (window_private->resize_count == 0) _gdk_moveresize_configure_done (display, window); } + + /* be sure we increment our update counter */ + _gdk_window_must_notify_updated (window); } break; Index: gdk/x11/gdkwindow-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v retrieving revision 1.179 diff -u -p -u -r1.179 gdkwindow-x11.c --- gdk/x11/gdkwindow-x11.c 3 Dec 2002 21:57:13 -0000 1.179 +++ gdk/x11/gdkwindow-x11.c 9 Dec 2002 16:44:50 -0000 @@ -365,6 +365,41 @@ check_leader_window_title (GdkDisplay *d } } +static void +create_update_counter (GdkDisplay *display, + GdkWindowImplX11 *impl) +{ + impl->update_counter = None; +#ifdef HAVE_XSYNC + if (g_getenv ("GDK_DISABLE_UPDATE_COUNTER") == NULL) + { + XSyncValue value; + /* we init to 1, so that 0 can be "invalid" */ + XSyncIntToValue (&value, 1); + impl->update_counter = XSyncCreateCounter (GDK_DISPLAY_XDISPLAY (display), + value); + + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_DRAWABLE_IMPL_X11 (impl)->xid, + + gdk_x11_get_xatom_by_name_for_display (display, "_METACITY_UPDATE_COUNTER"), + gdk_x11_get_xatom_by_name_for_display (display, "SYNC_COUNTER"), + 32, PropModeReplace, + (guchar *) &impl->update_counter, 1); + } +#endif /* HAVE_XSYNC */ +} + +static void +destroy_update_counter (GdkDisplay *display, + GdkWindowImplX11 *impl) +{ +#ifdef HAVE_XSYNC + if (impl->update_counter != None) + XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display), impl->update_counter); +#endif /* HAVE_XSYNC */ +} + /** * gdk_window_new: * @parent: a #GdkWindow, or %NULL to create the window as a child of @@ -616,7 +651,11 @@ gdk_window_new (GdkWindow *parent, { case GDK_WINDOW_DIALOG: XSetTransientForHint (xdisplay, xid, xparent); + /* FALL THROUGH */ case GDK_WINDOW_TOPLEVEL: + create_update_counter (gdk_drawable_get_display (window), + impl); + /* FALL THROUGH */ case GDK_WINDOW_TEMP: set_wm_protocols (window); break; @@ -877,6 +916,9 @@ _gdk_windowing_window_destroy (GdkWindow } #endif /* HAVE_XFT */ + destroy_update_counter (gdk_drawable_get_display (window), + GDK_WINDOW_IMPL_X11 (private->impl)); + if (private->window_type == GDK_WINDOW_FOREIGN) { if (!foreign_destroy && (private->parent != NULL)) @@ -5013,4 +5055,26 @@ gdk_window_begin_move_drag (GdkWindow *w timestamp); else emulate_move_drag (window, button, root_x, root_y, timestamp); +} + +void +_gdk_windowing_window_notify_updated (GdkWindow *window) +{ +#ifdef HAVE_XSYNC + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (impl->update_counter != None) + { + XSyncValue value; + + XSyncIntToValue (&value, 1); + + XSyncChangeCounter (GDK_DRAWABLE_XDISPLAY (window), + impl->update_counter, value); + } +#endif } Index: gdk/x11/gdkwindow-x11.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.h,v retrieving revision 1.6 diff -u -p -u -r1.6 gdkwindow-x11.h --- gdk/x11/gdkwindow-x11.h 9 Dec 2002 02:41:51 -0000 1.6 +++ gdk/x11/gdkwindow-x11.h 9 Dec 2002 16:44:50 -0000 @@ -96,6 +96,9 @@ struct _GdkWindowImplX11 * that might not even be part of this app */ Window focus_window; + + /* XSyncCounter */ + XID update_counter; }; struct _GdkWindowImplX11Class