aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2021-06-13 17:34:06 +0900
committerYuuki Harano2021-06-13 17:34:06 +0900
commit7d5e94bada09e642a8bfc4f66804f7948bad40bc (patch)
tree38629672102b31bb38a855f24d4dd009e212c10d /src
parent7673b6b9eb0af3add73e1614a466f142092b00aa (diff)
parentdc471feee3bcac872cc52cdc73282955cd2d219d (diff)
downloademacs-7d5e94bada09e642a8bfc4f66804f7948bad40bc.tar.gz
emacs-7d5e94bada09e642a8bfc4f66804f7948bad40bc.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
-rw-r--r--src/character.c16
-rw-r--r--src/character.h2
-rw-r--r--src/composite.c76
-rw-r--r--src/composite.h23
-rw-r--r--src/data.c4
-rw-r--r--src/editfns.c2
-rw-r--r--src/frame.c12
-rw-r--r--src/frame.h5
-rw-r--r--src/image.c23
-rw-r--r--src/keyboard.c122
-rw-r--r--src/minibuf.c2
-rw-r--r--src/nsfns.m16
-rw-r--r--src/nsimage.m9
-rw-r--r--src/nsterm.h6
-rw-r--r--src/nsterm.m158
-rw-r--r--src/window.c35
-rw-r--r--src/xdisp.c33
17 files changed, 348 insertions, 196 deletions
diff --git a/src/character.c b/src/character.c
index e874cf5e53c..38a81d36b09 100644
--- a/src/character.c
+++ b/src/character.c
@@ -328,12 +328,14 @@ strwidth (const char *str, ptrdiff_t len)
328 compositions. If PRECISION > 0, return the width of longest 328 compositions. If PRECISION > 0, return the width of longest
329 substring that doesn't exceed PRECISION, and set number of 329 substring that doesn't exceed PRECISION, and set number of
330 characters and bytes of the substring in *NCHARS and *NBYTES 330 characters and bytes of the substring in *NCHARS and *NBYTES
331 respectively. FROM and TO are zero-based character indices 331 respectively. FROM and TO are zero-based character indices that
332 that define the substring of STRING to consider. */ 332 define the substring of STRING to consider. If AUTO_COMP is
333 non-zero, account for automatic compositions in STRING. */
333 334
334ptrdiff_t 335ptrdiff_t
335lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, 336lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to,
336 ptrdiff_t precision, ptrdiff_t *nchars, ptrdiff_t *nbytes) 337 ptrdiff_t precision, ptrdiff_t *nchars, ptrdiff_t *nbytes,
338 bool auto_comp)
337{ 339{
338 /* This set multibyte to 0 even if STRING is multibyte when it 340 /* This set multibyte to 0 even if STRING is multibyte when it
339 contains only ascii and eight-bit-graphic, but that's 341 contains only ascii and eight-bit-graphic, but that's
@@ -370,9 +372,11 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to,
370 bytes = string_char_to_byte (string, end) - i_byte; 372 bytes = string_char_to_byte (string, end) - i_byte;
371 } 373 }
372#ifdef HAVE_WINDOW_SYSTEM 374#ifdef HAVE_WINDOW_SYSTEM
373 else if (f && FRAME_WINDOW_P (f) 375 else if (auto_comp
376 && f && FRAME_WINDOW_P (f)
374 && multibyte 377 && multibyte
375 && find_automatic_composition (i, -1, &ignore, &end, &val, string) 378 && find_automatic_composition (i, -1, i, &ignore,
379 &end, &val, string)
376 && end > i) 380 && end > i)
377 { 381 {
378 int j; 382 int j;
@@ -471,7 +475,7 @@ usage: (string-width STRING &optional FROM TO) */)
471 475
472 CHECK_STRING (str); 476 CHECK_STRING (str);
473 validate_subarray (str, from, to, SCHARS (str), &ifrom, &ito); 477 validate_subarray (str, from, to, SCHARS (str), &ifrom, &ito);
474 XSETFASTINT (val, lisp_string_width (str, ifrom, ito, -1, NULL, NULL)); 478 XSETFASTINT (val, lisp_string_width (str, ifrom, ito, -1, NULL, NULL, true));
475 return val; 479 return val;
476} 480}
477 481
diff --git a/src/character.h b/src/character.h
index 75351cd1edf..1a745484daa 100644
--- a/src/character.h
+++ b/src/character.h
@@ -573,7 +573,7 @@ extern ptrdiff_t strwidth (const char *, ptrdiff_t);
573extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, 573extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int,
574 ptrdiff_t *, ptrdiff_t *); 574 ptrdiff_t *, ptrdiff_t *);
575extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t, 575extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
576 ptrdiff_t, ptrdiff_t *, ptrdiff_t *); 576 ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool);
577 577
578extern Lisp_Object Vchar_unify_table; 578extern Lisp_Object Vchar_unify_table;
579extern Lisp_Object string_escape_byte8 (Lisp_Object); 579extern Lisp_Object string_escape_byte8 (Lisp_Object);
diff --git a/src/composite.c b/src/composite.c
index 17d5914e634..129e9d6bb25 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1473,14 +1473,60 @@ struct position_record
1473 (POSITION).pos--; \ 1473 (POSITION).pos--; \
1474 } while (0) 1474 } while (0)
1475 1475
1476/* This is like find_composition, but find an automatic composition 1476/* Similar to find_composition, but find an automatic composition instead.
1477 instead. It is assured that POS is not within a static 1477
1478 composition. If found, set *GSTRING to the glyph-string 1478 This function looks for automatic composition at or near position
1479 representing the composition, and return true. Otherwise, *GSTRING to 1479 POS of OBJECT (a buffer or a string). OBJECT defaults to the
1480 Qnil, and return false. */ 1480 current buffer. It must be assured that POS is not within a static
1481 composition. Also, the current buffer must be displayed in some
1482 window, otherwise the function will return FALSE.
1483
1484 If LIMIT is negative, and there's no composition that includes POS
1485 (i.e. starts at or before POS and ends at or after POS), return
1486 FALSE. In this case, the function is allowed to look from POS as
1487 far back as BACKLIM, and as far forward as POS+1 plus
1488 MAX_AUTO_COMPOSITION_LOOKBACK, the maximum number of look-back for
1489 automatic compositions (3) -- this is a limitation imposed by
1490 composition rules in composition-function-table, which see. If
1491 BACKLIM is negative, it stands for the beginning of OBJECT: BEGV
1492 for a buffer or position zero for a string.
1493
1494 If LIMIT is positive, search for a composition forward (LIMIT >
1495 POS) or backward (LIMIT < POS). In this case, LIMIT bounds the
1496 search for the first character of a composed sequence.
1497 (LIMIT == POS is the same as LIMIT < 0.) If LIMIT > POS, the
1498 function can find a composition that starts after POS.
1499
1500 BACKLIM limits how far back is the function allowed to look in
1501 OBJECT while trying to find a position where it is safe to start
1502 searching forward for compositions. Such a safe place is generally
1503 the position after a character that can never be composed.
1504
1505 If BACKLIM is negative, that means the first character position of
1506 OBJECT; this is useful when calling the function for the first time
1507 for a given buffer or string, since it is possible that a
1508 composition begins before POS. However, if POS is very far from
1509 the beginning of OBJECT, a negative value of BACKLIM could make the
1510 function slow. Also, in this case the function may return START
1511 and END that do not include POS, something that is not necessarily
1512 wanted, and needs to be explicitly checked by the caller.
1513
1514 When calling the function in a loop for the same buffer/string, the
1515 caller should generally set BACKLIM equal to POS, to avoid costly
1516 repeated searches backward. This is because if the previous
1517 positions were already checked for compositions, there should be no
1518 reason to re-check them.
1519
1520 If BACKLIM is positive, it must be less or equal to LIMIT.
1521
1522 If an automatic composition satisfying the above conditions is
1523 found, set *GSTRING to the Lispy glyph-string representing the
1524 composition, set *START and *END to the start and end of the
1525 composed sequence, and return TRUE. Otherwise, set *GSTRING to
1526 nil, and return FALSE. */
1481 1527
1482bool 1528bool
1483find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, 1529find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1484 ptrdiff_t *start, ptrdiff_t *end, 1530 ptrdiff_t *start, ptrdiff_t *end,
1485 Lisp_Object *gstring, Lisp_Object string) 1531 Lisp_Object *gstring, Lisp_Object string)
1486{ 1532{
@@ -1502,13 +1548,13 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit,
1502 cur.pos = pos; 1548 cur.pos = pos;
1503 if (NILP (string)) 1549 if (NILP (string))
1504 { 1550 {
1505 head = BEGV, tail = ZV, stop = GPT; 1551 head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT;
1506 cur.pos_byte = CHAR_TO_BYTE (cur.pos); 1552 cur.pos_byte = CHAR_TO_BYTE (cur.pos);
1507 cur.p = BYTE_POS_ADDR (cur.pos_byte); 1553 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1508 } 1554 }
1509 else 1555 else
1510 { 1556 {
1511 head = 0, tail = SCHARS (string), stop = -1; 1557 head = backlim < 0 ? 0 : backlim, tail = SCHARS (string), stop = -1;
1512 cur.pos_byte = string_char_to_byte (string, cur.pos); 1558 cur.pos_byte = string_char_to_byte (string, cur.pos);
1513 cur.p = SDATA (string) + cur.pos_byte; 1559 cur.p = SDATA (string) + cur.pos_byte;
1514 } 1560 }
@@ -1516,6 +1562,9 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit,
1516 /* Finding a composition covering the character after POS is the 1562 /* Finding a composition covering the character after POS is the
1517 same as setting LIMIT to POS. */ 1563 same as setting LIMIT to POS. */
1518 limit = pos; 1564 limit = pos;
1565
1566 eassert (backlim < 0 || backlim <= limit);
1567
1519 if (limit <= pos) 1568 if (limit <= pos)
1520 fore_check_limit = min (tail, pos + 1 + MAX_AUTO_COMPOSITION_LOOKBACK); 1569 fore_check_limit = min (tail, pos + 1 + MAX_AUTO_COMPOSITION_LOOKBACK);
1521 else 1570 else
@@ -1696,8 +1745,8 @@ composition_adjust_point (ptrdiff_t last_pt, ptrdiff_t new_pt)
1696 return new_pt; 1745 return new_pt;
1697 1746
1698 /* Next check the automatic composition. */ 1747 /* Next check the automatic composition. */
1699 if (! find_automatic_composition (new_pt, (ptrdiff_t) -1, &beg, &end, &val, 1748 if (! find_automatic_composition (new_pt, (ptrdiff_t) -1, (ptrdiff_t) -1,
1700 Qnil) 1749 &beg, &end, &val, Qnil)
1701 || beg == new_pt) 1750 || beg == new_pt)
1702 return new_pt; 1751 return new_pt;
1703 for (i = 0; i < LGSTRING_GLYPH_LEN (val); i++) 1752 for (i = 0; i < LGSTRING_GLYPH_LEN (val); i++)
@@ -1893,8 +1942,8 @@ See `find-composition' for more details. */)
1893 { 1942 {
1894 if (!NILP (BVAR (current_buffer, enable_multibyte_characters)) 1943 if (!NILP (BVAR (current_buffer, enable_multibyte_characters))
1895 && ! NILP (Vauto_composition_mode) 1944 && ! NILP (Vauto_composition_mode)
1896 && find_automatic_composition (from, to, &start, &end, &gstring, 1945 && find_automatic_composition (from, to, (ptrdiff_t) -1,
1897 string)) 1946 &start, &end, &gstring, string))
1898 return list3 (make_fixnum (start), make_fixnum (end), gstring); 1947 return list3 (make_fixnum (start), make_fixnum (end), gstring);
1899 return Qnil; 1948 return Qnil;
1900 } 1949 }
@@ -1902,7 +1951,8 @@ See `find-composition' for more details. */)
1902 { 1951 {
1903 ptrdiff_t s, e; 1952 ptrdiff_t s, e;
1904 1953
1905 if (find_automatic_composition (from, to, &s, &e, &gstring, string) 1954 if (find_automatic_composition (from, to, (ptrdiff_t) -1,
1955 &s, &e, &gstring, string)
1906 && (e <= fixed_pos ? e > end : s < start)) 1956 && (e <= fixed_pos ? e > end : s < start))
1907 return list3 (make_fixnum (s), make_fixnum (e), gstring); 1957 return list3 (make_fixnum (s), make_fixnum (e), gstring);
1908 } 1958 }
diff --git a/src/composite.h b/src/composite.h
index 75e5f9b9ecb..67e87201bf2 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -246,6 +246,11 @@ composition_valid_p (ptrdiff_t start, ptrdiff_t end, Lisp_Object prop)
246/* Macros for lispy glyph-string. This is completely different from 246/* Macros for lispy glyph-string. This is completely different from
247 struct glyph_string. */ 247 struct glyph_string. */
248 248
249/* LGSTRING is a string of font glyphs, LGLYPHs. It is represented as
250 a Lisp vector, with components shown below. Once LGSTRING was
251 processed by a shaping engine, it holds font glyphs for one or more
252 grapheme clusters. */
253
249#define LGSTRING_HEADER(lgs) AREF (lgs, 0) 254#define LGSTRING_HEADER(lgs) AREF (lgs, 0)
250#define LGSTRING_SET_HEADER(lgs, header) ASET (lgs, 0, header) 255#define LGSTRING_SET_HEADER(lgs, header) ASET (lgs, 0, header)
251 256
@@ -259,6 +264,10 @@ composition_valid_p (ptrdiff_t start, ptrdiff_t end, Lisp_Object prop)
259#define LGSTRING_ID(lgs) AREF (lgs, 1) 264#define LGSTRING_ID(lgs) AREF (lgs, 1)
260#define LGSTRING_SET_ID(lgs, id) ASET (lgs, 1, id) 265#define LGSTRING_SET_ID(lgs, id) ASET (lgs, 1, id)
261 266
267/* LGSTRING_GLYPH_LEN is the maximum number of LGLYPHs that the
268 LGSTRING can hold. This is NOT the actual number of valid LGLYPHs;
269 to find the latter, walk the glyphs returned by LGSTRING_GLYPH
270 until the first one that is nil. */
262#define LGSTRING_GLYPH_LEN(lgs) (ASIZE ((lgs)) - 2) 271#define LGSTRING_GLYPH_LEN(lgs) (ASIZE ((lgs)) - 2)
263#define LGSTRING_GLYPH(lgs, idx) AREF ((lgs), (idx) + 2) 272#define LGSTRING_GLYPH(lgs, idx) AREF ((lgs), (idx) + 2)
264#define LGSTRING_SET_GLYPH(lgs, idx, val) ASET ((lgs), (idx) + 2, (val)) 273#define LGSTRING_SET_GLYPH(lgs, idx, val) ASET ((lgs), (idx) + 2, (val))
@@ -278,6 +287,14 @@ enum lglyph_indices
278 LGLYPH_SIZE 287 LGLYPH_SIZE
279 }; 288 };
280 289
290/* Each LGLYPH is a single font glyph, whose font code is in
291 LGLYPH_CODE.
292 LGLYPH_FROM and LGLYPH_TO are indices into LGSTRING; all the
293 LGLYPHs that share the same values of LGLYPH_FROM and LGLYPH_TO
294 belong to the same grapheme cluster.
295 LGLYPH_CHAR is one of the characters, usually the first one, that
296 contributed to the glyph (since there isn't a 1:1 correspondence
297 between composed characters and the font glyphs). */
281#define LGLYPH_NEW() make_nil_vector (LGLYPH_SIZE) 298#define LGLYPH_NEW() make_nil_vector (LGLYPH_SIZE)
282#define LGLYPH_FROM(g) XFIXNUM (AREF ((g), LGLYPH_IX_FROM)) 299#define LGLYPH_FROM(g) XFIXNUM (AREF ((g), LGLYPH_IX_FROM))
283#define LGLYPH_TO(g) XFIXNUM (AREF ((g), LGLYPH_IX_TO)) 300#define LGLYPH_TO(g) XFIXNUM (AREF ((g), LGLYPH_IX_TO))
@@ -320,9 +337,9 @@ extern bool composition_gstring_p (Lisp_Object);
320extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t, 337extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
321 struct font_metrics *); 338 struct font_metrics *);
322 339
323extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *, 340extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t,
324 ptrdiff_t *, Lisp_Object *, 341 ptrdiff_t *, ptrdiff_t *,
325 Lisp_Object); 342 Lisp_Object *, Lisp_Object);
326 343
327extern void composition_compute_stop_pos (struct composition_it *, 344extern void composition_compute_stop_pos (struct composition_it *,
328 ptrdiff_t, ptrdiff_t, ptrdiff_t, 345 ptrdiff_t, ptrdiff_t, ptrdiff_t,
diff --git a/src/data.c b/src/data.c
index d547f5da5e0..059f31e514b 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2200,7 +2200,9 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
2200DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p, 2200DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
2201 1, 2, 0, 2201 1, 2, 0,
2202 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER. 2202 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER.
2203BUFFER defaults to the current buffer. */) 2203BUFFER defaults to the current buffer.
2204
2205Also see `buffer-local-boundp'.*/)
2204 (Lisp_Object variable, Lisp_Object buffer) 2206 (Lisp_Object variable, Lisp_Object buffer)
2205{ 2207{
2206 struct buffer *buf = decode_buffer (buffer); 2208 struct buffer *buf = decode_buffer (buffer);
diff --git a/src/editfns.c b/src/editfns.c
index 182d3ba6f2b..aa0f46fea04 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3390,7 +3390,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3390 ptrdiff_t nch, nby; 3390 ptrdiff_t nch, nby;
3391 nchars_string = SCHARS (arg); 3391 nchars_string = SCHARS (arg);
3392 width = lisp_string_width (arg, 0, nchars_string, prec, 3392 width = lisp_string_width (arg, 0, nchars_string, prec,
3393 &nch, &nby); 3393 &nch, &nby, false);
3394 if (prec < 0) 3394 if (prec < 0)
3395 nbytes = SBYTES (arg); 3395 nbytes = SBYTES (arg);
3396 else 3396 else
diff --git a/src/frame.c b/src/frame.c
index f8479f63f1d..3c7c4078cb0 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -985,6 +985,7 @@ make_frame (bool mini_p)
985 f->ns_transparent_titlebar = false; 985 f->ns_transparent_titlebar = false;
986#endif 986#endif
987#endif 987#endif
988 f->select_mini_window_flag = false;
988 /* This one should never be zero. */ 989 /* This one should never be zero. */
989 f->change_stamp = 1; 990 f->change_stamp = 1;
990 root_window = make_window (); 991 root_window = make_window ();
@@ -1545,7 +1546,17 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1545 tty->top_frame = frame; 1546 tty->top_frame = frame;
1546 } 1547 }
1547 1548
1549 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
1550
1548 selected_frame = frame; 1551 selected_frame = frame;
1552
1553 move_minibuffers_onto_frame (sf, for_deletion);
1554
1555 if (f->select_mini_window_flag
1556 && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
1557 f->selected_window = f->minibuffer_window;
1558 f->select_mini_window_flag = false;
1559
1549 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) 1560 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1550 last_nonminibuf_frame = XFRAME (selected_frame); 1561 last_nonminibuf_frame = XFRAME (selected_frame);
1551 1562
@@ -1562,7 +1573,6 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1562#endif 1573#endif
1563 internal_last_event_frame = Qnil; 1574 internal_last_event_frame = Qnil;
1564 1575
1565 move_minibuffers_onto_frame (sf, for_deletion);
1566 return frame; 1576 return frame;
1567} 1577}
1568 1578
diff --git a/src/frame.h b/src/frame.h
index b1ad525779c..d3ae548ed3b 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -462,6 +462,11 @@ struct frame
462 in X builds only. */ 462 in X builds only. */
463 bool_bf was_invisible : 1; 463 bool_bf was_invisible : 1;
464 464
465 /* True when the frame isn't selected, and selecting it in the
466 future should select the mini-window rather than the currently
467 selected window in the frame, assuming there is still an active
468 minibuffer in that mini-window. */
469 bool_bf select_mini_window_flag : 1;
465 /* Bitfield area ends here. */ 470 /* Bitfield area ends here. */
466 471
467 /* This frame's change stamp, set the last time window change 472 /* This frame's change stamp, set the last time window change
diff --git a/src/image.c b/src/image.c
index 9b8b7d97bda..916edd502da 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3276,19 +3276,16 @@ image_find_image_fd (Lisp_Object file, int *pfd)
3276 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ 3276 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
3277 fd = openp (search_path, file, Qnil, &file_found, 3277 fd = openp (search_path, file, Qnil, &file_found,
3278 pfd ? Qt : make_fixnum (R_OK), false, false); 3278 pfd ? Qt : make_fixnum (R_OK), false, false);
3279 if (fd >= 0 || fd == -2) 3279 if (fd == -2)
3280 { 3280 {
3281 file_found = ENCODE_FILE (file_found); 3281 /* The file exists locally, but has a file name handler.
3282 if (fd == -2) 3282 (This happens, e.g., under Auto Image File Mode.)
3283 { 3283 'openp' didn't open the file, so we should, because the
3284 /* The file exists locally, but has a file name handler. 3284 caller expects that. */
3285 (This happens, e.g., under Auto Image File Mode.) 3285 Lisp_Object encoded_name = ENCODE_FILE (file_found);
3286 'openp' didn't open the file, so we should, because the 3286 fd = emacs_open (SSDATA (encoded_name), O_RDONLY, 0);
3287 caller expects that. */
3288 fd = emacs_open (SSDATA (file_found), O_RDONLY, 0);
3289 }
3290 } 3287 }
3291 else /* fd < 0, but not -2 */ 3288 else if (fd < 0)
3292 return Qnil; 3289 return Qnil;
3293 if (pfd) 3290 if (pfd)
3294 *pfd = fd; 3291 *pfd = fd;
@@ -3296,8 +3293,8 @@ image_find_image_fd (Lisp_Object file, int *pfd)
3296} 3293}
3297 3294
3298/* Find image file FILE. Look in data-directory/images, then 3295/* Find image file FILE. Look in data-directory/images, then
3299 x-bitmap-file-path. Value is the encoded full name of the file 3296 x-bitmap-file-path. Value is the full name of the file found, or
3300 found, or nil if not found. */ 3297 nil if not found. */
3301 3298
3302Lisp_Object 3299Lisp_Object
3303image_find_image_file (Lisp_Object file) 3300image_find_image_file (Lisp_Object file)
diff --git a/src/keyboard.c b/src/keyboard.c
index b2aabdda325..87a9512a45b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2254,8 +2254,17 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2254 { 2254 {
2255 int i; 2255 int i;
2256 if (meta_key != 2) 2256 if (meta_key != 2)
2257 for (i = 0; i < n; i++) 2257 {
2258 events[i] = make_fixnum (XFIXNUM (events[i]) & ~0x80); 2258 for (i = 0; i < n; i++)
2259 {
2260 int c = XFIXNUM (events[i]);
2261 int modifier =
2262 (meta_key == 3 && c < 0x100 && (c & 0x80))
2263 ? meta_modifier
2264 : 0;
2265 events[i] = make_fixnum ((c & ~0x80) | modifier);
2266 }
2267 }
2259 } 2268 }
2260 else 2269 else
2261 { 2270 {
@@ -2264,7 +2273,7 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2264 int i; 2273 int i;
2265 for (i = 0; i < n; i++) 2274 for (i = 0; i < n; i++)
2266 src[i] = XFIXNUM (events[i]); 2275 src[i] = XFIXNUM (events[i]);
2267 if (meta_key != 2) 2276 if (meta_key < 2) /* input-meta-mode is t or nil */
2268 for (i = 0; i < n; i++) 2277 for (i = 0; i < n; i++)
2269 src[i] &= ~0x80; 2278 src[i] &= ~0x80;
2270 coding->destination = dest; 2279 coding->destination = dest;
@@ -2282,7 +2291,18 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2282 eassert (coding->carryover_bytes == 0); 2291 eassert (coding->carryover_bytes == 0);
2283 n = 0; 2292 n = 0;
2284 while (n < coding->produced_char) 2293 while (n < coding->produced_char)
2285 events[n++] = make_fixnum (string_char_advance (&p)); 2294 {
2295 int c = string_char_advance (&p);
2296 if (meta_key == 3)
2297 {
2298 int modifier
2299 = (c < 0x100 && (c & 0x80)
2300 ? meta_modifier
2301 : 0);
2302 c = (c & ~0x80) | modifier;
2303 }
2304 events[n++] = make_fixnum (c);
2305 }
2286 } 2306 }
2287 } 2307 }
2288 } 2308 }
@@ -5021,6 +5041,10 @@ static short const internal_border_parts[] = {
5021 5041
5022static Lisp_Object button_down_location; 5042static Lisp_Object button_down_location;
5023 5043
5044/* A cons recording the original frame-relative x and y coordinates of
5045 the down mouse event. */
5046static Lisp_Object frame_relative_event_pos;
5047
5024/* Information about the most recent up-going button event: Which 5048/* Information about the most recent up-going button event: Which
5025 button, what location, and what time. */ 5049 button, what location, and what time. */
5026 5050
@@ -5672,6 +5696,7 @@ make_lispy_event (struct input_event *event)
5672 double_click_count = 1; 5696 double_click_count = 1;
5673 button_down_time = event->timestamp; 5697 button_down_time = event->timestamp;
5674 *start_pos_ptr = Fcopy_alist (position); 5698 *start_pos_ptr = Fcopy_alist (position);
5699 frame_relative_event_pos = Fcons (event->x, event->y);
5675 ignore_mouse_drag_p = false; 5700 ignore_mouse_drag_p = false;
5676 } 5701 }
5677 5702
@@ -5694,20 +5719,12 @@ make_lispy_event (struct input_event *event)
5694 ignore_mouse_drag_p = false; 5719 ignore_mouse_drag_p = false;
5695 else 5720 else
5696 { 5721 {
5697 Lisp_Object new_down, down;
5698 intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz; 5722 intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz;
5699 5723
5700 /* The third element of every position 5724 xdiff = XFIXNUM (event->x)
5701 should be the (x,y) pair. */ 5725 - XFIXNUM (XCAR (frame_relative_event_pos));
5702 down = Fcar (Fcdr (Fcdr (start_pos))); 5726 ydiff = XFIXNUM (event->y)
5703 new_down = Fcar (Fcdr (Fcdr (position))); 5727 - XFIXNUM (XCDR (frame_relative_event_pos));
5704
5705 if (CONSP (down)
5706 && FIXNUMP (XCAR (down)) && FIXNUMP (XCDR (down)))
5707 {
5708 xdiff = XFIXNUM (XCAR (new_down)) - XFIXNUM (XCAR (down));
5709 ydiff = XFIXNUM (XCDR (new_down)) - XFIXNUM (XCDR (down));
5710 }
5711 5728
5712 if (! (0 < double_click_fuzz 5729 if (! (0 < double_click_fuzz
5713 && - double_click_fuzz < xdiff 5730 && - double_click_fuzz < xdiff
@@ -5724,12 +5741,51 @@ make_lispy_event (struct input_event *event)
5724 a click. But mouse-drag-region completely ignores 5741 a click. But mouse-drag-region completely ignores
5725 this case and it hasn't caused any real problem, so 5742 this case and it hasn't caused any real problem, so
5726 it's probably OK to ignore it as well. */ 5743 it's probably OK to ignore it as well. */
5727 && EQ (Fcar (Fcdr (start_pos)), Fcar (Fcdr (position))))) 5744 && (EQ (Fcar (Fcdr (start_pos)),
5745 Fcar (Fcdr (position))) /* Same buffer pos */
5746 || !EQ (Fcar (start_pos),
5747 Fcar (position))))) /* Different window */
5728 { 5748 {
5729 /* Mouse has moved enough. */ 5749 /* Mouse has moved enough. */
5730 button_down_time = 0; 5750 button_down_time = 0;
5731 click_or_drag_modifier = drag_modifier; 5751 click_or_drag_modifier = drag_modifier;
5732 } 5752 }
5753 else if (((!EQ (Fcar (start_pos), Fcar (position)))
5754 || (!EQ (Fcar (Fcdr (start_pos)),
5755 Fcar (Fcdr (position)))))
5756 /* Was the down event in a window body? */
5757 && FIXNUMP (Fcar (Fcdr (start_pos)))
5758 && WINDOW_LIVE_P (Fcar (start_pos))
5759 && !NILP (Ffboundp (Qwindow_edges)))
5760 /* If the window (etc.) at the mouse position has
5761 changed between the down event and the up event,
5762 we assume there's been a redisplay between the
5763 two events, and we pretend the mouse is still in
5764 the old window to prevent a spurious drag event
5765 being generated. */
5766 {
5767 Lisp_Object edges
5768 = call4 (Qwindow_edges, Fcar (start_pos), Qt, Qnil, Qt);
5769 int new_x = XFIXNUM (Fcar (frame_relative_event_pos));
5770 int new_y = XFIXNUM (Fcdr (frame_relative_event_pos));
5771
5772 /* If the up-event is outside the down-event's
5773 window, use coordinates that are within it. */
5774 if (new_x < XFIXNUM (Fcar (edges)))
5775 new_x = XFIXNUM (Fcar (edges));
5776 else if (new_x >= XFIXNUM (Fcar (Fcdr (Fcdr (edges)))))
5777 new_x = XFIXNUM (Fcar (Fcdr (Fcdr (edges)))) - 1;
5778 if (new_y < XFIXNUM (Fcar (Fcdr (edges))))
5779 new_y = XFIXNUM (Fcar (Fcdr (edges)));
5780 else if (new_y
5781 >= XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))))
5782 new_y = XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))) - 1;
5783
5784 position = make_lispy_position
5785 (XFRAME (event->frame_or_window),
5786 make_fixnum (new_x), make_fixnum (new_y),
5787 event->timestamp);
5788 }
5733 } 5789 }
5734 5790
5735 /* Don't check is_double; treat this as multiple if the 5791 /* Don't check is_double; treat this as multiple if the
@@ -7040,7 +7096,7 @@ tty_read_avail_input (struct terminal *terminal,
7040 buf.modifiers = 0; 7096 buf.modifiers = 0;
7041 if (tty->meta_key == 1 && (cbuf[i] & 0x80)) 7097 if (tty->meta_key == 1 && (cbuf[i] & 0x80))
7042 buf.modifiers = meta_modifier; 7098 buf.modifiers = meta_modifier;
7043 if (tty->meta_key != 2) 7099 if (tty->meta_key < 2)
7044 cbuf[i] &= ~0x80; 7100 cbuf[i] &= ~0x80;
7045 7101
7046 buf.code = cbuf[i]; 7102 buf.code = cbuf[i];
@@ -11047,7 +11103,10 @@ See also `current-input-mode'. */)
11047DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0, 11103DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
11048 doc: /* Enable or disable 8-bit input on TERMINAL. 11104 doc: /* Enable or disable 8-bit input on TERMINAL.
11049If META is t, Emacs will accept 8-bit input, and interpret the 8th 11105If META is t, Emacs will accept 8-bit input, and interpret the 8th
11050bit as the Meta modifier. 11106bit as the Meta modifier before it decodes the characters.
11107
11108If META is `encoded', Emacs will interpret the 8th bit of single-byte
11109characters after decoding the characters.
11051 11110
11052If META is nil, Emacs will ignore the top bit, on the assumption it is 11111If META is nil, Emacs will ignore the top bit, on the assumption it is
11053parity. 11112parity.
@@ -11076,6 +11135,8 @@ See also `current-input-mode'. */)
11076 new_meta = 0; 11135 new_meta = 0;
11077 else if (EQ (meta, Qt)) 11136 else if (EQ (meta, Qt))
11078 new_meta = 1; 11137 new_meta = 1;
11138 else if (EQ (meta, Qencoded))
11139 new_meta = 3;
11079 else 11140 else
11080 new_meta = 2; 11141 new_meta = 2;
11081 11142
@@ -11138,6 +11199,8 @@ Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
11138 (no effect except in CBREAK mode). 11199 (no effect except in CBREAK mode).
11139Third arg META t means accept 8-bit input (for a Meta key). 11200Third arg META t means accept 8-bit input (for a Meta key).
11140 META nil means ignore the top bit, on the assumption it is parity. 11201 META nil means ignore the top bit, on the assumption it is parity.
11202 META `encoded' means accept 8-bit input and interpret Meta after
11203 decoding the input characters.
11141 Otherwise, accept 8-bit input and don't use the top bit for Meta. 11204 Otherwise, accept 8-bit input and don't use the top bit for Meta.
11142Optional fourth arg QUIT if non-nil specifies character to use for quitting. 11205Optional fourth arg QUIT if non-nil specifies character to use for quitting.
11143See also `current-input-mode'. */) 11206See also `current-input-mode'. */)
@@ -11158,9 +11221,12 @@ The value is a list of the form (INTERRUPT FLOW META QUIT), where
11158 nil, Emacs is using CBREAK mode. 11221 nil, Emacs is using CBREAK mode.
11159 FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the 11222 FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the
11160 terminal; this does not apply if Emacs uses interrupt-driven input. 11223 terminal; this does not apply if Emacs uses interrupt-driven input.
11161 META is t if accepting 8-bit input with 8th bit as Meta flag. 11224 META is t if accepting 8-bit unencoded input with 8th bit as Meta flag.
11162 META nil means ignoring the top bit, on the assumption it is parity. 11225 META is `encoded' if accepting 8-bit encoded input with 8th bit as
11163 META is neither t nor nil if accepting 8-bit input and using 11226 Meta flag which has to be interpreted after decoding the input.
11227 META is nil if ignoring the top bit of input, on the assumption that
11228 it is a parity bit.
11229 META is neither t nor nil if accepting 8-bit input and using
11164 all 8 bits as the character code. 11230 all 8 bits as the character code.
11165 QUIT is the character Emacs currently uses to quit. 11231 QUIT is the character Emacs currently uses to quit.
11166The elements of this list correspond to the arguments of 11232The elements of this list correspond to the arguments of
@@ -11176,7 +11242,9 @@ The elements of this list correspond to the arguments of
11176 flow = FRAME_TTY (sf)->flow_control ? Qt : Qnil; 11242 flow = FRAME_TTY (sf)->flow_control ? Qt : Qnil;
11177 meta = (FRAME_TTY (sf)->meta_key == 2 11243 meta = (FRAME_TTY (sf)->meta_key == 2
11178 ? make_fixnum (0) 11244 ? make_fixnum (0)
11179 : (CURTTY ()->meta_key == 1 ? Qt : Qnil)); 11245 : (CURTTY ()->meta_key == 1
11246 ? Qt
11247 : (CURTTY ()->meta_key == 3 ? Qencoded : Qnil)));
11180 } 11248 }
11181 else 11249 else
11182 { 11250 {
@@ -11653,6 +11721,7 @@ syms_of_keyboard (void)
11653 DEFSYM (Qmake_frame_visible, "make-frame-visible"); 11721 DEFSYM (Qmake_frame_visible, "make-frame-visible");
11654 DEFSYM (Qselect_window, "select-window"); 11722 DEFSYM (Qselect_window, "select-window");
11655 DEFSYM (Qselection_request, "selection-request"); 11723 DEFSYM (Qselection_request, "selection-request");
11724 DEFSYM (Qwindow_edges, "window-edges");
11656 { 11725 {
11657 int i; 11726 int i;
11658 11727
@@ -11666,9 +11735,11 @@ syms_of_keyboard (void)
11666 } 11735 }
11667 } 11736 }
11668 DEFSYM (Qno_record, "no-record"); 11737 DEFSYM (Qno_record, "no-record");
11738 DEFSYM (Qencoded, "encoded");
11669 11739
11670 button_down_location = make_nil_vector (5); 11740 button_down_location = make_nil_vector (5);
11671 staticpro (&button_down_location); 11741 staticpro (&button_down_location);
11742 staticpro (&frame_relative_event_pos);
11672 mouse_syms = make_nil_vector (5); 11743 mouse_syms = make_nil_vector (5);
11673 staticpro (&mouse_syms); 11744 staticpro (&mouse_syms);
11674 wheel_syms = make_nil_vector (ARRAYELTS (lispy_wheel_names)); 11745 wheel_syms = make_nil_vector (ARRAYELTS (lispy_wheel_names));
@@ -12273,7 +12344,10 @@ Called with three arguments:
12273- the error data, a list of the form (SIGNALED-CONDITION . SIGNAL-DATA) 12344- the error data, a list of the form (SIGNALED-CONDITION . SIGNAL-DATA)
12274 such as what `condition-case' would bind its variable to, 12345 such as what `condition-case' would bind its variable to,
12275- the context (a string which normally goes at the start of the message), 12346- the context (a string which normally goes at the start of the message),
12276- the Lisp function within which the error was signaled. */); 12347- the Lisp function within which the error was signaled.
12348
12349Also see `set-message-function' (which controls how non-error messages
12350are displayed). */);
12277 Vcommand_error_function = intern ("command-error-default-function"); 12351 Vcommand_error_function = intern ("command-error-default-function");
12278 12352
12279 DEFVAR_LISP ("enable-disabled-menus-and-buttons", 12353 DEFVAR_LISP ("enable-disabled-menus-and-buttons",
diff --git a/src/minibuf.c b/src/minibuf.c
index cffb7fe787c..00069eabbe5 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2385,7 +2385,7 @@ default top level value is used. */);
2385 Vminibuffer_setup_hook = Qnil; 2385 Vminibuffer_setup_hook = Qnil;
2386 2386
2387 DEFVAR_LISP ("minibuffer-exit-hook", Vminibuffer_exit_hook, 2387 DEFVAR_LISP ("minibuffer-exit-hook", Vminibuffer_exit_hook,
2388 doc: /* Normal hook run just after exit from minibuffer. */); 2388 doc: /* Normal hook run whenever a minibuffer is exited. */);
2389 Vminibuffer_exit_hook = Qnil; 2389 Vminibuffer_exit_hook = Qnil;
2390 2390
2391 DEFVAR_LISP ("history-length", Vhistory_length, 2391 DEFVAR_LISP ("history-length", Vhistory_length,
diff --git a/src/nsfns.m b/src/nsfns.m
index d14f7b51eaf..454a6fdab62 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1953,8 +1953,11 @@ DEFUN ("ns-hide-emacs", Fns_hide_emacs, Sns_hide_emacs,
1953 doc: /* If ON is non-nil, the entire Emacs application is hidden. 1953 doc: /* If ON is non-nil, the entire Emacs application is hidden.
1954Otherwise if Emacs is hidden, it is unhidden. 1954Otherwise if Emacs is hidden, it is unhidden.
1955If ON is equal to `activate', Emacs is unhidden and becomes 1955If ON is equal to `activate', Emacs is unhidden and becomes
1956the active application. */) 1956the active application.
1957 (Lisp_Object on) 1957If ON is equal to `activate-front', Emacs is unhidden and
1958becomes the active application, but only the selected frame
1959is layered in front of the windows of other applications. */)
1960 (Lisp_Object on)
1958{ 1961{
1959 check_window_system (NULL); 1962 check_window_system (NULL);
1960 if (EQ (on, intern ("activate"))) 1963 if (EQ (on, intern ("activate")))
@@ -1962,6 +1965,12 @@ the active application. */)
1962 [NSApp unhide: NSApp]; 1965 [NSApp unhide: NSApp];
1963 [NSApp activateIgnoringOtherApps: YES]; 1966 [NSApp activateIgnoringOtherApps: YES];
1964 } 1967 }
1968 else if (EQ (on, intern ("activate-front")))
1969 {
1970 [NSApp unhide: NSApp];
1971 [[NSRunningApplication currentApplication]
1972 activateWithOptions: NSApplicationActivateIgnoringOtherApps];
1973 }
1965 else if (NILP (on)) 1974 else if (NILP (on))
1966 [NSApp unhide: NSApp]; 1975 [NSApp unhide: NSApp];
1967 else 1976 else
@@ -3024,7 +3033,8 @@ all_nonzero_ascii (unsigned char *str, ptrdiff_t n)
3024} 3033}
3025 3034
3026@implementation NSString (EmacsString) 3035@implementation NSString (EmacsString)
3027/* Make an NSString from a Lisp string. */ 3036/* Make an NSString from a Lisp string. STRING must not be in an
3037 encoded form (e.g. UTF-8). */
3028+ (NSString *)stringWithLispString:(Lisp_Object)string 3038+ (NSString *)stringWithLispString:(Lisp_Object)string
3029{ 3039{
3030 /* Shortcut for the common case. */ 3040 /* Shortcut for the common case. */
diff --git a/src/nsimage.m b/src/nsimage.m
index fa81a41a519..3c16cd371e6 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -254,15 +254,15 @@ ns_image_size_in_bytes (void *img)
254 NSImageRep *imgRep; 254 NSImageRep *imgRep;
255 Lisp_Object found; 255 Lisp_Object found;
256 EmacsImage *image; 256 EmacsImage *image;
257 NSString *filename;
257 258
258 /* Search bitmap-file-path for the file, if appropriate. */ 259 /* Search bitmap-file-path for the file, if appropriate. */
259 found = image_find_image_file (file); 260 found = image_find_image_file (file);
260 if (!STRINGP (found)) 261 if (!STRINGP (found))
261 return nil; 262 return nil;
262 found = ENCODE_FILE (found); 263 filename = [NSString stringWithLispString:found];
263 264
264 image = [[EmacsImage alloc] initByReferencingFile: 265 image = [[EmacsImage alloc] initByReferencingFile:filename];
265 [NSString stringWithLispString: found]];
266 266
267 image->bmRep = nil; 267 image->bmRep = nil;
268#ifdef NS_IMPL_COCOA 268#ifdef NS_IMPL_COCOA
@@ -277,8 +277,7 @@ ns_image_size_in_bytes (void *img)
277 } 277 }
278 278
279 [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])]; 279 [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])];
280 280 [image setName:filename];
281 [image setName: [NSString stringWithLispString: file]];
282 281
283 return image; 282 return image;
284} 283}
diff --git a/src/nsterm.h b/src/nsterm.h
index 017c2394ef1..e7ea907569e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -443,7 +443,6 @@ typedef id instancetype;
443 int maximized_width, maximized_height; 443 int maximized_width, maximized_height;
444 NSWindow *nonfs_window; 444 NSWindow *nonfs_window;
445 BOOL fs_is_native; 445 BOOL fs_is_native;
446 BOOL in_fullscreen_transition;
447#ifdef NS_DRAW_TO_BUFFER 446#ifdef NS_DRAW_TO_BUFFER
448 EmacsSurface *surface; 447 EmacsSurface *surface;
449#endif 448#endif
@@ -475,8 +474,6 @@ typedef id instancetype;
475- (void) toggleFullScreen: (id) sender; 474- (void) toggleFullScreen: (id) sender;
476- (BOOL) fsIsNative; 475- (BOOL) fsIsNative;
477- (BOOL) isFullscreen; 476- (BOOL) isFullscreen;
478- (BOOL) inFullScreenTransition;
479- (void) waitFullScreenTransition;
480#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 477#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
481- (void) updateCollectionBehavior; 478- (void) updateCollectionBehavior;
482#endif 479#endif
@@ -724,8 +721,9 @@ typedef id instancetype;
724 IOSurfaceRef currentSurface; 721 IOSurfaceRef currentSurface;
725 IOSurfaceRef lastSurface; 722 IOSurfaceRef lastSurface;
726 CGContextRef context; 723 CGContextRef context;
724 CGFloat scale;
727} 725}
728- (id) initWithSize: (NSSize)s ColorSpace: (CGColorSpaceRef)cs; 726- (id) initWithSize: (NSSize)s ColorSpace: (CGColorSpaceRef)cs Scale: (CGFloat)scale;
729- (void) dealloc; 727- (void) dealloc;
730- (NSSize) getSize; 728- (NSSize) getSize;
731- (CGContextRef) getContext; 729- (CGContextRef) getContext;
diff --git a/src/nsterm.m b/src/nsterm.m
index bb20886ab1d..838c14d5abb 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1640,8 +1640,6 @@ ns_make_frame_visible (struct frame *f)
1640 fullscreen also. So skip handleFS as this will print an error. */ 1640 fullscreen also. So skip handleFS as this will print an error. */
1641 if ([view fsIsNative] && [view isFullscreen]) 1641 if ([view fsIsNative] && [view isFullscreen])
1642 { 1642 {
1643 // maybe it is not necessary to wait
1644 [view waitFullScreenTransition];
1645 return; 1643 return;
1646 } 1644 }
1647 1645
@@ -2057,11 +2055,7 @@ ns_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_val
2057#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 2055#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
2058 // child frame must not be in fullscreen 2056 // child frame must not be in fullscreen
2059 if ([view fsIsNative] && [view isFullscreen]) 2057 if ([view fsIsNative] && [view isFullscreen])
2060 { 2058 [view toggleFullScreen:child];
2061 // in case child is going fullscreen
2062 [view waitFullScreenTransition];
2063 [view toggleFullScreen:child];
2064 }
2065 NSTRACE ("child setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary"); 2059 NSTRACE ("child setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary");
2066 [child setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; 2060 [child setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
2067#endif 2061#endif
@@ -7489,7 +7483,6 @@ not_in_argv (NSString *arg)
7489#endif 7483#endif
7490 fs_is_native = ns_use_native_fullscreen; 7484 fs_is_native = ns_use_native_fullscreen;
7491#endif 7485#endif
7492 in_fullscreen_transition = NO;
7493 7486
7494 maximized_width = maximized_height = -1; 7487 maximized_width = maximized_height = -1;
7495 nonfs_window = nil; 7488 nonfs_window = nil;
@@ -7862,7 +7855,6 @@ not_in_argv (NSString *arg)
7862- (void)windowWillEnterFullScreen:(NSNotification *)notification 7855- (void)windowWillEnterFullScreen:(NSNotification *)notification
7863{ 7856{
7864 NSTRACE ("[EmacsView windowWillEnterFullScreen:]"); 7857 NSTRACE ("[EmacsView windowWillEnterFullScreen:]");
7865 in_fullscreen_transition = YES;
7866 [self windowWillEnterFullScreen]; 7858 [self windowWillEnterFullScreen];
7867} 7859}
7868- (void)windowWillEnterFullScreen /* provided for direct calls */ 7860- (void)windowWillEnterFullScreen /* provided for direct calls */
@@ -7875,7 +7867,6 @@ not_in_argv (NSString *arg)
7875{ 7867{
7876 NSTRACE ("[EmacsView windowDidEnterFullScreen:]"); 7868 NSTRACE ("[EmacsView windowDidEnterFullScreen:]");
7877 [self windowDidEnterFullScreen]; 7869 [self windowDidEnterFullScreen];
7878 in_fullscreen_transition = NO;
7879} 7870}
7880 7871
7881- (void)windowDidEnterFullScreen /* provided for direct calls */ 7872- (void)windowDidEnterFullScreen /* provided for direct calls */
@@ -7914,7 +7905,6 @@ not_in_argv (NSString *arg)
7914- (void)windowWillExitFullScreen:(NSNotification *)notification 7905- (void)windowWillExitFullScreen:(NSNotification *)notification
7915{ 7906{
7916 NSTRACE ("[EmacsView windowWillExitFullScreen:]"); 7907 NSTRACE ("[EmacsView windowWillExitFullScreen:]");
7917 in_fullscreen_transition = YES;
7918 [self windowWillExitFullScreen]; 7908 [self windowWillExitFullScreen];
7919} 7909}
7920 7910
@@ -7934,7 +7924,6 @@ not_in_argv (NSString *arg)
7934{ 7924{
7935 NSTRACE ("[EmacsView windowDidExitFullScreen:]"); 7925 NSTRACE ("[EmacsView windowDidExitFullScreen:]");
7936 [self windowDidExitFullScreen]; 7926 [self windowDidExitFullScreen];
7937 in_fullscreen_transition = NO;
7938} 7927}
7939 7928
7940- (void)windowDidExitFullScreen /* provided for direct calls */ 7929- (void)windowDidExitFullScreen /* provided for direct calls */
@@ -7963,22 +7952,6 @@ not_in_argv (NSString *arg)
7963 [[self window] performZoom:self]; 7952 [[self window] performZoom:self];
7964} 7953}
7965 7954
7966- (BOOL)inFullScreenTransition
7967{
7968 return in_fullscreen_transition;
7969}
7970
7971- (void)waitFullScreenTransition
7972{
7973#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
7974 while ([self inFullScreenTransition])
7975 {
7976 NSTRACE ("wait for fullscreen");
7977 wait_reading_process_output (0, 300000000, 0, 1, Qnil, NULL, 0);
7978 }
7979#endif
7980}
7981
7982- (BOOL)fsIsNative 7955- (BOOL)fsIsNative
7983{ 7956{
7984 return fs_is_native; 7957 return fs_is_native;
@@ -8058,14 +8031,8 @@ not_in_argv (NSString *arg)
8058#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 8031#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
8059#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 8032#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
8060 if ([[self window] respondsToSelector: @selector(toggleFullScreen:)]) 8033 if ([[self window] respondsToSelector: @selector(toggleFullScreen:)])
8061 {
8062#endif
8063 [[self window] toggleFullScreen:sender];
8064 // wait for fullscreen animation complete (bug#28496)
8065 [self waitFullScreenTransition];
8066#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
8067 }
8068#endif 8034#endif
8035 [[self window] toggleFullScreen:sender];
8069#endif 8036#endif
8070 return; 8037 return;
8071 } 8038 }
@@ -8353,19 +8320,17 @@ not_in_argv (NSString *arg)
8353 8320
8354 surface = [[EmacsSurface alloc] initWithSize:s 8321 surface = [[EmacsSurface alloc] initWithSize:s
8355 ColorSpace:[[[self window] colorSpace] 8322 ColorSpace:[[[self window] colorSpace]
8356 CGColorSpace]]; 8323 CGColorSpace]
8324 Scale:scale];
8357 8325
8358 /* Since we're using NSViewLayerContentsRedrawOnSetNeedsDisplay 8326 /* Since we're using NSViewLayerContentsRedrawOnSetNeedsDisplay
8359 the layer's scale factor is not set automatically, so do it 8327 the layer's scale factor is not set automatically, so do it
8360 now. */ 8328 now. */
8361 [[self layer] setContentsScale:[[self window] backingScaleFactor]]; 8329 [[self layer] setContentsScale:scale];
8362 } 8330 }
8363 8331
8364 CGContextRef context = [surface getContext]; 8332 CGContextRef context = [surface getContext];
8365 8333
8366 CGContextTranslateCTM(context, 0, [surface getSize].height);
8367 CGContextScaleCTM(context, scale, -scale);
8368
8369 [NSGraphicsContext 8334 [NSGraphicsContext
8370 setCurrentContext:[NSGraphicsContext 8335 setCurrentContext:[NSGraphicsContext
8371 graphicsContextWithCGContext:context 8336 graphicsContextWithCGContext:context
@@ -8378,7 +8343,6 @@ not_in_argv (NSString *arg)
8378 NSTRACE ("[EmacsView unfocusDrawingBuffer]"); 8343 NSTRACE ("[EmacsView unfocusDrawingBuffer]");
8379 8344
8380 [NSGraphicsContext setCurrentContext:nil]; 8345 [NSGraphicsContext setCurrentContext:nil];
8381 [surface releaseContext];
8382 [self setNeedsDisplay:YES]; 8346 [self setNeedsDisplay:YES];
8383} 8347}
8384 8348
@@ -8516,7 +8480,11 @@ not_in_argv (NSString *arg)
8516 There's a private method, -[CALayer setContentsChanged], that we 8480 There's a private method, -[CALayer setContentsChanged], that we
8517 could use to force it, but we shouldn't often get the same 8481 could use to force it, but we shouldn't often get the same
8518 surface twice in a row. */ 8482 surface twice in a row. */
8483 [surface releaseContext];
8519 [[self layer] setContents:(id)[surface getSurface]]; 8484 [[self layer] setContents:(id)[surface getSurface]];
8485 [surface performSelectorOnMainThread:@selector (getContext)
8486 withObject:nil
8487 waitUntilDone:NO];
8520} 8488}
8521#endif 8489#endif
8522 8490
@@ -9717,17 +9685,20 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9717 probably be some sort of pruning job that removes excess 9685 probably be some sort of pruning job that removes excess
9718 surfaces. */ 9686 surfaces. */
9719 9687
9688#define CACHE_MAX_SIZE 2
9720 9689
9721- (id) initWithSize: (NSSize)s 9690- (id) initWithSize: (NSSize)s
9722 ColorSpace: (CGColorSpaceRef)cs 9691 ColorSpace: (CGColorSpaceRef)cs
9692 Scale: (CGFloat)scl
9723{ 9693{
9724 NSTRACE ("[EmacsSurface initWithSize:ColorSpace:]"); 9694 NSTRACE ("[EmacsSurface initWithSize:ColorSpace:]");
9725 9695
9726 [super init]; 9696 [super init];
9727 9697
9728 cache = [[NSMutableArray arrayWithCapacity:3] retain]; 9698 cache = [[NSMutableArray arrayWithCapacity:CACHE_MAX_SIZE] retain];
9729 size = s; 9699 size = s;
9730 colorSpace = cs; 9700 colorSpace = cs;
9701 scale = scl;
9731 9702
9732 return self; 9703 return self;
9733} 9704}
@@ -9740,8 +9711,6 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9740 9711
9741 if (currentSurface) 9712 if (currentSurface)
9742 CFRelease (currentSurface); 9713 CFRelease (currentSurface);
9743 if (lastSurface)
9744 CFRelease (lastSurface);
9745 9714
9746 for (id object in cache) 9715 for (id object in cache)
9747 CFRelease ((IOSurfaceRef)object); 9716 CFRelease ((IOSurfaceRef)object);
@@ -9764,50 +9733,66 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9764 calls cannot be nested. */ 9733 calls cannot be nested. */
9765- (CGContextRef) getContext 9734- (CGContextRef) getContext
9766{ 9735{
9767 IOSurfaceRef surface = NULL; 9736 NSTRACE ("[EmacsSurface getContext]");
9768
9769 NSTRACE ("[EmacsSurface getContextWithSize:]");
9770 NSTRACE_MSG ("IOSurface count: %lu", [cache count] + (lastSurface ? 1 : 0));
9771 9737
9772 for (id object in cache) 9738 if (!context)
9773 { 9739 {
9774 if (!IOSurfaceIsInUse ((IOSurfaceRef)object)) 9740 IOSurfaceRef surface = NULL;
9775 {
9776 surface = (IOSurfaceRef)object;
9777 [cache removeObject:object];
9778 break;
9779 }
9780 }
9781 9741
9782 if (!surface) 9742 NSTRACE_MSG ("IOSurface count: %lu", [cache count] + (lastSurface ? 1 : 0));
9783 {
9784 int bytesPerRow = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow,
9785 size.width * 4);
9786 9743
9787 surface = IOSurfaceCreate 9744 for (id object in cache)
9788 ((CFDictionaryRef)@{(id)kIOSurfaceWidth:[NSNumber numberWithInt:size.width], 9745 {
9789 (id)kIOSurfaceHeight:[NSNumber numberWithInt:size.height], 9746 if (!IOSurfaceIsInUse ((IOSurfaceRef)object))
9790 (id)kIOSurfaceBytesPerRow:[NSNumber numberWithInt:bytesPerRow], 9747 {
9791 (id)kIOSurfaceBytesPerElement:[NSNumber numberWithInt:4], 9748 surface = (IOSurfaceRef)object;
9792 (id)kIOSurfacePixelFormat:[NSNumber numberWithUnsignedInt:'BGRA']}); 9749 [cache removeObject:object];
9793 } 9750 break;
9751 }
9752 }
9794 9753
9795 IOReturn lockStatus = IOSurfaceLock (surface, 0, nil); 9754 if (!surface && [cache count] >= CACHE_MAX_SIZE)
9796 if (lockStatus != kIOReturnSuccess) 9755 {
9797 NSLog (@"Failed to lock surface: %x", lockStatus); 9756 /* Just grab the first one off the cache. This may result
9757 in tearing effects. The alternative is to wait for one
9758 of the surfaces to become free. */
9759 surface = (IOSurfaceRef)[cache firstObject];
9760 [cache removeObject:(id)surface];
9761 }
9762 else if (!surface)
9763 {
9764 int bytesPerRow = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow,
9765 size.width * 4);
9766
9767 surface = IOSurfaceCreate
9768 ((CFDictionaryRef)@{(id)kIOSurfaceWidth:[NSNumber numberWithInt:size.width],
9769 (id)kIOSurfaceHeight:[NSNumber numberWithInt:size.height],
9770 (id)kIOSurfaceBytesPerRow:[NSNumber numberWithInt:bytesPerRow],
9771 (id)kIOSurfaceBytesPerElement:[NSNumber numberWithInt:4],
9772 (id)kIOSurfacePixelFormat:[NSNumber numberWithUnsignedInt:'BGRA']});
9773 }
9774
9775 IOReturn lockStatus = IOSurfaceLock (surface, 0, nil);
9776 if (lockStatus != kIOReturnSuccess)
9777 NSLog (@"Failed to lock surface: %x", lockStatus);
9798 9778
9799 [self copyContentsTo:surface]; 9779 [self copyContentsTo:surface];
9800 9780
9801 currentSurface = surface; 9781 currentSurface = surface;
9782
9783 context = CGBitmapContextCreate (IOSurfaceGetBaseAddress (currentSurface),
9784 IOSurfaceGetWidth (currentSurface),
9785 IOSurfaceGetHeight (currentSurface),
9786 8,
9787 IOSurfaceGetBytesPerRow (currentSurface),
9788 colorSpace,
9789 (kCGImageAlphaPremultipliedFirst
9790 | kCGBitmapByteOrder32Host));
9791
9792 CGContextTranslateCTM(context, 0, size.height);
9793 CGContextScaleCTM(context, scale, -scale);
9794 }
9802 9795
9803 context = CGBitmapContextCreate (IOSurfaceGetBaseAddress (currentSurface),
9804 IOSurfaceGetWidth (currentSurface),
9805 IOSurfaceGetHeight (currentSurface),
9806 8,
9807 IOSurfaceGetBytesPerRow (currentSurface),
9808 colorSpace,
9809 (kCGImageAlphaPremultipliedFirst
9810 | kCGBitmapByteOrder32Host));
9811 return context; 9796 return context;
9812} 9797}
9813 9798
@@ -9818,6 +9803,9 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9818{ 9803{
9819 NSTRACE ("[EmacsSurface releaseContextAndGetSurface]"); 9804 NSTRACE ("[EmacsSurface releaseContextAndGetSurface]");
9820 9805
9806 if (!context)
9807 return;
9808
9821 CGContextRelease (context); 9809 CGContextRelease (context);
9822 context = NULL; 9810 context = NULL;
9823 9811
@@ -9825,11 +9813,8 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9825 if (lockStatus != kIOReturnSuccess) 9813 if (lockStatus != kIOReturnSuccess)
9826 NSLog (@"Failed to unlock surface: %x", lockStatus); 9814 NSLog (@"Failed to unlock surface: %x", lockStatus);
9827 9815
9828 /* Put lastSurface back on the end of the cache. It may not have 9816 /* Put currentSurface back on the end of the cache. */
9829 been displayed on the screen yet, but we probably want the new 9817 [cache addObject:(id)currentSurface];
9830 data and not some stale data anyway. */
9831 if (lastSurface)
9832 [cache addObject:(id)lastSurface];
9833 lastSurface = currentSurface; 9818 lastSurface = currentSurface;
9834 currentSurface = NULL; 9819 currentSurface = NULL;
9835} 9820}
@@ -9854,7 +9839,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9854 9839
9855 NSTRACE ("[EmacsSurface copyContentsTo:]"); 9840 NSTRACE ("[EmacsSurface copyContentsTo:]");
9856 9841
9857 if (! lastSurface) 9842 if (!lastSurface || lastSurface == destination)
9858 return; 9843 return;
9859 9844
9860 lockStatus = IOSurfaceLock (lastSurface, kIOSurfaceLockReadOnly, nil); 9845 lockStatus = IOSurfaceLock (lastSurface, kIOSurfaceLockReadOnly, nil);
@@ -9874,6 +9859,7 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
9874 NSLog (@"Failed to unlock source surface: %x", lockStatus); 9859 NSLog (@"Failed to unlock source surface: %x", lockStatus);
9875} 9860}
9876 9861
9862#undef CACHE_MAX_SIZE
9877 9863
9878@end /* EmacsSurface */ 9864@end /* EmacsSurface */
9879 9865
diff --git a/src/window.c b/src/window.c
index 9961c54161d..db324effcce 100644
--- a/src/window.c
+++ b/src/window.c
@@ -468,6 +468,7 @@ Return WINDOW. */)
468 else 468 else
469 { 469 {
470 fset_selected_window (XFRAME (frame), window); 470 fset_selected_window (XFRAME (frame), window);
471 /* Don't clear FRAME's select_mini_window_flag here. */
471 return window; 472 return window;
472 } 473 }
473} 474}
@@ -517,6 +518,9 @@ select_window (Lisp_Object window, Lisp_Object norecord,
517 /* Do not select a tooltip window (Bug#47207). */ 518 /* Do not select a tooltip window (Bug#47207). */
518 error ("Cannot select a tooltip window"); 519 error ("Cannot select a tooltip window");
519 520
521 /* We deinitely want to select WINDOW, not the mini-window. */
522 f->select_mini_window_flag = false;
523
520 /* Make the selected window's buffer current. */ 524 /* Make the selected window's buffer current. */
521 Fset_buffer (w->contents); 525 Fset_buffer (w->contents);
522 526
@@ -3242,6 +3246,9 @@ window-start value is reasonable when this function is called. */)
3242 if (EQ (selected_frame, w->frame)) 3246 if (EQ (selected_frame, w->frame))
3243 Fselect_window (window, Qnil); 3247 Fselect_window (window, Qnil);
3244 else 3248 else
3249 /* Do not clear f->select_mini_window_flag here. If the
3250 last selected window on F was an active minibuffer, we
3251 want to return to it on a later Fselect_frame. */
3245 fset_selected_window (f, window); 3252 fset_selected_window (f, window);
3246 } 3253 }
3247 } 3254 }
@@ -5141,37 +5148,23 @@ Signal an error when WINDOW is the only window on its frame. */)
5141 adjust_frame_glyphs (f); 5148 adjust_frame_glyphs (f);
5142 5149
5143 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f))) 5150 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
5144 /* We deleted the frame's selected window. */ 5151 /* We apparently deleted the frame's selected window; use the
5152 frame's first window as substitute but don't record it yet.
5153 `delete-window' may have something better up its sleeves. */
5145 { 5154 {
5146 /* Use the frame's first window as fallback ... */ 5155 /* Use the frame's first window as fallback ... */
5147 Lisp_Object new_selected_window = Fframe_first_window (frame); 5156 Lisp_Object new_selected_window = Fframe_first_window (frame);
5148 /* ... but preferably use its most recently used window. */
5149 Lisp_Object mru_window;
5150 5157
5151 /* `get-mru-window' might fail for some reason so play it safe
5152 - promote the first window _without recording it_ first. */
5153 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) 5158 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
5154 Fselect_window (new_selected_window, Qt); 5159 Fselect_window (new_selected_window, Qt);
5155 else 5160 else
5156 fset_selected_window (f, new_selected_window); 5161 /* Do not clear f->select_mini_window_flag here. If the
5157 5162 last selected window on F was an active minibuffer, we
5158 unblock_input (); 5163 want to return to it on a later Fselect_frame. */
5159
5160 /* Now look whether `get-mru-window' gets us something. */
5161 mru_window = call1 (Qget_mru_window, frame);
5162 if (WINDOW_LIVE_P (mru_window)
5163 && EQ (XWINDOW (mru_window)->frame, frame))
5164 new_selected_window = mru_window;
5165
5166 /* If all ended up well, we now promote the mru window. */
5167 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
5168 Fselect_window (new_selected_window, Qnil);
5169 else
5170 fset_selected_window (f, new_selected_window); 5164 fset_selected_window (f, new_selected_window);
5171 } 5165 }
5172 else
5173 unblock_input ();
5174 5166
5167 unblock_input ();
5175 FRAME_WINDOW_CHANGE (f) = true; 5168 FRAME_WINDOW_CHANGE (f) = true;
5176 } 5169 }
5177 else 5170 else
diff --git a/src/xdisp.c b/src/xdisp.c
index 74fa0a57e44..e95e64a24cd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10795,6 +10795,9 @@ include the height of both, if present, in the return value. */)
10795 it.max_descent = max (it.max_descent, it.descent); 10795 it.max_descent = max (it.max_descent, it.descent);
10796 } 10796 }
10797 } 10797 }
10798 else
10799 bidi_unshelve_cache (it2data, true);
10800
10798 if (!NILP (x_limit)) 10801 if (!NILP (x_limit))
10799 { 10802 {
10800 /* Don't return more than X-LIMIT. */ 10803 /* Don't return more than X-LIMIT. */
@@ -22386,15 +22389,23 @@ extend_face_to_end_of_line (struct it *it)
22386 it->face_id = (it->glyph_row->ends_at_zv_p ? 22389 it->face_id = (it->glyph_row->ends_at_zv_p ?
22387 default_face->id : face->id); 22390 default_face->id : face->id);
22388 22391
22389 /* Display fill-column indicator if needed. */
22390 const int indicator_column = fill_column_indicator_column (it, 1);
22391
22392 /* Make sure our idea of current_x is in sync with the glyphs 22392 /* Make sure our idea of current_x is in sync with the glyphs
22393 actually in the glyph row. They might differ because 22393 actually in the glyph row. They might differ because
22394 append_space_for_newline can insert one glyph without 22394 append_space_for_newline can insert one glyph without
22395 updating current_x. */ 22395 updating current_x. */
22396 it->current_x = it->glyph_row->used[TEXT_AREA]; 22396 it->current_x = it->glyph_row->used[TEXT_AREA];
22397 22397
22398 /* The above assignment causes the code below to use a
22399 non-standard semantics of it->current_x: it is measured
22400 relative to the beginning of the text-area, thus disregarding
22401 the window's hscroll. That is why we need to correct the
22402 indicator column for the hscroll, otherwise the indicator
22403 will not move together with the text as result of horizontal
22404 scrolling. */
22405 const int indicator_column =
22406 fill_column_indicator_column (it, 1) - it->first_visible_x;
22407
22408 /* Display fill-column indicator if needed. */
22398 while (it->current_x <= it->last_visible_x) 22409 while (it->current_x <= it->last_visible_x)
22399 { 22410 {
22400 if (it->current_x != indicator_column) 22411 if (it->current_x != indicator_column)
@@ -30305,7 +30316,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
30305 30316
30306 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */ 30317 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
30307 width = max (metrics_upper.width, metrics_lower.width) + 4; 30318 width = max (metrics_upper.width, metrics_lower.width) + 4;
30308 upper_xoff = upper_yoff = 2; /* the typical case */ 30319 upper_xoff = lower_xoff = 2; /* the typical case */
30309 if (base_width >= width) 30320 if (base_width >= width)
30310 { 30321 {
30311 /* Align the upper to the left, the lower to the right. */ 30322 /* Align the upper to the left, the lower to the right. */
@@ -30319,13 +30330,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
30319 if (metrics_upper.width >= metrics_lower.width) 30330 if (metrics_upper.width >= metrics_lower.width)
30320 lower_xoff = (width - metrics_lower.width) / 2; 30331 lower_xoff = (width - metrics_lower.width) / 2;
30321 else 30332 else
30322 { 30333 upper_xoff = (width - metrics_upper.width) / 2;
30323 /* FIXME: This code doesn't look right. It formerly was
30324 missing the "lower_xoff = 0;", which couldn't have
30325 been right since it left lower_xoff uninitialized. */
30326 lower_xoff = 0;
30327 upper_xoff = (width - metrics_upper.width) / 2;
30328 }
30329 } 30334 }
30330 30335
30331 /* +5 is for horizontal bars of a box plus 1-pixel spaces at 30336 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
@@ -35660,8 +35665,10 @@ as usual. If the function returns a string, the returned string is
35660displayed in the echo area. If this function returns any other non-nil 35665displayed in the echo area. If this function returns any other non-nil
35661value, this means that the message was already handled, and the original 35666value, this means that the message was already handled, and the original
35662message text will not be displayed in the echo area. 35667message text will not be displayed in the echo area.
35663See also `clear-message-function' that can be used to clear the 35668
35664message displayed by this function. */); 35669Also see `clear-message-function' (which can be used to clear the
35670message displayed by this function), and `command-error-function'
35671(which controls how error messages are displayed). */);
35665 Vset_message_function = Qnil; 35672 Vset_message_function = Qnil;
35666 35673
35667 DEFVAR_LISP ("clear-message-function", Vclear_message_function, 35674 DEFVAR_LISP ("clear-message-function", Vclear_message_function,