Keep track of scale factor by atimer and recreate cairo_surface_t
Otherwise texts become blurry when a frame moved from 1x monitor to 2x monitor. I need GTK's such signal, but there isn't. Instead I watch frame's monitor's scale factor periodically. We can see blurriness for a short time, but it is gone soon. * src/pgtkfns.c (update_watched_scale_factor): New function to check scale factor and recreate cairo_surface_t if changed. * src/pgtkfns.c (Fx_create_frame): Initialize atimer. (Fx_show_tip): Add an argument. * src/pgtkterm.c (FRAME_CR_SURFACE_DESIRED_WIDTH): Move macros to pgtkterm.h (x_free_frame_resources): Free atimer. (size_allocate): Add an argument. (pgtk_cr_update_surface_desired_size): Add an argument. Recreate if it is true. * src/pgtkterm.h (struct pgtk_output): New members. (FRAME_CR_SURFACE_DESIRED_HEIGHT): Move macros from pgtkterm.c
This commit is contained in:
parent
f638541785
commit
729311c22b
3 changed files with 45 additions and 9 deletions
|
@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "fontset.h"
|
||||
#include "font.h"
|
||||
#include "xsettings.h"
|
||||
#include "atimer.h"
|
||||
|
||||
|
||||
#ifdef HAVE_PGTK
|
||||
|
@ -1179,6 +1180,21 @@ pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
|
|||
RES_TYPE_STRING);
|
||||
}
|
||||
|
||||
static void update_watched_scale_factor(struct atimer *timer)
|
||||
{
|
||||
struct frame *f = timer->client_data;
|
||||
|
||||
double scale_factor = FRAME_SCALE_FACTOR (f);
|
||||
if (scale_factor != FRAME_X_OUTPUT (f)->watched_scale_factor)
|
||||
{
|
||||
FRAME_X_OUTPUT (f)->watched_scale_factor = scale_factor;
|
||||
pgtk_cr_update_surface_desired_size (f,
|
||||
FRAME_CR_SURFACE_DESIRED_WIDTH (f),
|
||||
FRAME_CR_SURFACE_DESIRED_HEIGHT (f),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
|
||||
Lisp definitions
|
||||
|
@ -1773,6 +1789,12 @@ This function is an internal primitive--use `make-frame' instead. */ )
|
|||
|
||||
FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
|
||||
FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
|
||||
FRAME_X_OUTPUT (f)->watched_scale_factor = 1.0;
|
||||
struct timespec ts = make_timespec (1, 0);
|
||||
FRAME_X_OUTPUT (f)->scale_factor_atimer = start_atimer(ATIMER_CONTINUOUS,
|
||||
ts,
|
||||
update_watched_scale_factor,
|
||||
f);
|
||||
|
||||
/* Make sure windows on this frame appear in calls to next-window
|
||||
and similar functions. */
|
||||
|
@ -3481,7 +3503,7 @@ Text larger than the specified size is clipped. */)
|
|||
gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
|
||||
unblock_input ();
|
||||
|
||||
pgtk_cr_update_surface_desired_size (tip_f, width, height);
|
||||
pgtk_cr_update_surface_desired_size (tip_f, width, height, false);
|
||||
|
||||
w->must_be_updated_p = true;
|
||||
update_single_window (w);
|
||||
|
|
|
@ -72,10 +72,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context)
|
||||
#define FRAME_CR_ACTIVE_CONTEXT(f) ((f)->output_data.pgtk->cr_active)
|
||||
#define FRAME_CR_SURFACE(f) (cairo_get_target (FRAME_CR_CONTEXT (f)))
|
||||
#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
|
||||
((f)->output_data.pgtk->cr_surface_desired_width)
|
||||
#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
|
||||
((f)->output_data.pgtk->cr_surface_desired_height)
|
||||
|
||||
/* Non-zero means that a HELP_EVENT has been generated since Emacs
|
||||
start. */
|
||||
|
@ -215,6 +211,12 @@ x_free_frame_resources (struct frame *f)
|
|||
|
||||
free_frame_faces (f);
|
||||
|
||||
if (FRAME_X_OUTPUT (f)->scale_factor_atimer != NULL)
|
||||
{
|
||||
cancel_atimer (FRAME_X_OUTPUT (f)->scale_factor_atimer);
|
||||
FRAME_X_OUTPUT (f)->scale_factor_atimer = NULL;
|
||||
}
|
||||
|
||||
#define CLEAR_IF_EQ(FIELD) \
|
||||
do { if (f == dpyinfo->FIELD) dpyinfo->FIELD = 0; } while (false)
|
||||
|
||||
|
@ -4845,7 +4847,7 @@ size_allocate (GtkWidget * widget, GtkAllocation * alloc,
|
|||
if (f)
|
||||
{
|
||||
xg_frame_resized (f, alloc->width, alloc->height);
|
||||
pgtk_cr_update_surface_desired_size (f, alloc->width, alloc->height);
|
||||
pgtk_cr_update_surface_desired_size (f, alloc->width, alloc->height, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6820,10 +6822,11 @@ If set to a non-float value, there will be no wait at all. */);
|
|||
* until a redrawn frame is completed.
|
||||
*/
|
||||
void
|
||||
pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height)
|
||||
pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height, bool force)
|
||||
{
|
||||
if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
|
||||
|| FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
|
||||
|| FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height
|
||||
|| force)
|
||||
{
|
||||
pgtk_cr_destroy_frame_context (f);
|
||||
FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
|
||||
|
|
|
@ -398,6 +398,13 @@ struct pgtk_output
|
|||
frame, or IMPLICIT if we received an EnterNotify.
|
||||
FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
|
||||
int focus_state;
|
||||
|
||||
/* Keep track of scale factor. If monitor's scale factor is changed, or
|
||||
monitor is switched and scale factor is changed, then recreate cairo_t
|
||||
and cairo_surface_t. I need GTK's such signal, but there isn't, so
|
||||
I watch it periodically with atimer. */
|
||||
double watched_scale_factor;
|
||||
struct atimer *scale_factor_atimer;
|
||||
};
|
||||
|
||||
/* this dummy decl needed to support TTYs */
|
||||
|
@ -521,6 +528,10 @@ enum
|
|||
(! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \
|
||||
: FRAME_SCROLL_BAR_COLS (f))
|
||||
|
||||
#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
|
||||
((f)->output_data.pgtk->cr_surface_desired_width)
|
||||
#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
|
||||
((f)->output_data.pgtk->cr_surface_desired_height)
|
||||
|
||||
/* Display init/shutdown functions implemented in pgtkterm.c */
|
||||
extern struct pgtk_display_info *pgtk_term_init (Lisp_Object display_name,
|
||||
|
@ -575,7 +586,7 @@ extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
|
|||
Lisp_Object old_value);
|
||||
|
||||
/* Cairo related functions implemented in pgtkterm.c */
|
||||
extern void pgtk_cr_update_surface_desired_size (struct frame *, int, int);
|
||||
extern void pgtk_cr_update_surface_desired_size (struct frame *, int, int, bool);
|
||||
extern cairo_t *pgtk_begin_cr_clip (struct frame *f);
|
||||
extern void pgtk_end_cr_clip (struct frame *f);
|
||||
extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f,
|
||||
|
|
Loading…
Add table
Reference in a new issue