]> git.eshelyaron.com Git - emacs.git/commitdiff
Add support for EWMH extended frame synchronization
authorPo Lu <luangruo@yahoo.com>
Sun, 6 Feb 2022 10:53:22 +0000 (18:53 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 6 Feb 2022 10:59:00 +0000 (18:59 +0800)
* 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.

src/xfns.c
src/xterm.c
src/xterm.h

index 51e4ed0e2fc4d1d0e34728b3442fcd1b47cfe068..1ed4f03205370b232f973a693c85df00c8a3fef1 100644 (file)
@@ -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
index 67b9f5b38c86f1c8a77eaaf1baecaaace791c206..167e3a44d234ce8014abaf2d5ee99d2cf60c990d 100644 (file)
@@ -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)
index 25ea257b518d3243ec1d3d81bac5d088e4b92a9d..d3678054a821bd72c1490b2e6916c147b9710587 100644 (file)
@@ -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.  */