diff options
author | Po Lu <luangruo@yahoo.com> | 2022-11-19 13:59:53 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-11-19 13:59:53 +0800 |
commit | b18d4dbe0d64bd1277731f9a7faedbb4dd3cd197 (patch) | |
tree | f611fd6ba7cf9a19f7b9ba317840d9b04daaea71 /src | |
parent | 10701635cfefde5e416215d72f4dababe0ce8d7f (diff) | |
download | emacs-b18d4dbe0d64bd1277731f9a7faedbb4dd3cd197.tar.gz emacs-b18d4dbe0d64bd1277731f9a7faedbb4dd3cd197.tar.bz2 emacs-b18d4dbe0d64bd1277731f9a7faedbb4dd3cd197.zip |
Fix automatic DPI adjustment and add workarounds for some systems
* lisp/faces.el (x-create-frame-with-faces): New field
`delayed-font'. Set the `font-parameter' property to `font' in
the given parameter list after face-set-after-frame-default is
called.
* src/fontset.c (Fset_fontset_font): Avoid changing
`font-parameter' with the call to Fmodify_frame_parameters.
* src/frame.c (gui_set_frame_parameters_1): New function.
Factor out gui_set_frame_parameters here, and add an argument
DEFAULT_PARAMETER. If the `font' parameter is set, and
`default_parameter' is not, then set the `font-parameter' frame
parameter to the `font' parameter as well, to keep track of
which user-specified `font' frame parameter set the default
face's font on the frame.
(gui_set_frame_parameters): Call gui_set_frame_parameters_1 with
new arg set to false.
(gui_set_font): Remove broken implementation of
`font-parameter'.
(gui_default_parameter): If the default value was used, then
call gui_set_frame_parameters_1 with the new argument set to
false. This is because no font was specified as a frame
parameter by the user, so Freconsider_frame_fonts is free to do
anything it wants.
(Freconsider_frame_fonts): If `font-parameter' is set, then use
it.
(syms_of_frame): New defsym Qfont_parameter.
* src/frame.h: Update prototypes.
* src/haikuterm.c (haiku_default_font_parameter):
* src/pgtkfns.c (pgtk_default_font_parameter):
* src/w32fns.c (w32_default_font_parameter): Stop setting
`font-parameter' here. This code resulted in decades of
automatic font rescaling not working correctly.
* src/xfaces.c (set_font_frame_param): Clear the
`font-parameter' frame parameter.
(Finternal_merge_in_global_face):
* src/xfns.c (x_default_font_parameter): Avoid changing
`font-parameter' in response to changes to face attributes.
* src/xsettings.c (apply_xft_settings): Add workaround for
Cairo. (bug#59371, bug#59347, bug#59283, bug#59271, bug#59285,
bug#59306.)
Diffstat (limited to 'src')
-rw-r--r-- | src/fontset.c | 12 | ||||
-rw-r--r-- | src/frame.c | 80 | ||||
-rw-r--r-- | src/frame.h | 1 | ||||
-rw-r--r-- | src/haikuterm.c | 15 | ||||
-rw-r--r-- | src/pgtkfns.c | 7 | ||||
-rw-r--r-- | src/w32fns.c | 8 | ||||
-rw-r--r-- | src/xfaces.c | 20 | ||||
-rw-r--r-- | src/xfns.c | 7 | ||||
-rw-r--r-- | src/xsettings.c | 8 |
9 files changed, 102 insertions, 56 deletions
diff --git a/src/fontset.c b/src/fontset.c index 4b91eff2ef6..b82737d005a 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -1663,7 +1663,17 @@ overwrites the previous settings. */) { update_auto_fontset_alist (font_object, fontset_obj); AUTO_FRAME_ARG (arg, Qfont, Fcons (fontset, font_object)); - Fmodify_frame_parameters (fr, arg); + +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (f)) + /* This is a window-system frame. Prevent changes of + the `font' parameter here from messing with the + `font-parameter' frame property, as the frame + parameter is not being changed by the user. */ + gui_set_frame_parameters_1 (f, arg, true); + else +#endif + Fmodify_frame_parameters (fr, arg); } } } diff --git a/src/frame.c b/src/frame.c index 151a4029958..b57b296be54 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4119,10 +4119,17 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what, If a parameter is not specially recognized, do nothing special; otherwise call the `gui_set_...' function for that parameter. Except for certain geometry properties, always call store_frame_param - to store the new value in the parameter alist. */ + to store the new value in the parameter alist. + + DEFAULT_PARAMETER should be set if the alist was not specified by + the user, or by the face code to set the `font' parameter. In that + case, the `font-parameter' frame parameter should not be changed, + so dynamic-setting.el can restore the user's selected font + correctly. */ void -gui_set_frame_parameters (struct frame *f, Lisp_Object alist) +gui_set_frame_parameters_1 (struct frame *f, Lisp_Object alist, + bool default_parameter) { Lisp_Object tail, frame; @@ -4249,7 +4256,7 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist) } else { - register Lisp_Object param_index, old_value; + Lisp_Object param_index, old_value; old_value = get_frame_param (f, prop); @@ -4260,6 +4267,12 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist) && XFIXNAT (param_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)]) (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value); + + if (!default_parameter && EQ (prop, Qfont)) + /* The user manually specified the `font' frame parameter. + Save that parameter for future use by the + dynamic-setting code. */ + store_frame_param (f, Qfont_parameter, val); } } @@ -4410,6 +4423,11 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist) SAFE_FREE (); } +void +gui_set_frame_parameters (struct frame *f, Lisp_Object alist) +{ + gui_set_frame_parameters_1 (f, alist, false); +} /* Insert a description of internally-recorded parameters of frame F into the parameter alist *ALISTPTR that is to be given to the user. @@ -4586,9 +4604,6 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { Lisp_Object font_object; int fontset = -1; -#ifdef HAVE_X_WINDOWS - Lisp_Object font_param = arg; -#endif /* Set the frame parameter back to the old value because we may fail to use ARG as the new parameter value. */ @@ -4627,16 +4642,10 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) error ("Unknown fontset: %s", SDATA (XCAR (arg))); font_object = XCDR (arg); arg = AREF (font_object, FONT_NAME_INDEX); -#ifdef HAVE_X_WINDOWS - font_param = Ffont_get (font_object, QCname); -#endif } else if (FONT_OBJECT_P (arg)) { font_object = arg; -#ifdef HAVE_X_WINDOWS - font_param = Ffont_get (font_object, QCname); -#endif /* This is to store the XLFD font name in the frame parameter for backward compatibility. We should store the font-object itself in the future. */ @@ -4667,9 +4676,7 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) if (FRAME_TERMINAL (f)->set_new_font_hook) FRAME_TERMINAL (f)->set_new_font_hook (f, font_object, fontset); store_frame_param (f, Qfont, arg); -#ifdef HAVE_X_WINDOWS - store_frame_param (f, Qfont_parameter, font_param); -#endif + /* Recalculate tabbar height. */ f->n_tab_bar_rows = 0; /* Recalculate toolbar height. */ @@ -5451,12 +5458,20 @@ gui_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop, enum resource_types type) { Lisp_Object tem; + bool was_unbound; tem = gui_frame_get_arg (f, alist, prop, xprop, xclass, type); + if (BASE_EQ (tem, Qunbound)) - tem = deflt; + { + tem = deflt; + was_unbound = true; + } + else + was_unbound = false; + AUTO_FRAME_ARG (arg, prop, tem); - gui_set_frame_parameters (f, arg); + gui_set_frame_parameters_1 (f, arg, was_unbound); return tem; } @@ -5959,16 +5974,26 @@ have changed. */) (Lisp_Object frame) { struct frame *f; - Lisp_Object params; + Lisp_Object params, font_parameter; f = decode_window_system_frame (frame); /* Kludge: if a `font' parameter was already specified, - create an alist containing just that parameter. (bug#59371) */ + create an alist containing just that parameter. (bug#59371) + + This sounds so simple, right? Well, read on below: */ params = Qnil; - if (!NILP (get_frame_param (f, Qfont))) - params = list1 (Fcons (Qfont, get_frame_param (f, Qfont))); + /* The difference between Qfont and Qfont_parameter is that the + latter is not set automatically by the likes of x_new_font, and + implicitly as the default face is realized. It is only set when + the user specifically specifies a `font' frame parameter, and is + cleared the moment the frame's font becomes defined by a face + attribute, instead of through the `font' frame parameter. */ + font_parameter = get_frame_param (f, Qfont_parameter); + + if (!NILP (font_parameter)) + params = list1 (Fcons (Qfont, font_parameter)); /* First, call this to reinitialize any font backend specific stuff. */ @@ -5976,10 +6001,22 @@ have changed. */) if (FRAME_RIF (f)->default_font_parameter) FRAME_RIF (f)->default_font_parameter (f, params); + /* For a mysterious reason, x_default_font_parameter sets Qfont to + nil in the alist! */ + + if (!NILP (font_parameter)) + params = list1 (Fcons (Qfont, font_parameter)); + /* Now call this to apply the existing value(s) of the `default' face. */ call2 (Qface_set_after_frame_default, frame, params); + /* Restore the value of the `font-parameter' parameter, as + `face-set-after-frame-default' will have changed it through its + calls to `set-face-attribute'. */ + if (!NILP (font_parameter)) + store_frame_param (f, Qfont_parameter, font_parameter); + return Qnil; } @@ -6240,6 +6277,7 @@ syms_of_frame (void) DEFSYM (Qiconify_top_level, "iconify-top-level"); DEFSYM (Qmake_invisible, "make-invisible"); DEFSYM (Quse_frame_synchronization, "use-frame-synchronization"); + DEFSYM (Qfont_parameter, "font-parameter"); { int i; diff --git a/src/frame.h b/src/frame.h index 458b6257e49..d6fd62b2ac2 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1670,6 +1670,7 @@ IMAGE_OPT_FROM_ID (struct frame *f, int id) /* The class of this X application. */ #define EMACS_CLASS "Emacs" +extern void gui_set_frame_parameters_1 (struct frame *, Lisp_Object, bool); extern void gui_set_frame_parameters (struct frame *, Lisp_Object); extern void gui_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object); extern void gui_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object); diff --git a/src/haikuterm.c b/src/haikuterm.c index 4e32b747160..496480cbc09 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3007,9 +3007,11 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms) font = font_open_by_spec (f, Ffont_get_system_font ()); if (NILP (font)) - font = !NILP (font_param) ? font_param - : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font", - RES_TYPE_STRING); + font = (!NILP (font_param) + ? font_param + : gui_display_get_arg (dpyinfo, parms, Qfont, + "font", "Font", + RES_TYPE_STRING)); if (! FONTP (font) && ! STRINGP (font)) { @@ -3029,13 +3031,6 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms) if (NILP (font)) error ("No suitable font was found"); } - else if (!NILP (font_param)) - { - /* Remember the explicit font parameter, so we can re-apply it - after we've applied the `default' face settings. */ - AUTO_FRAME_ARG (arg, Qfont_parameter, font_param); - gui_set_frame_parameters (f, arg); - } gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); diff --git a/src/pgtkfns.c b/src/pgtkfns.c index f370f039780..a32067af818 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -1121,13 +1121,6 @@ pgtk_default_font_parameter (struct frame *f, Lisp_Object parms) if (NILP (font)) error ("No suitable font was found"); } - else if (!NILP (font_param)) - { - /* Remember the explicit font parameter, so we can re-apply it after - we've applied the `default' face settings. */ - AUTO_FRAME_ARG (arg, Qfont_parameter, font_param); - gui_set_frame_parameters (f, arg); - } /* This call will make X resources override any system font setting. */ gui_default_parameter (f, parms, Qfont, font, "font", "Font", diff --git a/src/w32fns.c b/src/w32fns.c index e441665804e..887e5a1f7b7 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -5794,13 +5794,7 @@ w32_default_font_parameter (struct frame *f, Lisp_Object parms) if (NILP (font)) error ("No suitable font was found"); } - else if (!NILP (font_param)) - { - /* Remember the explicit font parameter, so we can re-apply it after - we've applied the `default' face settings. */ - gui_set_frame_parameters (f, Fcons (Fcons (Qfont_parameter, font_param), - Qnil)); - } + gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); } diff --git a/src/xfaces.c b/src/xfaces.c index ed76db9adb7..df078227c8a 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -3809,8 +3809,12 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface) ASET (lface, LFACE_FONT_INDEX, font); } f->default_face_done_p = false; - AUTO_FRAME_ARG (arg, Qfont, font); - Fmodify_frame_parameters (frame, arg); + AUTO_LIST2 (arg, AUTO_CONS_EXPR (Qfont, font), + /* Clear the `font-parameter' frame property, as the + font is now being specified by a face, not a + frame property. */ + AUTO_CONS_EXPR (Qfont_parameter, Qnil)); + gui_set_frame_parameters_1 (f, arg, true); } } @@ -4208,7 +4212,17 @@ Default face attributes override any local face attributes. */) { Lisp_Object name = newface->font->props[FONT_NAME_INDEX]; AUTO_FRAME_ARG (arg, Qfont, name); - Fmodify_frame_parameters (frame, arg); + +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (f)) + /* This is a window-system frame. Prevent changes of + the `font' parameter here from messing with the + `font-parameter' frame property, as the frame + parameter is not being changed by the user. */ + gui_set_frame_parameters_1 (f, arg, true); + else +#endif + Fmodify_frame_parameters (frame, arg); } if (STRINGP (gvec[LFACE_FOREGROUND_INDEX])) diff --git a/src/xfns.c b/src/xfns.c index 8ee26d713aa..2ff70f79851 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4551,13 +4551,6 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms) if (NILP (font)) error ("No suitable font was found"); } - else if (!NILP (font_param)) - { - /* Remember the explicit font parameter, so we can re-apply it after - we've applied the `default' face settings. */ - AUTO_FRAME_ARG (arg, Qfont_parameter, font_param); - gui_set_frame_parameters (f, arg); - } /* This call will make X resources override any system font setting. */ gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); diff --git a/src/xsettings.c b/src/xsettings.c index 1a9f1a8d5ae..f1ee84a1a02 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -886,6 +886,14 @@ apply_xft_settings (Display_Info *dpyinfo, } #endif +#ifdef USE_CAIRO + /* When Cairo is being used, set oldsettings.dpi to dpyinfo->resx. + This is a gross hack, but seeing as Cairo fails to report + anything reasonable, just use it to avoid config-changed events + being sent at startup. */ + oldsettings.dpi = dpyinfo->resx; +#endif + if ((settings->seen & SEEN_DPI) != 0 && settings->dpi > 0 /* The following conjunct avoids setting `changed' to true when |