aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-02-05 21:43:00 +0800
committerPo Lu2022-02-05 21:43:00 +0800
commit9e420cd893f5507b9d7d3888c3a6d709aa45e6ff (patch)
tree5a2d71ce0f282e7732f2774324970f4147ae3e24 /src
parent63eab2948a23c6302308358472fb7f718759f67a (diff)
downloademacs-9e420cd893f5507b9d7d3888c3a6d709aa45e6ff.tar.gz
emacs-9e420cd893f5507b9d7d3888c3a6d709aa45e6ff.zip
Add support for basic syncing with the window manager on resize
This is handled by GTK 3, so the code is disabled on that specific build. On other builds, this eliminates any unexposed part of a frame from showing up after a resize when `frame-resize-pixelwise' is t. * configure.ac: Check for the X Synchronization Extension if present. * src/Makefile.in (EMACS_CFLAGS): (LIBES): Add XSYNC_LIBS and XSYNC_CFLAGS. * src/xfns.c (append_wm_protocols): Declare `_NET_WM_SYNC_REQUEST' support if appropriate. (x_window): Adjust location of call to `append_wm_protocols' on Xt version to prevent it from being overwritten. (Fx_create_frame): Create basic counter. * src/xterm.c (XTframe_up_to_date): Set counter value to the one asked for by the window manager. (handle_one_xevent): Handle _NET_WM_SYNC_REQUEST. (x_free_frame_resources): Free frame counter if present. (x_term_init): Test for XSync and set fields accordingly. * src/xterm.h (struct x_display_info): New fields for XSync support and new atoms. (struct x_output): New fields for counter status. (FRAME_X_BASIC_COUNTER): New macro.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in7
-rw-r--r--src/xfns.c33
-rw-r--r--src/xterm.c59
-rw-r--r--src/xterm.h29
4 files changed, 120 insertions, 8 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 706beb453b6..186e06735cc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -264,6 +264,9 @@ XFIXES_CFLAGS = @XFIXES_CFLAGS@
264XINPUT_LIBS = @XINPUT_LIBS@ 264XINPUT_LIBS = @XINPUT_LIBS@
265XINPUT_CFLAGS = @XINPUT_CFLAGS@ 265XINPUT_CFLAGS = @XINPUT_CFLAGS@
266 266
267XSYNC_LIBS = @XSYNC_LIBS@
268XSYNC_CFLAGS = @XSYNC_CFLAGS@
269
267XDBE_LIBS = @XDBE_LIBS@ 270XDBE_LIBS = @XDBE_LIBS@
268XDBE_CFLAGS = @XDBE_CFLAGS@ 271XDBE_CFLAGS = @XDBE_CFLAGS@
269 272
@@ -396,7 +399,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
396 $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \ 399 $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
397 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ 400 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
398 $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ 401 $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
399 $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \ 402 $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) \
400 $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \ 403 $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
401 $(WERROR_CFLAGS) $(HAIKU_CFLAGS) 404 $(WERROR_CFLAGS) $(HAIKU_CFLAGS)
402ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS) 405ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
@@ -548,7 +551,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE
548 $(WEBKIT_LIBS) \ 551 $(WEBKIT_LIBS) \
549 $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ 552 $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
550 $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \ 553 $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
551 $(XDBE_LIBS) \ 554 $(XDBE_LIBS) $(XSYNC_LIBS) \
552 $(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \ 555 $(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \
553 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 556 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
554 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 557 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
diff --git a/src/xfns.c b/src/xfns.c
index 4719c5dac7d..bfb61c1205e 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2367,6 +2367,9 @@ append_wm_protocols (struct x_display_info *dpyinfo,
2367 Atom protos[10]; 2367 Atom protos[10];
2368 int num_protos = 0; 2368 int num_protos = 0;
2369 bool found_wm_ping = false; 2369 bool found_wm_ping = false;
2370#if !defined HAVE_GTK3 && defined HAVE_XSYNC
2371 bool found_wm_sync_request = false;
2372#endif
2370 unsigned long bytes_after; 2373 unsigned long bytes_after;
2371 2374
2372 block_input (); 2375 block_input ();
@@ -2385,6 +2388,11 @@ append_wm_protocols (struct x_display_info *dpyinfo,
2385 if (existing_protocols[nitems] 2388 if (existing_protocols[nitems]
2386 == dpyinfo->Xatom_net_wm_ping) 2389 == dpyinfo->Xatom_net_wm_ping)
2387 found_wm_ping = true; 2390 found_wm_ping = true;
2391#if !defined HAVE_GTK3 && defined HAVE_XSYNC
2392 else if (existing_protocols[nitems]
2393 == dpyinfo->Xatom_net_wm_sync_request)
2394 found_wm_sync_request = true;
2395#endif
2388 } 2396 }
2389 } 2397 }
2390 2398
@@ -2393,6 +2401,10 @@ append_wm_protocols (struct x_display_info *dpyinfo,
2393 2401
2394 if (!found_wm_ping) 2402 if (!found_wm_ping)
2395 protos[num_protos++] = dpyinfo->Xatom_net_wm_ping; 2403 protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
2404#if !defined HAVE_GTK3 && defined HAVE_XSYNC
2405 if (!found_wm_sync_request)
2406 protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
2407#endif
2396 2408
2397 if (num_protos) 2409 if (num_protos)
2398 XChangeProperty (dpyinfo->display, 2410 XChangeProperty (dpyinfo->display,
@@ -3842,7 +3854,6 @@ x_window (struct frame *f)
3842 FRAME_X_VISUAL (f), 3854 FRAME_X_VISUAL (f),
3843 attribute_mask, &attributes); 3855 attribute_mask, &attributes);
3844 initial_set_up_x_back_buffer (f); 3856 initial_set_up_x_back_buffer (f);
3845 append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
3846 3857
3847#ifdef HAVE_X_I18N 3858#ifdef HAVE_X_I18N
3848 if (use_xim) 3859 if (use_xim)
@@ -3891,6 +3902,8 @@ x_window (struct frame *f)
3891 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2); 3902 XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
3892 } 3903 }
3893 3904
3905 append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
3906
3894 /* x_set_name normally ignores requests to set the name if the 3907 /* x_set_name normally ignores requests to set the name if the
3895 requested name is the same as the current name. This is the one 3908 requested name is the same as the current name. This is the one
3896 place where that assumption isn't correct; f->name is set, but 3909 place where that assumption isn't correct; f->name is set, but
@@ -4795,6 +4808,24 @@ This function is an internal primitive--use `make-frame' instead. */)
4795 (unsigned char *) &dpyinfo->client_leader_window, 1); 4808 (unsigned char *) &dpyinfo->client_leader_window, 1);
4796 } 4809 }
4797 4810
4811#ifdef HAVE_XSYNC
4812 if (dpyinfo->xsync_supported_p)
4813 {
4814#ifndef HAVE_GTK3
4815 XSyncValue initial_value;
4816
4817 XSyncIntToValue (&initial_value, 0);
4818 FRAME_X_BASIC_COUNTER (f) = XSyncCreateCounter (FRAME_X_DISPLAY (f),
4819 initial_value);
4820
4821 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
4822 dpyinfo->Xatom_net_wm_sync_request_counter,
4823 XA_CARDINAL, 32, PropModeReplace,
4824 (unsigned char *) &FRAME_X_BASIC_COUNTER (f), 1);
4825#endif
4826 }
4827#endif
4828
4798 unblock_input (); 4829 unblock_input ();
4799 4830
4800 /* Works iff frame has been already mapped. */ 4831 /* Works iff frame has been already mapped. */
diff --git a/src/xterm.c b/src/xterm.c
index 34a85aa7456..4b4eae53be5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -122,6 +122,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
122#include <X11/extensions/Xrandr.h> 122#include <X11/extensions/Xrandr.h>
123#endif 123#endif
124 124
125#ifdef HAVE_XSYNC
126#include <X11/extensions/sync.h>
127#endif
128
125/* Load sys/types.h if not already loaded. 129/* Load sys/types.h if not already loaded.
126 In some systems loading it twice is suicidal. */ 130 In some systems loading it twice is suicidal. */
127#ifndef makedev 131#ifndef makedev
@@ -1849,6 +1853,17 @@ XTframe_up_to_date (struct frame *f)
1849 FRAME_MOUSE_UPDATE (f); 1853 FRAME_MOUSE_UPDATE (f);
1850 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f)) 1854 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1851 show_back_buffer (f); 1855 show_back_buffer (f);
1856
1857#ifdef HAVE_XSYNC
1858 if (FRAME_X_OUTPUT (f)->sync_end_pending_p
1859 && FRAME_X_BASIC_COUNTER (f))
1860 {
1861 XSyncSetCounter (FRAME_X_DISPLAY (f),
1862 FRAME_X_BASIC_COUNTER (f),
1863 FRAME_X_OUTPUT (f)->pending_basic_counter_value);
1864 FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
1865 }
1866#endif
1852 unblock_input (); 1867 unblock_input ();
1853} 1868}
1854 1869
@@ -9086,6 +9101,26 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9086 goto done; 9101 goto done;
9087 } 9102 }
9088 9103
9104#if defined HAVE_XSYNC && !defined HAVE_GTK3
9105 if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
9106 && event->xclient.format == 32)
9107 {
9108 struct frame *f
9109 = x_top_window_to_frame (dpyinfo,
9110 event->xclient.window);
9111
9112 if (f)
9113 {
9114 XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value,
9115 event->xclient.data.l[2], event->xclient.data.l[3]);
9116 FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
9117
9118 *finish = X_EVENT_DROP;
9119 goto done;
9120 }
9121 }
9122#endif
9123
9089 goto done; 9124 goto done;
9090 } 9125 }
9091 9126
@@ -14745,9 +14780,15 @@ x_free_frame_resources (struct frame *f)
14745 14780
14746 tear_down_x_back_buffer (f); 14781 tear_down_x_back_buffer (f);
14747 if (FRAME_X_WINDOW (f)) 14782 if (FRAME_X_WINDOW (f))
14748 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 14783 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
14749#endif /* !USE_X_TOOLKIT */ 14784#endif /* !USE_X_TOOLKIT */
14750 14785
14786#ifdef HAVE_XSYNC
14787 if (FRAME_X_BASIC_COUNTER (f))
14788 XSyncDestroyCounter (FRAME_X_DISPLAY (f),
14789 FRAME_X_BASIC_COUNTER (f));
14790#endif
14791
14751 unload_color (f, FRAME_FOREGROUND_PIXEL (f)); 14792 unload_color (f, FRAME_FOREGROUND_PIXEL (f));
14752 unload_color (f, FRAME_BACKGROUND_PIXEL (f)); 14793 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
14753 unload_color (f, f->output_data.x->cursor_pixel); 14794 unload_color (f, f->output_data.x->cursor_pixel);
@@ -15628,6 +15669,19 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15628 } 15669 }
15629#endif 15670#endif
15630 15671
15672#ifdef HAVE_XSYNC
15673 int xsync_event_base, xsync_error_base;
15674 dpyinfo->xsync_supported_p
15675 = XSyncQueryExtension (dpyinfo->display,
15676 &xsync_event_base,
15677 &xsync_error_base);
15678
15679 if (dpyinfo->xsync_supported_p)
15680 dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
15681 &dpyinfo->xsync_major,
15682 &dpyinfo->xsync_minor);
15683#endif
15684
15631 /* See if a private colormap is requested. */ 15685 /* See if a private colormap is requested. */
15632 if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen)) 15686 if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
15633 { 15687 {
@@ -15887,6 +15941,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15887 ATOM_REFS_INIT ("ATOM", Xatom_ATOM) 15941 ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
15888 ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR) 15942 ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
15889 ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER) 15943 ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
15944 ATOM_REFS_INIT ("XATOM_COUNTER", Xatom_XEMBED_INFO)
15890 ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO) 15945 ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
15891 /* For properties of font. */ 15946 /* For properties of font. */
15892 ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE) 15947 ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
@@ -15921,6 +15976,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
15921 ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents) 15976 ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
15922 ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop) 15977 ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
15923 ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea) 15978 ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
15979 ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
15980 ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter)
15924 /* Session management */ 15981 /* Session management */
15925 ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) 15982 ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
15926 ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) 15983 ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
diff --git a/src/xterm.h b/src/xterm.h
index 99d339e1f94..25ea257b518 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -99,6 +99,10 @@ typedef GtkWidget *xt_or_gtk_widget;
99#include <X11/XKBlib.h> 99#include <X11/XKBlib.h>
100#endif 100#endif
101 101
102#ifdef HAVE_XSYNC
103#include <X11/extensions/sync.h>
104#endif
105
102#include "dispextern.h" 106#include "dispextern.h"
103#include "termhooks.h" 107#include "termhooks.h"
104 108
@@ -366,9 +370,9 @@ struct x_display_info
366 370
367 /* More atoms, which are selection types. */ 371 /* More atoms, which are selection types. */
368 Atom Xatom_CLIPBOARD, Xatom_TIMESTAMP, Xatom_TEXT, Xatom_DELETE, 372 Atom Xatom_CLIPBOARD, Xatom_TIMESTAMP, Xatom_TEXT, Xatom_DELETE,
369 Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING, 373 Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING,
370 Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL, 374 Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL,
371 Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER; 375 Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER, Xatom_COUNTER;
372 376
373 /* More atoms for font properties. The last three are private 377 /* More atoms for font properties. The last three are private
374 properties, see the comments in src/fontset.h. */ 378 properties, see the comments in src/fontset.h. */
@@ -498,7 +502,8 @@ struct x_display_info
498 Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below, 502 Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below,
499 Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar, 503 Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar,
500 Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea, 504 Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea,
501 Xatom_net_wm_opaque_region, Xatom_net_wm_ping; 505 Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request,
506 Xatom_net_wm_sync_request_counter;
502 507
503 /* XSettings atoms and windows. */ 508 /* XSettings atoms and windows. */
504 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; 509 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -565,6 +570,12 @@ struct x_display_info
565 int xfixes_major; 570 int xfixes_major;
566 int xfixes_minor; 571 int xfixes_minor;
567#endif 572#endif
573
574#ifdef HAVE_XSYNC
575 bool xsync_supported_p;
576 int xsync_major;
577 int xsync_minor;
578#endif
568}; 579};
569 580
570#ifdef HAVE_X_I18N 581#ifdef HAVE_X_I18N
@@ -801,6 +812,13 @@ struct x_output
801 XFontSet xic_xfs; 812 XFontSet xic_xfs;
802#endif 813#endif
803 814
815#ifdef HAVE_XSYNC
816 XSyncCounter basic_frame_counter;
817 XSyncValue pending_basic_counter_value;
818
819 bool_bf sync_end_pending_p;
820#endif
821
804 /* Relief GCs, colors etc. */ 822 /* Relief GCs, colors etc. */
805 struct relief 823 struct relief
806 { 824 {
@@ -963,6 +981,9 @@ extern void x_mark_frame_dirty (struct frame *f);
963 || (FRAME_DISPLAY_INFO (f)->xrender_major > (major)))) 981 || (FRAME_DISPLAY_INFO (f)->xrender_major > (major))))
964#endif 982#endif
965 983
984#ifdef HAVE_XSYNC
985#define FRAME_X_BASIC_COUNTER(f) FRAME_X_OUTPUT (f)->basic_frame_counter
986#endif
966 987
967/* This is the Colormap which frame F uses. */ 988/* This is the Colormap which frame F uses. */
968#define FRAME_X_COLORMAP(f) FRAME_DISPLAY_INFO (f)->cmap 989#define FRAME_X_COLORMAP(f) FRAME_DISPLAY_INFO (f)->cmap