diff options
| author | Andrea Corallo | 2021-04-19 18:46:50 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2021-04-19 18:46:50 +0200 |
| commit | b5c76530fab4b99e76249bfb9a105b30bef4ce67 (patch) | |
| tree | 319d7a65b6f818cebed9833534a423fbcb79a9b5 /src | |
| parent | e54066f3d459f67a1ee4e44552bf0356d010e03f (diff) | |
| parent | 0a4dc70830f5e8286b47120cabc750cca07a75c1 (diff) | |
| download | emacs-b5c76530fab4b99e76249bfb9a105b30bef4ce67.tar.gz emacs-b5c76530fab4b99e76249bfb9a105b30bef4ce67.zip | |
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 2 | ||||
| -rw-r--r-- | src/character.c | 56 | ||||
| -rw-r--r-- | src/character.h | 4 | ||||
| -rw-r--r-- | src/editfns.c | 9 | ||||
| -rw-r--r-- | src/eval.c | 34 | ||||
| -rw-r--r-- | src/frame.c | 16 | ||||
| -rw-r--r-- | src/image.c | 58 | ||||
| -rw-r--r-- | src/minibuf.c | 38 | ||||
| -rw-r--r-- | src/w32fns.c | 2 | ||||
| -rw-r--r-- | src/w32term.c | 20 | ||||
| -rw-r--r-- | src/window.c | 71 | ||||
| -rw-r--r-- | src/window.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 129 | ||||
| -rw-r--r-- | src/xfns.c | 2 | ||||
| -rw-r--r-- | src/xselect.c | 21 |
15 files changed, 359 insertions, 104 deletions
diff --git a/src/alloc.c b/src/alloc.c index fee8cc08aa4..76d8c7ddd11 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -6268,7 +6268,7 @@ For further details, see Info node `(elisp)Garbage Collection'. */) | |||
| 6268 | } | 6268 | } |
| 6269 | 6269 | ||
| 6270 | DEFUN ("garbage-collect-maybe", Fgarbage_collect_maybe, | 6270 | DEFUN ("garbage-collect-maybe", Fgarbage_collect_maybe, |
| 6271 | Sgarbage_collect_maybe, 1, 1, "", | 6271 | Sgarbage_collect_maybe, 1, 1, 0, |
| 6272 | doc: /* Call `garbage-collect' if enough allocation happened. | 6272 | doc: /* Call `garbage-collect' if enough allocation happened. |
| 6273 | FACTOR determines what "enough" means here: | 6273 | FACTOR determines what "enough" means here: |
| 6274 | If FACTOR is a positive number N, it means to run GC if more than | 6274 | If FACTOR is a positive number N, it means to run GC if more than |
diff --git a/src/character.c b/src/character.c index a599a0355f4..41abb83a48b 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -321,28 +321,32 @@ strwidth (const char *str, ptrdiff_t len) | |||
| 321 | return c_string_width ((const unsigned char *) str, len, -1, NULL, NULL); | 321 | return c_string_width ((const unsigned char *) str, len, -1, NULL, NULL); |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | /* Return width of Lisp string STRING when displayed in the current | 324 | /* Return width of a (substring of a) Lisp string STRING when |
| 325 | buffer. The width is measured by how many columns it occupies on | 325 | displayed in the current buffer. The width is measured by how many |
| 326 | the screen while paying attention to compositions. If PRECISION > | 326 | columns it occupies on the screen while paying attention to |
| 327 | 0, return the width of longest substring that doesn't exceed | 327 | compositions. If PRECISION > 0, return the width of longest |
| 328 | PRECISION, and set number of characters and bytes of the substring | 328 | substring that doesn't exceed PRECISION, and set number of |
| 329 | in *NCHARS and *NBYTES respectively. */ | 329 | characters and bytes of the substring in *NCHARS and *NBYTES |
| 330 | respectively. FROM and TO are zero-based character indices | ||
| 331 | that define the substring of STRING to consider. */ | ||
| 330 | 332 | ||
| 331 | ptrdiff_t | 333 | ptrdiff_t |
| 332 | lisp_string_width (Lisp_Object string, ptrdiff_t precision, | 334 | lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, |
| 333 | ptrdiff_t *nchars, ptrdiff_t *nbytes) | 335 | ptrdiff_t precision, ptrdiff_t *nchars, ptrdiff_t *nbytes) |
| 334 | { | 336 | { |
| 335 | ptrdiff_t len = SCHARS (string); | ||
| 336 | /* This set multibyte to 0 even if STRING is multibyte when it | 337 | /* This set multibyte to 0 even if STRING is multibyte when it |
| 337 | contains only ascii and eight-bit-graphic, but that's | 338 | contains only ascii and eight-bit-graphic, but that's |
| 338 | intentional. */ | 339 | intentional. */ |
| 339 | bool multibyte = len < SBYTES (string); | 340 | bool multibyte = SCHARS (string) < SBYTES (string); |
| 340 | unsigned char *str = SDATA (string); | 341 | unsigned char *str = SDATA (string); |
| 341 | ptrdiff_t i = 0, i_byte = 0; | 342 | ptrdiff_t i = from, i_byte = from ? string_char_to_byte (string, from) : 0; |
| 343 | ptrdiff_t from_byte = i_byte; | ||
| 342 | ptrdiff_t width = 0; | 344 | ptrdiff_t width = 0; |
| 343 | struct Lisp_Char_Table *dp = buffer_display_table (); | 345 | struct Lisp_Char_Table *dp = buffer_display_table (); |
| 344 | 346 | ||
| 345 | while (i < len) | 347 | eassert (precision <= 0 || (nchars && nbytes)); |
| 348 | |||
| 349 | while (i < to) | ||
| 346 | { | 350 | { |
| 347 | ptrdiff_t chars, bytes, thiswidth; | 351 | ptrdiff_t chars, bytes, thiswidth; |
| 348 | Lisp_Object val; | 352 | Lisp_Object val; |
| @@ -375,8 +379,8 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, | |||
| 375 | 379 | ||
| 376 | if (0 < precision && precision - width < thiswidth) | 380 | if (0 < precision && precision - width < thiswidth) |
| 377 | { | 381 | { |
| 378 | *nchars = i; | 382 | *nchars = i - from; |
| 379 | *nbytes = i_byte; | 383 | *nbytes = i_byte - from_byte; |
| 380 | return width; | 384 | return width; |
| 381 | } | 385 | } |
| 382 | if (INT_ADD_WRAPV (thiswidth, width, &width)) | 386 | if (INT_ADD_WRAPV (thiswidth, width, &width)) |
| @@ -387,27 +391,37 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, | |||
| 387 | 391 | ||
| 388 | if (precision > 0) | 392 | if (precision > 0) |
| 389 | { | 393 | { |
| 390 | *nchars = i; | 394 | *nchars = i - from; |
| 391 | *nbytes = i_byte; | 395 | *nbytes = i_byte - from_byte; |
| 392 | } | 396 | } |
| 393 | 397 | ||
| 394 | return width; | 398 | return width; |
| 395 | } | 399 | } |
| 396 | 400 | ||
| 397 | DEFUN ("string-width", Fstring_width, Sstring_width, 1, 1, 0, | 401 | DEFUN ("string-width", Fstring_width, Sstring_width, 1, 3, 0, |
| 398 | doc: /* Return width of STRING when displayed in the current buffer. | 402 | doc: /* Return width of STRING when displayed in the current buffer. |
| 399 | Width is measured by how many columns it occupies on the screen. | 403 | Width is measured by how many columns it occupies on the screen. |
| 404 | Optional arguments FROM and TO specify the substring of STRING to | ||
| 405 | consider, and are interpreted as in `substring'. | ||
| 406 | |||
| 400 | When calculating width of a multibyte character in STRING, | 407 | When calculating width of a multibyte character in STRING, |
| 401 | only the base leading-code is considered; the validity of | 408 | only the base leading-code is considered; the validity of |
| 402 | the following bytes is not checked. Tabs in STRING are always | 409 | the following bytes is not checked. Tabs in STRING are always |
| 403 | taken to occupy `tab-width' columns. | 410 | taken to occupy `tab-width' columns. The effect of faces and fonts |
| 404 | usage: (string-width STRING) */) | 411 | used for non-Latin and other unusual characters (such as emoji) is |
| 405 | (Lisp_Object str) | 412 | ignored as well, as are display properties and invisible text. |
| 413 | For these reasons, the results are not generally reliable; | ||
| 414 | for accurate dimensions of text as it will be displayed, | ||
| 415 | use `window-text-pixel-size' instead. | ||
| 416 | usage: (string-width STRING &optional FROM TO) */) | ||
| 417 | (Lisp_Object str, Lisp_Object from, Lisp_Object to) | ||
| 406 | { | 418 | { |
| 407 | Lisp_Object val; | 419 | Lisp_Object val; |
| 420 | ptrdiff_t ifrom, ito; | ||
| 408 | 421 | ||
| 409 | CHECK_STRING (str); | 422 | CHECK_STRING (str); |
| 410 | XSETFASTINT (val, lisp_string_width (str, -1, NULL, NULL)); | 423 | validate_subarray (str, from, to, SCHARS (str), &ifrom, &ito); |
| 424 | XSETFASTINT (val, lisp_string_width (str, ifrom, ito, -1, NULL, NULL)); | ||
| 411 | return val; | 425 | return val; |
| 412 | } | 426 | } |
| 413 | 427 | ||
diff --git a/src/character.h b/src/character.h index cbf43097ae2..d19e1e2604c 100644 --- a/src/character.h +++ b/src/character.h | |||
| @@ -572,8 +572,8 @@ extern ptrdiff_t str_to_unibyte (const unsigned char *, unsigned char *, | |||
| 572 | extern ptrdiff_t strwidth (const char *, ptrdiff_t); | 572 | 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, | 575 | extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 576 | ptrdiff_t *, ptrdiff_t *); | 576 | ptrdiff_t, ptrdiff_t *, ptrdiff_t *); |
| 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/editfns.c b/src/editfns.c index 87e743afc31..bc73c1e2c5b 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3386,12 +3386,11 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 3386 | else | 3386 | else |
| 3387 | { | 3387 | { |
| 3388 | ptrdiff_t nch, nby; | 3388 | ptrdiff_t nch, nby; |
| 3389 | width = lisp_string_width (arg, prec, &nch, &nby); | 3389 | nchars_string = SCHARS (arg); |
| 3390 | width = lisp_string_width (arg, 0, nchars_string, prec, | ||
| 3391 | &nch, &nby); | ||
| 3390 | if (prec < 0) | 3392 | if (prec < 0) |
| 3391 | { | 3393 | nbytes = SBYTES (arg); |
| 3392 | nchars_string = SCHARS (arg); | ||
| 3393 | nbytes = SBYTES (arg); | ||
| 3394 | } | ||
| 3395 | else | 3394 | else |
| 3396 | { | 3395 | { |
| 3397 | nchars_string = nch; | 3396 | nchars_string = nch; |
diff --git a/src/eval.c b/src/eval.c index cf5ca3b4bbd..aeedcc50cc0 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1310,7 +1310,7 @@ DEFUN ("condition-case", Fcondition_case, Scondition_case, 2, UNEVALLED, 0, | |||
| 1310 | doc: /* Regain control when an error is signaled. | 1310 | doc: /* Regain control when an error is signaled. |
| 1311 | Executes BODYFORM and returns its value if no error happens. | 1311 | Executes BODYFORM and returns its value if no error happens. |
| 1312 | Each element of HANDLERS looks like (CONDITION-NAME BODY...) | 1312 | Each element of HANDLERS looks like (CONDITION-NAME BODY...) |
| 1313 | where the BODY is made of Lisp expressions. | 1313 | or (:success BODY...), where the BODY is made of Lisp expressions. |
| 1314 | 1314 | ||
| 1315 | A handler is applicable to an error if CONDITION-NAME is one of the | 1315 | A handler is applicable to an error if CONDITION-NAME is one of the |
| 1316 | error's condition names. Handlers may also apply when non-error | 1316 | error's condition names. Handlers may also apply when non-error |
| @@ -1332,6 +1332,10 @@ with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error. | |||
| 1332 | Then the value of the last BODY form is returned from the `condition-case' | 1332 | Then the value of the last BODY form is returned from the `condition-case' |
| 1333 | expression. | 1333 | expression. |
| 1334 | 1334 | ||
| 1335 | The special handler (:success BODY...) is invoked if BODYFORM terminated | ||
| 1336 | without signalling an error. BODY is then evaluated with VAR bound to | ||
| 1337 | the value returned by BODYFORM. | ||
| 1338 | |||
| 1335 | See also the function `signal' for more info. | 1339 | See also the function `signal' for more info. |
| 1336 | usage: (condition-case VAR BODYFORM &rest HANDLERS) */) | 1340 | usage: (condition-case VAR BODYFORM &rest HANDLERS) */) |
| 1337 | (Lisp_Object args) | 1341 | (Lisp_Object args) |
| @@ -1355,16 +1359,21 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1355 | 1359 | ||
| 1356 | CHECK_SYMBOL (var); | 1360 | CHECK_SYMBOL (var); |
| 1357 | 1361 | ||
| 1362 | Lisp_Object success_handler = Qnil; | ||
| 1363 | |||
| 1358 | for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) | 1364 | for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) |
| 1359 | { | 1365 | { |
| 1360 | Lisp_Object tem = XCAR (tail); | 1366 | Lisp_Object tem = XCAR (tail); |
| 1361 | clausenb++; | ||
| 1362 | if (! (NILP (tem) | 1367 | if (! (NILP (tem) |
| 1363 | || (CONSP (tem) | 1368 | || (CONSP (tem) |
| 1364 | && (SYMBOLP (XCAR (tem)) | 1369 | && (SYMBOLP (XCAR (tem)) |
| 1365 | || CONSP (XCAR (tem)))))) | 1370 | || CONSP (XCAR (tem)))))) |
| 1366 | error ("Invalid condition handler: %s", | 1371 | error ("Invalid condition handler: %s", |
| 1367 | SDATA (Fprin1_to_string (tem, Qt))); | 1372 | SDATA (Fprin1_to_string (tem, Qt))); |
| 1373 | if (EQ (XCAR (tem), QCsuccess)) | ||
| 1374 | success_handler = XCDR (tem); | ||
| 1375 | else | ||
| 1376 | clausenb++; | ||
| 1368 | } | 1377 | } |
| 1369 | 1378 | ||
| 1370 | /* The first clause is the one that should be checked first, so it | 1379 | /* The first clause is the one that should be checked first, so it |
| @@ -1378,7 +1387,8 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1378 | Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses); | 1387 | Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses); |
| 1379 | clauses += clausenb; | 1388 | clauses += clausenb; |
| 1380 | for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) | 1389 | for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) |
| 1381 | *--clauses = XCAR (tail); | 1390 | if (!EQ (XCAR (XCAR (tail)), QCsuccess)) |
| 1391 | *--clauses = XCAR (tail); | ||
| 1382 | for (ptrdiff_t i = 0; i < clausenb; i++) | 1392 | for (ptrdiff_t i = 0; i < clausenb; i++) |
| 1383 | { | 1393 | { |
| 1384 | Lisp_Object clause = clauses[i]; | 1394 | Lisp_Object clause = clauses[i]; |
| @@ -1418,6 +1428,23 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1418 | 1428 | ||
| 1419 | Lisp_Object result = eval_sub (bodyform); | 1429 | Lisp_Object result = eval_sub (bodyform); |
| 1420 | handlerlist = oldhandlerlist; | 1430 | handlerlist = oldhandlerlist; |
| 1431 | if (!NILP (success_handler)) | ||
| 1432 | { | ||
| 1433 | if (NILP (var)) | ||
| 1434 | return Fprogn (success_handler); | ||
| 1435 | |||
| 1436 | Lisp_Object handler_var = var; | ||
| 1437 | if (!NILP (Vinternal_interpreter_environment)) | ||
| 1438 | { | ||
| 1439 | result = Fcons (Fcons (var, result), | ||
| 1440 | Vinternal_interpreter_environment); | ||
| 1441 | handler_var = Qinternal_interpreter_environment; | ||
| 1442 | } | ||
| 1443 | |||
| 1444 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 1445 | specbind (handler_var, result); | ||
| 1446 | return unbind_to (count, Fprogn (success_handler)); | ||
| 1447 | } | ||
| 1421 | return result; | 1448 | return result; |
| 1422 | } | 1449 | } |
| 1423 | 1450 | ||
| @@ -4490,6 +4517,7 @@ alist of active lexical bindings. */); | |||
| 4490 | defsubr (&Sthrow); | 4517 | defsubr (&Sthrow); |
| 4491 | defsubr (&Sunwind_protect); | 4518 | defsubr (&Sunwind_protect); |
| 4492 | defsubr (&Scondition_case); | 4519 | defsubr (&Scondition_case); |
| 4520 | DEFSYM (QCsuccess, ":success"); | ||
| 4493 | defsubr (&Ssignal); | 4521 | defsubr (&Ssignal); |
| 4494 | defsubr (&Scommandp); | 4522 | defsubr (&Scommandp); |
| 4495 | defsubr (&Sautoload); | 4523 | defsubr (&Sautoload); |
diff --git a/src/frame.c b/src/frame.c index bbdc3b55992..097cd555c64 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -1384,7 +1384,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor | |||
| 1384 | especially when deleting the initial frame during startup. */ | 1384 | especially when deleting the initial frame during startup. */ |
| 1385 | CHECK_FRAME (frame); | 1385 | CHECK_FRAME (frame); |
| 1386 | f = XFRAME (frame); | 1386 | f = XFRAME (frame); |
| 1387 | if (!FRAME_LIVE_P (f)) | 1387 | /* Silently ignore dead and tooltip frames (Bug#47207). */ |
| 1388 | if (!FRAME_LIVE_P (f) || FRAME_TOOLTIP_P (f)) | ||
| 1388 | return Qnil; | 1389 | return Qnil; |
| 1389 | else if (f == sf) | 1390 | else if (f == sf) |
| 1390 | return frame; | 1391 | return frame; |
| @@ -1508,7 +1509,16 @@ redisplay will display FRAME. | |||
| 1508 | This function returns FRAME, or nil if FRAME has been deleted. */) | 1509 | This function returns FRAME, or nil if FRAME has been deleted. */) |
| 1509 | (Lisp_Object frame, Lisp_Object norecord) | 1510 | (Lisp_Object frame, Lisp_Object norecord) |
| 1510 | { | 1511 | { |
| 1511 | return do_switch_frame (frame, 1, 0, norecord); | 1512 | struct frame *f; |
| 1513 | |||
| 1514 | CHECK_LIVE_FRAME (frame); | ||
| 1515 | f = XFRAME (frame); | ||
| 1516 | |||
| 1517 | if (FRAME_TOOLTIP_P (f)) | ||
| 1518 | /* Do not select a tooltip frame (Bug#47207). */ | ||
| 1519 | error ("Cannot select a tooltip frame"); | ||
| 1520 | else | ||
| 1521 | return do_switch_frame (frame, 1, 0, norecord); | ||
| 1512 | } | 1522 | } |
| 1513 | 1523 | ||
| 1514 | DEFUN ("handle-switch-frame", Fhandle_switch_frame, | 1524 | DEFUN ("handle-switch-frame", Fhandle_switch_frame, |
| @@ -1523,6 +1533,7 @@ necessarily represent user-visible input focus. */) | |||
| 1523 | /* Preserve prefix arg that the command loop just cleared. */ | 1533 | /* Preserve prefix arg that the command loop just cleared. */ |
| 1524 | kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); | 1534 | kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); |
| 1525 | run_hook (Qmouse_leave_buffer_hook); | 1535 | run_hook (Qmouse_leave_buffer_hook); |
| 1536 | |||
| 1526 | return do_switch_frame (event, 0, 0, Qnil); | 1537 | return do_switch_frame (event, 0, 0, Qnil); |
| 1527 | } | 1538 | } |
| 1528 | 1539 | ||
| @@ -3747,6 +3758,7 @@ window state change flag is reset. */) | |||
| 3747 | DEFUN ("frame-scale-factor", Fframe_scale_factor, Sframe_scale_factor, | 3758 | DEFUN ("frame-scale-factor", Fframe_scale_factor, Sframe_scale_factor, |
| 3748 | 0, 1, 0, | 3759 | 0, 1, 0, |
| 3749 | doc: /* Return FRAMEs scale factor. | 3760 | doc: /* Return FRAMEs scale factor. |
| 3761 | If FRAME is omitted or nil, the selected frame is used. | ||
| 3750 | The scale factor is the amount by which a logical pixel size must be | 3762 | The scale factor is the amount by which a logical pixel size must be |
| 3751 | multiplied to find the real number of pixels. */) | 3763 | multiplied to find the real number of pixels. */) |
| 3752 | (Lisp_Object frame) | 3764 | (Lisp_Object frame) |
diff --git a/src/image.c b/src/image.c index 18126a804f3..f2fb69ab743 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1987,46 +1987,68 @@ scale_image_size (int size, size_t divisor, size_t multiplier) | |||
| 1987 | return INT_MAX; | 1987 | return INT_MAX; |
| 1988 | } | 1988 | } |
| 1989 | 1989 | ||
| 1990 | /* Return a size, in pixels, from the value specified by SYMBOL, which | ||
| 1991 | may be an integer or a pair of the form (VALUE . 'em) where VALUE | ||
| 1992 | is a float that is multiplied by the font size to get the final | ||
| 1993 | dimension. | ||
| 1994 | |||
| 1995 | If the value doesn't exist in the image spec, or is invalid, return | ||
| 1996 | -1. | ||
| 1997 | */ | ||
| 1998 | static int | ||
| 1999 | image_get_dimension (struct image *img, Lisp_Object symbol) | ||
| 2000 | { | ||
| 2001 | Lisp_Object value = image_spec_value (img->spec, symbol, NULL); | ||
| 2002 | |||
| 2003 | if (FIXNATP (value)) | ||
| 2004 | return min (XFIXNAT (value), INT_MAX); | ||
| 2005 | if (CONSP (value) && NUMBERP (CAR (value)) && EQ (Qem, CDR (value))) | ||
| 2006 | return min (img->face_font_size * XFLOATINT (CAR (value)), INT_MAX); | ||
| 2007 | |||
| 2008 | return -1; | ||
| 2009 | } | ||
| 2010 | |||
| 1990 | /* Compute the desired size of an image with native size WIDTH x HEIGHT. | 2011 | /* Compute the desired size of an image with native size WIDTH x HEIGHT. |
| 1991 | Use SPEC to deduce the size. Store the desired size into | 2012 | Use SPEC to deduce the size. Store the desired size into |
| 1992 | *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */ | 2013 | *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */ |
| 1993 | static void | 2014 | static void |
| 1994 | compute_image_size (size_t width, size_t height, | 2015 | compute_image_size (size_t width, size_t height, |
| 1995 | Lisp_Object spec, | 2016 | struct image *img, |
| 1996 | int *d_width, int *d_height) | 2017 | int *d_width, int *d_height) |
| 1997 | { | 2018 | { |
| 1998 | Lisp_Object value; | 2019 | Lisp_Object value; |
| 2020 | int int_value; | ||
| 1999 | int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1; | 2021 | int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1; |
| 2000 | double scale = 1; | 2022 | double scale = 1; |
| 2001 | 2023 | ||
| 2002 | value = image_spec_value (spec, QCscale, NULL); | 2024 | value = image_spec_value (img->spec, QCscale, NULL); |
| 2003 | if (NUMBERP (value)) | 2025 | if (NUMBERP (value)) |
| 2004 | scale = XFLOATINT (value); | 2026 | scale = XFLOATINT (value); |
| 2005 | 2027 | ||
| 2006 | value = image_spec_value (spec, QCmax_width, NULL); | 2028 | int_value = image_get_dimension (img, QCmax_width); |
| 2007 | if (FIXNATP (value)) | 2029 | if (int_value >= 0) |
| 2008 | max_width = min (XFIXNAT (value), INT_MAX); | 2030 | max_width = int_value; |
| 2009 | 2031 | ||
| 2010 | value = image_spec_value (spec, QCmax_height, NULL); | 2032 | int_value = image_get_dimension (img, QCmax_height); |
| 2011 | if (FIXNATP (value)) | 2033 | if (int_value >= 0) |
| 2012 | max_height = min (XFIXNAT (value), INT_MAX); | 2034 | max_height = int_value; |
| 2013 | 2035 | ||
| 2014 | /* If width and/or height is set in the display spec assume we want | 2036 | /* If width and/or height is set in the display spec assume we want |
| 2015 | to scale to those values. If either h or w is unspecified, the | 2037 | to scale to those values. If either h or w is unspecified, the |
| 2016 | unspecified should be calculated from the specified to preserve | 2038 | unspecified should be calculated from the specified to preserve |
| 2017 | aspect ratio. */ | 2039 | aspect ratio. */ |
| 2018 | value = image_spec_value (spec, QCwidth, NULL); | 2040 | int_value = image_get_dimension (img, QCwidth); |
| 2019 | if (FIXNATP (value)) | 2041 | if (int_value >= 0) |
| 2020 | { | 2042 | { |
| 2021 | desired_width = min (XFIXNAT (value) * scale, INT_MAX); | 2043 | desired_width = int_value * scale; |
| 2022 | /* :width overrides :max-width. */ | 2044 | /* :width overrides :max-width. */ |
| 2023 | max_width = -1; | 2045 | max_width = -1; |
| 2024 | } | 2046 | } |
| 2025 | 2047 | ||
| 2026 | value = image_spec_value (spec, QCheight, NULL); | 2048 | int_value = image_get_dimension (img, QCheight); |
| 2027 | if (FIXNATP (value)) | 2049 | if (int_value >= 0) |
| 2028 | { | 2050 | { |
| 2029 | desired_height = min (XFIXNAT (value) * scale, INT_MAX); | 2051 | desired_height = int_value * scale; |
| 2030 | /* :height overrides :max-height. */ | 2052 | /* :height overrides :max-height. */ |
| 2031 | max_height = -1; | 2053 | max_height = -1; |
| 2032 | } | 2054 | } |
| @@ -2216,7 +2238,7 @@ image_set_transform (struct frame *f, struct image *img) | |||
| 2216 | } | 2238 | } |
| 2217 | else | 2239 | else |
| 2218 | #endif | 2240 | #endif |
| 2219 | compute_image_size (img->width, img->height, img->spec, &width, &height); | 2241 | compute_image_size (img->width, img->height, img, &width, &height); |
| 2220 | 2242 | ||
| 2221 | /* Determine rotation. */ | 2243 | /* Determine rotation. */ |
| 2222 | double rotation = 0.0; | 2244 | double rotation = 0.0; |
| @@ -9210,7 +9232,7 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 9210 | 9232 | ||
| 9211 | compute_image_size (MagickGetImageWidth (image_wand), | 9233 | compute_image_size (MagickGetImageWidth (image_wand), |
| 9212 | MagickGetImageHeight (image_wand), | 9234 | MagickGetImageHeight (image_wand), |
| 9213 | img->spec, &desired_width, &desired_height); | 9235 | img, &desired_width, &desired_height); |
| 9214 | 9236 | ||
| 9215 | if (desired_width != -1 && desired_height != -1) | 9237 | if (desired_width != -1 && desired_height != -1) |
| 9216 | { | 9238 | { |
| @@ -10068,7 +10090,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 10068 | viewbox_height = dimension_data.height; | 10090 | viewbox_height = dimension_data.height; |
| 10069 | } | 10091 | } |
| 10070 | 10092 | ||
| 10071 | compute_image_size (viewbox_width, viewbox_height, img->spec, | 10093 | compute_image_size (viewbox_width, viewbox_height, img, |
| 10072 | &width, &height); | 10094 | &width, &height); |
| 10073 | 10095 | ||
| 10074 | width *= FRAME_SCALE_FACTOR (f); | 10096 | width *= FRAME_SCALE_FACTOR (f); |
| @@ -10777,6 +10799,8 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 10777 | DEFSYM (QCmax_width, ":max-width"); | 10799 | DEFSYM (QCmax_width, ":max-width"); |
| 10778 | DEFSYM (QCmax_height, ":max-height"); | 10800 | DEFSYM (QCmax_height, ":max-height"); |
| 10779 | 10801 | ||
| 10802 | DEFSYM (Qem, "em"); | ||
| 10803 | |||
| 10780 | #ifdef HAVE_NATIVE_TRANSFORMS | 10804 | #ifdef HAVE_NATIVE_TRANSFORMS |
| 10781 | DEFSYM (Qscale, "scale"); | 10805 | DEFSYM (Qscale, "scale"); |
| 10782 | DEFSYM (Qrotate, "rotate"); | 10806 | DEFSYM (Qrotate, "rotate"); |
diff --git a/src/minibuf.c b/src/minibuf.c index c9831fd50f4..a3c1b99bf32 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -112,13 +112,15 @@ choose_minibuf_frame (void) | |||
| 112 | { | 112 | { |
| 113 | if (FRAMEP (selected_frame) | 113 | if (FRAMEP (selected_frame) |
| 114 | && FRAME_LIVE_P (XFRAME (selected_frame)) | 114 | && FRAME_LIVE_P (XFRAME (selected_frame)) |
| 115 | && WINDOW_LIVE_P (XFRAME (selected_frame)->minibuffer_window) | ||
| 115 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) | 116 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) |
| 116 | { | 117 | { |
| 117 | struct frame *sf = XFRAME (selected_frame); | 118 | struct frame *sf = XFRAME (selected_frame); |
| 118 | /* I don't think that any frames may validly have a null minibuffer | 119 | /* I don't think that any frames may validly have a null |
| 119 | window anymore. */ | 120 | minibuffer window anymore. (2021-04-15): Tooltip frames have |
| 120 | if (NILP (sf->minibuffer_window)) | 121 | a null MB. Comment out the following. */ |
| 121 | emacs_abort (); | 122 | /* if (NILP (sf->minibuffer_window)) */ |
| 123 | /* emacs_abort (); */ | ||
| 122 | 124 | ||
| 123 | minibuf_window = sf->minibuffer_window; | 125 | minibuf_window = sf->minibuffer_window; |
| 124 | } | 126 | } |
| @@ -195,7 +197,9 @@ move_minibuffers_onto_frame (struct frame *of, bool for_deletion) | |||
| 195 | && (for_deletion || minibuf_follows_frame () || FRAME_INITIAL_P (of)))) | 197 | && (for_deletion || minibuf_follows_frame () || FRAME_INITIAL_P (of)))) |
| 196 | return; | 198 | return; |
| 197 | if (FRAME_LIVE_P (f) | 199 | if (FRAME_LIVE_P (f) |
| 198 | && !EQ (f->minibuffer_window, of->minibuffer_window)) | 200 | && !EQ (f->minibuffer_window, of->minibuffer_window) |
| 201 | && WINDOW_LIVE_P (f->minibuffer_window) /* F not a tootip frame */ | ||
| 202 | && WINDOW_LIVE_P (of->minibuffer_window)) | ||
| 199 | { | 203 | { |
| 200 | zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); | 204 | zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); |
| 201 | if (for_deletion && XFRAME (MB_frame) != of) | 205 | if (for_deletion && XFRAME (MB_frame) != of) |
| @@ -636,6 +640,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 636 | mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); | 640 | mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); |
| 637 | 641 | ||
| 638 | if (minibuf_level > 1 | 642 | if (minibuf_level > 1 |
| 643 | && WINDOW_LIVE_P (XFRAME (MB_frame)->minibuffer_window) | ||
| 639 | && !EQ (XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame, | 644 | && !EQ (XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame, |
| 640 | MB_frame) | 645 | MB_frame) |
| 641 | && minibuf_moves_frame_when_opened () | 646 | && minibuf_moves_frame_when_opened () |
| @@ -908,11 +913,13 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 908 | unbind_to (count, Qnil); | 913 | unbind_to (count, Qnil); |
| 909 | 914 | ||
| 910 | /* Switch the frame back to the calling frame. */ | 915 | /* Switch the frame back to the calling frame. */ |
| 911 | if ((!EQ (selected_frame, calling_frame) | 916 | if (FRAMEP (calling_frame) |
| 912 | || !EQ (XWINDOW (XFRAME (calling_frame)->minibuffer_window)->frame, | 917 | && FRAME_LIVE_P (XFRAME (calling_frame)) |
| 913 | calling_frame)) | 918 | && (!EQ (selected_frame, calling_frame) |
| 914 | && FRAMEP (calling_frame) | 919 | || (WINDOW_LIVE_P (XFRAME (calling_frame)->minibuffer_window) |
| 915 | && FRAME_LIVE_P (XFRAME (calling_frame))) | 920 | && !EQ (XWINDOW (XFRAME (calling_frame)->minibuffer_window) |
| 921 | ->frame, | ||
| 922 | calling_frame)))) | ||
| 916 | call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); | 923 | call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); |
| 917 | 924 | ||
| 918 | /* Add the value to the appropriate history list, if any. This is | 925 | /* Add the value to the appropriate history list, if any. This is |
| @@ -1056,10 +1063,13 @@ read_minibuf_unwind (void) | |||
| 1056 | { | 1063 | { |
| 1057 | f = XFRAME (exp_MB_frame); | 1064 | f = XFRAME (exp_MB_frame); |
| 1058 | window = f->minibuffer_window; | 1065 | window = f->minibuffer_window; |
| 1059 | w = XWINDOW (window); | 1066 | if (WINDOW_LIVE_P (window)) |
| 1060 | if (EQ (w->frame, exp_MB_frame) | 1067 | { |
| 1061 | && EQ (w->contents, nth_minibuffer (minibuf_level))) | 1068 | w = XWINDOW (window); |
| 1062 | goto found; | 1069 | if (EQ (w->frame, exp_MB_frame) |
| 1070 | && EQ (w->contents, nth_minibuffer (minibuf_level))) | ||
| 1071 | goto found; | ||
| 1072 | } | ||
| 1063 | } | 1073 | } |
| 1064 | return; /* expired minibuffer not found. Maybe we should output an | 1074 | return; /* expired minibuffer not found. Maybe we should output an |
| 1065 | error, here. */ | 1075 | error, here. */ |
diff --git a/src/w32fns.c b/src/w32fns.c index 9db367bfafe..c07f32ab0cc 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -7434,6 +7434,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | |||
| 7434 | set_window_buffer (window, tip_buf, false, false); | 7434 | set_window_buffer (window, tip_buf, false, false); |
| 7435 | w = XWINDOW (window); | 7435 | w = XWINDOW (window); |
| 7436 | w->pseudo_window_p = true; | 7436 | w->pseudo_window_p = true; |
| 7437 | /* Try to avoid that `other-window' select us (Bug#47207). */ | ||
| 7438 | Fset_window_parameter (window, Qno_other_window, Qt); | ||
| 7437 | 7439 | ||
| 7438 | /* Set up the frame's root window. Note: The following code does not | 7440 | /* Set up the frame's root window. Note: The following code does not |
| 7439 | try to size the window or its frame correctly. Its only purpose is | 7441 | try to size the window or its frame correctly. Its only purpose is |
diff --git a/src/w32term.c b/src/w32term.c index 0ee805a8526..361cf33c024 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -2031,8 +2031,11 @@ w32_draw_image_relief (struct glyph_string *s) | |||
| 2031 | if (s->hl == DRAW_IMAGE_SUNKEN | 2031 | if (s->hl == DRAW_IMAGE_SUNKEN |
| 2032 | || s->hl == DRAW_IMAGE_RAISED) | 2032 | || s->hl == DRAW_IMAGE_RAISED) |
| 2033 | { | 2033 | { |
| 2034 | thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief | 2034 | thick = (tab_bar_button_relief < 0 |
| 2035 | : DEFAULT_TOOL_BAR_BUTTON_RELIEF; | 2035 | ? DEFAULT_TAB_BAR_BUTTON_RELIEF |
| 2036 | : (tool_bar_button_relief < 0 | ||
| 2037 | ? DEFAULT_TOOL_BAR_BUTTON_RELIEF | ||
| 2038 | : min (tool_bar_button_relief, 1000000))); | ||
| 2036 | raised_p = s->hl == DRAW_IMAGE_RAISED; | 2039 | raised_p = s->hl == DRAW_IMAGE_RAISED; |
| 2037 | } | 2040 | } |
| 2038 | else | 2041 | else |
| @@ -2045,6 +2048,19 @@ w32_draw_image_relief (struct glyph_string *s) | |||
| 2045 | y1 = y + s->slice.height - 1; | 2048 | y1 = y + s->slice.height - 1; |
| 2046 | 2049 | ||
| 2047 | extra_x = extra_y = 0; | 2050 | extra_x = extra_y = 0; |
| 2051 | if (s->face->id == TAB_BAR_FACE_ID) | ||
| 2052 | { | ||
| 2053 | if (CONSP (Vtab_bar_button_margin) | ||
| 2054 | && FIXNUMP (XCAR (Vtab_bar_button_margin)) | ||
| 2055 | && FIXNUMP (XCDR (Vtab_bar_button_margin))) | ||
| 2056 | { | ||
| 2057 | extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)); | ||
| 2058 | extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)); | ||
| 2059 | } | ||
| 2060 | else if (FIXNUMP (Vtab_bar_button_margin)) | ||
| 2061 | extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin); | ||
| 2062 | } | ||
| 2063 | |||
| 2048 | if (s->face->id == TOOL_BAR_FACE_ID) | 2064 | if (s->face->id == TOOL_BAR_FACE_ID) |
| 2049 | { | 2065 | { |
| 2050 | if (CONSP (Vtool_bar_button_margin) | 2066 | if (CONSP (Vtool_bar_button_margin) |
diff --git a/src/window.c b/src/window.c index 661b1ae112c..399b24b1e9e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -215,20 +215,6 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) | |||
| 215 | w->horizontal = horflag; | 215 | w->horizontal = horflag; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | static void | ||
| 219 | wset_update_mode_line (struct window *w) | ||
| 220 | { | ||
| 221 | /* If this window is the selected window on its frame, set the | ||
| 222 | global variable update_mode_lines, so that gui_consider_frame_title | ||
| 223 | will consider this frame's title for redisplay. */ | ||
| 224 | Lisp_Object fselected_window = XFRAME (WINDOW_FRAME (w))->selected_window; | ||
| 225 | |||
| 226 | if (WINDOWP (fselected_window) && XWINDOW (fselected_window) == w) | ||
| 227 | update_mode_lines = 42; | ||
| 228 | else | ||
| 229 | w->update_mode_line = true; | ||
| 230 | } | ||
| 231 | |||
| 232 | /* True if leaf window W doesn't reflect the actual state | 218 | /* True if leaf window W doesn't reflect the actual state |
| 233 | of displayed buffer due to its text or overlays change. */ | 219 | of displayed buffer due to its text or overlays change. */ |
| 234 | 220 | ||
| @@ -518,10 +504,18 @@ select_window (Lisp_Object window, Lisp_Object norecord, | |||
| 518 | { | 504 | { |
| 519 | struct window *w; | 505 | struct window *w; |
| 520 | struct frame *sf; | 506 | struct frame *sf; |
| 507 | Lisp_Object frame; | ||
| 508 | struct frame *f; | ||
| 521 | 509 | ||
| 522 | CHECK_LIVE_WINDOW (window); | 510 | CHECK_LIVE_WINDOW (window); |
| 523 | 511 | ||
| 524 | w = XWINDOW (window); | 512 | w = XWINDOW (window); |
| 513 | frame = WINDOW_FRAME (w); | ||
| 514 | f = XFRAME (frame); | ||
| 515 | |||
| 516 | if (FRAME_TOOLTIP_P (f)) | ||
| 517 | /* Do not select a tooltip window (Bug#47207). */ | ||
| 518 | error ("Cannot select a tooltip window"); | ||
| 525 | 519 | ||
| 526 | /* Make the selected window's buffer current. */ | 520 | /* Make the selected window's buffer current. */ |
| 527 | Fset_buffer (w->contents); | 521 | Fset_buffer (w->contents); |
| @@ -542,14 +536,14 @@ select_window (Lisp_Object window, Lisp_Object norecord, | |||
| 542 | redisplay_other_windows (); | 536 | redisplay_other_windows (); |
| 543 | 537 | ||
| 544 | sf = SELECTED_FRAME (); | 538 | sf = SELECTED_FRAME (); |
| 545 | if (XFRAME (WINDOW_FRAME (w)) != sf) | 539 | if (f != sf) |
| 546 | { | 540 | { |
| 547 | fset_selected_window (XFRAME (WINDOW_FRAME (w)), window); | 541 | fset_selected_window (f, window); |
| 548 | /* Use this rather than Fhandle_switch_frame | 542 | /* Use this rather than Fhandle_switch_frame |
| 549 | so that FRAME_FOCUS_FRAME is moved appropriately as we | 543 | so that FRAME_FOCUS_FRAME is moved appropriately as we |
| 550 | move around in the state where a minibuffer in a separate | 544 | move around in the state where a minibuffer in a separate |
| 551 | frame is active. */ | 545 | frame is active. */ |
| 552 | Fselect_frame (WINDOW_FRAME (w), norecord); | 546 | Fselect_frame (frame, norecord); |
| 553 | /* Fselect_frame called us back so we've done all the work already. */ | 547 | /* Fselect_frame called us back so we've done all the work already. */ |
| 554 | eassert (EQ (window, selected_window)); | 548 | eassert (EQ (window, selected_window)); |
| 555 | return window; | 549 | return window; |
| @@ -2556,8 +2550,13 @@ window_list (void) | |||
| 2556 | if (!CONSP (Vwindow_list)) | 2550 | if (!CONSP (Vwindow_list)) |
| 2557 | { | 2551 | { |
| 2558 | Lisp_Object tail, frame; | 2552 | Lisp_Object tail, frame; |
| 2553 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2559 | 2554 | ||
| 2560 | Vwindow_list = Qnil; | 2555 | Vwindow_list = Qnil; |
| 2556 | /* Don't allow quitting in Fnconc. Otherwise we might end up | ||
| 2557 | with a too short Vwindow_list and Fkill_buffer not being able | ||
| 2558 | to replace a buffer in all windows showing it (Bug#47244). */ | ||
| 2559 | specbind (Qinhibit_quit, Qt); | ||
| 2561 | FOR_EACH_FRAME (tail, frame) | 2560 | FOR_EACH_FRAME (tail, frame) |
| 2562 | { | 2561 | { |
| 2563 | Lisp_Object arglist = Qnil; | 2562 | Lisp_Object arglist = Qnil; |
| @@ -2569,6 +2568,8 @@ window_list (void) | |||
| 2569 | arglist = Fnreverse (arglist); | 2568 | arglist = Fnreverse (arglist); |
| 2570 | Vwindow_list = nconc2 (Vwindow_list, arglist); | 2569 | Vwindow_list = nconc2 (Vwindow_list, arglist); |
| 2571 | } | 2570 | } |
| 2571 | |||
| 2572 | unbind_to (count, Qnil); | ||
| 2572 | } | 2573 | } |
| 2573 | 2574 | ||
| 2574 | return Vwindow_list; | 2575 | return Vwindow_list; |
| @@ -2603,7 +2604,7 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, | |||
| 2603 | candidate_p = false; | 2604 | candidate_p = false; |
| 2604 | else if (MINI_WINDOW_P (w) | 2605 | else if (MINI_WINDOW_P (w) |
| 2605 | && (EQ (minibuf, Qlambda) | 2606 | && (EQ (minibuf, Qlambda) |
| 2606 | || (WINDOWP (minibuf) && !EQ (minibuf, window)))) | 2607 | || (WINDOW_LIVE_P (minibuf) && !EQ (minibuf, window)))) |
| 2607 | { | 2608 | { |
| 2608 | /* If MINIBUF is `lambda' don't consider any mini-windows. | 2609 | /* If MINIBUF is `lambda' don't consider any mini-windows. |
| 2609 | If it is a window, consider only that one. */ | 2610 | If it is a window, consider only that one. */ |
| @@ -2666,12 +2667,12 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object | |||
| 2666 | Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; | 2667 | Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; |
| 2667 | 2668 | ||
| 2668 | XSETWINDOW (*window, w); | 2669 | XSETWINDOW (*window, w); |
| 2669 | /* MINIBUF nil may or may not include minibuffers. Decide if it | 2670 | /* MINIBUF nil may or may not include minibuffer windows. Decide if |
| 2670 | does. */ | 2671 | it does. But first make sure that this frame's minibuffer window |
| 2671 | if (NILP (*minibuf)) | 2672 | is live (Bug#47207). */ |
| 2672 | *minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents) | 2673 | if (WINDOW_LIVE_P (miniwin) && NILP (*minibuf)) |
| 2673 | ? miniwin | 2674 | *minibuf = (this_minibuffer_depth (XWINDOW (miniwin)->contents) |
| 2674 | : Qlambda; | 2675 | ? miniwin : Qlambda); |
| 2675 | else if (!EQ (*minibuf, Qt)) | 2676 | else if (!EQ (*minibuf, Qt)) |
| 2676 | *minibuf = Qlambda; | 2677 | *minibuf = Qlambda; |
| 2677 | 2678 | ||
| @@ -2682,9 +2683,10 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object | |||
| 2682 | /* ALL_FRAMES nil doesn't specify which frames to include. */ | 2683 | /* ALL_FRAMES nil doesn't specify which frames to include. */ |
| 2683 | if (NILP (*all_frames)) | 2684 | if (NILP (*all_frames)) |
| 2684 | *all_frames | 2685 | *all_frames |
| 2685 | = (!EQ (*minibuf, Qlambda) | 2686 | /* Once more make sure that this frame's minibuffer window is live |
| 2686 | ? FRAME_MINIBUF_WINDOW (XFRAME (w->frame)) | 2687 | before including it (Bug#47207). */ |
| 2687 | : Qnil); | 2688 | = ((WINDOW_LIVE_P (miniwin) && !EQ (*minibuf, Qlambda)) |
| 2689 | ? miniwin : Qnil); | ||
| 2688 | else if (EQ (*all_frames, Qvisible)) | 2690 | else if (EQ (*all_frames, Qvisible)) |
| 2689 | ; | 2691 | ; |
| 2690 | else if (EQ (*all_frames, make_fixnum (0))) | 2692 | else if (EQ (*all_frames, make_fixnum (0))) |
| @@ -2705,6 +2707,8 @@ static Lisp_Object | |||
| 2705 | next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, | 2707 | next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, |
| 2706 | bool next_p) | 2708 | bool next_p) |
| 2707 | { | 2709 | { |
| 2710 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2711 | |||
| 2708 | decode_next_window_args (&window, &minibuf, &all_frames); | 2712 | decode_next_window_args (&window, &minibuf, &all_frames); |
| 2709 | 2713 | ||
| 2710 | /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just | 2714 | /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just |
| @@ -2713,6 +2717,9 @@ next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, | |||
| 2713 | && !EQ (all_frames, XWINDOW (window)->frame)) | 2717 | && !EQ (all_frames, XWINDOW (window)->frame)) |
| 2714 | return Fframe_first_window (all_frames); | 2718 | return Fframe_first_window (all_frames); |
| 2715 | 2719 | ||
| 2720 | /* Don't allow quitting in Fmemq. */ | ||
| 2721 | specbind (Qinhibit_quit, Qt); | ||
| 2722 | |||
| 2716 | if (next_p) | 2723 | if (next_p) |
| 2717 | { | 2724 | { |
| 2718 | Lisp_Object list; | 2725 | Lisp_Object list; |
| @@ -2762,6 +2769,8 @@ next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, | |||
| 2762 | window = candidate; | 2769 | window = candidate; |
| 2763 | } | 2770 | } |
| 2764 | 2771 | ||
| 2772 | unbind_to (count, Qnil); | ||
| 2773 | |||
| 2765 | return window; | 2774 | return window; |
| 2766 | } | 2775 | } |
| 2767 | 2776 | ||
| @@ -2852,10 +2861,14 @@ static Lisp_Object | |||
| 2852 | window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) | 2861 | window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) |
| 2853 | { | 2862 | { |
| 2854 | Lisp_Object tail, list, rest; | 2863 | Lisp_Object tail, list, rest; |
| 2864 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2855 | 2865 | ||
| 2856 | decode_next_window_args (&window, &minibuf, &all_frames); | 2866 | decode_next_window_args (&window, &minibuf, &all_frames); |
| 2857 | list = Qnil; | 2867 | list = Qnil; |
| 2858 | 2868 | ||
| 2869 | /* Don't allow quitting in Fmemq and Fnconc. */ | ||
| 2870 | specbind (Qinhibit_quit, Qt); | ||
| 2871 | |||
| 2859 | for (tail = window_list (); CONSP (tail); tail = XCDR (tail)) | 2872 | for (tail = window_list (); CONSP (tail); tail = XCDR (tail)) |
| 2860 | if (candidate_window_p (XCAR (tail), window, minibuf, all_frames)) | 2873 | if (candidate_window_p (XCAR (tail), window, minibuf, all_frames)) |
| 2861 | list = Fcons (XCAR (tail), list); | 2874 | list = Fcons (XCAR (tail), list); |
| @@ -2870,6 +2883,9 @@ window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) | |||
| 2870 | XSETCDR (tail, Qnil); | 2883 | XSETCDR (tail, Qnil); |
| 2871 | list = nconc2 (rest, list); | 2884 | list = nconc2 (rest, list); |
| 2872 | } | 2885 | } |
| 2886 | |||
| 2887 | unbind_to (count, Qnil); | ||
| 2888 | |||
| 2873 | return list; | 2889 | return list; |
| 2874 | } | 2890 | } |
| 2875 | 2891 | ||
| @@ -8225,6 +8241,7 @@ syms_of_window (void) | |||
| 8225 | DEFSYM (Qmode_line_format, "mode-line-format"); | 8241 | DEFSYM (Qmode_line_format, "mode-line-format"); |
| 8226 | DEFSYM (Qheader_line_format, "header-line-format"); | 8242 | DEFSYM (Qheader_line_format, "header-line-format"); |
| 8227 | DEFSYM (Qtab_line_format, "tab-line-format"); | 8243 | DEFSYM (Qtab_line_format, "tab-line-format"); |
| 8244 | DEFSYM (Qno_other_window, "no-other-window"); | ||
| 8228 | 8245 | ||
| 8229 | DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function, | 8246 | DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function, |
| 8230 | doc: /* Non-nil means call as function to display a help buffer. | 8247 | doc: /* Non-nil means call as function to display a help buffer. |
diff --git a/src/window.h b/src/window.h index b6f88e8f55f..2400c422c15 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1141,6 +1141,7 @@ extern void wset_redisplay (struct window *w); | |||
| 1141 | extern void fset_redisplay (struct frame *f); | 1141 | extern void fset_redisplay (struct frame *f); |
| 1142 | extern void bset_redisplay (struct buffer *b); | 1142 | extern void bset_redisplay (struct buffer *b); |
| 1143 | extern void bset_update_mode_line (struct buffer *b); | 1143 | extern void bset_update_mode_line (struct buffer *b); |
| 1144 | extern void wset_update_mode_line (struct window *w); | ||
| 1144 | /* Call this to tell redisplay to look for other windows than selected-window | 1145 | /* Call this to tell redisplay to look for other windows than selected-window |
| 1145 | that need to be redisplayed. Calling one of the *set_redisplay functions | 1146 | that need to be redisplayed. Calling one of the *set_redisplay functions |
| 1146 | above already does it, so it's only needed in unusual cases. */ | 1147 | above already does it, so it's only needed in unusual cases. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 50d9040057a..8ffec93e45d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -869,6 +869,19 @@ bset_update_mode_line (struct buffer *b) | |||
| 869 | b->text->redisplay = true; | 869 | b->text->redisplay = true; |
| 870 | } | 870 | } |
| 871 | 871 | ||
| 872 | void | ||
| 873 | wset_update_mode_line (struct window *w) | ||
| 874 | { | ||
| 875 | w->update_mode_line = true; | ||
| 876 | /* When a window's mode line needs to be updated, the window's frame's | ||
| 877 | title may also need to be updated, but we don't need to worry about it | ||
| 878 | here. Instead, `gui_consider_frame_title' is automatically called | ||
| 879 | whenever w->update_mode_line is set for that frame's selected window. | ||
| 880 | But for this to work reliably, we have to make sure the window | ||
| 881 | is considered, so we have to mark it for redisplay. */ | ||
| 882 | wset_redisplay (w); | ||
| 883 | } | ||
| 884 | |||
| 872 | DEFUN ("set-buffer-redisplay", Fset_buffer_redisplay, | 885 | DEFUN ("set-buffer-redisplay", Fset_buffer_redisplay, |
| 873 | Sset_buffer_redisplay, 4, 4, 0, | 886 | Sset_buffer_redisplay, 4, 4, 0, |
| 874 | doc: /* Mark the current buffer for redisplay. | 887 | doc: /* Mark the current buffer for redisplay. |
| @@ -13682,6 +13695,7 @@ void | |||
| 13682 | handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, | 13695 | handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, |
| 13683 | int modifiers) | 13696 | int modifiers) |
| 13684 | { | 13697 | { |
| 13698 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); | ||
| 13685 | struct window *w = XWINDOW (f->tab_bar_window); | 13699 | struct window *w = XWINDOW (f->tab_bar_window); |
| 13686 | int hpos, vpos, prop_idx; | 13700 | int hpos, vpos, prop_idx; |
| 13687 | bool close_p; | 13701 | bool close_p; |
| @@ -13703,13 +13717,22 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, | |||
| 13703 | return; | 13717 | return; |
| 13704 | 13718 | ||
| 13705 | if (down_p) | 13719 | if (down_p) |
| 13706 | f->last_tab_bar_item = prop_idx; /* record the pressed tab */ | 13720 | { |
| 13721 | /* Show the clicked button in pressed state. */ | ||
| 13722 | if (!NILP (Vmouse_highlight)) | ||
| 13723 | show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN); | ||
| 13724 | f->last_tab_bar_item = prop_idx; /* record the pressed tab */ | ||
| 13725 | } | ||
| 13707 | else | 13726 | else |
| 13708 | { | 13727 | { |
| 13709 | Lisp_Object key, frame; | 13728 | Lisp_Object key, frame; |
| 13710 | struct input_event event; | 13729 | struct input_event event; |
| 13711 | EVENT_INIT (event); | 13730 | EVENT_INIT (event); |
| 13712 | 13731 | ||
| 13732 | /* Show item in released state. */ | ||
| 13733 | if (!NILP (Vmouse_highlight)) | ||
| 13734 | show_mouse_face (hlinfo, DRAW_IMAGE_RAISED); | ||
| 13735 | |||
| 13713 | key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY); | 13736 | key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY); |
| 13714 | 13737 | ||
| 13715 | XSETFRAME (frame, f); | 13738 | XSETFRAME (frame, f); |
| @@ -13722,6 +13745,97 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, | |||
| 13722 | } | 13745 | } |
| 13723 | } | 13746 | } |
| 13724 | 13747 | ||
| 13748 | |||
| 13749 | /* Possibly highlight a tab-bar item on frame F when mouse moves to | ||
| 13750 | tab-bar window-relative coordinates X/Y. Called from | ||
| 13751 | note_mouse_highlight. */ | ||
| 13752 | |||
| 13753 | static void | ||
| 13754 | note_tab_bar_highlight (struct frame *f, int x, int y) | ||
| 13755 | { | ||
| 13756 | Lisp_Object window = f->tab_bar_window; | ||
| 13757 | struct window *w = XWINDOW (window); | ||
| 13758 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); | ||
| 13759 | int hpos, vpos; | ||
| 13760 | struct glyph *glyph; | ||
| 13761 | struct glyph_row *row; | ||
| 13762 | int i; | ||
| 13763 | Lisp_Object enabled_p; | ||
| 13764 | int prop_idx; | ||
| 13765 | bool close_p; | ||
| 13766 | enum draw_glyphs_face draw = DRAW_IMAGE_RAISED; | ||
| 13767 | int rc; | ||
| 13768 | |||
| 13769 | /* Function note_mouse_highlight is called with negative X/Y | ||
| 13770 | values when mouse moves outside of the frame. */ | ||
| 13771 | if (x <= 0 || y <= 0) | ||
| 13772 | { | ||
| 13773 | clear_mouse_face (hlinfo); | ||
| 13774 | return; | ||
| 13775 | } | ||
| 13776 | |||
| 13777 | rc = get_tab_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx, &close_p); | ||
| 13778 | if (rc < 0) | ||
| 13779 | { | ||
| 13780 | /* Not on tab-bar item. */ | ||
| 13781 | clear_mouse_face (hlinfo); | ||
| 13782 | return; | ||
| 13783 | } | ||
| 13784 | else if (rc == 0) | ||
| 13785 | /* On same tab-bar item as before. */ | ||
| 13786 | goto set_help_echo; | ||
| 13787 | |||
| 13788 | clear_mouse_face (hlinfo); | ||
| 13789 | |||
| 13790 | bool mouse_down_p = false; | ||
| 13791 | #ifndef HAVE_NS | ||
| 13792 | /* Mouse is down, but on different tab-bar item? */ | ||
| 13793 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 13794 | mouse_down_p = (gui_mouse_grabbed (dpyinfo) | ||
| 13795 | && f == dpyinfo->last_mouse_frame); | ||
| 13796 | |||
| 13797 | if (mouse_down_p && f->last_tab_bar_item != prop_idx) | ||
| 13798 | return; | ||
| 13799 | #endif | ||
| 13800 | draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; | ||
| 13801 | |||
| 13802 | /* If tab-bar item is not enabled, don't highlight it. */ | ||
| 13803 | enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P); | ||
| 13804 | if (!NILP (enabled_p) && !NILP (Vmouse_highlight)) | ||
| 13805 | { | ||
| 13806 | /* Compute the x-position of the glyph. In front and past the | ||
| 13807 | image is a space. We include this in the highlighted area. */ | ||
| 13808 | row = MATRIX_ROW (w->current_matrix, vpos); | ||
| 13809 | for (i = x = 0; i < hpos; ++i) | ||
| 13810 | x += row->glyphs[TEXT_AREA][i].pixel_width; | ||
| 13811 | |||
| 13812 | /* Record this as the current active region. */ | ||
| 13813 | hlinfo->mouse_face_beg_col = hpos; | ||
| 13814 | hlinfo->mouse_face_beg_row = vpos; | ||
| 13815 | hlinfo->mouse_face_beg_x = x; | ||
| 13816 | hlinfo->mouse_face_past_end = false; | ||
| 13817 | |||
| 13818 | hlinfo->mouse_face_end_col = hpos + 1; | ||
| 13819 | hlinfo->mouse_face_end_row = vpos; | ||
| 13820 | hlinfo->mouse_face_end_x = x + glyph->pixel_width; | ||
| 13821 | hlinfo->mouse_face_window = window; | ||
| 13822 | hlinfo->mouse_face_face_id = TAB_BAR_FACE_ID; | ||
| 13823 | |||
| 13824 | /* Display it as active. */ | ||
| 13825 | show_mouse_face (hlinfo, draw); | ||
| 13826 | } | ||
| 13827 | |||
| 13828 | set_help_echo: | ||
| 13829 | |||
| 13830 | /* Set help_echo_string to a help string to display for this tab-bar item. | ||
| 13831 | XTread_socket does the rest. */ | ||
| 13832 | help_echo_object = help_echo_window = Qnil; | ||
| 13833 | help_echo_pos = -1; | ||
| 13834 | help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_HELP); | ||
| 13835 | if (NILP (help_echo_string)) | ||
| 13836 | help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION); | ||
| 13837 | } | ||
| 13838 | |||
| 13725 | #endif /* HAVE_WINDOW_SYSTEM */ | 13839 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 13726 | 13840 | ||
| 13727 | /* Find the tab-bar item at X coordinate and return its information. */ | 13841 | /* Find the tab-bar item at X coordinate and return its information. */ |
| @@ -31860,6 +31974,11 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row, | |||
| 31860 | static void | 31974 | static void |
| 31861 | show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw) | 31975 | show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw) |
| 31862 | { | 31976 | { |
| 31977 | /* Don't bother doing anything if the mouse-face window is not set | ||
| 31978 | up. */ | ||
| 31979 | if (!WINDOWP (hlinfo->mouse_face_window)) | ||
| 31980 | return; | ||
| 31981 | |||
| 31863 | struct window *w = XWINDOW (hlinfo->mouse_face_window); | 31982 | struct window *w = XWINDOW (hlinfo->mouse_face_window); |
| 31864 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 31983 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 31865 | 31984 | ||
| @@ -33414,9 +33533,13 @@ note_mouse_highlight (struct frame *f, int x, int y) | |||
| 33414 | frame_to_window_pixel_xy (w, &x, &y); | 33533 | frame_to_window_pixel_xy (w, &x, &y); |
| 33415 | 33534 | ||
| 33416 | #if defined (HAVE_WINDOW_SYSTEM) | 33535 | #if defined (HAVE_WINDOW_SYSTEM) |
| 33417 | /* We don't highlight tab-bar buttons. */ | 33536 | /* Handle tab-bar window differently since it doesn't display a |
| 33537 | buffer. */ | ||
| 33418 | if (EQ (window, f->tab_bar_window)) | 33538 | if (EQ (window, f->tab_bar_window)) |
| 33419 | return; | 33539 | { |
| 33540 | note_tab_bar_highlight (f, x, y); | ||
| 33541 | return; | ||
| 33542 | } | ||
| 33420 | #endif | 33543 | #endif |
| 33421 | 33544 | ||
| 33422 | #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR) | 33545 | #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR) |
diff --git a/src/xfns.c b/src/xfns.c index 0507dc8f61d..f120653ee7b 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -7076,6 +7076,8 @@ Text larger than the specified size is clipped. */) | |||
| 7076 | set_window_buffer (window, tip_buf, false, false); | 7076 | set_window_buffer (window, tip_buf, false, false); |
| 7077 | w = XWINDOW (window); | 7077 | w = XWINDOW (window); |
| 7078 | w->pseudo_window_p = true; | 7078 | w->pseudo_window_p = true; |
| 7079 | /* Try to avoid that `other-window' select us (Bug#47207). */ | ||
| 7080 | Fset_window_parameter (window, Qno_other_window, Qt); | ||
| 7079 | 7081 | ||
| 7080 | /* Set up the frame's root window. Note: The following code does not | 7082 | /* Set up the frame's root window. Note: The following code does not |
| 7081 | try to size the window or its frame correctly. Its only purpose is | 7083 | try to size the window or its frame correctly. Its only purpose is |
diff --git a/src/xselect.c b/src/xselect.c index 030f6240712..cd6d86bdf4c 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -1482,14 +1482,21 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, | |||
| 1482 | = XGetSelectionOwner (display, selection_atom) != 0; | 1482 | = XGetSelectionOwner (display, selection_atom) != 0; |
| 1483 | unblock_input (); | 1483 | unblock_input (); |
| 1484 | if (there_is_a_selection_owner) | 1484 | if (there_is_a_selection_owner) |
| 1485 | signal_error ("Selection owner couldn't convert", | 1485 | { |
| 1486 | actual_type | 1486 | AUTO_STRING (format, "Selection owner couldn't convert: %s"); |
| 1487 | ? list2 (target_type, | 1487 | CALLN (Fmessage, format, |
| 1488 | x_atom_to_symbol (dpyinfo, actual_type)) | 1488 | actual_type |
| 1489 | : target_type); | 1489 | ? list2 (target_type, |
| 1490 | x_atom_to_symbol (dpyinfo, actual_type)) | ||
| 1491 | : target_type); | ||
| 1492 | return Qnil; | ||
| 1493 | } | ||
| 1490 | else | 1494 | else |
| 1491 | signal_error ("No selection", | 1495 | { |
| 1492 | x_atom_to_symbol (dpyinfo, selection_atom)); | 1496 | AUTO_STRING (format, "No selection: %s"); |
| 1497 | CALLN (Fmessage, format, x_atom_to_symbol (dpyinfo, selection_atom)); | ||
| 1498 | return Qnil; | ||
| 1499 | } | ||
| 1493 | } | 1500 | } |
| 1494 | 1501 | ||
| 1495 | if (actual_type == dpyinfo->Xatom_INCR) | 1502 | if (actual_type == dpyinfo->Xatom_INCR) |