aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGregory Heytings2022-08-23 17:50:41 +0200
committerGregory Heytings2022-08-23 17:50:41 +0200
commit3bf19c417fd39766ee9c7a793c9faadd3bd88478 (patch)
treecb94043bbe5c5e87585be7958f4bfa7496002373 /src
parentea8e0f67bbb6eccf4c860348589d5d3abf8ade84 (diff)
parent1c837c42c22181e5fe998c7ea1c6e12c4e711872 (diff)
downloademacs-3bf19c417fd39766ee9c7a793c9faadd3bd88478.tar.gz
emacs-3bf19c417fd39766ee9c7a793c9faadd3bd88478.zip
Merge master into feature/improved-locked-narrowing.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c1
-rw-r--r--src/buffer.h9
-rw-r--r--src/editfns.c12
-rw-r--r--src/pdumper.c3
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xfns.c7
-rw-r--r--src/xml.c16
-rw-r--r--src/xterm.c110
-rw-r--r--src/xterm.h5
9 files changed, 133 insertions, 33 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 4fd5b2be3e9..d4a0c37bed5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -597,6 +597,7 @@ even if it is dead. The return value is never nil. */)
597 set_buffer_intervals (b, NULL); 597 set_buffer_intervals (b, NULL);
598 BUF_UNCHANGED_MODIFIED (b) = 1; 598 BUF_UNCHANGED_MODIFIED (b) = 1;
599 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; 599 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
600 BUF_CHARS_UNCHANGED_MODIFIED (b) = 1;
600 BUF_END_UNCHANGED (b) = 0; 601 BUF_END_UNCHANGED (b) = 0;
601 BUF_BEG_UNCHANGED (b) = 0; 602 BUF_BEG_UNCHANGED (b) = 0;
602 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ 603 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
diff --git a/src/buffer.h b/src/buffer.h
index 47b4bdf749b..77f9ea20afa 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -149,12 +149,18 @@ enum { BEG = 1, BEG_BYTE = BEG };
149#define BUF_BEG_UNCHANGED(buf) ((buf)->text->beg_unchanged) 149#define BUF_BEG_UNCHANGED(buf) ((buf)->text->beg_unchanged)
150#define BUF_END_UNCHANGED(buf) ((buf)->text->end_unchanged) 150#define BUF_END_UNCHANGED(buf) ((buf)->text->end_unchanged)
151 151
152#define BUF_CHARS_UNCHANGED_MODIFIED(buf) \
153 ((buf)->text->chars_unchanged_modified)
154
152#define UNCHANGED_MODIFIED \ 155#define UNCHANGED_MODIFIED \
153 BUF_UNCHANGED_MODIFIED (current_buffer) 156 BUF_UNCHANGED_MODIFIED (current_buffer)
154#define OVERLAY_UNCHANGED_MODIFIED \ 157#define OVERLAY_UNCHANGED_MODIFIED \
155 BUF_OVERLAY_UNCHANGED_MODIFIED (current_buffer) 158 BUF_OVERLAY_UNCHANGED_MODIFIED (current_buffer)
156#define BEG_UNCHANGED BUF_BEG_UNCHANGED (current_buffer) 159#define BEG_UNCHANGED BUF_BEG_UNCHANGED (current_buffer)
157#define END_UNCHANGED BUF_END_UNCHANGED (current_buffer) 160#define END_UNCHANGED BUF_END_UNCHANGED (current_buffer)
161
162#define CHARS_UNCHANGED_MODIFIED \
163 BUF_CHARS_UNCHANGED_MODIFIED (current_buffer)
158 164
159/* Functions to set PT in the current buffer, or another buffer. */ 165/* Functions to set PT in the current buffer, or another buffer. */
160 166
@@ -268,6 +274,9 @@ struct buffer_text
268 end_unchanged contain no useful information. */ 274 end_unchanged contain no useful information. */
269 modiff_count overlay_unchanged_modified; 275 modiff_count overlay_unchanged_modified;
270 276
277 /* CHARS_MODIFF as of last redisplay that finished. */
278 modiff_count chars_unchanged_modified;
279
271 /* Properties of this buffer's text. */ 280 /* Properties of this buffer's text. */
272 INTERVAL intervals; 281 INTERVAL intervals;
273 282
diff --git a/src/editfns.c b/src/editfns.c
index d7a62d914b8..8018065568c 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -729,7 +729,7 @@ bol (Lisp_Object n, ptrdiff_t *out_count)
729 return charpos; 729 return charpos;
730} 730}
731 731
732DEFUN ("bol", Fbol, Sbol, 0, 1, 0, 732DEFUN ("pos-bol", Fpos_bol, Spos_bol, 0, 1, 0,
733 doc: /* Return the position of the first character on the current line. 733 doc: /* Return the position of the first character on the current line.
734With optional argument N, scan forward N - 1 lines first. 734With optional argument N, scan forward N - 1 lines first.
735If the scan reaches the end of the buffer, return that position. 735If the scan reaches the end of the buffer, return that position.
@@ -748,7 +748,7 @@ This function does not move point. Also see `line-beginning-position'. */)
748DEFUN ("line-beginning-position", 748DEFUN ("line-beginning-position",
749 Fline_beginning_position, Sline_beginning_position, 0, 1, 0, 749 Fline_beginning_position, Sline_beginning_position, 0, 1, 0,
750 doc: /* Return the position of the first character in the current line/field. 750 doc: /* Return the position of the first character in the current line/field.
751This function is like `bol' (which see), but respects fields. 751This function is like `pos-bol' (which see), but respects fields.
752 752
753This function constrains the returned position to the current field 753This function constrains the returned position to the current field
754unless that position would be on a different line from the original, 754unless that position would be on a different line from the original,
@@ -784,7 +784,7 @@ eol (Lisp_Object n)
784 NULL); 784 NULL);
785} 785}
786 786
787DEFUN ("eol", Feol, Seol, 0, 1, 0, 787DEFUN ("pos-eol", Fpos_eol, Spos_eol, 0, 1, 0,
788 doc: /* Return the position of the last character on the current line. 788 doc: /* Return the position of the last character on the current line.
789With argument N not nil or 1, move forward N - 1 lines first. 789With argument N not nil or 1, move forward N - 1 lines first.
790If scan reaches end of buffer, return that position. 790If scan reaches end of buffer, return that position.
@@ -804,7 +804,7 @@ DEFUN ("line-end-position", Fline_end_position, Sline_end_position, 0, 1, 0,
804With argument N not nil or 1, move forward N - 1 lines first. 804With argument N not nil or 1, move forward N - 1 lines first.
805If scan reaches end of buffer, return that position. 805If scan reaches end of buffer, return that position.
806 806
807This function is like `eol' (which see), but respects fields. 807This function is like `pos-eol' (which see), but respects fields.
808 808
809This function constrains the returned position to the current field 809This function constrains the returned position to the current field
810unless that would be on a different line from the original, 810unless that would be on a different line from the original,
@@ -4693,8 +4693,8 @@ it to be non-nil. */);
4693 4693
4694 defsubr (&Sline_beginning_position); 4694 defsubr (&Sline_beginning_position);
4695 defsubr (&Sline_end_position); 4695 defsubr (&Sline_end_position);
4696 defsubr (&Sbol); 4696 defsubr (&Spos_bol);
4697 defsubr (&Seol); 4697 defsubr (&Spos_eol);
4698 4698
4699 defsubr (&Ssave_excursion); 4699 defsubr (&Ssave_excursion);
4700 defsubr (&Ssave_current_buffer); 4700 defsubr (&Ssave_current_buffer);
diff --git a/src/pdumper.c b/src/pdumper.c
index fb70df994a6..903298f17d2 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2764,6 +2764,7 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
2764 DUMP_FIELD_COPY (out, buffer, own_text.end_unchanged); 2764 DUMP_FIELD_COPY (out, buffer, own_text.end_unchanged);
2765 DUMP_FIELD_COPY (out, buffer, own_text.unchanged_modified); 2765 DUMP_FIELD_COPY (out, buffer, own_text.unchanged_modified);
2766 DUMP_FIELD_COPY (out, buffer, own_text.overlay_unchanged_modified); 2766 DUMP_FIELD_COPY (out, buffer, own_text.overlay_unchanged_modified);
2767 DUMP_FIELD_COPY (out, buffer, own_text.chars_unchanged_modified);
2767 if (buffer->own_text.intervals) 2768 if (buffer->own_text.intervals)
2768 dump_field_fixup_later (ctx, out, buffer, &buffer->own_text.intervals); 2769 dump_field_fixup_later (ctx, out, buffer, &buffer->own_text.intervals);
2769 dump_field_lv_rawptr (ctx, out, buffer, &buffer->own_text.markers, 2770 dump_field_lv_rawptr (ctx, out, buffer, &buffer->own_text.markers,
@@ -2911,7 +2912,7 @@ dump_native_comp_unit (struct dump_context *ctx,
2911 struct Lisp_Native_Comp_Unit *comp_u) 2912 struct Lisp_Native_Comp_Unit *comp_u)
2912{ 2913{
2913 if (!CONSP (comp_u->file)) 2914 if (!CONSP (comp_u->file))
2914 error ("Trying to dump non fixed-up eln file\n"); 2915 error ("Trying to dump non fixed-up eln file");
2915 2916
2916 /* Have function documentation always lazy loaded to optimize load-time. */ 2917 /* Have function documentation always lazy loaded to optimize load-time. */
2917 comp_u->data_fdoc_v = Qnil; 2918 comp_u->data_fdoc_v = Qnil;
diff --git a/src/xdisp.c b/src/xdisp.c
index 2ee02684dc4..7ca726b2cd3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -17358,6 +17358,7 @@ mark_window_display_accurate_1 (struct window *w, bool accurate_p)
17358 17358
17359 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); 17359 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
17360 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); 17360 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
17361 BUF_CHARS_UNCHANGED_MODIFIED (b) = BUF_CHARS_MODIFF (b);
17361 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b); 17362 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
17362 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b); 17363 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
17363 17364
@@ -19620,7 +19621,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19620 /* Check whether the buffer to be displayed contains long lines. */ 19621 /* Check whether the buffer to be displayed contains long lines. */
19621 if (!NILP (Vlong_line_threshold) 19622 if (!NILP (Vlong_line_threshold)
19622 && !current_buffer->long_line_optimizations_p 19623 && !current_buffer->long_line_optimizations_p
19623 && MODIFF - UNCHANGED_MODIFIED > 8) 19624 && CHARS_MODIFF - CHARS_UNCHANGED_MODIFIED > 8)
19624 { 19625 {
19625 ptrdiff_t cur, next, found, max = 0, threshold; 19626 ptrdiff_t cur, next, found, max = 0, threshold;
19626 threshold = XFIXNUM (Vlong_line_threshold); 19627 threshold = XFIXNUM (Vlong_line_threshold);
diff --git a/src/xfns.c b/src/xfns.c
index a275e3e11a8..0b1f707e9fc 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -965,7 +965,7 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
965 } 965 }
966#endif 966#endif
967 967
968#if defined HAVE_XSYNC && !defined USE_GTK 968#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
969 /* Frame synchronization can't be used in child frames since 969 /* Frame synchronization can't be used in child frames since
970 they are not directly managed by the compositing manager. 970 they are not directly managed by the compositing manager.
971 Re-enabling vsync in former child frames also leads to 971 Re-enabling vsync in former child frames also leads to
@@ -2421,7 +2421,7 @@ static void
2421x_set_use_frame_synchronization (struct frame *f, Lisp_Object arg, 2421x_set_use_frame_synchronization (struct frame *f, Lisp_Object arg,
2422 Lisp_Object oldval) 2422 Lisp_Object oldval)
2423{ 2423{
2424#if !defined USE_GTK && defined HAVE_XSYNC 2424#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
2425 struct x_display_info *dpyinfo; 2425 struct x_display_info *dpyinfo;
2426 2426
2427 dpyinfo = FRAME_DISPLAY_INFO (f); 2427 dpyinfo = FRAME_DISPLAY_INFO (f);
@@ -5156,7 +5156,8 @@ This function is an internal primitive--use `make-frame' instead. */)
5156 ((STRINGP (value) 5156 ((STRINGP (value)
5157 && !strcmp (SSDATA (value), "extended")) ? 2 : 1)); 5157 && !strcmp (SSDATA (value), "extended")) ? 2 : 1));
5158 5158
5159#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK 5159#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK \
5160 && defined HAVE_CLOCK_GETTIME
5160 x_sync_init_fences (f); 5161 x_sync_init_fences (f);
5161#endif 5162#endif
5162#endif 5163#endif
diff --git a/src/xml.c b/src/xml.c
index 522efd224c6..2cccff12331 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -186,6 +186,12 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url,
186 186
187 xmlCheckVersion (LIBXML_VERSION); 187 xmlCheckVersion (LIBXML_VERSION);
188 188
189 if (NILP (start))
190 start = Fpoint_min ();
191
192 if (NILP (end))
193 end = Fpoint_max ();
194
189 validate_region (&start, &end); 195 validate_region (&start, &end);
190 196
191 istart = XFIXNUM (start); 197 istart = XFIXNUM (start);
@@ -269,8 +275,11 @@ xml_cleanup_parser (void)
269 275
270DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region, 276DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region,
271 Slibxml_parse_html_region, 277 Slibxml_parse_html_region,
272 2, 4, 0, 278 0, 4, 0,
273 doc: /* Parse the region as an HTML document and return the parse tree. 279 doc: /* Parse the region as an HTML document and return the parse tree.
280If START is nil, it defaults to `point-min'. If END is nil, it
281defaults to `point-max'.
282
274If BASE-URL is non-nil, it is used to expand relative URLs. 283If BASE-URL is non-nil, it is used to expand relative URLs.
275 284
276If you want comments to be stripped, use the `xml-remove-comments' 285If you want comments to be stripped, use the `xml-remove-comments'
@@ -284,8 +293,11 @@ function to strip comments before calling this function. */)
284 293
285DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region, 294DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region,
286 Slibxml_parse_xml_region, 295 Slibxml_parse_xml_region,
287 2, 4, 0, 296 0, 4, 0,
288 doc: /* Parse the region as an XML document and return the parse tree. 297 doc: /* Parse the region as an XML document and return the parse tree.
298If START is nil, it defaults to `point-min'. If END is nil, it
299defaults to `point-max'.
300
289If BASE-URL is non-nil, it is used to expand relative URLs. 301If BASE-URL is non-nil, it is used to expand relative URLs.
290 302
291If you want comments to be stripped, use the `xml-remove-comments' 303If you want comments to be stripped, use the `xml-remove-comments'
diff --git a/src/xterm.c b/src/xterm.c
index 39e5a8e1861..3dfa908f1e2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -6655,7 +6655,7 @@ x_set_frame_alpha (struct frame *f)
6655 Starting and ending an update 6655 Starting and ending an update
6656 ***********************************************************************/ 6656 ***********************************************************************/
6657 6657
6658#if defined HAVE_XSYNC && !defined USE_GTK 6658#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
6659 6659
6660/* Wait for an event matching PREDICATE to show up in the event 6660/* Wait for an event matching PREDICATE to show up in the event
6661 queue, or TIMEOUT to elapse. 6661 queue, or TIMEOUT to elapse.
@@ -7029,7 +7029,7 @@ x_sync_handle_frame_drawn (struct x_display_info *dpyinfo,
7029static void 7029static void
7030x_update_begin (struct frame *f) 7030x_update_begin (struct frame *f)
7031{ 7031{
7032#if defined HAVE_XSYNC && !defined USE_GTK 7032#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7033 /* If F is double-buffered, we can make the entire frame center 7033 /* If F is double-buffered, we can make the entire frame center
7034 around XdbeSwapBuffers. */ 7034 around XdbeSwapBuffers. */
7035#ifdef HAVE_XDBE 7035#ifdef HAVE_XDBE
@@ -7138,7 +7138,7 @@ show_back_buffer (struct frame *f)
7138 7138
7139 if (FRAME_X_DOUBLE_BUFFERED_P (f)) 7139 if (FRAME_X_DOUBLE_BUFFERED_P (f))
7140 { 7140 {
7141#if defined HAVE_XSYNC && !defined USE_GTK 7141#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7142 /* Wait for drawing of the previous frame to complete before 7142 /* Wait for drawing of the previous frame to complete before
7143 displaying this new frame. */ 7143 displaying this new frame. */
7144 x_sync_wait_for_frame_drawn_event (f); 7144 x_sync_wait_for_frame_drawn_event (f);
@@ -7157,7 +7157,7 @@ show_back_buffer (struct frame *f)
7157 swap_info.swap_action = XdbeCopied; 7157 swap_info.swap_action = XdbeCopied;
7158 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1); 7158 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
7159 7159
7160#if defined HAVE_XSYNC && !defined USE_GTK 7160#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7161 /* Finish the frame here. */ 7161 /* Finish the frame here. */
7162 x_sync_update_finish (f); 7162 x_sync_update_finish (f);
7163#endif 7163#endif
@@ -7211,7 +7211,7 @@ x_update_end (struct frame *f)
7211 /* If double buffering is disabled, finish the update here. 7211 /* If double buffering is disabled, finish the update here.
7212 Otherwise, finish the update when the back buffer is next 7212 Otherwise, finish the update when the back buffer is next
7213 displayed. */ 7213 displayed. */
7214#if defined HAVE_XSYNC && !defined USE_GTK 7214#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7215#ifdef HAVE_XDBE 7215#ifdef HAVE_XDBE
7216 if (!FRAME_X_DOUBLE_BUFFERED_P (f)) 7216 if (!FRAME_X_DOUBLE_BUFFERED_P (f))
7217#endif 7217#endif
@@ -7600,7 +7600,7 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
7600#ifndef USE_GTK 7600#ifndef USE_GTK
7601 struct frame *focus_frame; 7601 struct frame *focus_frame;
7602 Time old_time; 7602 Time old_time;
7603#if defined HAVE_XSYNC 7603#if defined HAVE_XSYNC && defined HAVE_CLOCK_GETTIME
7604 uint64_t monotonic_time; 7604 uint64_t monotonic_time;
7605#endif 7605#endif
7606 7606
@@ -7615,7 +7615,7 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
7615 if (!send_event || time > dpyinfo->last_user_time) 7615 if (!send_event || time > dpyinfo->last_user_time)
7616 dpyinfo->last_user_time = time; 7616 dpyinfo->last_user_time = time;
7617 7617
7618#if defined HAVE_XSYNC && !defined USE_GTK 7618#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
7619 if (!send_event) 7619 if (!send_event)
7620 { 7620 {
7621 /* See if the current CLOCK_MONOTONIC time is reasonably close 7621 /* See if the current CLOCK_MONOTONIC time is reasonably close
@@ -13442,10 +13442,20 @@ x_query_pointer_1 (struct x_display_info *dpyinfo,
13442 x_uncatch_errors_after_check (); 13442 x_uncatch_errors_after_check ();
13443 13443
13444 if (had_errors) 13444 if (had_errors)
13445 rc = XQueryPointer (dpyinfo->display, w, root_return, 13445 {
13446 child_return, root_x_return, 13446 /* If the specified client pointer is the display's client
13447 root_y_return, win_x_return, 13447 pointer, clear it now. A new client pointer might not be
13448 win_y_return, mask_return); 13448 found before the next call to x_query_pointer_1 and
13449 waiting for the error leads to excessive syncing. */
13450
13451 if (client_pointer_device == dpyinfo->client_pointer_device)
13452 dpyinfo->client_pointer_device = -1;
13453
13454 rc = XQueryPointer (dpyinfo->display, w, root_return,
13455 child_return, root_x_return,
13456 root_y_return, win_x_return,
13457 win_y_return, mask_return);
13458 }
13449 else 13459 else
13450 { 13460 {
13451 state = 0; 13461 state = 0;
@@ -17985,7 +17995,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17985 goto done; 17995 goto done;
17986 } 17996 }
17987 17997
17988#if defined HAVE_XSYNC && !defined USE_GTK 17998#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
17989 /* These messages are sent by the compositing manager after a 17999 /* These messages are sent by the compositing manager after a
17990 frame is drawn under extended synchronization. */ 18000 frame is drawn under extended synchronization. */
17991 if (event->xclient.message_type 18001 if (event->xclient.message_type
@@ -20260,7 +20270,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20260 { 20270 {
20261 block_input (); 20271 block_input ();
20262 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 20272 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
20263 RevertToParent, CurrentTime); 20273 RevertToParent, event->xbutton.time);
20264 if (FRAME_PARENT_FRAME (f)) 20274 if (FRAME_PARENT_FRAME (f))
20265 XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); 20275 XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
20266 unblock_input (); 20276 unblock_input ();
@@ -21524,7 +21534,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21524 else 21534 else
21525 { 21535 {
21526 dpyinfo->grabbed &= ~(1 << xev->detail); 21536 dpyinfo->grabbed &= ~(1 << xev->detail);
21527 device->grab &= ~(1 << xev->detail); 21537 if (device)
21538 device->grab &= ~(1 << xev->detail);
21528 } 21539 }
21529#ifdef XIPointerEmulated 21540#ifdef XIPointerEmulated
21530 } 21541 }
@@ -21841,8 +21852,26 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21841 if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf))) 21852 if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
21842 { 21853 {
21843 block_input (); 21854 block_input ();
21855#if defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)
21856 if (device)
21857 {
21858 /* This can generate XI_BadDevice if the
21859 device's attachment was destroyed
21860 server-side. */
21861 x_ignore_errors_for_next_request (dpyinfo);
21862 XISetFocus (dpyinfo->display, device->attachment,
21863 /* Note that the input extension
21864 only supports RevertToParent-type
21865 behavior. */
21866 FRAME_OUTER_WINDOW (f), xev->time);
21867 x_stop_ignoring_errors (dpyinfo);
21868 }
21869#else
21870 /* Non-no toolkit builds without GTK 3 use core
21871 events to handle focus. */
21844 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 21872 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
21845 RevertToParent, CurrentTime); 21873 RevertToParent, xev->time);
21874#endif
21846 if (FRAME_PARENT_FRAME (f)) 21875 if (FRAME_PARENT_FRAME (f))
21847 XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); 21876 XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
21848 unblock_input (); 21877 unblock_input ();
@@ -26995,7 +27024,7 @@ x_free_frame_resources (struct frame *f)
26995 XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor); 27024 XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor);
26996 27025
26997 /* Free sync fences. */ 27026 /* Free sync fences. */
26998#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK 27027#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
26999 x_sync_free_fences (f); 27028 x_sync_free_fences (f);
27000#endif 27029#endif
27001 } 27030 }
@@ -27708,6 +27737,42 @@ xi_select_hierarchy_events (struct x_display_info *dpyinfo)
27708 27737
27709#endif 27738#endif
27710 27739
27740#if defined HAVE_XINPUT2 && defined HAVE_GTK3
27741
27742/* Look up whether or not GTK already initialized the X input
27743 extension.
27744
27745 Value is 0 if GTK was not built with the input extension, or if it
27746 was explictly disabled, 1 if GTK enabled the input extension and
27747 the version was successfully determined, and 2 if that information
27748 could not be determined. */
27749
27750static int
27751xi_check_toolkit (Display *display)
27752{
27753 GdkDisplay *gdpy;
27754 GdkDeviceManager *manager;
27755
27756 gdpy = gdk_x11_lookup_xdisplay (display);
27757 eassume (gdpy);
27758 manager = gdk_display_get_device_manager (gdpy);
27759
27760 if (!strcmp (G_OBJECT_TYPE_NAME (manager),
27761 "GdkX11DeviceManagerXI2"))
27762 return 1;
27763
27764 if (!strcmp (G_OBJECT_TYPE_NAME (manager),
27765 "GdkX11DeviceManagerCore"))
27766 return 0;
27767
27768 /* Something changed in GDK so this information is no longer
27769 available. */
27770
27771 return 2;
27772}
27773
27774#endif
27775
27711/* Open a connection to X display DISPLAY_NAME, and return 27776/* Open a connection to X display DISPLAY_NAME, and return
27712 the structure that describes the open display. 27777 the structure that describes the open display.
27713 If we cannot contact the display, return null. */ 27778 If we cannot contact the display, return null. */
@@ -28252,6 +28317,17 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
28252 28317
28253 dpyinfo->client_pointer_device = -1; 28318 dpyinfo->client_pointer_device = -1;
28254 28319
28320#ifdef HAVE_GTK3
28321 /* GTK gets a chance to request use of the input extension first.
28322 If we later try to enable it if GDK did not, then GTK will not
28323 get the resulting extension events. */
28324
28325 rc = xi_check_toolkit (dpyinfo->display);
28326
28327 if (!rc)
28328 goto skip_xi_setup;
28329#endif
28330
28255 if (XQueryExtension (dpyinfo->display, "XInputExtension", 28331 if (XQueryExtension (dpyinfo->display, "XInputExtension",
28256 &dpyinfo->xi2_opcode, &xi_first_event, 28332 &dpyinfo->xi2_opcode, &xi_first_event,
28257 &xi_first_error)) 28333 &xi_first_error))
@@ -28348,9 +28424,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
28348 } 28424 }
28349 28425
28350 dpyinfo->xi2_version = minor; 28426 dpyinfo->xi2_version = minor;
28351#ifndef HAVE_GTK3
28352 skip_xi_setup: 28427 skip_xi_setup:
28353#endif
28354 ; 28428 ;
28355#endif 28429#endif
28356 28430
diff --git a/src/xterm.h b/src/xterm.h
index e97f3d4c831..8500ec27710 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1119,7 +1119,7 @@ struct x_output
1119 frame. */ 1119 frame. */
1120 bool_bf waiting_for_frame_p : 1; 1120 bool_bf waiting_for_frame_p : 1;
1121 1121
1122#ifndef USE_GTK 1122#if !defined USE_GTK && defined HAVE_CLOCK_GETTIME
1123 /* Whether or not Emacs should wait for the compositing manager to 1123 /* Whether or not Emacs should wait for the compositing manager to
1124 draw frames before starting a new frame. */ 1124 draw frames before starting a new frame. */
1125 bool_bf use_vsync_p : 1; 1125 bool_bf use_vsync_p : 1;
@@ -1577,7 +1577,8 @@ extern void x_make_frame_invisible (struct frame *);
1577extern void x_iconify_frame (struct frame *); 1577extern void x_iconify_frame (struct frame *);
1578extern void x_free_frame_resources (struct frame *); 1578extern void x_free_frame_resources (struct frame *);
1579extern void x_wm_set_size_hint (struct frame *, long, bool); 1579extern void x_wm_set_size_hint (struct frame *, long, bool);
1580#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK 1580#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK \
1581 && defined HAVE_CLOCK_GETTIME
1581extern void x_sync_init_fences (struct frame *); 1582extern void x_sync_init_fences (struct frame *);
1582#endif 1583#endif
1583 1584