From: Po Lu Date: Mon, 31 Jan 2022 12:21:04 +0000 (+0800) Subject: Implement `alpha-background' on PGTK X-Git-Tag: emacs-29.0.90~2627 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=46473a4eac2579b88ec843e1301eb2a89835e2ae;p=emacs.git 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. --- diff --git a/src/ftcrfont.c b/src/ftcrfont.c index 558e44d5b91..c327146ba28 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 b961cdedca9..b59bf4ebad5 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 5980b31d6e2..c7987afc7db 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 efbeaafaf1a..9bb611e4c58 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 42b03e315ef..4d2285cdb0a 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);