[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master b828d36dede: Automatically redraw frames for filtered faces
From: |
Daniel Colascione |
Subject: |
master b828d36dede: Automatically redraw frames for filtered faces |
Date: |
Fri, 3 Jan 2025 23:49:19 -0500 (EST) |
branch: master
commit b828d36deded145ebbd3419f618cf52f7862c4c8
Author: Daniel Colascione <dancol@dancol.org>
Commit: Daniel Colascione <dancol@dancol.org>
Automatically redraw frames for filtered faces
Automatically redraw frames when we detect that a window
parameter used in a face filter is changed. (Bug#75291)
* src/window.c (Fset_window_parameter): redraw window, actually
whole frame in this implementation, on face-relevant parameter
change
(syms_of_window): add window_auto_redraw_on_parameter_change
* src/xfaces.c (evaluate_face_filter): record properties
---
src/window.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
src/xfaces.c | 3 +++
2 files changed, 50 insertions(+)
diff --git a/src/window.c b/src/window.c
index 5a10c381eaf..17bbe213e05 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2394,8 +2394,41 @@ Return VALUE. */)
{
register struct window *w = decode_any_window (window);
Lisp_Object old_alist_elt;
+ struct frame* f;
old_alist_elt = Fassq (parameter, w->window_parameters);
+
+ /* If this window parameter has been used in a face remapping filter
+ expression anywhere at any time and we changed its value, force a
+ from-scratch redisplay to make sure that everything that depends on
+ a face filtered on the window parameter value is up-to-date.
+
+ We compare with Qt here instead of using !NILP so that users can
+ set this property to a non-nil, non-t value to inhibit this
+ mechanism for a specific window parameter.
+
+ FIXME: instead of taking a sledgehammer to redisplay, we could be
+ more precise in tracking which display bits depend on which
+ remapped faces. In particular, 1) if a window parameter named in a
+ face filter affects only faces used in drawing fringes, we don't
+ need to redraw TTY frames, but if the filter is ever used in a
+ non-fringe context (e.g. the 'face' text property), we need to
+ redraw TTY frames too. 2) In the fringe case, we should limit the
+ redraw damage to the fringes of the affected window and not the
+ whole frame containing the window. Today, we seldom change window
+ parameters named in face filters. We should implement the
+ optimizations above when this assumption no longer holds. */
+ if (SYMBOLP (parameter)
+ && WINDOW_LIVE_P (window)
+ && EQ (Fget (parameter, QCfiltered), Qt)
+ && FRAME_WINDOW_P ((f = WINDOW_XFRAME (w)))
+ && !EQ (CDR_SAFE (old_alist_elt), value)
+ && window_auto_redraw_on_parameter_change)
+ {
+ f->face_change = 1;
+ fset_redisplay (f);
+ }
+
if (NILP (old_alist_elt))
wset_window_parameters
(w, Fcons (Fcons (parameter, value), w->window_parameters));
@@ -9071,6 +9104,20 @@ Elisp for testing purposes only. */);
window_dead_windows_table
= CALLN (Fmake_hash_table, QCweakness, Qt);
+ DEFVAR_BOOL ("window-auto-redraw-on-parameter-change",
+ window_auto_redraw_on_parameter_change,
+ doc: /* When non-nil, redraw based on face filters.
+When this variable is non-nil, force a potentially expensive redraw when
+a window parameter named in a `:window' expression for ':filtered'
+changes. This redraw is necessary for correctness; this variable is an
+escape hatch to recover performance in the case that our assumption that
+these parameter changes are rare does not hold.
+
+You can also inhibit the automatic redraw for a specific window
+parameter by setting the `:filtered` symbol property of the parameter
+name to `'ignore'. */);
+ window_auto_redraw_on_parameter_change = true;
+
defsubr (&Sselected_window);
defsubr (&Sold_selected_window);
defsubr (&Sminibuffer_window);
diff --git a/src/xfaces.c b/src/xfaces.c
index d1ca2e0d5d4..75fe73154ca 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -2512,6 +2512,9 @@ evaluate_face_filter (Lisp_Object filter, struct window
*w,
if (!NILP (filter))
goto err;
+ if (NILP (Fget (parameter, QCfiltered)))
+ Fput (parameter, QCfiltered, Qt);
+
bool match = false;
if (w)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master b828d36dede: Automatically redraw frames for filtered faces,
Daniel Colascione <=