]> git.eshelyaron.com Git - emacs.git/commitdiff
Make frame synchronization a frame parameter
authorPo Lu <luangruo@yahoo.com>
Mon, 1 Aug 2022 01:56:12 +0000 (09:56 +0800)
committerPo Lu <luangruo@yahoo.com>
Mon, 1 Aug 2022 01:56:12 +0000 (09:56 +0800)
* doc/lispref/frames.texi (Management Parameters): Document
`use-frame-synchronization'.
* etc/NEWS: Update entry.

* src/frame.c (frame_parms): New frame parameter
`use-frame-synchronization'.
(syms_of_frame): New defsym.
* src/haikufns.c (haiku_frame_parm_handlers):
* src/nsfns.m (ns_frame_parm_handlers):
* src/pgtkfns.c (pgtk_frame_parm_handlers):
* src/w32fns.c (w32_frame_parm_handlers): Update frame param
handlers correctly.
* src/xfns.c (x_set_use_frame_synchronization): New function.
(Fx_create_frame): Set default value of said parameter.
(x_frame_parm_handlers): Add handler.

* src/xterm.c (x_sync_wait_for_frame_drawn_event): Clear
parameter if sync fails.

doc/lispref/frames.texi
etc/NEWS
src/frame.c
src/haikufns.c
src/nsfns.m
src/pgtkfns.c
src/w32fns.c
src/xfns.c
src/xterm.c

index ed56fa777d2ac69594deb93c46307fd7ed74b2ef..e5dec4f8072790ce10399e167254d9a87459ffcd 100644 (file)
@@ -2180,10 +2180,20 @@ If non-@code{nil}, the frame is visible on all virtual desktops on systems
 with virtual desktops.
 
 @vindex shaded@r{, a frame parameter}
-@item sticky
+@item shaded
 If non-@code{nil}, tell the window manager to display the frame in a
 way that its contents are hidden, leaving only the title bar.
 
+@vindex use-frame-synchronization@r{, a frame parameter}
+@item use-frame-synchronization
+If non-@code{nil}, synchronize the frame redisplay with the refresh
+rate of the monitor to avoid graphics tearing.  At present, this is
+only implemented on the X window system inside no-toolkit and X
+toolkit builds, does not work correctly with toolkit scroll bars, and
+requires a compositing manager supporting the relevant display
+synchronization protocols.  The @code{synchronizeResize} X resource
+must also be set to the string @code{"extended"}.
+
 @vindex inhibit-double-buffering@r{, a frame parameter}
 @item inhibit-double-buffering
 If non-@code{nil}, the frame is drawn to the screen without double
index ba05b49176175da37d078eda84665ac831ba5be2..963aa22c6804f74dc476b9242b31cdaaf3bf425c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -620,6 +620,9 @@ requires an X compositing manager supporting the extended frame
 synchronization protocol (see
 https://fishsoup.net/misc/wm-spec-synchronization.html).
 
+This behavior can be toggled on and off via the frame parameter
+'use-frame-synchronization'.
+
 +++
 ** New frame parameter 'alpha-background' and X resource "alphaBackground".
 This controls the opacity of the text background when running on a
index a39e1c4944f11d18cbc8664289213634fdf5cd51..25d71e0769f5ac0aa53e7b39ccbae0bf3e407b3c 100644 (file)
@@ -3916,9 +3916,10 @@ static const struct frame_parm_table frame_parms[] =
   {"z-group",                  SYMBOL_INDEX (Qz_group)},
   {"override-redirect",                SYMBOL_INDEX (Qoverride_redirect)},
   {"no-special-glyphs",                SYMBOL_INDEX (Qno_special_glyphs)},
-  {"alpha-background",          SYMBOL_INDEX (Qalpha_background)},
+  {"alpha-background",         SYMBOL_INDEX (Qalpha_background)},
+  {"use-frame-synchronization",        SYMBOL_INDEX (Quse_frame_synchronization)},
 #ifdef HAVE_X_WINDOWS
-  {"shaded",                   SYMBOL_INDEX (Qshaded)},
+  {"shaded",                   SYMBOL_INDEX (Qshaded)},
 #endif
 #ifdef NS_IMPL_COCOA
   {"ns-appearance",            SYMBOL_INDEX (Qns_appearance)},
@@ -6195,6 +6196,7 @@ syms_of_frame (void)
   DEFSYM (Qtop_only, "top-only");
   DEFSYM (Qiconify_top_level, "iconify-top-level");
   DEFSYM (Qmake_invisible, "make-invisible");
+  DEFSYM (Quse_frame_synchronization, "use-frame-synchronization");
 
   {
     int i;
index f3667ac2f9db025df112285f88ff81b1a85f20af..055a33e2c1e45f75fc253640d02ad7a813979f4b 100644 (file)
@@ -3128,6 +3128,7 @@ frame_parm_handler haiku_frame_parm_handlers[] =
     haiku_set_override_redirect,
     gui_set_no_special_glyphs,
     gui_set_alpha_background,
+    NULL,
   };
 
 void
index 433df0596101a08fa1b6e1ef86df22404df82d1c..1d3dcd31243412a26b68c179645866879ad543d2 100644 (file)
@@ -1057,6 +1057,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
   gui_set_alpha_background,
+  NULL,
 #ifdef NS_IMPL_COCOA
   ns_set_appearance,
   ns_set_transparent_titlebar,
index d998c3d938c56f5973f238573898787d31b27c14..beaf28f69d9d494219f1600af3cc34bdfaa796e6 100644 (file)
@@ -991,6 +991,7 @@ frame_parm_handler pgtk_frame_parm_handlers[] =
     pgtk_set_override_redirect,
     gui_set_no_special_glyphs,
     pgtk_set_alpha_background,
+    NULL,
   };
 
 
index 5e42a1df6ff96cc4e9e9ba2c8ce500bfab408475..28d13a68d453cbe22d8c1bc0d66d716d549179eb 100644 (file)
@@ -10508,6 +10508,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
   gui_set_alpha_background,
+  0, /* x_set_use_frame_synchronization */
 };
 
 void
index 1ae615fad449547cfbfe7feed961a73ebc4422f3..c149eaeca3b6fc39fd3b4aa29c647a261be2946f 100644 (file)
@@ -2431,6 +2431,28 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
     }
 }
 
+static void
+x_set_use_frame_synchronization (struct frame *f, Lisp_Object arg,
+                                Lisp_Object oldval)
+{
+#if !defined USE_GTK && defined HAVE_XSYNC
+  struct x_display_info *dpyinfo;
+
+  dpyinfo = FRAME_DISPLAY_INFO (f);
+
+  if (!NILP (arg) && FRAME_X_EXTENDED_COUNTER (f))
+    FRAME_X_OUTPUT (f)->use_vsync_p
+      = x_wm_supports (f, dpyinfo->Xatom_net_wm_frame_drawn);
+  else
+    FRAME_X_OUTPUT (f)->use_vsync_p = false;
+
+  store_frame_param (f, Quse_frame_synchronization,
+                    FRAME_X_OUTPUT (f)->use_vsync_p ? Qt : Qnil);
+#else
+  store_frame_param (f, Quse_frame_synchronization, Qnil);
+#endif
+}
+
 \f
 /* Record in frame F the specified or default value according to ALIST
    of the parameter named PROP (a Lisp symbol).  If no value is
@@ -5150,17 +5172,15 @@ This function is an internal primitive--use `make-frame' instead.  */)
                       ((STRINGP (value)
                         && !strcmp (SSDATA (value), "extended")) ? 2 : 1));
 #endif
-
-#ifndef USE_GTK
-      if (FRAME_X_EXTENDED_COUNTER (f))
-       FRAME_X_OUTPUT (f)->use_vsync_p
-         = x_wm_supports (f, dpyinfo->Xatom_net_wm_frame_drawn);
-#endif
     }
 #endif
 
   unblock_input ();
 
+  /* Set whether or not frame synchronization is enabled.  */
+  gui_default_parameter (f, parms, Quse_frame_synchronization, Qt,
+                        NULL, NULL, RES_TYPE_BOOLEAN);
+
   /* Works iff frame has been already mapped.  */
   gui_default_parameter (f, parms, Qskip_taskbar, Qnil,
                          NULL, NULL, RES_TYPE_BOOLEAN);
@@ -9775,6 +9795,7 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_override_redirect,
   gui_set_no_special_glyphs,
   x_set_alpha_background,
+  x_set_use_frame_synchronization,
   x_set_shaded,
 };
 
index d7d4cb418f3e1e9c198324831bf63bc24221be35..986973eb7880cdc0040962a2a19d6cb067722f5a 100644 (file)
@@ -6689,6 +6689,9 @@ x_sync_wait_for_frame_drawn_event (struct frame *f)
       fprintf (stderr, "Warning: compositing manager spent more than 1 second "
               "drawing a frame.  Frame synchronization has been disabled\n");
       FRAME_X_OUTPUT (f)->use_vsync_p = false;
+
+      /* Also change the frame parameter to reflect the new state.  */
+      store_frame_param (f, Quse_frame_synchronization, Qnil);
     }
 
   FRAME_X_WAITING_FOR_DRAW (f) = false;