From: Po Lu Date: Sun, 6 Feb 2022 10:53:22 +0000 (+0800) Subject: Add support for EWMH extended frame synchronization X-Git-Tag: emacs-29.0.90~2486 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=30c6074d5a8ba16cab90528f703039c2eddf82c1;p=emacs.git Add support for EWMH extended frame synchronization * src/xfns.c (Fx_create_frame): Populate both counter variables. * src/xterm.c (XTframe_up_to_date): (handle_one_xevent): Support extended synchronization. (x_free_frame_resources): Destroy extended counter. (x_term_init): Intern new atom _NET_WM_FRAME_DRAWN. * src/xterm.h (struct x_display_info): New atom `_NET_WM_FRAME_DRAWN'. (struct x_output): New fields for extended counter tracking. (FRAME_X_EXTENDED_COUNTER): New macro. --- diff --git a/src/xfns.c b/src/xfns.c index 51e4ed0e2fc..1ed4f032053 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4813,15 +4813,25 @@ This function is an internal primitive--use `make-frame' instead. */) { #ifndef HAVE_GTK3 XSyncValue initial_value; + XSyncCounter counters[2]; XSyncIntToValue (&initial_value, 0); - FRAME_X_BASIC_COUNTER (f) = XSyncCreateCounter (FRAME_X_DISPLAY (f), - initial_value); + counters[0] + = FRAME_X_BASIC_COUNTER (f) + = XSyncCreateCounter (FRAME_X_DISPLAY (f), + initial_value); + counters[1] + = FRAME_X_EXTENDED_COUNTER (f) + = XSyncCreateCounter (FRAME_X_DISPLAY (f), + initial_value); + + FRAME_X_OUTPUT (f)->current_extended_counter_value + = initial_value; XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), dpyinfo->Xatom_net_wm_sync_request_counter, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &FRAME_X_BASIC_COUNTER (f), 1); + (unsigned char *) &counters, 2); #endif } #endif diff --git a/src/xterm.c b/src/xterm.c index 67b9f5b38c8..167e3a44d23 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1856,13 +1856,33 @@ XTframe_up_to_date (struct frame *f) #ifdef HAVE_XSYNC if (FRAME_X_OUTPUT (f)->sync_end_pending_p - && FRAME_X_BASIC_COUNTER (f)) + && FRAME_X_BASIC_COUNTER (f) != None) { XSyncSetCounter (FRAME_X_DISPLAY (f), FRAME_X_BASIC_COUNTER (f), FRAME_X_OUTPUT (f)->pending_basic_counter_value); FRAME_X_OUTPUT (f)->sync_end_pending_p = false; } + + if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p + && FRAME_X_EXTENDED_COUNTER (f) != None) + { + XSyncValue add; + Bool overflow_p; + + XSyncIntToValue (&add, 1); + XSyncValueAdd (&FRAME_X_OUTPUT (f)->current_extended_counter_value, + add, add, &overflow_p); + + if (overflow_p) + emacs_abort (); + + XSyncSetCounter (FRAME_X_DISPLAY (f), + FRAME_X_EXTENDED_COUNTER (f), + FRAME_X_OUTPUT (f)->current_extended_counter_value); + + FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false; + } #endif unblock_input (); } @@ -9112,9 +9132,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (f) { - XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value, - event->xclient.data.l[2], event->xclient.data.l[3]); - FRAME_X_OUTPUT (f)->sync_end_pending_p = true; + if (event->xclient.data.l[4] == 0) + { + XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value, + event->xclient.data.l[2], event->xclient.data.l[3]); + FRAME_X_OUTPUT (f)->sync_end_pending_p = true; + } + else if (event->xclient.data.l[4] == 1) + FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true; *finish = X_EVENT_DROP; goto done; @@ -14788,6 +14813,10 @@ x_free_frame_resources (struct frame *f) if (FRAME_X_BASIC_COUNTER (f) != None) XSyncDestroyCounter (FRAME_X_DISPLAY (f), FRAME_X_BASIC_COUNTER (f)); + + if (FRAME_X_EXTENDED_COUNTER (f) != None) + XSyncDestroyCounter (FRAME_X_DISPLAY (f), + FRAME_X_EXTENDED_COUNTER (f)); #endif unload_color (f, FRAME_FOREGROUND_PIXEL (f)); @@ -15993,6 +16022,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea) ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request) ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter) + ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn) /* Session management */ ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) diff --git a/src/xterm.h b/src/xterm.h index 25ea257b518..d3678054a82 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -503,7 +503,7 @@ struct x_display_info Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar, Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea, Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request, - Xatom_net_wm_sync_request_counter; + Xatom_net_wm_sync_request_counter, Xatom_net_wm_frame_drawn; /* XSettings atoms and windows. */ Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; @@ -814,9 +814,12 @@ struct x_output #ifdef HAVE_XSYNC XSyncCounter basic_frame_counter; + XSyncCounter extended_frame_counter; XSyncValue pending_basic_counter_value; + XSyncValue current_extended_counter_value; - bool_bf sync_end_pending_p; + bool_bf sync_end_pending_p : 1; + bool_bf ext_sync_end_pending_p : 1; #endif /* Relief GCs, colors etc. */ @@ -983,6 +986,7 @@ extern void x_mark_frame_dirty (struct frame *f); #ifdef HAVE_XSYNC #define FRAME_X_BASIC_COUNTER(f) FRAME_X_OUTPUT (f)->basic_frame_counter +#define FRAME_X_EXTENDED_COUNTER(f) FRAME_X_OUTPUT (f)->extended_frame_counter #endif /* This is the Colormap which frame F uses. */