emacs-diffs
[Top][All Lists]
Advanced

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

master 46473a4eac: Implement `alpha-background' on PGTK


From: Po Lu
Subject: master 46473a4eac: Implement `alpha-background' on PGTK
Date: Mon, 31 Jan 2022 07:23:22 -0500 (EST)

branch: master
commit 46473a4eac2579b88ec843e1301eb2a89835e2ae
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Implement `alpha-background' on PGTK
    
    * src/ftcrfont.c (ftcrfont_draw): Respect alpha-background where
    appropriate.
    * src/gtkutil.c (xg_create_frame_widgets): Swap some
    conditionals around to get the right visual and signal handlers
    on PGTK.
    (xg_widget_style_updated): Likewise.
    * src/pgtkfns.c (pgtk_set_alpha_background): New function.
    (pgtk_frame_parm_handlers): Add it instead of the generic param
    handler.
    (Fx_create_frame): Fix typo.
    * src/pgtkterm.c (pgtk_fill_rectangle):
    (pgtk_set_cr_source_with_gc_foreground):
    (pgtk_set_cr_source_with_gc_background):
    (pgtk_set_cr_source_with_color): New argument
    `respect_alpha_backend'.  All callers changed.
    * src/pgtkterm.h: Update function prototypes.
---
 src/ftcrfont.c |   4 +-
 src/gtkutil.c  |  40 ++++++++++-------
 src/pgtkfns.c  |  22 ++++++++-
 src/pgtkterm.c | 137 +++++++++++++++++++++++++++++++++------------------------
 src/pgtkterm.h |   9 ++--
 5 files changed, 130 insertions(+), 82 deletions(-)

diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 558e44d5b9..c327146ba2 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -557,7 +557,7 @@ ftcrfont_draw (struct glyph_string *s,
 #ifdef HAVE_X_WINDOWS
       x_set_cr_source_with_gc_background (f, s->gc);
 #else
-      pgtk_set_cr_source_with_color (f, s->xgcv.background);
+      pgtk_set_cr_source_with_color (f, s->xgcv.background, true);
 #endif
 #else
       struct face *face = s->face;
@@ -589,7 +589,7 @@ ftcrfont_draw (struct glyph_string *s,
 #ifdef HAVE_X_WINDOWS
   x_set_cr_source_with_gc_foreground (f, s->gc);
 #else
-  pgtk_set_cr_source_with_color (f, s->xgcv.foreground);
+  pgtk_set_cr_source_with_color (f, s->xgcv.foreground, false);
 #endif
 #else
   uint32_t col = s->hl == DRAW_CURSOR ?
diff --git a/src/gtkutil.c b/src/gtkutil.c
index b961cdedca..b59bf4ebad 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -81,11 +81,11 @@ static void xg_im_context_commit (GtkIMContext *, gchar *, 
gpointer);
 static void xg_im_context_preedit_changed (GtkIMContext *, gpointer);
 static void xg_im_context_preedit_end (GtkIMContext *, gpointer);
 static bool xg_widget_key_press_event_cb (GtkWidget *, GdkEvent *, gpointer);
+#endif
 
 #if GTK_CHECK_VERSION (3, 10, 0)
 static void xg_widget_style_updated (GtkWidget *, gpointer);
 #endif
-#endif
 
 #ifndef HAVE_GTK3
 
@@ -1464,13 +1464,6 @@ xg_create_frame_widgets (struct frame *f)
     }
   else
     wtop = gtk_window_new (type);
-
-#if GTK_CHECK_VERSION (3, 10, 0)
-  g_signal_connect (G_OBJECT (wtop), "style-updated",
-                   G_CALLBACK (xg_widget_style_updated), f);
-#endif
-
-  gtk_widget_set_app_paintable (wtop, f->alpha_background != 1.0);
 #else
   if (f->tooltip)
     {
@@ -1480,6 +1473,12 @@ xg_create_frame_widgets (struct frame *f)
   gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK);
 #endif
 
+  gtk_widget_set_app_paintable (wtop, f->alpha_background != 1.0);
+#if GTK_CHECK_VERSION (3, 10, 0)
+  g_signal_connect (G_OBJECT (wtop), "style-updated",
+                   G_CALLBACK (xg_widget_style_updated), f);
+#endif
+
   /* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
      has backported it to Gtk+ 2.0 and they add the resize grip for
      Gtk+ 2.0 applications also.  But it has a bug that makes Emacs loop
@@ -1606,10 +1605,12 @@ xg_create_frame_widgets (struct frame *f)
 
   if (!visual)
     emacs_abort ();
+#else
+  GdkVisual *visual = gdk_screen_get_argb_visual (screen);
+#endif
 
   gtk_widget_set_visual (wtop, visual);
   gtk_widget_set_visual (wfixed, visual);
-#endif
 
 #ifndef HAVE_PGTK
   /* Must realize the windows so the X window gets created.  It is used
@@ -6398,6 +6399,7 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
 
   return result;
 }
+#endif
 
 #if GTK_CHECK_VERSION (3, 10, 0)
 static void
@@ -6406,12 +6408,20 @@ xg_widget_style_updated (GtkWidget *widget, gpointer 
user_data)
   struct frame *f = user_data;
 
   if (f->alpha_background < 1.0)
-    XChangeProperty (FRAME_X_DISPLAY (f),
-                    FRAME_X_WINDOW (f),
-                    FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
-                    XA_CARDINAL, 32, PropModeReplace,
-                    NULL, 0);
-}
+    {
+#ifndef HAVE_PGTK
+      XChangeProperty (FRAME_X_DISPLAY (f),
+                      FRAME_X_WINDOW (f),
+                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
+                      XA_CARDINAL, 32, PropModeReplace,
+                      NULL, 0);
+#else
+      if (FRAME_GTK_OUTER_WIDGET (f)
+         && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f)))
+       gdk_window_set_opaque_region (gtk_widget_get_window 
(FRAME_GTK_OUTER_WIDGET (f)),
+                                     NULL);
 #endif
+    }
+}
 #endif
 #endif /* USE_GTK */
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 5980b31d6e..c7987afc7d 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -234,6 +234,24 @@ x_set_background_color (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
   unblock_input ();
 }
 
+static void
+pgtk_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object 
oldval)
+{
+  gui_set_alpha_background (f, arg, oldval);
+
+  /* This prevents GTK from painting the window's background, which
+     interferes with transparent background in some environments */
+
+  gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
+                               f->alpha_background != 1.0);
+
+  if (FRAME_GTK_OUTER_WIDGET (f)
+      && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f))
+      && f->alpha_background != 1.0)
+    gdk_window_set_opaque_region (gtk_widget_get_window 
(FRAME_GTK_OUTER_WIDGET (f)),
+                                 NULL);
+}
+
 static void
 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
@@ -1043,7 +1061,7 @@ frame_parm_handler pgtk_frame_parm_handlers[] = {
   x_set_z_group,
   x_set_override_redirect,
   gui_set_no_special_glyphs,
-  gui_set_alpha_background,
+  pgtk_set_alpha_background,
 };
 
 
@@ -1668,7 +1686,7 @@ This function is an internal primitive--use `make-frame' 
instead.  */ )
                         RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qalpha, Qnil,
                         "alpha", "Alpha", RES_TYPE_NUMBER);
-  gui_default_parameter (f, parms, Qalpha, Qnil,
+  gui_default_parameter (f, parms, Qalpha_background, Qnil,
                          "alphaBackground", "AlphaBackground", 
RES_TYPE_NUMBER);
 
   if (!NILP (parent_frame))
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index efbeaafaf1..9bb611e4c5 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -101,7 +101,8 @@ static void pgtk_delete_display (struct pgtk_display_info 
*dpyinfo);
 static void pgtk_clear_frame_area (struct frame *f, int x, int y, int width,
                                   int height);
 static void pgtk_fill_rectangle (struct frame *f, unsigned long color, int x,
-                                int y, int width, int height);
+                                int y, int width, int height,
+                                bool respect_alpha_background);
 static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
                              enum glyph_row_area area, cairo_t * cr);
 static struct frame *pgtk_any_window_to_frame (GdkWindow * window);
@@ -1243,7 +1244,7 @@ pgtk_compute_glyph_string_overhangs (struct glyph_string 
*s)
 static void
 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
 {
-  pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h);
+  pgtk_fill_rectangle (s->f, s->xgcv.background, x, y, w, h, true);
 }
 
 
@@ -1328,13 +1329,13 @@ x_draw_glyph_string_background (struct glyph_string *s, 
bool force_p)
 
 static void
 pgtk_draw_rectangle (struct frame *f, unsigned long color, int x, int y,
-                    int width, int height)
+                    int width, int height, bool respect_alpha_background)
 {
   cairo_t *cr;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
-  cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
+  pgtk_set_cr_source_with_color (f, color, true);
+  cairo_rectangle (cr, x + 0.5, y + 0.5, width, respect_alpha_background);
   cairo_set_line_width (cr, 1);
   cairo_stroke (cr);
   pgtk_end_cr_clip (f);
@@ -1363,7 +1364,8 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
          struct glyph *g = s->first_glyph + i;
          pgtk_draw_rectangle (s->f,
                               s->face->foreground, x, s->y,
-                              g->pixel_width - 1, s->height - 1);
+                              g->pixel_width - 1, s->height - 1,
+                              false);
          x += g->pixel_width;
        }
     }
@@ -1413,7 +1415,7 @@ x_draw_composite_glyph_string_foreground (struct 
glyph_string *s)
     {
       if (s->cmp_from == 0)
        pgtk_draw_rectangle (s->f, s->face->foreground, x, s->y,
-                            s->width - 1, s->height - 1);
+                            s->width - 1, s->height - 1, false);
     }
   else if (!s->first_glyph->u.cmp.automatic)
     {
@@ -1555,7 +1557,8 @@ x_draw_glyphless_glyph_string_foreground (struct 
glyph_string *s)
        pgtk_draw_rectangle (s->f, s->face->foreground,
                             x, s->ybase - glyph->ascent,
                             glyph->pixel_width - 1,
-                            glyph->ascent + glyph->descent - 1);
+                            glyph->ascent + glyph->descent - 1,
+                            false);
       x += glyph->pixel_width;
     }
 }
@@ -1658,7 +1661,7 @@ x_fill_trapezoid_for_relief (struct frame *f, unsigned 
long color, int x,
   cairo_t *cr;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   cairo_move_to (cr, top_p ? x : x + height, y);
   cairo_line_to (cr, x, y + height);
   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
@@ -1685,7 +1688,7 @@ x_erase_corners_for_relief (struct frame *f, unsigned 
long color, int x,
   int i;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   for (i = 0; i < CORNER_LAST; i++)
     if (corners & (1 << i))
       {
@@ -1818,7 +1821,7 @@ x_draw_relief_rect (struct frame *f,
   if (left_p)
     {
       pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
-                          vwidth, bottom_y + 1 - top_y);
+                          vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_LEFT;
       if (bot_p)
@@ -1827,7 +1830,7 @@ x_draw_relief_rect (struct frame *f,
   if (right_p)
     {
       pgtk_fill_rectangle (f, bottom_right_color, right_x + 1 - vwidth, top_y,
-                          vwidth, bottom_y + 1 - top_y);
+                          vwidth, bottom_y + 1 - top_y, false);
       if (top_p)
        corners |= 1 << CORNER_TOP_RIGHT;
       if (bot_p)
@@ -1837,7 +1840,7 @@ x_draw_relief_rect (struct frame *f,
     {
       if (!right_p)
        pgtk_fill_rectangle (f, top_left_color, left_x, top_y,
-                            right_x + 1 - left_x, hwidth);
+                            right_x + 1 - left_x, hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, top_left_color, left_x, top_y,
                                     right_x + 1 - left_x, hwidth, 1);
@@ -1847,7 +1850,7 @@ x_draw_relief_rect (struct frame *f,
       if (!left_p)
        pgtk_fill_rectangle (f, bottom_right_color, left_x,
                             bottom_y + 1 - hwidth, right_x + 1 - left_x,
-                            hwidth);
+                            hwidth, false);
       else
        x_fill_trapezoid_for_relief (f, bottom_right_color,
                                     left_x, bottom_y + 1 - hwidth,
@@ -1855,10 +1858,10 @@ x_draw_relief_rect (struct frame *f,
     }
   if (left_p && vwidth > 1)
     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
-                        1, bottom_y + 1 - top_y);
+                        1, bottom_y + 1 - top_y, false);
   if (top_p && hwidth > 1)
     pgtk_fill_rectangle (f, bottom_right_color, left_x, top_y,
-                        right_x + 1 - left_x, 1);
+                        right_x + 1 - left_x, 1, false);
   if (corners)
     {
       x_erase_corners_for_relief (f, FRAME_BACKGROUND_PIXEL (f), left_x,
@@ -1893,23 +1896,25 @@ x_draw_box_rect (struct glyph_string *s,
 
   /* Top.  */
   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                      left_x, top_y, right_x - left_x + 1, hwidth);
+                      left_x, top_y, right_x - left_x + 1, hwidth,
+                      false);
 
   /* Left.  */
   if (left_p)
     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                        left_x, top_y, vwidth, bottom_y - top_y + 1);
+                        left_x, top_y, vwidth, bottom_y - top_y + 1,
+                        false);
 
   /* Bottom.  */
   pgtk_fill_rectangle (s->f, s->xgcv.foreground,
                       left_x, bottom_y - hwidth + 1, right_x - left_x + 1,
-                      hwidth);
+                      hwidth, false);
 
   /* Right.  */
   if (right_p)
     pgtk_fill_rectangle (s->f, s->xgcv.foreground,
                         right_x - vwidth + 1, top_y, vwidth,
-                        bottom_y - top_y + 1);
+                        bottom_y - top_y + 1, false);
 
   s->xgcv.foreground = foreground_backup;
 
@@ -1979,7 +1984,7 @@ x_draw_horizontal_wave (struct frame *f, unsigned long 
color, int x, int y,
   int xoffset, n;
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, false);
   cairo_rectangle (cr, x, y, width, height);
   cairo_clip (cr);
 
@@ -2155,7 +2160,7 @@ x_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
     cairo_rectangle (cr, dest_x, dest_y, width, height);
   else
     {
-      pgtk_set_cr_source_with_gc_background (f, gc);
+      pgtk_set_cr_source_with_gc_background (f, gc, false);
       cairo_rectangle (cr, dest_x, dest_y, width, height);
       cairo_fill_preserve (cr);
     }
@@ -2172,7 +2177,7 @@ x_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
     }
   else
     {
-      pgtk_set_cr_source_with_gc_foreground (f, gc);
+      pgtk_set_cr_source_with_gc_foreground (f, gc, false);
       cairo_clip (cr);
       cairo_mask (cr, image);
     }
@@ -2222,7 +2227,7 @@ x_draw_image_foreground (struct glyph_string *s)
              int relief = eabs (s->img->relief);
              pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, y - 
relief,
                                   s->slice.width + relief*2 - 1,
-                                  s->slice.height + relief*2 - 1);
+                                  s->slice.height + relief*2 - 1, false);
            }
        }
       pgtk_end_cr_clip (s->f);
@@ -2230,7 +2235,7 @@ x_draw_image_foreground (struct glyph_string *s)
   else
     /* Draw a rectangle if image could not be loaded.  */
     pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y,
-                        s->slice.width - 1, s->slice.height - 1);
+                        s->slice.width - 1, s->slice.height - 1, false);
 }
 
 /* Draw image glyph string S.
@@ -2375,7 +2380,8 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
            }
          else
            {
-             pgtk_fill_rectangle (s->f, color, x, y, w, h);
+             pgtk_fill_rectangle (s->f, color, x, y, w, h,
+                                  false);
            }
 
          pgtk_end_cr_clip (s->f);
@@ -2601,11 +2607,13 @@ pgtk_draw_glyph_string (struct glyph_string *s)
              y = s->ybase + position;
              if (s->face->underline_defaulted_p)
                pgtk_fill_rectangle (s->f, s->xgcv.foreground,
-                                    s->x, y, s->width, thickness);
+                                    s->x, y, s->width, thickness,
+                                    false);
              else
                {
                  pgtk_fill_rectangle (s->f, s->face->underline_color,
-                                      s->x, y, s->width, thickness);
+                                      s->x, y, s->width, thickness,
+                                      false);
                }
            }
        }
@@ -2616,11 +2624,11 @@ pgtk_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->overline_color_defaulted_p)
            pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, s->y + dy,
-                                s->width, h);
+                                s->width, h, false);
          else
            {
              pgtk_fill_rectangle (s->f, s->face->overline_color, s->x,
-                                  s->y + dy, s->width, h);
+                                  s->y + dy, s->width, h, false);
            }
        }
 
@@ -2641,11 +2649,11 @@ pgtk_draw_glyph_string (struct glyph_string *s)
 
          if (s->face->strike_through_color_defaulted_p)
            pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, glyph_y + dy,
-                                s->width, h);
+                                s->width, h, false);
          else
            {
              pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x,
-                                  glyph_y + dy, s->width, h);
+                                  glyph_y + dy, s->width, h, false);
            }
        }
 
@@ -2778,7 +2786,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row 
*row)
   /* The foreground of cursor_gc is typically the same as the normal
      background color, which can cause the cursor box to be invisible.  */
   cairo_t *cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color);
+  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->cursor_color, false);
 
   /* When on R2L character, show cursor at the right edge of the
      glyph, unless the cursor box is as wide as the glyph or wider
@@ -2792,7 +2800,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row 
*row)
     }
   /* Set clipping, draw the rectangle, and reset clipping again.  */
   pgtk_clip_to_row (w, row, TEXT_AREA, cr);
-  pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color, x, y, wd, h - 1);
+  pgtk_draw_rectangle (f, FRAME_X_OUTPUT (f)->cursor_color, x, y, wd, h - 1, 
false);
   pgtk_end_cr_clip (f);
 }
 
@@ -2866,7 +2874,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width,
 
          pgtk_fill_rectangle (f, color, x,
                               WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                              width, row->height);
+                              width, row->height, false);
        }
       else                     /* HBAR_CURSOR */
        {
@@ -2887,7 +2895,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row 
*row, int width,
          pgtk_fill_rectangle (f, color, x,
                               WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
                                                        row->height - width),
-                              w->phys_cursor_width - 1, width);
+                              w->phys_cursor_width - 1, width, false);
        }
 
       pgtk_end_cr_clip (f);
@@ -3241,7 +3249,7 @@ pgtk_draw_vertical_window_border (struct window *w, int 
x, int y0, int y1)
 
   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
   if (face)
-    pgtk_set_cr_source_with_color (f, face->foreground);
+    pgtk_set_cr_source_with_color (f, face->foreground, false);
 
   cairo_rectangle (cr, x, y0, 1, y1 - y0);
   cairo_fill (cr);
@@ -3272,32 +3280,32 @@ pgtk_draw_window_divider (struct window *w, int x0, int 
x1, int y0, int y1)
   if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
     /* Vertical.  */
     {
-      pgtk_set_cr_source_with_color (f, color_first);
+      pgtk_set_cr_source_with_color (f, color_first, false);
       cairo_rectangle (cr, x0, y0, 1, y1 - y0);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0 + 1, y0, x1 - x0 - 2, y1 - y0);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color_last);
+      pgtk_set_cr_source_with_color (f, color_last, false);
       cairo_rectangle (cr, x1 - 1, y0, 1, y1 - y0);
       cairo_fill (cr);
     }
   else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
     /* Horizontal.  */
     {
-      pgtk_set_cr_source_with_color (f, color_first);
+      pgtk_set_cr_source_with_color (f, color_first, false);
       cairo_rectangle (cr, x0, y0, x1 - x0, 1);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0, y0 + 1, x1 - x0, y1 - y0 - 2);
       cairo_fill (cr);
-      pgtk_set_cr_source_with_color (f, color_last);
+      pgtk_set_cr_source_with_color (f, color_last, false);
       cairo_rectangle (cr, x0, y1 - 1, x1 - x0, 1);
       cairo_fill (cr);
     }
   else
     {
-      pgtk_set_cr_source_with_color (f, color);
+      pgtk_set_cr_source_with_color (f, color, false);
       cairo_rectangle (cr, x0, y0, x1 - x0, y1 - y0);
       cairo_fill (cr);
     }
@@ -3520,7 +3528,7 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC * gc, 
cairo_pattern_t * image,
     cairo_rectangle (cr, dest_x, dest_y, width, height);
   else
     {
-      pgtk_set_cr_source_with_gc_background (f, gc);
+      pgtk_set_cr_source_with_gc_background (f, gc, false);
       cairo_rectangle (cr, dest_x, dest_y, width, height);
       cairo_fill_preserve (cr);
     }
@@ -3536,7 +3544,7 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC * gc, 
cairo_pattern_t * image,
     }
   else
     {
-      pgtk_set_cr_source_with_gc_foreground (f, gc);
+      pgtk_set_cr_source_with_gc_foreground (f, gc, false);
       cairo_clip (cr);
       cairo_mask (cr, image);
     }
@@ -3568,7 +3576,7 @@ pgtk_draw_fringe_bitmap (struct window *w, struct 
glyph_row *row,
        }
       else
        {
-         pgtk_set_cr_source_with_color (f, face->background);
+         pgtk_set_cr_source_with_color (f, face->background, true);
          cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
          cairo_fill (cr);
        }
@@ -4970,11 +4978,11 @@ pgtk_handle_event (GtkWidget *widget, GdkEvent *event, 
gpointer *data)
 
 static void
 pgtk_fill_rectangle (struct frame *f, unsigned long color, int x, int y,
-                    int width, int height)
+                    int width, int height, bool respect_alpha_background)
 {
   cairo_t *cr;
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, color);
+  pgtk_set_cr_source_with_color (f, color, respect_alpha_background);
   cairo_rectangle (cr, x, y, width, height);
   cairo_fill (cr);
   pgtk_end_cr_clip (f);
@@ -6913,7 +6921,8 @@ pgtk_clear_area (struct frame *f, int x, int y, int 
width, int height)
   eassert (width > 0 && height > 0);
 
   cr = pgtk_begin_cr_clip (f);
-  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color);
+  pgtk_set_cr_source_with_color (f, FRAME_X_OUTPUT (f)->background_color,
+                                true);
   cairo_rectangle (cr, x, y, width, height);
   cairo_fill (cr);
   pgtk_end_cr_clip (f);
@@ -7095,25 +7104,39 @@ pgtk_end_cr_clip (struct frame *f)
 }
 
 void
-pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC * gc)
+pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC *gc,
+                                      bool respects_alpha_background)
 {
-  pgtk_set_cr_source_with_color (f, gc->foreground);
+  pgtk_set_cr_source_with_color (f, gc->foreground,
+                                respects_alpha_background);
 }
 
 void
-pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC * gc)
+pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC *gc,
+                                      bool respects_alpha_background)
 {
-  pgtk_set_cr_source_with_color (f, gc->background);
+  pgtk_set_cr_source_with_color (f, gc->background,
+                                respects_alpha_background);
 }
 
 void
-pgtk_set_cr_source_with_color (struct frame *f, unsigned long color)
+pgtk_set_cr_source_with_color (struct frame *f, unsigned long color,
+                              bool respects_alpha_background)
 {
   Emacs_Color col;
   col.pixel = color;
   pgtk_query_color (f, &col);
-  cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
-                       col.green / 65535.0, col.blue / 65535.0);
+
+  if (!respects_alpha_background)
+    cairo_set_source_rgb (FRAME_CR_CONTEXT (f), col.red / 65535.0,
+                         col.green / 65535.0, col.blue / 65535.0);
+  else
+    {
+      cairo_set_source_rgba (FRAME_CR_CONTEXT (f), col.red / 65535.0,
+                            col.green / 65535.0, col.blue / 65535.0,
+                            f->alpha_background);
+      cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
+    }
 }
 
 void
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 42b03e315e..4d2285cdb0 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -591,12 +591,9 @@ extern void x_set_z_group (struct frame *f, Lisp_Object 
new_value,
 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,
-                                                  Emacs_GC * gc);
-extern void pgtk_set_cr_source_with_gc_background (struct frame *f,
-                                                  Emacs_GC * gc);
-extern void pgtk_set_cr_source_with_color (struct frame *f,
-                                          unsigned long color);
+extern void pgtk_set_cr_source_with_gc_foreground (struct frame *, Emacs_GC *, 
bool);
+extern void pgtk_set_cr_source_with_gc_background (struct frame *, Emacs_GC *, 
bool);
+extern void pgtk_set_cr_source_with_color (struct frame *, unsigned long, 
bool);
 extern void pgtk_cr_draw_frame (cairo_t * cr, struct frame *f);
 extern void pgtk_cr_destroy_frame_context (struct frame *f);
 extern Lisp_Object pgtk_cr_export_frames (Lisp_Object frames, 
cairo_surface_type_t surface_type);



reply via email to

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