From: Po Lu Date: Tue, 15 Nov 2022 11:07:44 +0000 (+0800) Subject: Fix recent Cairo xsettings changes X-Git-Tag: emacs-29.0.90~1616^2~158 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=833e60ae1a5dd4301eb556460285414f4fea9fec;p=emacs.git Fix recent Cairo xsettings changes * lisp/dynamic-setting.el (font-setting-change-default-font): Instead of setting the font frame parameter, just clear the font and face cache and redraw the display. This will re-open all fonts as well. * src/ftcrfont.c (ftcrfont_get_default_font_options): New function. * src/ftfont.h: Export. * src/xsettings.c (apply_xft_settings): Call that function to obtain the default font settings on Cairo. (bug#58912, bug#59283, bug#59271) --- diff --git a/lisp/dynamic-setting.el b/lisp/dynamic-setting.el index 8ac9a1e9e6a..ff7bf182d1b 100644 --- a/lisp/dynamic-setting.el +++ b/lisp/dynamic-setting.el @@ -51,19 +51,12 @@ the current form for the frame (i.e. hinting or somesuch changed)." ;; Set the font on all current and future frames, as though ;; the `default' face had been "set for this session": (set-frame-font new-font nil frame-list) - ;; Just redraw the existing fonts on all frames: - (dolist (f frame-list) - (let ((frame-font - (or (font-get (face-attribute 'default :font f 'default) - :user-spec) - (frame-parameter f 'font-parameter)))) - (when frame-font - (set-frame-parameter f 'font-parameter frame-font) - (set-face-attribute 'default f - :width 'normal - :weight 'normal - :slant 'normal - :font frame-font)))))))) + ;; Just redraw the existing fonts on all frames, by clearing + ;; the font and face caches. This will cause all fonts to be + ;; recreated. + (clear-font-cache) + (clear-face-cache t) + (redraw-display))))) (defun dynamic-setting-handle-config-changed-event (event) "Handle config-changed-event on the display in EVENT. diff --git a/src/ftcrfont.c b/src/ftcrfont.c index dc765e5aee4..ede8f1323cd 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -737,7 +737,7 @@ struct font_driver const ftcrfont_driver = .filter_properties = ftfont_filter_properties, .combining_capability = ftfont_combining_capability, #ifdef HAVE_PGTK - .cached_font_ok = ftcrfont_cached_font_ok + .cached_font_ok = ftcrfont_cached_font_ok, #endif }; #ifdef HAVE_HARFBUZZ @@ -755,6 +755,42 @@ syms_of_ftcrfont (void) pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper); } +#ifdef HAVE_X_WINDOWS + +/* Place the default font options used by Cairo on the given display + in OPTIONS. */ + +void +ftcrfont_get_default_font_options (struct x_display_info *dpyinfo, + cairo_font_options_t *options) +{ + Pixmap drawable; + cairo_surface_t *surface; + + /* Cairo doesn't allow fetching the default font options for a + display, so the only option is to create a drawable, and an Xlib + surface for that drawable, and to get the font options from there + instead. */ + + drawable = XCreatePixmap (dpyinfo->display, dpyinfo->root_window, + 1, 1, dpyinfo->n_planes); + surface = cairo_xlib_surface_create (dpyinfo->display, drawable, + dpyinfo->visual, 1, 1); + + if (!surface) + { + XFreePixmap (dpyinfo->display, drawable); + return; + } + + cairo_surface_get_font_options (surface, options); + XFreePixmap (dpyinfo->display, drawable); + cairo_surface_destroy (surface); + return; +} + +#endif + static void syms_of_ftcrfont_for_pdumper (void) { diff --git a/src/ftfont.h b/src/ftfont.h index cfab8d3154f..ee56e2d7608 100644 --- a/src/ftfont.h +++ b/src/ftfont.h @@ -84,4 +84,11 @@ struct font_info #endif }; +#if defined USE_CAIRO && defined HAVE_X_WINDOWS + +extern void ftcrfont_get_default_font_options (struct x_display_info *, + cairo_font_options_t *); + +#endif /* USE_CAIRO && HAVE_X_WINDOWS */ + #endif /* EMACS_FTFONT_H */ diff --git a/src/xsettings.c b/src/xsettings.c index 15e7ff54995..1a9f1a8d5ae 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -56,6 +56,7 @@ typedef unsigned int CARD32; #ifdef USE_CAIRO #include +#include "ftfont.h" #elif defined HAVE_XFT #include #endif @@ -826,6 +827,7 @@ apply_xft_settings (Display_Info *dpyinfo, #else FcConfigSubstitute (NULL, pat, FcMatchPattern); options = cairo_font_options_create (); + ftcrfont_get_default_font_options (dpyinfo, options); cairo_ft_font_options_substitute (options, pat); cairo_font_options_destroy (options); FcDefaultSubstitute (pat);