#include "gdkdisplay.h"
#include "gdkeventsource.h"
#include "gdkeventtranslator.h"
+#include "gdkframeclockprivate.h"
#include "gdkinternals.h"
#include "gdkscreen.h"
#include "gdkinternals.h"
GDK_WINDOW_STATE_ICONIFIED);
}
+ if (window_impl->toplevel &&
+ window_impl->toplevel->frame_pending)
+ {
+ window_impl->toplevel->frame_pending = FALSE;
+ _gdk_frame_clock_thaw (gdk_window_get_frame_clock (event->any.window));
+ }
+
+ if (toplevel)
+ gdk_window_freeze_toplevel_updates_libgtk_only (window);
+
_gdk_x11_window_grab_check_unmap (window, xevent->xany.serial);
}
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_ICONIFIED,
0);
+
+ if (toplevel)
+ gdk_window_thaw_toplevel_updates_libgtk_only (window);
}
break;
}
#ifdef HAVE_XSYNC
- if (!is_substructure && toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+ if (!is_substructure && toplevel && display_x11->use_sync && toplevel->pending_counter_value != 0)
{
- toplevel->current_counter_value = toplevel->pending_counter_value;
- XSyncIntToValue (&toplevel->pending_counter_value, 0);
+ toplevel->configure_counter_value = toplevel->pending_counter_value;
+ toplevel->configure_counter_value_is_extended = toplevel->pending_counter_value_is_extended;
+ toplevel->pending_counter_value = 0;
}
#endif
return return_val;
}
+static GdkFrameTimings *
+find_frame_timings (GdkFrameClock *clock,
+ guint64 serial)
+{
+ gint64 start_frame, end_frame, i;
+
+ start_frame = gdk_frame_clock_get_history_start (clock);
+ end_frame = gdk_frame_clock_get_frame_counter (clock);
+ for (i = end_frame; i >= start_frame; i--)
+ {
+ GdkFrameTimings *timings = gdk_frame_clock_get_timings (clock, i);
+
+ if (timings->cookie == serial)
+ return timings;
+ }
+
+ return NULL;
+}
+
GdkFilterReturn
_gdk_wm_protocols_filter (GdkXEvent *xev,
GdkEvent *event,
GdkDisplay *display;
Atom atom;
- if (!GDK_IS_X11_WINDOW (win))
+ if (!GDK_IS_X11_WINDOW (win) || GDK_WINDOW_DESTROYED (win))
return GDK_FILTER_CONTINUE;
if (xevent->type != ClientMessage)
display = GDK_WINDOW_DISPLAY (win);
+ /* This isn't actually WM_PROTOCOLS because that wouldn't leave enough space
+ * in the message for everything that gets stuffed in */
+ if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_FRAME_DRAWN"))
+ {
+ GdkWindowImplX11 *window_impl;
+ window_impl = GDK_WINDOW_IMPL_X11 (win->impl);
+ if (window_impl->toplevel)
+ {
+ guint32 d0 = xevent->xclient.data.l[0];
+ guint32 d1 = xevent->xclient.data.l[1];
+ guint32 d2 = xevent->xclient.data.l[2];
+ guint32 d3 = xevent->xclient.data.l[3];
+
+ guint64 serial = ((guint64)d1 << 32) | d0;
+ gint64 frame_drawn_time = ((guint64)d3 << 32) | d2;
+ gint64 refresh_interval, presentation_time;
+
+ GdkFrameClock *clock = gdk_window_get_frame_clock (win);
+ GdkFrameTimings *timings = find_frame_timings (clock, serial);
+
+ if (timings)
+ timings->drawn_time = frame_drawn_time;
+
+ if (window_impl->toplevel->frame_pending)
+ {
+ window_impl->toplevel->frame_pending = FALSE;
+ _gdk_frame_clock_thaw (clock);
+ }
+
+ gdk_frame_clock_get_refresh_info (clock,
+ frame_drawn_time,
+ &refresh_interval,
+ &presentation_time);
+ if (presentation_time != 0)
+ window_impl->toplevel->throttled_presentation_time = presentation_time + refresh_interval;
+ }
+
+ return GDK_FILTER_REMOVE;
+ }
+
+ if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_FRAME_TIMINGS"))
+ {
+ GdkWindowImplX11 *window_impl;
+ window_impl = GDK_WINDOW_IMPL_X11 (win->impl);
+ if (window_impl->toplevel)
+ {
+ guint32 d0 = xevent->xclient.data.l[0];
+ guint32 d1 = xevent->xclient.data.l[1];
+ guint32 d2 = xevent->xclient.data.l[2];
+ guint32 d3 = xevent->xclient.data.l[3];
+
+ guint64 serial = ((guint64)d1 << 32) | d0;
+
+ GdkFrameClock *clock = gdk_window_get_frame_clock (win);
+ GdkFrameTimings *timings = find_frame_timings (clock, serial);
+
+ if (timings)
+ {
+ gint32 presentation_time_offset = (gint32)d2;
+ gint32 refresh_interval = d3;
+
+ if (timings->drawn_time && presentation_time_offset)
+ timings->presentation_time = timings->drawn_time + presentation_time_offset;
+
+ if (refresh_interval)
+ timings->refresh_interval = refresh_interval;
+
+ timings->complete = TRUE;
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ _gdk_frame_clock_debug_print_timings (clock, timings);
+#endif /* G_ENABLE_DEBUG */
+ }
+ }
+ }
+
if (xevent->xclient.message_type != gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS"))
return GDK_FILTER_CONTINUE;
}
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
{
- GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (win);
/* There is no way of knowing reliably whether we are viewable;
* so trap errors asynchronously around the XSetInputFocus call
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
GDK_X11_DISPLAY (display)->use_sync)
{
- GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (win);
if (toplevel)
{
#ifdef HAVE_XSYNC
- XSyncIntsToValue (&toplevel->pending_counter_value,
- xevent->xclient.data.l[2],
- xevent->xclient.data.l[3]);
+ toplevel->pending_counter_value = xevent->xclient.data.l[2] + ((gint64)xevent->xclient.data.l[3] << 32);
+ toplevel->pending_counter_value_is_extended = xevent->xclient.data.l[4] != 0;
#endif
}
return GDK_FILTER_REMOVE;
* structures in places
*/
for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
- _gdk_x11_screen_init_events (display_x11->screens[i]);
+ _gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screens[i]));
/*set the default screen */
display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];