aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2022-01-14 19:28:07 +0000
committerAlan Mackenzie2022-01-14 19:28:07 +0000
commitd87a34597c9f0be967f75ff8cfd0ace4392da63f (patch)
treec9474eb0156af143ce61a0c5bcec659546b56300 /src
parent57b698f15913385aec7bc9745016b961c0aa5c55 (diff)
parentd29291d665e808307126bf52c3e748fef78f0f9c (diff)
downloademacs-d87a34597c9f0be967f75ff8cfd0ace4392da63f.tar.gz
emacs-d87a34597c9f0be967f75ff8cfd0ace4392da63f.zip
Merge branch 'master' into scratch/correct-warning-pos
Merge branch: commit d29291d665e808307126bf52c3e748fef78f0f9c (HEAD -> master, origin/master, origin/HEAD) Author: Stefan Monnier <monnier@iro.umontreal.ca> Date: Fri Jan 14 12:26:30 2022 -0500 (macroexp--expand-all): Fix bug#53227 and bug#46636
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c2
-rw-r--r--src/data.c16
-rw-r--r--src/font.c43
-rw-r--r--src/frame.c5
-rw-r--r--src/ftfont.c21
-rw-r--r--src/gtkutil.c11
-rw-r--r--src/haiku_draw_support.cc2
-rw-r--r--src/haiku_support.cc30
-rw-r--r--src/haikuterm.c7
-rw-r--r--src/window.c3
-rw-r--r--src/xdisp.c14
-rw-r--r--src/xfns.c4
-rw-r--r--src/xterm.c157
-rw-r--r--src/xwidget.c4
14 files changed, 255 insertions, 64 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 10ac91915c6..a3091015d9b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1247,7 +1247,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1247 { /* Look in local_var_alist. */ 1247 { /* Look in local_var_alist. */
1248 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 1248 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1249 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */ 1249 XSETSYMBOL (variable, sym); /* Update In case of aliasing. */
1250 result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil); 1250 result = assq_no_quit (variable, BVAR (buf, local_var_alist));
1251 if (!NILP (result)) 1251 if (!NILP (result))
1252 { 1252 {
1253 if (blv->fwd.fwdptr) 1253 if (blv->fwd.fwdptr)
diff --git a/src/data.c b/src/data.c
index e999cee242e..7422348e392 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2180,7 +2180,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
2180 2180
2181 /* Make sure this buffer has its own value of symbol. */ 2181 /* Make sure this buffer has its own value of symbol. */
2182 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ 2182 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
2183 tem = Fassq (variable, BVAR (current_buffer, local_var_alist)); 2183 tem = assq_no_quit (variable, BVAR (current_buffer, local_var_alist));
2184 if (NILP (tem)) 2184 if (NILP (tem))
2185 { 2185 {
2186 if (let_shadows_buffer_binding_p (sym)) 2186 if (let_shadows_buffer_binding_p (sym))
@@ -2260,7 +2260,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
2260 2260
2261 /* Get rid of this buffer's alist element, if any. */ 2261 /* Get rid of this buffer's alist element, if any. */
2262 XSETSYMBOL (variable, sym); /* Propagate variable indirection. */ 2262 XSETSYMBOL (variable, sym); /* Propagate variable indirection. */
2263 tem = Fassq (variable, BVAR (current_buffer, local_var_alist)); 2263 tem = assq_no_quit (variable, BVAR (current_buffer, local_var_alist));
2264 if (!NILP (tem)) 2264 if (!NILP (tem))
2265 bset_local_var_alist 2265 bset_local_var_alist
2266 (current_buffer, 2266 (current_buffer,
@@ -2301,7 +2301,7 @@ Also see `buffer-local-boundp'.*/)
2301 case SYMBOL_PLAINVAL: return Qnil; 2301 case SYMBOL_PLAINVAL: return Qnil;
2302 case SYMBOL_LOCALIZED: 2302 case SYMBOL_LOCALIZED:
2303 { 2303 {
2304 Lisp_Object tail, elt, tmp; 2304 Lisp_Object tmp;
2305 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 2305 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
2306 XSETBUFFER (tmp, buf); 2306 XSETBUFFER (tmp, buf);
2307 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ 2307 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
@@ -2309,13 +2309,9 @@ Also see `buffer-local-boundp'.*/)
2309 if (EQ (blv->where, tmp)) /* The binding is already loaded. */ 2309 if (EQ (blv->where, tmp)) /* The binding is already loaded. */
2310 return blv_found (blv) ? Qt : Qnil; 2310 return blv_found (blv) ? Qt : Qnil;
2311 else 2311 else
2312 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail)) 2312 return NILP (assq_no_quit (variable, BVAR (buf, local_var_alist)))
2313 { 2313 ? Qnil
2314 elt = XCAR (tail); 2314 : Qt;
2315 if (EQ (variable, XCAR (elt)))
2316 return Qt;
2317 }
2318 return Qnil;
2319 } 2315 }
2320 case SYMBOL_FORWARDED: 2316 case SYMBOL_FORWARDED:
2321 { 2317 {
diff --git a/src/font.c b/src/font.c
index 266e5bc75c6..7e0219181c9 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2183,7 +2183,9 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
2183 2183
2184 /* Score three style numeric fields. Maximum difference is 127. */ 2184 /* Score three style numeric fields. Maximum difference is 127. */
2185 for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++) 2185 for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++)
2186 if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])) 2186 if (! NILP (spec_prop[i])
2187 && ! EQ (AREF (entity, i), spec_prop[i])
2188 && FIXNUMP (AREF (entity, i)))
2187 { 2189 {
2188 EMACS_INT diff = ((XFIXNUM (AREF (entity, i)) >> 8) 2190 EMACS_INT diff = ((XFIXNUM (AREF (entity, i)) >> 8)
2189 - (XFIXNUM (spec_prop[i]) >> 8)); 2191 - (XFIXNUM (spec_prop[i]) >> 8));
@@ -2764,26 +2766,31 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
2764 { 2766 {
2765 if (FIXNUMP (AREF (spec, prop))) 2767 if (FIXNUMP (AREF (spec, prop)))
2766 { 2768 {
2767 int required = XFIXNUM (AREF (spec, prop)) >> 8; 2769 if (!FIXNUMP (AREF (entity, prop)))
2768 int candidate = XFIXNUM (AREF (entity, prop)) >> 8; 2770 prop = FONT_SPEC_MAX;
2771 else
2772 {
2773 int required = XFIXNUM (AREF (spec, prop)) >> 8;
2774 int candidate = XFIXNUM (AREF (entity, prop)) >> 8;
2769 2775
2770 if (candidate != required 2776 if (candidate != required
2771#ifdef HAVE_NTGUI 2777#ifdef HAVE_NTGUI
2772 /* A kludge for w32 font search, where listing a 2778 /* A kludge for w32 font search, where listing a
2773 family returns only 4 standard weights: regular, 2779 family returns only 4 standard weights: regular,
2774 italic, bold, bold-italic. For other values one 2780 italic, bold, bold-italic. For other values one
2775 must specify the font, not just the family in the 2781 must specify the font, not just the family in the
2776 :family attribute of the face. But specifying 2782 :family attribute of the face. But specifying
2777 :family in the face attributes looks for regular 2783 :family in the face attributes looks for regular
2778 weight, so if we require exact match, the 2784 weight, so if we require exact match, the
2779 non-regular font will be rejected. So we relax 2785 non-regular font will be rejected. So we relax
2780 the accuracy of the match here, and let 2786 the accuracy of the match here, and let
2781 font_sort_entities find the best match. */ 2787 font_sort_entities find the best match. */
2782 && (prop != FONT_WEIGHT_INDEX 2788 && (prop != FONT_WEIGHT_INDEX
2783 || eabs (candidate - required) > 100) 2789 || eabs (candidate - required) > 100)
2784#endif 2790#endif
2785 ) 2791 )
2786 prop = FONT_SPEC_MAX; 2792 prop = FONT_SPEC_MAX;
2793 }
2787 } 2794 }
2788 } 2795 }
2789 if (prop < FONT_SPEC_MAX 2796 if (prop < FONT_SPEC_MAX
diff --git a/src/frame.c b/src/frame.c
index c0f4f3ecde3..e5d74edc168 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2382,9 +2382,12 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2382} 2382}
2383 2383
2384DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "", 2384DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
2385 doc: /* Delete FRAME, permanently eliminating it from use. 2385 doc: /* Delete FRAME, eliminating it from use.
2386FRAME must be a live frame and defaults to the selected one. 2386FRAME must be a live frame and defaults to the selected one.
2387 2387
2388When `undelete-frame-mode' is enabled, the 16 most recently deleted
2389frames can be undeleted with `undelete-frame', which see.
2390
2388A frame may not be deleted if its minibuffer serves as surrogate 2391A frame may not be deleted if its minibuffer serves as surrogate
2389minibuffer for another frame. Normally, you may not delete a frame if 2392minibuffer for another frame. Normally, you may not delete a frame if
2390all other frames are invisible, but if the second optional argument 2393all other frames are invisible, but if the second optional argument
diff --git a/src/ftfont.c b/src/ftfont.c
index 2bdcce306bc..5797300d231 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -189,6 +189,24 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
189 return Qnil; 189 return Qnil;
190 if (FcPatternGetInteger (p, FC_INDEX, 0, &idx) != FcResultMatch) 190 if (FcPatternGetInteger (p, FC_INDEX, 0, &idx) != FcResultMatch)
191 return Qnil; 191 return Qnil;
192#ifdef FC_VARIABLE
193 /* This is a virtual/meta FcPattern for a variable weight font, from
194 which it is possible to extract an FcRange value specifying the
195 minimum and maximum weights available in this file. We don't
196 need to know that information explicitly, so skip it. We will be
197 called with an FcPattern for each actually available, non-virtual
198 weight.
199
200 Fontconfig started generating virtual/meta patterns for variable
201 weight fonts in the same release that FC_VARIABLE was added, so
202 we conditionalize on that constant. This also ensures that
203 FcPatternGetRange is available. */
204 FcRange *range;
205 if (FcPatternGetRange (p, FC_WEIGHT, 0, &range) == FcResultMatch
206 && FcPatternGetBool (p, FC_VARIABLE, 0, &b) == FcResultMatch
207 && b == FcTrue)
208 return Qnil;
209#endif /* FC_VARIABLE */
192 210
193 file = (char *) str; 211 file = (char *) str;
194 key = Fcons (build_unibyte_string (file), make_fixnum (idx)); 212 key = Fcons (build_unibyte_string (file), make_fixnum (idx));
@@ -863,6 +881,9 @@ ftfont_list (struct frame *f, Lisp_Object spec)
863#if defined HAVE_XFT && defined FC_COLOR 881#if defined HAVE_XFT && defined FC_COLOR
864 FC_COLOR, 882 FC_COLOR,
865#endif 883#endif
884#ifdef FC_VARIABLE
885 FC_VARIABLE,
886#endif /* FC_VARIABLE */
866 NULL); 887 NULL);
867 if (! objset) 888 if (! objset)
868 goto err; 889 goto err;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 1db166b1bad..36ed55bc039 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -6255,16 +6255,19 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
6255 kbd_buffer_store_buffered_event (&inev, &xg_pending_quit_event); 6255 kbd_buffer_store_buffered_event (&inev, &xg_pending_quit_event);
6256 } 6256 }
6257 6257
6258#ifdef USABLE_SIGIO 6258 XNoOp (FRAME_X_DISPLAY (f));
6259 raise (SIGIO);
6260#endif
6261 return true; 6259 return true;
6262} 6260}
6263 6261
6264bool 6262bool
6265xg_filter_key (struct frame *frame, XEvent *xkey) 6263xg_filter_key (struct frame *frame, XEvent *xkey)
6266{ 6264{
6267 GdkEvent *xg_event = gdk_event_new (GDK_KEY_PRESS); 6265 GdkEvent *xg_event = gdk_event_new ((xkey->type == ButtonPress
6266#ifdef HAVE_XINPUT2
6267 || (xkey->type == GenericEvent
6268 && xkey->xgeneric.evtype == XI_KeyPress)
6269#endif
6270 ) ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
6268 GdkDisplay *dpy = gtk_widget_get_display (FRAME_GTK_WIDGET (frame)); 6271 GdkDisplay *dpy = gtk_widget_get_display (FRAME_GTK_WIDGET (frame));
6269 GdkKeymap *keymap = gdk_keymap_get_for_display (dpy); 6272 GdkKeymap *keymap = gdk_keymap_get_for_display (dpy);
6270 GdkModifierType consumed; 6273 GdkModifierType consumed;
diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
index 5d355ac2058..270a619b89b 100644
--- a/src/haiku_draw_support.cc
+++ b/src/haiku_draw_support.cc
@@ -313,7 +313,7 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
313 BRect bounds = bc.Bounds (); 313 BRect bounds = bc.Bounds ();
314 for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y) 314 for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y)
315 { 315 {
316 for (int x = 0; x <= BE_RECT_WIDTH (bounds); ++x) 316 for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x)
317 { 317 {
318 if (bits[y * (stride / 4) + x] == 0xFF000000) 318 if (bits[y * (stride / 4) + x] == 0xFF000000)
319 bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color); 319 bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color);
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 531dfb5c642..d49e319b98c 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -136,6 +136,15 @@ gui_abort (const char *msg)
136 emacs_abort (); 136 emacs_abort ();
137} 137}
138 138
139/* Convert a raw character RAW produced by the keycode KEY into a key
140 symbol and place it in KEYSYM.
141
142 If RAW cannot be converted into a keysym, value is 0. If RAW can
143 be converted into a keysym, but it should be ignored, value is -1.
144
145 Any other value means success, and that the keysym should be used
146 instead of mapping the keycode into a character. */
147
139static int 148static int
140keysym_from_raw_char (int32 raw, int32 key, unsigned *code) 149keysym_from_raw_char (int32 raw, int32 key, unsigned *code)
141{ 150{
@@ -186,6 +195,19 @@ keysym_from_raw_char (int32 raw, int32 key, unsigned *code)
186 195
187 case B_FUNCTION_KEY: 196 case B_FUNCTION_KEY:
188 *code = XK_F1 + key - 2; 197 *code = XK_F1 + key - 2;
198
199 if (*code - XK_F1 == 12)
200 *code = XK_Print;
201 else if (*code - XK_F1 == 13)
202 /* Okay, Scroll Lock is a bit too much: keyboard.c doesn't
203 know about it yet, and it shouldn't, since that's a
204 modifier key.
205
206 *code = XK_Scroll_Lock; */
207 return -1;
208 else if (*code - XK_F1 == 14)
209 *code = XK_Pause;
210
189 break; 211 break;
190 212
191 default: 213 default:
@@ -693,6 +715,7 @@ public:
693 rq.window = this; 715 rq.window = this;
694 716
695 int32 raw, key; 717 int32 raw, key;
718 int ret;
696 msg->FindInt32 ("raw_char", &raw); 719 msg->FindInt32 ("raw_char", &raw);
697 msg->FindInt32 ("key", &key); 720 msg->FindInt32 ("key", &key);
698 721
@@ -711,9 +734,14 @@ public:
711 if (mods & B_OPTION_KEY) 734 if (mods & B_OPTION_KEY)
712 rq.modifiers |= HAIKU_MODIFIER_SUPER; 735 rq.modifiers |= HAIKU_MODIFIER_SUPER;
713 736
714 if (!keysym_from_raw_char (raw, key, &rq.keysym)) 737 ret = keysym_from_raw_char (raw, key, &rq.keysym);
738
739 if (!ret)
715 rq.keysym = 0; 740 rq.keysym = 0;
716 741
742 if (ret < 0)
743 return;
744
717 rq.multibyte_char = 0; 745 rq.multibyte_char = 0;
718 746
719 if (!rq.keysym) 747 if (!rq.keysym)
diff --git a/src/haikuterm.c b/src/haikuterm.c
index be28649aef2..3e99cc1c8d9 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -2222,6 +2222,7 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2222 void *view = FRAME_HAIKU_VIEW (XFRAME (WINDOW_FRAME (w))); 2222 void *view = FRAME_HAIKU_VIEW (XFRAME (WINDOW_FRAME (w)));
2223 struct face *face = p->face; 2223 struct face *face = p->face;
2224 2224
2225 block_input ();
2225 BView_draw_lock (view); 2226 BView_draw_lock (view);
2226 BView_StartClip (view); 2227 BView_StartClip (view);
2227 2228
@@ -2256,6 +2257,7 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2256 } 2257 }
2257 BView_EndClip (view); 2258 BView_EndClip (view);
2258 BView_draw_unlock (view); 2259 BView_draw_unlock (view);
2260 unblock_input ();
2259} 2261}
2260 2262
2261static void 2263static void
@@ -3233,7 +3235,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3233 struct frame *f = haiku_window_to_frame (b->window); 3235 struct frame *f = haiku_window_to_frame (b->window);
3234 3236
3235 if (!f) 3237 if (!f)
3236 continue; 3238 {
3239 free (b->ref);
3240 continue;
3241 }
3237 3242
3238 inev.kind = DRAG_N_DROP_EVENT; 3243 inev.kind = DRAG_N_DROP_EVENT;
3239 inev.arg = build_string_from_utf8 (b->ref); 3244 inev.arg = build_string_from_utf8 (b->ref);
diff --git a/src/window.c b/src/window.c
index 7155f0e6bc3..2a5e4042a48 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5861,7 +5861,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5861 5861
5862 /* We moved the window start towards ZV, so PT may be now 5862 /* We moved the window start towards ZV, so PT may be now
5863 in the scroll margin at the top. */ 5863 in the scroll margin at the top. */
5864 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 5864 if (IT_CHARPOS (it) < PT)
5865 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
5865 if (IT_CHARPOS (it) == PT 5866 if (IT_CHARPOS (it) == PT
5866 && it.current_y >= this_scroll_margin 5867 && it.current_y >= this_scroll_margin
5867 && it.current_y <= last_y - WINDOW_TAB_LINE_HEIGHT (w) 5868 && it.current_y <= last_y - WINDOW_TAB_LINE_HEIGHT (w)
diff --git a/src/xdisp.c b/src/xdisp.c
index 2326df4300d..977d31703fb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -18557,6 +18557,20 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp,
18557 || (NILP (g->object) 18557 || (NILP (g->object)
18558 && (g->charpos == PT 18558 && (g->charpos == PT
18559 || (g->charpos == 0 && endpos - 1 == PT))); 18559 || (g->charpos == 0 && endpos - 1 == PT)));
18560 /* Perhaps the point position is inside
18561 invisible text? In that case, we trust
18562 'set_cursor_from_row' to do its job and
18563 find the best position for the cursor. */
18564 if (!exact_match_p)
18565 {
18566 Lisp_Object val =
18567 get_char_property_and_overlay (make_fixnum (PT),
18568 Qinvisible,
18569 Qnil, NULL);
18570
18571 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
18572 exact_match_p = true;
18573 }
18560 } 18574 }
18561 if (at_zv_p || exact_match_p) 18575 if (at_zv_p || exact_match_p)
18562 { 18576 {
diff --git a/src/xfns.c b/src/xfns.c
index 028ee29a4aa..ffad0bc3d1a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3347,6 +3347,8 @@ setup_xi_event_mask (struct frame *f)
3347 XISetMask (m, XI_Motion); 3347 XISetMask (m, XI_Motion);
3348 XISetMask (m, XI_Enter); 3348 XISetMask (m, XI_Enter);
3349 XISetMask (m, XI_Leave); 3349 XISetMask (m, XI_Leave);
3350 XISetMask (m, XI_FocusIn);
3351 XISetMask (m, XI_FocusOut);
3350 XISetMask (m, XI_KeyPress); 3352 XISetMask (m, XI_KeyPress);
3351 XISetMask (m, XI_KeyRelease); 3353 XISetMask (m, XI_KeyRelease);
3352 XISelectEvents (FRAME_X_DISPLAY (f), 3354 XISelectEvents (FRAME_X_DISPLAY (f),
@@ -3359,6 +3361,8 @@ setup_xi_event_mask (struct frame *f)
3359#ifdef USE_X_TOOLKIT 3361#ifdef USE_X_TOOLKIT
3360 XISetMask (m, XI_KeyPress); 3362 XISetMask (m, XI_KeyPress);
3361 XISetMask (m, XI_KeyRelease); 3363 XISetMask (m, XI_KeyRelease);
3364 XISetMask (m, XI_FocusIn);
3365 XISetMask (m, XI_FocusOut);
3362 3366
3363 XISelectEvents (FRAME_X_DISPLAY (f), 3367 XISelectEvents (FRAME_X_DISPLAY (f),
3364 FRAME_OUTER_WINDOW (f), 3368 FRAME_OUTER_WINDOW (f),
diff --git a/src/xterm.c b/src/xterm.c
index 52715892703..ec415f5ffaf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -20,6 +20,72 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
20/* New display code by Gerd Moellmann <gerd@gnu.org>. */ 20/* New display code by Gerd Moellmann <gerd@gnu.org>. */
21/* Xt features made by Fred Pierresteguy. */ 21/* Xt features made by Fred Pierresteguy. */
22 22
23/* X window system support for GNU Emacs
24
25 This file is part of the X window system support for GNU Emacs. It
26 contains subroutines comprising the redisplay interface, setting up
27 scroll bars and widgets, and handling input.
28
29 INPUT
30
31 Emacs handles input by running pselect in a loop, which returns
32 whenever there is input available on the connection to the X
33 server. On some systems, Emacs also arranges for any new input on
34 that connection to send an asynchronous signal. Whenever pselect
35 returns, or such a signal is received and input is not blocked,
36 XTread_socket is called and translates X11 events read by Xlib into
37 struct input_events, which are then stored in the keyboard buffer,
38 to be processed and acted upon at some later time. The function
39 handle_one_xevent is responsible for handling core events after
40 they are filtered, and filtering X Input Extension events. It also
41 performs actions on some special events, such as updating the
42 dimensions of a frame after a ConfigureNotify is sent by the X
43 server to inform us that it changed.
44
45 Before such events are translated, an Emacs build with
46 internationalization enabled (the default since X11R6) will filter
47 events through an X Input Method (XIM) or GTK, which might decide
48 to intercept the event and send a different one in its place, for
49 reasons such as enabling the user to insert international
50 characters that aren't on his keyboard by typing a sequence of
51 characters which are. See the function x_filter_event and its
52 callers for more details.
53
54 Events that cause Emacs to quit are treated specially by the code
55 that stores them in the keyboard buffer and generally cause an
56 immediate interrupt. Such an interrupt can lead to a longjmp from
57 the code that stored the keyboard event, which isn't safe inside
58 XTread_socket. To avoid this problem, XTread_socket is provided a
59 special event buffer named hold_quit. When a quit event is
60 encountered, it is stored inside this special buffer, which will
61 cause the keyboard code that called XTread_socket to store it at a
62 later time when it is safe to do so.
63
64 handle_one_xevent will generally have to determine which frame an
65 event should be attributed to. This is not easy, because events
66 can come from multiple X windows, and a frame can also have
67 multiple windows. handle_one_xevent usually calls the function
68 x_any_window_to_frame, which searches for a frame by toplevel
69 window and widget windows. There are also some other functions for
70 searching by specific types of window, such as
71 x_top_window_to_frame (which only searches for frames by toplevel
72 window), and x_menubar_window_to_frame (which will only search
73 through frame menu bars).
74
75 INPUT FOCUS
76
77 Under X, the window where keyboard input is sent is not always
78 explictly defined. When there is a focus window, it receives what
79 is referred to as "explicit focus", but when there is none, it
80 receives "implicit focus" whenever the pointer enters it, and loses
81 that focus when the pointer leaves. When the toplevel window of a
82 frame receives an explicit focus event (FocusIn or FocusOut), we
83 treat that frame as having the current input focus, but when there
84 is no focus window, we treat each frame as having the input focus
85 whenever the pointer enters it, and undo that treatment when the
86 pointer leaves it. See the callers of x_detect_focus_change for
87 more details. */
88
23#include <config.h> 89#include <config.h>
24#include <stdlib.h> 90#include <stdlib.h>
25#include <math.h> 91#include <math.h>
@@ -4126,7 +4192,9 @@ x_draw_glyph_string (struct glyph_string *s)
4126 area_max_x = area_x + area_width - 1; 4192 area_max_x = area_x + area_width - 1;
4127 4193
4128 decoration_width = s->width; 4194 decoration_width = s->width;
4129 if (area_max_x < (s->x + decoration_width - 1)) 4195 if (!s->row->mode_line_p
4196 && !s->row->tab_line_p
4197 && area_max_x < (s->x + decoration_width - 1))
4130 decoration_width -= (s->x + decoration_width - 1) - area_max_x; 4198 decoration_width -= (s->x + decoration_width - 1) - area_max_x;
4131 4199
4132 /* Draw relief if not yet drawn. */ 4200 /* Draw relief if not yet drawn. */
@@ -5252,21 +5320,18 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
5252 int focus_state 5320 int focus_state
5253 = focus_frame ? focus_frame->output_data.x->focus_state : 0; 5321 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
5254 5322
5255#ifdef USE_GTK
5256 if (xi_event->evtype == XI_FocusIn 5323 if (xi_event->evtype == XI_FocusIn
5257 || xi_event->evtype == XI_FocusOut) 5324 || xi_event->evtype == XI_FocusOut)
5258 x_focus_changed ((xi_event->evtype == XI_FocusIn 5325 x_focus_changed ((xi_event->evtype == XI_FocusIn
5259 ? FocusIn : FocusOut), 5326 ? FocusIn : FocusOut),
5260 FOCUS_EXPLICIT, 5327 FOCUS_EXPLICIT,
5261 dpyinfo, frame, bufp); 5328 dpyinfo, frame, bufp);
5262 else 5329 else if ((xi_event->evtype == XI_Enter
5263#endif 5330 || xi_event->evtype == XI_Leave)
5264 if ((xi_event->evtype == XI_Enter 5331 && (((XIEnterEvent *) xi_event)->detail
5265 || xi_event->evtype == XI_Leave) 5332 != XINotifyInferior)
5266 && (((XIEnterEvent *) xi_event)->detail 5333 && ((XIEnterEvent *) xi_event)->focus
5267 != XINotifyInferior) 5334 && !(focus_state & FOCUS_EXPLICIT))
5268 && ((XIEnterEvent *) xi_event)->focus
5269 && !(focus_state & FOCUS_EXPLICIT))
5270 x_focus_changed ((xi_event->evtype == XI_Enter 5335 x_focus_changed ((xi_event->evtype == XI_Enter
5271 ? FocusIn : FocusOut), 5336 ? FocusIn : FocusOut),
5272 FOCUS_IMPLICIT, 5337 FOCUS_IMPLICIT,
@@ -5386,8 +5451,6 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
5386 dpyinfo->super_mod_mask = 0; 5451 dpyinfo->super_mod_mask = 0;
5387 dpyinfo->hyper_mod_mask = 0; 5452 dpyinfo->hyper_mod_mask = 0;
5388 5453
5389 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
5390
5391#ifdef HAVE_XKB 5454#ifdef HAVE_XKB
5392 if (dpyinfo->xkb_desc) 5455 if (dpyinfo->xkb_desc)
5393 { 5456 {
@@ -5432,6 +5495,8 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
5432 } 5495 }
5433#endif 5496#endif
5434 5497
5498 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
5499
5435 syms = XGetKeyboardMapping (dpyinfo->display, 5500 syms = XGetKeyboardMapping (dpyinfo->display,
5436 min_code, max_code - min_code + 1, 5501 min_code, max_code - min_code + 1,
5437 &syms_per_code); 5502 &syms_per_code);
@@ -5924,7 +5989,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
5924 if (!f1 && insist > 0) 5989 if (!f1 && insist > 0)
5925 f1 = SELECTED_FRAME (); 5990 f1 = SELECTED_FRAME ();
5926 5991
5927 if (f1) 5992 if (f1 && FRAME_X_P (f1))
5928 { 5993 {
5929 /* Ok, we found a frame. Store all the values. 5994 /* Ok, we found a frame. Store all the values.
5930 last_mouse_glyph is a rectangle used to reduce the 5995 last_mouse_glyph is a rectangle used to reduce the
@@ -5934,7 +5999,6 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
5934 on it, i.e. into the same rectangles that matrices on 5999 on it, i.e. into the same rectangles that matrices on
5935 the frame are divided into. */ 6000 the frame are divided into. */
5936 6001
5937 /* FIXME: what if F1 is not an X frame? */
5938 dpyinfo = FRAME_DISPLAY_INFO (f1); 6002 dpyinfo = FRAME_DISPLAY_INFO (f1);
5939 remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph); 6003 remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
5940 dpyinfo->last_mouse_glyph_frame = f1; 6004 dpyinfo->last_mouse_glyph_frame = f1;
@@ -8285,8 +8349,10 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
8285 && event->type == GenericEvent 8349 && event->type == GenericEvent
8286 && (event->xgeneric.extension 8350 && (event->xgeneric.extension
8287 == dpyinfo->xi2_opcode) 8351 == dpyinfo->xi2_opcode)
8288 && (event->xgeneric.evtype 8352 && ((event->xgeneric.evtype
8289 == XI_KeyPress)) 8353 == XI_KeyPress)
8354 || (event->xgeneric.evtype
8355 == XI_KeyRelease)))
8290 { 8356 {
8291 f1 = x_any_window_to_frame (dpyinfo, 8357 f1 = x_any_window_to_frame (dpyinfo,
8292 ((XIDeviceEvent *) 8358 ((XIDeviceEvent *)
@@ -9458,7 +9524,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9458 9524
9459 case EnterNotify: 9525 case EnterNotify:
9460 x_display_set_last_user_time (dpyinfo, event->xcrossing.time); 9526 x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
9461 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 9527
9528 if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
9529 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
9462 9530
9463#ifdef HAVE_XWIDGETS 9531#ifdef HAVE_XWIDGETS
9464 { 9532 {
@@ -9540,7 +9608,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9540 } 9608 }
9541#endif 9609#endif
9542 x_display_set_last_user_time (dpyinfo, event->xcrossing.time); 9610 x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
9543 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 9611
9612 if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
9613 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
9544 9614
9545 f = x_top_window_to_frame (dpyinfo, event->xcrossing.window); 9615 f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
9546#if defined HAVE_X_TOOLKIT && defined HAVE_XINPUT2 9616#if defined HAVE_X_TOOLKIT && defined HAVE_XINPUT2
@@ -10151,13 +10221,23 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10151 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 10221 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
10152 goto XI_OTHER; 10222 goto XI_OTHER;
10153 case XI_Enter: 10223 case XI_Enter:
10154 any = x_any_window_to_frame (dpyinfo, enter->event); 10224
10225 any = x_top_window_to_frame (dpyinfo, enter->event);
10155 ev.x = lrint (enter->event_x); 10226 ev.x = lrint (enter->event_x);
10156 ev.y = lrint (enter->event_y); 10227 ev.y = lrint (enter->event_y);
10157 ev.window = leave->event; 10228 ev.window = enter->event;
10158
10159 x_display_set_last_user_time (dpyinfo, xi_event->time); 10229 x_display_set_last_user_time (dpyinfo, xi_event->time);
10160 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 10230
10231 /* There is no need to handle entry/exit events for
10232 passive focus from non-top windows at all, since they
10233 are an inferiors of the frame's top window, which will
10234 get virtual events. */
10235 if (any)
10236 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
10237
10238 if (!any)
10239 any = x_any_window_to_frame (dpyinfo, enter->event);
10240
10161 { 10241 {
10162#ifdef HAVE_XWIDGETS 10242#ifdef HAVE_XWIDGETS
10163 struct xwidget_view *xwidget_view = xwidget_view_from_window (enter->event); 10243 struct xwidget_view *xwidget_view = xwidget_view_from_window (enter->event);
@@ -10221,11 +10301,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10221 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); 10301 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev);
10222#endif 10302#endif
10223 goto XI_OTHER; 10303 goto XI_OTHER;
10304
10224 case XI_Leave: 10305 case XI_Leave:
10225 ev.x = lrint (leave->event_x); 10306 ev.x = lrint (leave->event_x);
10226 ev.y = lrint (leave->event_y); 10307 ev.y = lrint (leave->event_y);
10227 ev.window = leave->event; 10308 ev.window = leave->event;
10228 any = x_any_window_to_frame (dpyinfo, leave->event); 10309 any = x_top_window_to_frame (dpyinfo, leave->event);
10229 10310
10230#ifdef HAVE_XWIDGETS 10311#ifdef HAVE_XWIDGETS
10231 { 10312 {
@@ -10243,7 +10324,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10243#endif 10324#endif
10244 10325
10245 x_display_set_last_user_time (dpyinfo, xi_event->time); 10326 x_display_set_last_user_time (dpyinfo, xi_event->time);
10246 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 10327
10328 if (any)
10329 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
10330
10331 if (!any)
10332 any = x_any_window_to_frame (dpyinfo, leave->event);
10247 10333
10248#ifndef USE_X_TOOLKIT 10334#ifndef USE_X_TOOLKIT
10249 f = x_top_window_to_frame (dpyinfo, leave->event); 10335 f = x_top_window_to_frame (dpyinfo, leave->event);
@@ -11167,6 +11253,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11167 case XI_PropertyEvent: 11253 case XI_PropertyEvent:
11168 case XI_HierarchyChanged: 11254 case XI_HierarchyChanged:
11169 case XI_DeviceChanged: 11255 case XI_DeviceChanged:
11256
11257#ifdef XISlaveSwitch
11258 if (xi_event->evtype == XI_DeviceChanged
11259 && (((XIDeviceChangedEvent *) xi_event)->reason
11260 == XISlaveSwitch))
11261 goto XI_OTHER;
11262#endif
11170 x_init_master_valuators (dpyinfo); 11263 x_init_master_valuators (dpyinfo);
11171 goto XI_OTHER; 11264 goto XI_OTHER;
11172#ifdef XI_TouchBegin 11265#ifdef XI_TouchBegin
@@ -11433,6 +11526,22 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11433 11526
11434 x_find_modifier_meanings (dpyinfo); 11527 x_find_modifier_meanings (dpyinfo);
11435 } 11528 }
11529 else
11530 {
11531 dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
11532 (XkbKeySymsMask
11533 | XkbKeyTypesMask
11534 | XkbModifierMapMask
11535 | XkbVirtualModsMask),
11536 XkbUseCoreKbd);
11537
11538 if (dpyinfo->xkb_desc)
11539 XkbGetNames (dpyinfo->display,
11540 XkbGroupNamesMask | XkbVirtualModNamesMask,
11541 dpyinfo->xkb_desc);
11542 }
11543
11544 XkbRefreshKeyboardMapping (&xkbevent->map);
11436 } 11545 }
11437 } 11546 }
11438#endif 11547#endif
diff --git a/src/xwidget.c b/src/xwidget.c
index 7d6d256a191..45879b15cbe 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -1447,8 +1447,8 @@ xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event)
1447#ifdef HAVE_XINPUT2 1447#ifdef HAVE_XINPUT2
1448 else if (event->type == GenericEvent) 1448 else if (event->type == GenericEvent)
1449 { 1449 {
1450 xg_event->crossing.x = (gdouble) xev->event_x; 1450 xg_event->crossing.x = x;
1451 xg_event->crossing.y = (gdouble) xev->event_y; 1451 xg_event->crossing.y = y;
1452 xg_event->crossing.x_root = (gdouble) xev->root_x; 1452 xg_event->crossing.x_root = (gdouble) xev->root_x;
1453 xg_event->crossing.y_root = (gdouble) xev->root_y; 1453 xg_event->crossing.y_root = (gdouble) xev->root_y;
1454 xg_event->crossing.time = xev->time; 1454 xg_event->crossing.time = xev->time;