diff options
| author | Eli Zaretskii | 2015-09-26 09:50:58 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-09-26 09:50:58 +0300 |
| commit | e573d08ef15f0431ad8289b4242c49826f20efb6 (patch) | |
| tree | 323f37b911569c654747df2047f236ad5d316587 /src | |
| parent | 3fbc53b09c21d5657c62a4a295b5b70a6ea5d661 (diff) | |
| download | emacs-e573d08ef15f0431ad8289b4242c49826f20efb6.tar.gz emacs-e573d08ef15f0431ad8289b4242c49826f20efb6.zip | |
Make face realization be more frame-specific
* src/frame.h (struct f): New flag face_change.
* src/xfaces.c (Finternal_make_lisp_face)
(Finternal_copy_lisp_face, Finternal_set_lisp_face_attribute)
(update_face_from_frame_parameter): Set the face_change flag only
for the frame whose faces are affected.
* src/xdisp.c (init_iterator): If a frame's face_change flag is
set, free faces only on that frame.
(redisplay_internal): Disable "display optimization 1" if the
frame's face_change flag is set.
(redisplay_window): Don't allow skipping a window's redisplay if
its frame's face_change flag is set.
* src/frame.c (x_set_screen_gamma): Instead of calling
Fclear_face_cache, call clear_face_cache and set
windows_or_buffers_changed to a non-zero value. This avoids
setting the global face_change flag that triggers face realization
on all frames and thorough redisplay of all of them.
* lisp/term/tty-colors.el (tty-register-default-colors): Don't
clear face cache if the selected frame is a GUI frame.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 3 | ||||
| -rw-r--r-- | src/frame.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 16 | ||||
| -rw-r--r-- | src/xfaces.c | 40 |
4 files changed, 44 insertions, 18 deletions
diff --git a/src/frame.c b/src/frame.c index 0e95749a055..121c55fdb20 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -3539,7 +3539,8 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu | |||
| 3539 | (f, bgcolor, Qnil); | 3539 | (f, bgcolor, Qnil); |
| 3540 | } | 3540 | } |
| 3541 | 3541 | ||
| 3542 | Fclear_face_cache (Qnil); | 3542 | clear_face_cache (true); |
| 3543 | windows_or_buffers_changed = 70; | ||
| 3543 | } | 3544 | } |
| 3544 | 3545 | ||
| 3545 | 3546 | ||
diff --git a/src/frame.h b/src/frame.h index 546bede213d..af0dadb3d99 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -335,6 +335,9 @@ struct frame | |||
| 335 | /* Set to true after this frame was made by `make-frame'. */ | 335 | /* Set to true after this frame was made by `make-frame'. */ |
| 336 | bool_bf after_make_frame : 1; | 336 | bool_bf after_make_frame : 1; |
| 337 | 337 | ||
| 338 | /* Non-zero if this frame's faces need to be recomputed. */ | ||
| 339 | bool_bf face_change : 1; | ||
| 340 | |||
| 338 | /* Bitfield area ends here. */ | 341 | /* Bitfield area ends here. */ |
| 339 | 342 | ||
| 340 | /* Number of lines (rounded up) of tool bar. REMOVE THIS */ | 343 | /* Number of lines (rounded up) of tool bar. REMOVE THIS */ |
diff --git a/src/xdisp.c b/src/xdisp.c index bac74e2a34f..2c38aa9ccff 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2661,10 +2661,18 @@ init_iterator (struct it *it, struct window *w, | |||
| 2661 | free realized faces now because they depend on face definitions | 2661 | free realized faces now because they depend on face definitions |
| 2662 | that might have changed. Don't free faces while there might be | 2662 | that might have changed. Don't free faces while there might be |
| 2663 | desired matrices pending which reference these faces. */ | 2663 | desired matrices pending which reference these faces. */ |
| 2664 | if (face_change && !inhibit_free_realized_faces) | 2664 | if (!inhibit_free_realized_faces) |
| 2665 | { | 2665 | { |
| 2666 | face_change = false; | 2666 | if (face_change) |
| 2667 | free_all_realized_faces (Qnil); | 2667 | { |
| 2668 | face_change = false; | ||
| 2669 | free_all_realized_faces (Qnil); | ||
| 2670 | } | ||
| 2671 | else if (XFRAME (w->frame)->face_change) | ||
| 2672 | { | ||
| 2673 | XFRAME (w->frame)->face_change = 0; | ||
| 2674 | free_all_realized_faces (w->frame); | ||
| 2675 | } | ||
| 2668 | } | 2676 | } |
| 2669 | 2677 | ||
| 2670 | /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */ | 2678 | /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */ |
| @@ -13541,6 +13549,7 @@ redisplay_internal (void) | |||
| 13541 | && FRAME_VISIBLE_P (XFRAME (w->frame)) | 13549 | && FRAME_VISIBLE_P (XFRAME (w->frame)) |
| 13542 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) | 13550 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) |
| 13543 | && !XFRAME (w->frame)->cursor_type_changed | 13551 | && !XFRAME (w->frame)->cursor_type_changed |
| 13552 | && !XFRAME (w->frame)->face_change | ||
| 13544 | /* Make sure recorded data applies to current buffer, etc. */ | 13553 | /* Make sure recorded data applies to current buffer, etc. */ |
| 13545 | && this_line_buffer == current_buffer | 13554 | && this_line_buffer == current_buffer |
| 13546 | && match_p | 13555 | && match_p |
| @@ -15887,6 +15896,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 15887 | && REDISPLAY_SOME_P () | 15896 | && REDISPLAY_SOME_P () |
| 15888 | && !w->redisplay | 15897 | && !w->redisplay |
| 15889 | && !w->update_mode_line | 15898 | && !w->update_mode_line |
| 15899 | && !f->face_change | ||
| 15890 | && !f->redisplay | 15900 | && !f->redisplay |
| 15891 | && !buffer->text->redisplay | 15901 | && !buffer->text->redisplay |
| 15892 | && BUF_PT (buffer) == w->last_point) | 15902 | && BUF_PT (buffer) == w->last_point) |
diff --git a/src/xfaces.c b/src/xfaces.c index 94f3c4d67c2..40713f167ff 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -687,7 +687,6 @@ clear_face_cache (bool clear_fonts_p) | |||
| 687 | #endif /* HAVE_WINDOW_SYSTEM */ | 687 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | |||
| 691 | DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0, | 690 | DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0, |
| 692 | doc: /* Clear face caches on all frames. | 691 | doc: /* Clear face caches on all frames. |
| 693 | Optional THOROUGHLY non-nil means try to free unused fonts, too. */) | 692 | Optional THOROUGHLY non-nil means try to free unused fonts, too. */) |
| @@ -2528,7 +2527,10 @@ Value is a vector of face attributes. */) | |||
| 2528 | free realized faces. */ | 2527 | free realized faces. */ |
| 2529 | if (NILP (Fget (face, Qface_no_inherit))) | 2528 | if (NILP (Fget (face, Qface_no_inherit))) |
| 2530 | { | 2529 | { |
| 2531 | face_change = true; | 2530 | if (f) |
| 2531 | f->face_change = 1; | ||
| 2532 | else | ||
| 2533 | face_change = true; | ||
| 2532 | windows_or_buffers_changed = 54; | 2534 | windows_or_buffers_changed = 54; |
| 2533 | } | 2535 | } |
| 2534 | 2536 | ||
| @@ -2576,6 +2578,7 @@ The value is TO. */) | |||
| 2576 | (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame) | 2578 | (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame) |
| 2577 | { | 2579 | { |
| 2578 | Lisp_Object lface, copy; | 2580 | Lisp_Object lface, copy; |
| 2581 | struct frame *f; | ||
| 2579 | 2582 | ||
| 2580 | CHECK_SYMBOL (from); | 2583 | CHECK_SYMBOL (from); |
| 2581 | CHECK_SYMBOL (to); | 2584 | CHECK_SYMBOL (to); |
| @@ -2586,6 +2589,7 @@ The value is TO. */) | |||
| 2586 | strings etc. because 20.2 didn't do it either. */ | 2589 | strings etc. because 20.2 didn't do it either. */ |
| 2587 | lface = lface_from_face_name (NULL, from, true); | 2590 | lface = lface_from_face_name (NULL, from, true); |
| 2588 | copy = Finternal_make_lisp_face (to, Qnil); | 2591 | copy = Finternal_make_lisp_face (to, Qnil); |
| 2592 | f = NULL; | ||
| 2589 | } | 2593 | } |
| 2590 | else | 2594 | else |
| 2591 | { | 2595 | { |
| @@ -2596,6 +2600,7 @@ The value is TO. */) | |||
| 2596 | CHECK_LIVE_FRAME (new_frame); | 2600 | CHECK_LIVE_FRAME (new_frame); |
| 2597 | lface = lface_from_face_name (XFRAME (frame), from, true); | 2601 | lface = lface_from_face_name (XFRAME (frame), from, true); |
| 2598 | copy = Finternal_make_lisp_face (to, new_frame); | 2602 | copy = Finternal_make_lisp_face (to, new_frame); |
| 2603 | f = XFRAME (new_frame); | ||
| 2599 | } | 2604 | } |
| 2600 | 2605 | ||
| 2601 | vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE); | 2606 | vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE); |
| @@ -2607,7 +2612,10 @@ The value is TO. */) | |||
| 2607 | free realized faces. */ | 2612 | free realized faces. */ |
| 2608 | if (NILP (Fget (to, Qface_no_inherit))) | 2613 | if (NILP (Fget (to, Qface_no_inherit))) |
| 2609 | { | 2614 | { |
| 2610 | face_change = true; | 2615 | if (f) |
| 2616 | f->face_change = 1; | ||
| 2617 | else | ||
| 2618 | face_change = true; | ||
| 2611 | windows_or_buffers_changed = 55; | 2619 | windows_or_buffers_changed = 55; |
| 2612 | } | 2620 | } |
| 2613 | 2621 | ||
| @@ -2630,6 +2638,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 2630 | /* Set one of enum font_property_index (> 0) if ATTR is one of | 2638 | /* Set one of enum font_property_index (> 0) if ATTR is one of |
| 2631 | font-related attributes other than QCfont and QCfontset. */ | 2639 | font-related attributes other than QCfont and QCfontset. */ |
| 2632 | enum font_property_index prop_index = 0; | 2640 | enum font_property_index prop_index = 0; |
| 2641 | struct frame *f; | ||
| 2633 | 2642 | ||
| 2634 | CHECK_SYMBOL (face); | 2643 | CHECK_SYMBOL (face); |
| 2635 | CHECK_SYMBOL (attr); | 2644 | CHECK_SYMBOL (attr); |
| @@ -2650,6 +2659,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 2650 | /* Set lface to the Lisp attribute vector of FACE. */ | 2659 | /* Set lface to the Lisp attribute vector of FACE. */ |
| 2651 | if (EQ (frame, Qt)) | 2660 | if (EQ (frame, Qt)) |
| 2652 | { | 2661 | { |
| 2662 | f = NULL; | ||
| 2653 | lface = lface_from_face_name (NULL, face, true); | 2663 | lface = lface_from_face_name (NULL, face, true); |
| 2654 | 2664 | ||
| 2655 | /* When updating face-new-frame-defaults, we put :ignore-defface | 2665 | /* When updating face-new-frame-defaults, we put :ignore-defface |
| @@ -2665,9 +2675,10 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 2665 | { | 2675 | { |
| 2666 | if (NILP (frame)) | 2676 | if (NILP (frame)) |
| 2667 | frame = selected_frame; | 2677 | frame = selected_frame; |
| 2678 | f = XFRAME (frame); | ||
| 2668 | 2679 | ||
| 2669 | CHECK_LIVE_FRAME (frame); | 2680 | CHECK_LIVE_FRAME (frame); |
| 2670 | lface = lface_from_face_name (XFRAME (frame), face, false); | 2681 | lface = lface_from_face_name (f, face, false); |
| 2671 | 2682 | ||
| 2672 | /* If a frame-local face doesn't exist yet, create one. */ | 2683 | /* If a frame-local face doesn't exist yet, create one. */ |
| 2673 | if (NILP (lface)) | 2684 | if (NILP (lface)) |
| @@ -2989,11 +3000,11 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 2989 | else if (EQ (attr, QCfont)) | 3000 | else if (EQ (attr, QCfont)) |
| 2990 | { | 3001 | { |
| 2991 | #ifdef HAVE_WINDOW_SYSTEM | 3002 | #ifdef HAVE_WINDOW_SYSTEM |
| 2992 | if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame))) | 3003 | if (EQ (frame, Qt) || FRAME_WINDOW_P (f)) |
| 2993 | { | 3004 | { |
| 2994 | if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3005 | if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
| 2995 | { | 3006 | { |
| 2996 | struct frame *f; | 3007 | struct frame *f1; |
| 2997 | 3008 | ||
| 2998 | old_value = LFACE_FONT (lface); | 3009 | old_value = LFACE_FONT (lface); |
| 2999 | if (! FONTP (value)) | 3010 | if (! FONTP (value)) |
| @@ -3013,28 +3024,29 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3013 | signal_error ("Invalid font or font-spec", value); | 3024 | signal_error ("Invalid font or font-spec", value); |
| 3014 | } | 3025 | } |
| 3015 | if (EQ (frame, Qt)) | 3026 | if (EQ (frame, Qt)) |
| 3016 | f = XFRAME (selected_frame); | 3027 | f1 = XFRAME (selected_frame); |
| 3017 | else | 3028 | else |
| 3018 | f = XFRAME (frame); | 3029 | f1 = XFRAME (frame); |
| 3019 | 3030 | ||
| 3020 | /* FIXME: | 3031 | /* FIXME: |
| 3021 | If frame is t, and selected frame is a tty frame, the font | 3032 | If frame is t, and selected frame is a tty frame, the font |
| 3022 | can't be realized. An improvement would be to loop over frames | 3033 | can't be realized. An improvement would be to loop over frames |
| 3023 | for a non-tty frame and use that. See discussion in Bug#18573. | 3034 | for a non-tty frame and use that. See discussion in Bug#18573. |
| 3024 | For a daemon, frame may be an initial frame (Bug#18869). */ | 3035 | For a daemon, frame may be an initial frame (Bug#18869). */ |
| 3025 | if (FRAME_WINDOW_P (f)) | 3036 | if (FRAME_WINDOW_P (f1)) |
| 3026 | { | 3037 | { |
| 3027 | if (! FONT_OBJECT_P (value)) | 3038 | if (! FONT_OBJECT_P (value)) |
| 3028 | { | 3039 | { |
| 3029 | Lisp_Object *attrs = XVECTOR (lface)->contents; | 3040 | Lisp_Object *attrs = XVECTOR (lface)->contents; |
| 3030 | Lisp_Object font_object; | 3041 | Lisp_Object font_object; |
| 3031 | 3042 | ||
| 3032 | font_object = font_load_for_lface (f, attrs, value); | 3043 | font_object = font_load_for_lface (f1, attrs, value); |
| 3033 | if (NILP (font_object)) | 3044 | if (NILP (font_object)) |
| 3034 | signal_error ("Font not available", value); | 3045 | signal_error ("Font not available", value); |
| 3035 | value = font_object; | 3046 | value = font_object; |
| 3036 | } | 3047 | } |
| 3037 | set_lface_from_font (f, lface, value, true); | 3048 | set_lface_from_font (f1, lface, value, true); |
| 3049 | f1->face_change = 1; | ||
| 3038 | } | 3050 | } |
| 3039 | } | 3051 | } |
| 3040 | else | 3052 | else |
| @@ -3045,7 +3057,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3045 | else if (EQ (attr, QCfontset)) | 3057 | else if (EQ (attr, QCfontset)) |
| 3046 | { | 3058 | { |
| 3047 | #ifdef HAVE_WINDOW_SYSTEM | 3059 | #ifdef HAVE_WINDOW_SYSTEM |
| 3048 | if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame))) | 3060 | if (EQ (frame, Qt) || FRAME_WINDOW_P (f)) |
| 3049 | { | 3061 | { |
| 3050 | Lisp_Object tmp; | 3062 | Lisp_Object tmp; |
| 3051 | 3063 | ||
| @@ -3107,7 +3119,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3107 | && NILP (Fget (face, Qface_no_inherit)) | 3119 | && NILP (Fget (face, Qface_no_inherit)) |
| 3108 | && NILP (Fequal (old_value, value))) | 3120 | && NILP (Fequal (old_value, value))) |
| 3109 | { | 3121 | { |
| 3110 | face_change = true; | 3122 | f->face_change = true; |
| 3111 | windows_or_buffers_changed = 56; | 3123 | windows_or_buffers_changed = 56; |
| 3112 | } | 3124 | } |
| 3113 | 3125 | ||
| @@ -3280,7 +3292,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param, | |||
| 3280 | if (!NILP (face) | 3292 | if (!NILP (face) |
| 3281 | && NILP (Fget (face, Qface_no_inherit))) | 3293 | && NILP (Fget (face, Qface_no_inherit))) |
| 3282 | { | 3294 | { |
| 3283 | face_change = true; | 3295 | f->face_change = true; |
| 3284 | windows_or_buffers_changed = 57; | 3296 | windows_or_buffers_changed = 57; |
| 3285 | } | 3297 | } |
| 3286 | } | 3298 | } |