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.)
This commit is contained in:
parent
10701635cf
commit
b18d4dbe0d
10 changed files with 112 additions and 56 deletions
|
@ -2200,8 +2200,13 @@ the X resource \"reverseVideo\" is present, handle that."
|
|||
border-color cursor-color mouse-color
|
||||
visibility scroll-bar-foreground
|
||||
scroll-bar-background))
|
||||
(delayed-font nil)
|
||||
frame success)
|
||||
(dolist (param delayed-params)
|
||||
;; Save the font used here. Once the frame is created, set the
|
||||
;; `font-parameter' frame parameter.
|
||||
(when (and (eq param 'font) (assq 'font parameters))
|
||||
(setq delayed-font (cdr (assq 'font parameters))))
|
||||
(setq params (assq-delete-all param params)))
|
||||
(setq frame (x-create-frame `((visibility . nil) . ,params)))
|
||||
(unwind-protect
|
||||
|
@ -2212,6 +2217,11 @@ the X resource \"reverseVideo\" is present, handle that."
|
|||
(x-handle-reverse-video frame parameters)
|
||||
(frame-set-background-mode frame t)
|
||||
(face-set-after-frame-default frame parameters)
|
||||
;; The code above will not set the `font-parameter' frame
|
||||
;; property, which is used by dynamic-setting.el to respect
|
||||
;; fonts specified by the user via frame parameters (as
|
||||
;; opposed to face attributes). Set the parameter manually.
|
||||
(set-frame-parameter frame 'font-parameter delayed-font)
|
||||
;; Mark frame as 'was-invisible' when it was created as
|
||||
;; invisible or iconified and PARAMETERS contains either a
|
||||
;; width or height specification. This should be sufficient
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
80
src/frame.c
80
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
20
src/xfaces.c
20
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]))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue