aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-11-19 13:59:53 +0800
committerPo Lu2022-11-19 13:59:53 +0800
commitb18d4dbe0d64bd1277731f9a7faedbb4dd3cd197 (patch)
treef611fd6ba7cf9a19f7b9ba317840d9b04daaea71 /src
parent10701635cfefde5e416215d72f4dababe0ce8d7f (diff)
downloademacs-b18d4dbe0d64bd1277731f9a7faedbb4dd3cd197.tar.gz
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.c12
-rw-r--r--src/frame.c80
-rw-r--r--src/frame.h1
-rw-r--r--src/haikuterm.c15
-rw-r--r--src/pgtkfns.c7
-rw-r--r--src/w32fns.c8
-rw-r--r--src/xfaces.c20
-rw-r--r--src/xfns.c7
-rw-r--r--src/xsettings.c8
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. */)
1663 { 1663 {
1664 update_auto_fontset_alist (font_object, fontset_obj); 1664 update_auto_fontset_alist (font_object, fontset_obj);
1665 AUTO_FRAME_ARG (arg, Qfont, Fcons (fontset, font_object)); 1665 AUTO_FRAME_ARG (arg, Qfont, Fcons (fontset, font_object));
1666 Fmodify_frame_parameters (fr, arg); 1666
1667#ifdef HAVE_WINDOW_SYSTEM
1668 if (FRAME_WINDOW_P (f))
1669 /* This is a window-system frame. Prevent changes of
1670 the `font' parameter here from messing with the
1671 `font-parameter' frame property, as the frame
1672 parameter is not being changed by the user. */
1673 gui_set_frame_parameters_1 (f, arg, true);
1674 else
1675#endif
1676 Fmodify_frame_parameters (fr, arg);
1667 } 1677 }
1668 } 1678 }
1669 } 1679 }
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,
4119 If a parameter is not specially recognized, do nothing special; 4119 If a parameter is not specially recognized, do nothing special;
4120 otherwise call the `gui_set_...' function for that parameter. 4120 otherwise call the `gui_set_...' function for that parameter.
4121 Except for certain geometry properties, always call store_frame_param 4121 Except for certain geometry properties, always call store_frame_param
4122 to store the new value in the parameter alist. */ 4122 to store the new value in the parameter alist.
4123
4124 DEFAULT_PARAMETER should be set if the alist was not specified by
4125 the user, or by the face code to set the `font' parameter. In that
4126 case, the `font-parameter' frame parameter should not be changed,
4127 so dynamic-setting.el can restore the user's selected font
4128 correctly. */
4123 4129
4124void 4130void
4125gui_set_frame_parameters (struct frame *f, Lisp_Object alist) 4131gui_set_frame_parameters_1 (struct frame *f, Lisp_Object alist,
4132 bool default_parameter)
4126{ 4133{
4127 Lisp_Object tail, frame; 4134 Lisp_Object tail, frame;
4128 4135
@@ -4249,7 +4256,7 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
4249 } 4256 }
4250 else 4257 else
4251 { 4258 {
4252 register Lisp_Object param_index, old_value; 4259 Lisp_Object param_index, old_value;
4253 4260
4254 old_value = get_frame_param (f, prop); 4261 old_value = get_frame_param (f, prop);
4255 4262
@@ -4260,6 +4267,12 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
4260 && XFIXNAT (param_index) < ARRAYELTS (frame_parms) 4267 && XFIXNAT (param_index) < ARRAYELTS (frame_parms)
4261 && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)]) 4268 && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])
4262 (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value); 4269 (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value);
4270
4271 if (!default_parameter && EQ (prop, Qfont))
4272 /* The user manually specified the `font' frame parameter.
4273 Save that parameter for future use by the
4274 dynamic-setting code. */
4275 store_frame_param (f, Qfont_parameter, val);
4263 } 4276 }
4264 } 4277 }
4265 4278
@@ -4410,6 +4423,11 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
4410 SAFE_FREE (); 4423 SAFE_FREE ();
4411} 4424}
4412 4425
4426void
4427gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
4428{
4429 gui_set_frame_parameters_1 (f, alist, false);
4430}
4413 4431
4414/* Insert a description of internally-recorded parameters of frame F 4432/* Insert a description of internally-recorded parameters of frame F
4415 into the parameter alist *ALISTPTR that is to be given to the user. 4433 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)
4586{ 4604{
4587 Lisp_Object font_object; 4605 Lisp_Object font_object;
4588 int fontset = -1; 4606 int fontset = -1;
4589#ifdef HAVE_X_WINDOWS
4590 Lisp_Object font_param = arg;
4591#endif
4592 4607
4593 /* Set the frame parameter back to the old value because we may 4608 /* Set the frame parameter back to the old value because we may
4594 fail to use ARG as the new parameter value. */ 4609 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)
4627 error ("Unknown fontset: %s", SDATA (XCAR (arg))); 4642 error ("Unknown fontset: %s", SDATA (XCAR (arg)));
4628 font_object = XCDR (arg); 4643 font_object = XCDR (arg);
4629 arg = AREF (font_object, FONT_NAME_INDEX); 4644 arg = AREF (font_object, FONT_NAME_INDEX);
4630#ifdef HAVE_X_WINDOWS
4631 font_param = Ffont_get (font_object, QCname);
4632#endif
4633 } 4645 }
4634 else if (FONT_OBJECT_P (arg)) 4646 else if (FONT_OBJECT_P (arg))
4635 { 4647 {
4636 font_object = arg; 4648 font_object = arg;
4637#ifdef HAVE_X_WINDOWS
4638 font_param = Ffont_get (font_object, QCname);
4639#endif
4640 /* This is to store the XLFD font name in the frame parameter for 4649 /* This is to store the XLFD font name in the frame parameter for
4641 backward compatibility. We should store the font-object 4650 backward compatibility. We should store the font-object
4642 itself in the future. */ 4651 itself in the future. */
@@ -4667,9 +4676,7 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
4667 if (FRAME_TERMINAL (f)->set_new_font_hook) 4676 if (FRAME_TERMINAL (f)->set_new_font_hook)
4668 FRAME_TERMINAL (f)->set_new_font_hook (f, font_object, fontset); 4677 FRAME_TERMINAL (f)->set_new_font_hook (f, font_object, fontset);
4669 store_frame_param (f, Qfont, arg); 4678 store_frame_param (f, Qfont, arg);
4670#ifdef HAVE_X_WINDOWS 4679
4671 store_frame_param (f, Qfont_parameter, font_param);
4672#endif
4673 /* Recalculate tabbar height. */ 4680 /* Recalculate tabbar height. */
4674 f->n_tab_bar_rows = 0; 4681 f->n_tab_bar_rows = 0;
4675 /* Recalculate toolbar height. */ 4682 /* Recalculate toolbar height. */
@@ -5451,12 +5458,20 @@ gui_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
5451 enum resource_types type) 5458 enum resource_types type)
5452{ 5459{
5453 Lisp_Object tem; 5460 Lisp_Object tem;
5461 bool was_unbound;
5454 5462
5455 tem = gui_frame_get_arg (f, alist, prop, xprop, xclass, type); 5463 tem = gui_frame_get_arg (f, alist, prop, xprop, xclass, type);
5464
5456 if (BASE_EQ (tem, Qunbound)) 5465 if (BASE_EQ (tem, Qunbound))
5457 tem = deflt; 5466 {
5467 tem = deflt;
5468 was_unbound = true;
5469 }
5470 else
5471 was_unbound = false;
5472
5458 AUTO_FRAME_ARG (arg, prop, tem); 5473 AUTO_FRAME_ARG (arg, prop, tem);
5459 gui_set_frame_parameters (f, arg); 5474 gui_set_frame_parameters_1 (f, arg, was_unbound);
5460 return tem; 5475 return tem;
5461} 5476}
5462 5477
@@ -5959,16 +5974,26 @@ have changed. */)
5959 (Lisp_Object frame) 5974 (Lisp_Object frame)
5960{ 5975{
5961 struct frame *f; 5976 struct frame *f;
5962 Lisp_Object params; 5977 Lisp_Object params, font_parameter;
5963 5978
5964 f = decode_window_system_frame (frame); 5979 f = decode_window_system_frame (frame);
5965 5980
5966 /* Kludge: if a `font' parameter was already specified, 5981 /* Kludge: if a `font' parameter was already specified,
5967 create an alist containing just that parameter. (bug#59371) */ 5982 create an alist containing just that parameter. (bug#59371)
5983
5984 This sounds so simple, right? Well, read on below: */
5968 params = Qnil; 5985 params = Qnil;
5969 5986
5970 if (!NILP (get_frame_param (f, Qfont))) 5987 /* The difference between Qfont and Qfont_parameter is that the
5971 params = list1 (Fcons (Qfont, get_frame_param (f, Qfont))); 5988 latter is not set automatically by the likes of x_new_font, and
5989 implicitly as the default face is realized. It is only set when
5990 the user specifically specifies a `font' frame parameter, and is
5991 cleared the moment the frame's font becomes defined by a face
5992 attribute, instead of through the `font' frame parameter. */
5993 font_parameter = get_frame_param (f, Qfont_parameter);
5994
5995 if (!NILP (font_parameter))
5996 params = list1 (Fcons (Qfont, font_parameter));
5972 5997
5973 /* First, call this to reinitialize any font backend specific 5998 /* First, call this to reinitialize any font backend specific
5974 stuff. */ 5999 stuff. */
@@ -5976,10 +6001,22 @@ have changed. */)
5976 if (FRAME_RIF (f)->default_font_parameter) 6001 if (FRAME_RIF (f)->default_font_parameter)
5977 FRAME_RIF (f)->default_font_parameter (f, params); 6002 FRAME_RIF (f)->default_font_parameter (f, params);
5978 6003
6004 /* For a mysterious reason, x_default_font_parameter sets Qfont to
6005 nil in the alist! */
6006
6007 if (!NILP (font_parameter))
6008 params = list1 (Fcons (Qfont, font_parameter));
6009
5979 /* Now call this to apply the existing value(s) of the `default' 6010 /* Now call this to apply the existing value(s) of the `default'
5980 face. */ 6011 face. */
5981 call2 (Qface_set_after_frame_default, frame, params); 6012 call2 (Qface_set_after_frame_default, frame, params);
5982 6013
6014 /* Restore the value of the `font-parameter' parameter, as
6015 `face-set-after-frame-default' will have changed it through its
6016 calls to `set-face-attribute'. */
6017 if (!NILP (font_parameter))
6018 store_frame_param (f, Qfont_parameter, font_parameter);
6019
5983 return Qnil; 6020 return Qnil;
5984} 6021}
5985 6022
@@ -6240,6 +6277,7 @@ syms_of_frame (void)
6240 DEFSYM (Qiconify_top_level, "iconify-top-level"); 6277 DEFSYM (Qiconify_top_level, "iconify-top-level");
6241 DEFSYM (Qmake_invisible, "make-invisible"); 6278 DEFSYM (Qmake_invisible, "make-invisible");
6242 DEFSYM (Quse_frame_synchronization, "use-frame-synchronization"); 6279 DEFSYM (Quse_frame_synchronization, "use-frame-synchronization");
6280 DEFSYM (Qfont_parameter, "font-parameter");
6243 6281
6244 { 6282 {
6245 int i; 6283 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)
1670/* The class of this X application. */ 1670/* The class of this X application. */
1671#define EMACS_CLASS "Emacs" 1671#define EMACS_CLASS "Emacs"
1672 1672
1673extern void gui_set_frame_parameters_1 (struct frame *, Lisp_Object, bool);
1673extern void gui_set_frame_parameters (struct frame *, Lisp_Object); 1674extern void gui_set_frame_parameters (struct frame *, Lisp_Object);
1674extern void gui_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object); 1675extern void gui_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object);
1675extern void gui_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object); 1676extern 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)
3007 font = font_open_by_spec (f, Ffont_get_system_font ()); 3007 font = font_open_by_spec (f, Ffont_get_system_font ());
3008 3008
3009 if (NILP (font)) 3009 if (NILP (font))
3010 font = !NILP (font_param) ? font_param 3010 font = (!NILP (font_param)
3011 : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font", 3011 ? font_param
3012 RES_TYPE_STRING); 3012 : gui_display_get_arg (dpyinfo, parms, Qfont,
3013 "font", "Font",
3014 RES_TYPE_STRING));
3013 3015
3014 if (! FONTP (font) && ! STRINGP (font)) 3016 if (! FONTP (font) && ! STRINGP (font))
3015 { 3017 {
@@ -3029,13 +3031,6 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
3029 if (NILP (font)) 3031 if (NILP (font))
3030 error ("No suitable font was found"); 3032 error ("No suitable font was found");
3031 } 3033 }
3032 else if (!NILP (font_param))
3033 {
3034 /* Remember the explicit font parameter, so we can re-apply it
3035 after we've applied the `default' face settings. */
3036 AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
3037 gui_set_frame_parameters (f, arg);
3038 }
3039 3034
3040 gui_default_parameter (f, parms, Qfont, font, "font", "Font", 3035 gui_default_parameter (f, parms, Qfont, font, "font", "Font",
3041 RES_TYPE_STRING); 3036 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)
1121 if (NILP (font)) 1121 if (NILP (font))
1122 error ("No suitable font was found"); 1122 error ("No suitable font was found");
1123 } 1123 }
1124 else if (!NILP (font_param))
1125 {
1126 /* Remember the explicit font parameter, so we can re-apply it after
1127 we've applied the `default' face settings. */
1128 AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
1129 gui_set_frame_parameters (f, arg);
1130 }
1131 1124
1132 /* This call will make X resources override any system font setting. */ 1125 /* This call will make X resources override any system font setting. */
1133 gui_default_parameter (f, parms, Qfont, font, "font", "Font", 1126 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)
5794 if (NILP (font)) 5794 if (NILP (font))
5795 error ("No suitable font was found"); 5795 error ("No suitable font was found");
5796 } 5796 }
5797 else if (!NILP (font_param)) 5797
5798 {
5799 /* Remember the explicit font parameter, so we can re-apply it after
5800 we've applied the `default' face settings. */
5801 gui_set_frame_parameters (f, Fcons (Fcons (Qfont_parameter, font_param),
5802 Qnil));
5803 }
5804 gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); 5798 gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
5805} 5799}
5806 5800
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)
3809 ASET (lface, LFACE_FONT_INDEX, font); 3809 ASET (lface, LFACE_FONT_INDEX, font);
3810 } 3810 }
3811 f->default_face_done_p = false; 3811 f->default_face_done_p = false;
3812 AUTO_FRAME_ARG (arg, Qfont, font); 3812 AUTO_LIST2 (arg, AUTO_CONS_EXPR (Qfont, font),
3813 Fmodify_frame_parameters (frame, arg); 3813 /* Clear the `font-parameter' frame property, as the
3814 font is now being specified by a face, not a
3815 frame property. */
3816 AUTO_CONS_EXPR (Qfont_parameter, Qnil));
3817 gui_set_frame_parameters_1 (f, arg, true);
3814 } 3818 }
3815} 3819}
3816 3820
@@ -4208,7 +4212,17 @@ Default face attributes override any local face attributes. */)
4208 { 4212 {
4209 Lisp_Object name = newface->font->props[FONT_NAME_INDEX]; 4213 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
4210 AUTO_FRAME_ARG (arg, Qfont, name); 4214 AUTO_FRAME_ARG (arg, Qfont, name);
4211 Fmodify_frame_parameters (frame, arg); 4215
4216#ifdef HAVE_WINDOW_SYSTEM
4217 if (FRAME_WINDOW_P (f))
4218 /* This is a window-system frame. Prevent changes of
4219 the `font' parameter here from messing with the
4220 `font-parameter' frame property, as the frame
4221 parameter is not being changed by the user. */
4222 gui_set_frame_parameters_1 (f, arg, true);
4223 else
4224#endif
4225 Fmodify_frame_parameters (frame, arg);
4212 } 4226 }
4213 4227
4214 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX])) 4228 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)
4551 if (NILP (font)) 4551 if (NILP (font))
4552 error ("No suitable font was found"); 4552 error ("No suitable font was found");
4553 } 4553 }
4554 else if (!NILP (font_param))
4555 {
4556 /* Remember the explicit font parameter, so we can re-apply it after
4557 we've applied the `default' face settings. */
4558 AUTO_FRAME_ARG (arg, Qfont_parameter, font_param);
4559 gui_set_frame_parameters (f, arg);
4560 }
4561 4554
4562 /* This call will make X resources override any system font setting. */ 4555 /* This call will make X resources override any system font setting. */
4563 gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); 4556 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,
886 } 886 }
887#endif 887#endif
888 888
889#ifdef USE_CAIRO
890 /* When Cairo is being used, set oldsettings.dpi to dpyinfo->resx.
891 This is a gross hack, but seeing as Cairo fails to report
892 anything reasonable, just use it to avoid config-changed events
893 being sent at startup. */
894 oldsettings.dpi = dpyinfo->resx;
895#endif
896
889 if ((settings->seen & SEEN_DPI) != 0 897 if ((settings->seen & SEEN_DPI) != 0
890 && settings->dpi > 0 898 && settings->dpi > 0
891 /* The following conjunct avoids setting `changed' to true when 899 /* The following conjunct avoids setting `changed' to true when