diff options
| author | Yuuki Harano | 2021-06-13 17:34:06 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-06-13 17:34:06 +0900 |
| commit | 7d5e94bada09e642a8bfc4f66804f7948bad40bc (patch) | |
| tree | 38629672102b31bb38a855f24d4dd009e212c10d /src | |
| parent | 7673b6b9eb0af3add73e1614a466f142092b00aa (diff) | |
| parent | dc471feee3bcac872cc52cdc73282955cd2d219d (diff) | |
| download | emacs-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.c | 16 | ||||
| -rw-r--r-- | src/character.h | 2 | ||||
| -rw-r--r-- | src/composite.c | 76 | ||||
| -rw-r--r-- | src/composite.h | 23 | ||||
| -rw-r--r-- | src/data.c | 4 | ||||
| -rw-r--r-- | src/editfns.c | 2 | ||||
| -rw-r--r-- | src/frame.c | 12 | ||||
| -rw-r--r-- | src/frame.h | 5 | ||||
| -rw-r--r-- | src/image.c | 23 | ||||
| -rw-r--r-- | src/keyboard.c | 122 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/nsfns.m | 16 | ||||
| -rw-r--r-- | src/nsimage.m | 9 | ||||
| -rw-r--r-- | src/nsterm.h | 6 | ||||
| -rw-r--r-- | src/nsterm.m | 158 | ||||
| -rw-r--r-- | src/window.c | 35 | ||||
| -rw-r--r-- | src/xdisp.c | 33 |
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 | ||
| 334 | ptrdiff_t | 335 | ptrdiff_t |
| 335 | lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, | 336 | lisp_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); | |||
| 573 | extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, | 573 | extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, |
| 574 | ptrdiff_t *, ptrdiff_t *); | 574 | ptrdiff_t *, ptrdiff_t *); |
| 575 | extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t, | 575 | extern 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 | ||
| 578 | extern Lisp_Object Vchar_unify_table; | 578 | extern Lisp_Object Vchar_unify_table; |
| 579 | extern Lisp_Object string_escape_byte8 (Lisp_Object); | 579 | extern 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 | ||
| 1482 | bool | 1528 | bool |
| 1483 | find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, | 1529 | find_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); | |||
| 320 | extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t, | 337 | extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 321 | struct font_metrics *); | 338 | struct font_metrics *); |
| 322 | 339 | ||
| 323 | extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *, | 340 | extern 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 | ||
| 327 | extern void composition_compute_stop_pos (struct composition_it *, | 344 | extern 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. */) | |||
| 2200 | DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p, | 2200 | DEFUN ("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. |
| 2203 | BUFFER defaults to the current buffer. */) | 2203 | BUFFER defaults to the current buffer. |
| 2204 | |||
| 2205 | Also 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 | ||
| 3302 | Lisp_Object | 3299 | Lisp_Object |
| 3303 | image_find_image_file (Lisp_Object file) | 3300 | image_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 | ||
| 5022 | static Lisp_Object button_down_location; | 5042 | static 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. */ | ||
| 5046 | static 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'. */) | |||
| 11047 | DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0, | 11103 | DEFUN ("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. |
| 11049 | If META is t, Emacs will accept 8-bit input, and interpret the 8th | 11105 | If META is t, Emacs will accept 8-bit input, and interpret the 8th |
| 11050 | bit as the Meta modifier. | 11106 | bit as the Meta modifier before it decodes the characters. |
| 11107 | |||
| 11108 | If META is `encoded', Emacs will interpret the 8th bit of single-byte | ||
| 11109 | characters after decoding the characters. | ||
| 11051 | 11110 | ||
| 11052 | If META is nil, Emacs will ignore the top bit, on the assumption it is | 11111 | If META is nil, Emacs will ignore the top bit, on the assumption it is |
| 11053 | parity. | 11112 | parity. |
| @@ -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). |
| 11139 | Third arg META t means accept 8-bit input (for a Meta key). | 11200 | Third 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. |
| 11142 | Optional fourth arg QUIT if non-nil specifies character to use for quitting. | 11205 | Optional fourth arg QUIT if non-nil specifies character to use for quitting. |
| 11143 | See also `current-input-mode'. */) | 11206 | See 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. |
| 11166 | The elements of this list correspond to the arguments of | 11232 | The 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 | |||
| 12349 | Also see `set-message-function' (which controls how non-error messages | ||
| 12350 | are 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. |
| 1954 | Otherwise if Emacs is hidden, it is unhidden. | 1954 | Otherwise if Emacs is hidden, it is unhidden. |
| 1955 | If ON is equal to `activate', Emacs is unhidden and becomes | 1955 | If ON is equal to `activate', Emacs is unhidden and becomes |
| 1956 | the active application. */) | 1956 | the active application. |
| 1957 | (Lisp_Object on) | 1957 | If ON is equal to `activate-front', Emacs is unhidden and |
| 1958 | becomes the active application, but only the selected frame | ||
| 1959 | is 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 | |||
| 35660 | displayed in the echo area. If this function returns any other non-nil | 35665 | displayed in the echo area. If this function returns any other non-nil |
| 35661 | value, this means that the message was already handled, and the original | 35666 | value, this means that the message was already handled, and the original |
| 35662 | message text will not be displayed in the echo area. | 35667 | message text will not be displayed in the echo area. |
| 35663 | See also `clear-message-function' that can be used to clear the | 35668 | |
| 35664 | message displayed by this function. */); | 35669 | Also see `clear-message-function' (which can be used to clear the |
| 35670 | message 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, |