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.
This commit is contained in:
parent
3fbc53b09c
commit
e573d08ef1
5 changed files with 49 additions and 21 deletions
|
@ -810,9 +810,11 @@ Value is the modified color alist for FRAME."
|
|||
(while colors
|
||||
(tty-color-define (car color) (cadr color) (cddr color))
|
||||
(setq colors (cdr colors) color (car colors)))
|
||||
;; Modifying color mappings means realized faces don't
|
||||
;; use the right colors, so clear them.
|
||||
(clear-face-cache)))
|
||||
;; Modifying color mappings means realized faces don't use the
|
||||
;; right colors, so clear them, if we modified colors on a TTY
|
||||
;; frame.
|
||||
(or (display-graphic-p)
|
||||
(clear-face-cache))))
|
||||
|
||||
(defun tty-color-canonicalize (color)
|
||||
"Return COLOR in canonical form.
|
||||
|
|
|
@ -3539,7 +3539,8 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
|
|||
(f, bgcolor, Qnil);
|
||||
}
|
||||
|
||||
Fclear_face_cache (Qnil);
|
||||
clear_face_cache (true);
|
||||
windows_or_buffers_changed = 70;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -335,6 +335,9 @@ struct frame
|
|||
/* Set to true after this frame was made by `make-frame'. */
|
||||
bool_bf after_make_frame : 1;
|
||||
|
||||
/* Non-zero if this frame's faces need to be recomputed. */
|
||||
bool_bf face_change : 1;
|
||||
|
||||
/* Bitfield area ends here. */
|
||||
|
||||
/* Number of lines (rounded up) of tool bar. REMOVE THIS */
|
||||
|
|
16
src/xdisp.c
16
src/xdisp.c
|
@ -2661,10 +2661,18 @@ init_iterator (struct it *it, struct window *w,
|
|||
free realized faces now because they depend on face definitions
|
||||
that might have changed. Don't free faces while there might be
|
||||
desired matrices pending which reference these faces. */
|
||||
if (face_change && !inhibit_free_realized_faces)
|
||||
if (!inhibit_free_realized_faces)
|
||||
{
|
||||
face_change = false;
|
||||
free_all_realized_faces (Qnil);
|
||||
if (face_change)
|
||||
{
|
||||
face_change = false;
|
||||
free_all_realized_faces (Qnil);
|
||||
}
|
||||
else if (XFRAME (w->frame)->face_change)
|
||||
{
|
||||
XFRAME (w->frame)->face_change = 0;
|
||||
free_all_realized_faces (w->frame);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
|
||||
|
@ -13541,6 +13549,7 @@ redisplay_internal (void)
|
|||
&& FRAME_VISIBLE_P (XFRAME (w->frame))
|
||||
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
|
||||
&& !XFRAME (w->frame)->cursor_type_changed
|
||||
&& !XFRAME (w->frame)->face_change
|
||||
/* Make sure recorded data applies to current buffer, etc. */
|
||||
&& this_line_buffer == current_buffer
|
||||
&& match_p
|
||||
|
@ -15887,6 +15896,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
|
|||
&& REDISPLAY_SOME_P ()
|
||||
&& !w->redisplay
|
||||
&& !w->update_mode_line
|
||||
&& !f->face_change
|
||||
&& !f->redisplay
|
||||
&& !buffer->text->redisplay
|
||||
&& BUF_PT (buffer) == w->last_point)
|
||||
|
|
40
src/xfaces.c
40
src/xfaces.c
|
@ -687,7 +687,6 @@ clear_face_cache (bool clear_fonts_p)
|
|||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
|
||||
doc: /* Clear face caches on all frames.
|
||||
Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
|
||||
|
@ -2528,7 +2527,10 @@ Value is a vector of face attributes. */)
|
|||
free realized faces. */
|
||||
if (NILP (Fget (face, Qface_no_inherit)))
|
||||
{
|
||||
face_change = true;
|
||||
if (f)
|
||||
f->face_change = 1;
|
||||
else
|
||||
face_change = true;
|
||||
windows_or_buffers_changed = 54;
|
||||
}
|
||||
|
||||
|
@ -2576,6 +2578,7 @@ The value is TO. */)
|
|||
(Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
|
||||
{
|
||||
Lisp_Object lface, copy;
|
||||
struct frame *f;
|
||||
|
||||
CHECK_SYMBOL (from);
|
||||
CHECK_SYMBOL (to);
|
||||
|
@ -2586,6 +2589,7 @@ The value is TO. */)
|
|||
strings etc. because 20.2 didn't do it either. */
|
||||
lface = lface_from_face_name (NULL, from, true);
|
||||
copy = Finternal_make_lisp_face (to, Qnil);
|
||||
f = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2596,6 +2600,7 @@ The value is TO. */)
|
|||
CHECK_LIVE_FRAME (new_frame);
|
||||
lface = lface_from_face_name (XFRAME (frame), from, true);
|
||||
copy = Finternal_make_lisp_face (to, new_frame);
|
||||
f = XFRAME (new_frame);
|
||||
}
|
||||
|
||||
vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
|
||||
|
@ -2607,7 +2612,10 @@ The value is TO. */)
|
|||
free realized faces. */
|
||||
if (NILP (Fget (to, Qface_no_inherit)))
|
||||
{
|
||||
face_change = true;
|
||||
if (f)
|
||||
f->face_change = 1;
|
||||
else
|
||||
face_change = true;
|
||||
windows_or_buffers_changed = 55;
|
||||
}
|
||||
|
||||
|
@ -2630,6 +2638,7 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
/* Set one of enum font_property_index (> 0) if ATTR is one of
|
||||
font-related attributes other than QCfont and QCfontset. */
|
||||
enum font_property_index prop_index = 0;
|
||||
struct frame *f;
|
||||
|
||||
CHECK_SYMBOL (face);
|
||||
CHECK_SYMBOL (attr);
|
||||
|
@ -2650,6 +2659,7 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
/* Set lface to the Lisp attribute vector of FACE. */
|
||||
if (EQ (frame, Qt))
|
||||
{
|
||||
f = NULL;
|
||||
lface = lface_from_face_name (NULL, face, true);
|
||||
|
||||
/* 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
|
|||
{
|
||||
if (NILP (frame))
|
||||
frame = selected_frame;
|
||||
f = XFRAME (frame);
|
||||
|
||||
CHECK_LIVE_FRAME (frame);
|
||||
lface = lface_from_face_name (XFRAME (frame), face, false);
|
||||
lface = lface_from_face_name (f, face, false);
|
||||
|
||||
/* If a frame-local face doesn't exist yet, create one. */
|
||||
if (NILP (lface))
|
||||
|
@ -2989,11 +3000,11 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
else if (EQ (attr, QCfont))
|
||||
{
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
|
||||
if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
|
||||
{
|
||||
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
|
||||
{
|
||||
struct frame *f;
|
||||
struct frame *f1;
|
||||
|
||||
old_value = LFACE_FONT (lface);
|
||||
if (! FONTP (value))
|
||||
|
@ -3013,28 +3024,29 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
signal_error ("Invalid font or font-spec", value);
|
||||
}
|
||||
if (EQ (frame, Qt))
|
||||
f = XFRAME (selected_frame);
|
||||
f1 = XFRAME (selected_frame);
|
||||
else
|
||||
f = XFRAME (frame);
|
||||
f1 = XFRAME (frame);
|
||||
|
||||
/* FIXME:
|
||||
If frame is t, and selected frame is a tty frame, the font
|
||||
can't be realized. An improvement would be to loop over frames
|
||||
for a non-tty frame and use that. See discussion in Bug#18573.
|
||||
For a daemon, frame may be an initial frame (Bug#18869). */
|
||||
if (FRAME_WINDOW_P (f))
|
||||
if (FRAME_WINDOW_P (f1))
|
||||
{
|
||||
if (! FONT_OBJECT_P (value))
|
||||
{
|
||||
Lisp_Object *attrs = XVECTOR (lface)->contents;
|
||||
Lisp_Object font_object;
|
||||
|
||||
font_object = font_load_for_lface (f, attrs, value);
|
||||
font_object = font_load_for_lface (f1, attrs, value);
|
||||
if (NILP (font_object))
|
||||
signal_error ("Font not available", value);
|
||||
value = font_object;
|
||||
}
|
||||
set_lface_from_font (f, lface, value, true);
|
||||
set_lface_from_font (f1, lface, value, true);
|
||||
f1->face_change = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3045,7 +3057,7 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
else if (EQ (attr, QCfontset))
|
||||
{
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
|
||||
if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
|
||||
{
|
||||
Lisp_Object tmp;
|
||||
|
||||
|
@ -3107,7 +3119,7 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
&& NILP (Fget (face, Qface_no_inherit))
|
||||
&& NILP (Fequal (old_value, value)))
|
||||
{
|
||||
face_change = true;
|
||||
f->face_change = true;
|
||||
windows_or_buffers_changed = 56;
|
||||
}
|
||||
|
||||
|
@ -3280,7 +3292,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
|
|||
if (!NILP (face)
|
||||
&& NILP (Fget (face, Qface_no_inherit)))
|
||||
{
|
||||
face_change = true;
|
||||
f->face_change = true;
|
||||
windows_or_buffers_changed = 57;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue