The MPX code has not been tested under X toolkit or GTK+ 2.x builds
and is not expected to work there.
+** Framework for doing animations
+Emacs does animations all over the place, usually "pluse" animations.
+These currently animate by waiting for a small but fixed amount of
+time between each redisplay, which causes screen tearing by not
+synchronizing with the vertical refresh. Frame synchronization works
+by causing redisplay to delay until the next time the monitor can
+refresh; this works, but can cause substandard frame rate when
+redisplay happens less often than the monitor refreshing, as redisplay
+will have to continually wait for missed monitor refresh.
+
+The right remedy for this problem is to define a function that returns
+the amount of time remaining before the next vertical blanking period,
+and to schedule animation redisplay within that period, using the
+information provided by the _NET_WM_FRAME_DRAWN and
+_NET_WM_FRAME_TIMINGS compositor messages on X and the
+BScreen::GetMonitorInfo function on Haiku. Ideally, all features
+performing animations should be modified to use that method of
+scheduling redisplay. Examples include xref-pulse-momentarily and
+pixel-scroll-precision-start-momentum.
+
\f
This file is part of GNU Emacs.
x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
bool send_event)
{
+#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
+ uint_fast64_t monotonic_time;
+ uint_fast64_t monotonic_ms;
+ int_fast64_t diff_ms;
+#endif
#ifndef USE_GTK
struct frame *focus_frame;
Time old_time;
{
/* See if the current CLOCK_MONOTONIC time is reasonably close
to the X server time. */
- uint_fast64_t monotonic_time = x_sync_current_monotonic_time ();
- uint_fast64_t monotonic_ms = monotonic_time / 1000;
- int_fast64_t diff_ms;
+ monotonic_time = x_sync_current_monotonic_time ();
+ monotonic_ms = monotonic_time / 1000;
dpyinfo->server_time_monotonic_p
= (monotonic_time != 0
monotonic_time,
&dpyinfo->server_time_offset))
dpyinfo->server_time_offset = 0;
+
+ /* If the server time is reasonably close to the monotonic
+ time after the latter is truncated to CARD32, simply make
+ the offset that between the server time in ms and the
+ actual time in ms. */
+
+ monotonic_ms = monotonic_ms & 0xffffffff;
+ if (!INT_SUBTRACT_WRAPV (time, monotonic_ms, &diff_ms)
+ && -500 < diff_ms && diff_ms < 500)
+ {
+ /* The server timestamp overflowed. Make the time
+ offset exactly how much it overflowed by. */
+
+ if (INT_SUBTRACT_WRAPV (monotonic_time / 1000, monotonic_ms,
+ &dpyinfo->server_time_offset)
+ || INT_MULTIPLY_WRAPV (dpyinfo->server_time_offset,
+ 1000, &dpyinfo->server_time_offset)
+ || INT_SUBTRACT_WRAPV (0, dpyinfo->server_time_offset,
+ &dpyinfo->server_time_offset))
+ dpyinfo->server_time_offset = 0;
+ }
}
}
#endif