emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk 729311c 1/3: Keep track of scale factor by atimer and recre


From: Yuuki Harano
Subject: feature/pgtk 729311c 1/3: Keep track of scale factor by atimer and recreate cairo_surface_t
Date: Sat, 4 Dec 2021 02:34:51 -0500 (EST)

branch: feature/pgtk
commit 729311c22b230faab9f8714ca2b6cb8f73ac0737
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Yuuki Harano <masm+github@masm11.me>

    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
---
 src/pgtkfns.c  | 24 +++++++++++++++++++++++-
 src/pgtkterm.c | 17 ++++++++++-------
 src/pgtkterm.h | 13 ++++++++++++-
 3 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 4f1f9fa..febc90a 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -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);
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 1fc8fa9..4c953fa 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -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;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index c16221d..e76411c 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -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,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]