summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-01-31 10:15:47 +0800
committerPo Lu <luangruo@yahoo.com>2022-01-31 10:15:47 +0800
commit1555453694d9c2861c447b2f030b125f60e48297 (patch)
treecedd9f133ad03b211c4bec5b37c9b2c3324b1c63
parent58bb9eb4005599155a8fce8d5c5beb531a72c534 (diff)
downloademacs-1555453694d9c2861c447b2f030b125f60e48297.tar.gz
Implement `alpha-background' on non-Cairo builds
* src/frame.c (gui_set_alpha_background): Recompute basic faces so xft face ext info gets reset. * src/gtkutil.c (xg_create_frame_widgets): Attach to style updated signal. (xg_update_frame_menubar): Set menu bar visual correctly. (xg_widget_style_updated): New function. * src/xfns.c (x_set_alpha_background): New function. (x_frame_parm_handlers): Use x_set_alpha_background instead. * src/xfont.c (xfont_draw): * src/xftfont.c (xftfont_draw): Handle `alpha-background' parameter. * src/xterm.c (x_xr_ensure_picture): Export function. (x_update_opaque_region): New function. (x_fill_rectangle): New parameter `respect_alpha_background'. All callers changed. (handle_one_xevent): Set opaque region on ConfigureNotify. (x_drop_xrender_surfaces): Set opaque region. (x_xrender_color_from_gc_foreground): (x_xrender_color_from_gc_background): Premultiply alpha with components if asked for. * src/xterm.h (struct x_display_info): New atom `Xatom_net_wm_opaque_region'.
-rw-r--r--src/frame.c1
-rw-r--r--src/gtkutil.c42
-rw-r--r--src/xfns.c22
-rw-r--r--src/xfont.c25
-rw-r--r--src/xftfont.c39
-rw-r--r--src/xterm.c220
-rw-r--r--src/xterm.h12
7 files changed, 291 insertions, 70 deletions
diff --git a/src/frame.c b/src/frame.c
index f94dff0a607..8750fe4889c 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -5050,6 +5050,7 @@ gui_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
f->alpha_background = alpha;
+ recompute_basic_faces (f);
SET_FRAME_GARBAGED (f);
}
diff --git a/src/gtkutil.c b/src/gtkutil.c
index ef6270dbcf8..c46a2b3a6a1 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -81,6 +81,10 @@ 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);
+
+#if GTK_CHECK_VERSION (3, 10, 0)
+static void xg_widget_style_updated (GtkWidget *, gpointer);
+#endif
#endif
#ifndef HAVE_GTK3
@@ -1460,6 +1464,13 @@ 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)
{
@@ -1467,10 +1478,6 @@ xg_create_frame_widgets (struct frame *f)
}
wtop = gtk_window_new (type);
gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK);
-
- /* This prevents GTK from painting the window's background, which
- would interfere with transparent background in some environments */
- gtk_widget_set_app_paintable (wtop, TRUE);
#endif
/* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
@@ -4044,6 +4051,18 @@ xg_update_frame_menubar (struct frame *f)
gtk_widget_show_all (x->menubar_widget);
gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req);
req.height *= xg_get_scale (f);
+
+#ifndef HAVE_PGTK
+ if (FRAME_DISPLAY_INFO (f)->n_planes == 32)
+ {
+ GdkScreen *screen = gtk_widget_get_screen (x->menubar_widget);
+ GdkVisual *visual = gdk_screen_get_system_visual (screen);
+
+ gtk_widget_realize (x->menubar_widget);
+ gtk_widget_set_visual (x->menubar_widget, visual);
+ }
+#endif
+
if (FRAME_MENUBAR_HEIGHT (f) != (req.height * scale))
{
FRAME_MENUBAR_HEIGHT (f) = req.height * scale;
@@ -6390,5 +6409,20 @@ xg_filter_key (struct frame *frame, XEvent *xkey)
return result;
}
+
+#if GTK_CHECK_VERSION (3, 10, 0)
+static void
+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);
+}
+#endif
#endif
#endif /* USE_GTK */
diff --git a/src/xfns.c b/src/xfns.c
index 7fe181fa3fd..c0198fdc9d1 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -728,6 +728,26 @@ x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value
}
static void
+x_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 (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);
+ }
+}
+
+static void
x_set_tool_bar_position (struct frame *f,
Lisp_Object new_value,
Lisp_Object old_value)
@@ -8583,7 +8603,7 @@ frame_parm_handler x_frame_parm_handlers[] =
x_set_z_group,
x_set_override_redirect,
gui_set_no_special_glyphs,
- gui_set_alpha_background,
+ x_set_alpha_background,
};
void
diff --git a/src/xfont.c b/src/xfont.c
index b5765cfa7b8..7a50378a006 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -1003,6 +1003,31 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
unblock_input ();
}
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+ if (with_background
+ && FRAME_DISPLAY_INFO (s->f)->n_planes == 32
+ && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
+ {
+ x_xr_ensure_picture (s->f);
+
+ if (FRAME_X_PICTURE (s->f) != None)
+ {
+ XRenderColor xc;
+ int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+ x_xr_apply_ext_clip (s->f, gc);
+ x_xrender_color_from_gc_background (s->f, gc, &xc, true);
+ XRenderFillRectangle (FRAME_X_DISPLAY (s->f),
+ PictOpSrc, FRAME_X_PICTURE (s->f),
+ &xc, x, y - ascent, s->width, height);
+ x_xr_reset_ext_clip (s->f);
+ x_mark_frame_dirty (s->f);
+
+ with_background = false;
+ }
+ }
+#endif
+
if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
{
USE_SAFE_ALLOCA;
diff --git a/src/xftfont.c b/src/xftfont.c
index c2175d96141..1fcc0f45284 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -33,6 +33,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "ftfont.h"
#include "pdumper.h"
+#ifdef HAVE_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+
#ifndef FC_LCD_FILTER
/* Older fontconfig versions don't have FC_LCD_FILTER. */
# define FC_LCD_FILTER "lcdfilter"
@@ -496,7 +500,40 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
height = ascent =
s->first_glyph->slice.glyphless.lower_yoff
- s->first_glyph->slice.glyphless.upper_yoff;
- XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
+
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+ if (with_background
+ && FRAME_DISPLAY_INFO (s->f)->n_planes == 32
+ && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
+ {
+ x_xr_ensure_picture (s->f);
+
+ if (FRAME_X_PICTURE (s->f) != None)
+ {
+ XRenderColor xc;
+ int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
+
+ if (s->num_clips > 0)
+ XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (s->f),
+ FRAME_X_PICTURE (s->f),
+ 0, 0, s->clip, s->num_clips);
+ else
+ x_xr_reset_ext_clip (f);
+ x_xrender_color_from_gc_background (s->f, s->gc, &xc, true);
+ XRenderFillRectangle (FRAME_X_DISPLAY (s->f),
+ PictOpSrc, FRAME_X_PICTURE (s->f),
+ &xc, x, y - ascent, s->width, height);
+ x_xr_reset_ext_clip (f);
+ x_mark_frame_dirty (s->f);
+
+ with_background = false;
+ }
+ else
+ XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
+ }
+ else
+#endif
+ XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
}
code = alloca (sizeof (FT_UInt) * len);
for (i = 0; i < len; i++)
diff --git a/src/xterm.c b/src/xterm.c
index e41319e95ec..08b00f80514 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -341,6 +341,7 @@ static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
static void x_initialize (void);
static bool x_get_current_wm_state (struct frame *, Window, int *, bool *);
+static void x_update_opaque_region (struct frame *);
/* Flush display of frame F. */
@@ -361,6 +362,7 @@ x_flush (struct frame *f)
static void
x_drop_xrender_surfaces (struct frame *f)
{
+ x_update_opaque_region (f);
font_drop_xrender_surfaces (f);
#ifdef HAVE_XRENDER
@@ -375,7 +377,7 @@ x_drop_xrender_surfaces (struct frame *f)
}
#ifdef HAVE_XRENDER
-MAYBE_UNUSED static void
+void
x_xr_ensure_picture (struct frame *f)
{
if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f))
@@ -444,6 +446,18 @@ record_event (char *locus, int type)
#endif
+static void
+x_update_opaque_region (struct frame *f)
+{
+ 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);
+}
+
+
#if defined USE_CAIRO || defined HAVE_XRENDER
static struct x_gc_ext_data *
x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
@@ -1244,8 +1258,8 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
#endif /* USE_CAIRO */
-#if defined HAVE_XRENDER && !defined USE_CAIRO
-MAYBE_UNUSED static void
+#if defined HAVE_XRENDER
+void
x_xr_apply_ext_clip (struct frame *f, GC gc)
{
eassert (FRAME_X_PICTURE (f) != None);
@@ -1259,7 +1273,7 @@ x_xr_apply_ext_clip (struct frame *f, GC gc)
data->n_clip_rects);
}
-MAYBE_UNUSED static void
+void
x_xr_reset_ext_clip (struct frame *f)
{
XRenderPictureAttributes attrs = { .clip_mask = None };
@@ -1301,7 +1315,8 @@ x_reset_clip_rectangles (struct frame *f, GC gc)
}
static void
-x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
+x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
+ bool respect_alpha_background)
{
#ifdef USE_CAIRO
Display *dpy = FRAME_X_DISPLAY (f);
@@ -1339,6 +1354,29 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
}
x_end_cr_clip (f);
#else
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+ if (respect_alpha_background
+ && FRAME_DISPLAY_INFO (f)->n_planes == 32
+ && FRAME_CHECK_XR_VERSION (f, 0, 2))
+ {
+ x_xr_ensure_picture (f);
+
+ if (FRAME_X_PICTURE (f) != None)
+ {
+ XRenderColor xc;
+
+ x_xr_apply_ext_clip (f, gc);
+ x_xrender_color_from_gc_foreground (f, gc, &xc, true);
+ XRenderFillRectangle (FRAME_X_DISPLAY (f),
+ PictOpSrc, FRAME_X_PICTURE (f),
+ &xc, x, y, width, height);
+ x_xr_reset_ext_clip (f);
+ x_mark_frame_dirty (f);
+
+ return;
+ }
+ }
+#endif
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
gc, x, y, width, height);
#endif
@@ -1346,7 +1384,8 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
static void
-x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
+x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
+ bool respect_alpha_background)
{
#ifdef USE_CAIRO
cairo_t *cr;
@@ -1357,6 +1396,30 @@ x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
cairo_fill (cr);
x_end_cr_clip (f);
#else
+#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
+ if (respect_alpha_background
+ && FRAME_DISPLAY_INFO (f)->n_planes == 32
+ && FRAME_CHECK_XR_VERSION (f, 0, 2))
+ {
+ x_xr_ensure_picture (f);
+
+ if (FRAME_X_PICTURE (f) != None)
+ {
+ XRenderColor xc;
+
+ x_xr_apply_ext_clip (f, gc);
+ x_xrender_color_from_gc_background (f, gc, &xc, true);
+ XRenderFillRectangle (FRAME_X_DISPLAY (f),
+ PictOpSrc, FRAME_X_PICTURE (f),
+ &xc, x, y, width, height);
+ x_xr_reset_ext_clip (f);
+ x_mark_frame_dirty (f);
+
+ return;
+ }
+ }
+#endif
+
XGCValues xgcv;
Display *dpy = FRAME_X_DISPLAY (f);
XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
@@ -1397,7 +1460,7 @@ x_clear_window (struct frame *f)
x_end_cr_clip (f);
#else
#ifndef USE_GTK
- if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ if (FRAME_X_DOUBLE_BUFFERED_P (f) || (f->alpha_background != 1.0))
#endif
x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
#ifndef USE_GTK
@@ -1655,7 +1718,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
face->foreground);
#ifdef USE_CAIRO
- x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
+ x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false);
#else
XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
f->output_data.x->normal_gc, x, y0, x, y1);
@@ -1688,13 +1751,13 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
XSetForeground (display, f->output_data.x->normal_gc, color_first);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0, y0, 1, y1 - y0);
+ x0, y0, 1, y1 - y0, false);
XSetForeground (display, f->output_data.x->normal_gc, color);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+ x0 + 1, y0, x1 - x0 - 2, y1 - y0, false);
XSetForeground (display, f->output_data.x->normal_gc, color_last);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x1 - 1, y0, 1, y1 - y0);
+ x1 - 1, y0, 1, y1 - y0, false);
}
else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
/* A horizontal divider, at least three pixels high: Draw first and
@@ -1702,13 +1765,13 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
XSetForeground (display, f->output_data.x->normal_gc, color_first);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0, y0, x1 - x0, 1);
+ x0, y0, x1 - x0, 1, false);
XSetForeground (display, f->output_data.x->normal_gc, color);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+ x0, y0 + 1, x1 - x0, y1 - y0 - 2, false);
XSetForeground (display, f->output_data.x->normal_gc, color_last);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0, y1 - 1, x1 - x0, 1);
+ x0, y1 - 1, x1 - x0, 1, false);
}
else
{
@@ -1716,7 +1779,7 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
differently. */
XSetForeground (display, f->output_data.x->normal_gc, color);
x_fill_rectangle (f, f->output_data.x->normal_gc,
- x0, y0, x1 - x0, y1 - y0);
+ x0, y0, x1 - x0, y1 - y0, false);
}
}
@@ -1841,10 +1904,10 @@ x_clear_under_internal_border (struct frame *f)
GC gc = f->output_data.x->normal_gc;
XSetForeground (display, gc, color);
- x_fill_rectangle (f, gc, 0, margin, width, border);
- x_fill_rectangle (f, gc, 0, 0, border, height);
- x_fill_rectangle (f, gc, width - border, 0, border, height);
- x_fill_rectangle (f, gc, 0, height - border, width, border);
+ x_fill_rectangle (f, gc, 0, margin, width, border, false);
+ x_fill_rectangle (f, gc, 0, 0, border, height, false);
+ x_fill_rectangle (f, gc, width - border, 0, border, height, false);
+ x_fill_rectangle (f, gc, 0, height - border, width, border, false);
XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
}
else
@@ -1949,7 +2012,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
else
XSetBackground (display, face->gc, face->background);
- x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
+ x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
+ true);
if (!face->stipple)
XSetForeground (display, face->gc, face->foreground);
@@ -2293,7 +2357,7 @@ x_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)
{
- x_clear_rectangle (s->f, s->gc, x, y, w, h);
+ x_clear_rectangle (s->f, s->gc, x, y, w, h, true);
}
@@ -2319,9 +2383,10 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
/* Fill background with a stipple pattern. */
XSetFillStyle (display, s->gc, FillOpaqueStippled);
x_fill_rectangle (s->f, s->gc, s->x,
- s->y + box_line_width,
- s->background_width,
- s->height - 2 * box_line_width);
+ s->y + box_line_width,
+ s->background_width,
+ s->height - 2 * box_line_width,
+ false);
XSetFillStyle (display, s->gc, FillSolid);
s->background_filled_p = true;
}
@@ -2416,7 +2481,8 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
x_fill_rectangle (s->f, s->gc, s->x,
s->y + box_line_width,
s->background_width,
- s->height - 2 * box_line_width);
+ s->height - 2 * box_line_width,
+ false);
XSetFillStyle (display, s->gc, FillSolid);
}
else
@@ -3344,7 +3410,7 @@ x_draw_relief_rect (struct frame *f,
if (left_p)
{
x_fill_rectangle (f, top_left_gc, 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)
@@ -3353,7 +3419,7 @@ x_draw_relief_rect (struct frame *f,
if (right_p)
{
x_fill_rectangle (f, bottom_right_gc, 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)
@@ -3363,7 +3429,7 @@ x_draw_relief_rect (struct frame *f,
{
if (!right_p)
x_fill_rectangle (f, top_left_gc, 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_gc, left_x, top_y,
right_x + 1 - left_x, hwidth, 1);
@@ -3372,7 +3438,7 @@ x_draw_relief_rect (struct frame *f,
{
if (!left_p)
x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
- right_x + 1 - left_x, hwidth);
+ right_x + 1 - left_x, hwidth, false);
else
x_fill_trapezoid_for_relief (f, bottom_right_gc,
left_x, bottom_y + 1 - hwidth,
@@ -3380,10 +3446,10 @@ x_draw_relief_rect (struct frame *f,
}
if (left_p && vwidth > 1)
x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
- 1, bottom_y + 1 - top_y);
+ 1, bottom_y + 1 - top_y, false);
if (top_p && hwidth > 1)
x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
- right_x + 1 - left_x, 1);
+ right_x + 1 - left_x, 1, false);
if (corners)
{
XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
@@ -3505,21 +3571,25 @@ x_draw_box_rect (struct glyph_string *s,
/* Top. */
x_fill_rectangle (s->f, s->gc,
- 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)
x_fill_rectangle (s->f, s->gc,
- left_x, top_y, vwidth, bottom_y - top_y + 1);
+ left_x, top_y, vwidth, bottom_y - top_y + 1,
+ false);
/* Bottom. */
x_fill_rectangle (s->f, s->gc,
- left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
+ left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth,
+ false);
/* Right. */
if (right_p)
x_fill_rectangle (s->f, s->gc,
- right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
+ right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1,
+ false);
XSetForeground (display, s->gc, xgcv.foreground);
x_reset_clip_rectangles (s->f, s->gc);
@@ -3934,7 +4004,7 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
/* Fill background with a stipple pattern. */
XSetFillStyle (display, s->gc, FillOpaqueStippled);
- x_fill_rectangle (s->f, s->gc, x, y, w, h);
+ x_fill_rectangle (s->f, s->gc, x, y, w, h, false);
XSetFillStyle (display, s->gc, FillSolid);
}
else
@@ -4139,7 +4209,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
{
/* Fill background with a stipple pattern. */
XSetFillStyle (display, gc, FillOpaqueStippled);
- x_fill_rectangle (s->f, gc, x, y, w, h);
+ x_fill_rectangle (s->f, gc, x, y, w, h, true);
XSetFillStyle (display, gc, FillSolid);
}
else
@@ -4147,7 +4217,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
XGCValues xgcv;
XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
XSetForeground (display, gc, xgcv.background);
- x_fill_rectangle (s->f, gc, x, y, w, h);
+ x_fill_rectangle (s->f, gc, x, y, w, h, true);
XSetForeground (display, gc, xgcv.foreground);
}
@@ -4497,7 +4567,8 @@ x_draw_glyph_string (struct glyph_string *s)
y = s->ybase + position;
if (s->face->underline_defaulted_p)
x_fill_rectangle (s->f, s->gc,
- s->x, y, decoration_width, thickness);
+ s->x, y, decoration_width, thickness,
+ false);
else
{
Display *display = FRAME_X_DISPLAY (s->f);
@@ -4505,7 +4576,8 @@ x_draw_glyph_string (struct glyph_string *s)
XGetGCValues (display, s->gc, GCForeground, &xgcv);
XSetForeground (display, s->gc, s->face->underline_color);
x_fill_rectangle (s->f, s->gc,
- s->x, y, decoration_width, thickness);
+ s->x, y, decoration_width, thickness,
+ false);
XSetForeground (display, s->gc, xgcv.foreground);
}
}
@@ -4517,7 +4589,7 @@ x_draw_glyph_string (struct glyph_string *s)
if (s->face->overline_color_defaulted_p)
x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- decoration_width, h);
+ decoration_width, h, false);
else
{
Display *display = FRAME_X_DISPLAY (s->f);
@@ -4525,7 +4597,7 @@ x_draw_glyph_string (struct glyph_string *s)
XGetGCValues (display, s->gc, GCForeground, &xgcv);
XSetForeground (display, s->gc, s->face->overline_color);
x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- decoration_width, h);
+ decoration_width, h, false);
XSetForeground (display, s->gc, xgcv.foreground);
}
}
@@ -4547,7 +4619,7 @@ x_draw_glyph_string (struct glyph_string *s)
if (s->face->strike_through_color_defaulted_p)
x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
- s->width, h);
+ s->width, h, false);
else
{
Display *display = FRAME_X_DISPLAY (s->f);
@@ -4555,7 +4627,7 @@ x_draw_glyph_string (struct glyph_string *s)
XGetGCValues (display, s->gc, GCForeground, &xgcv);
XSetForeground (display, s->gc, s->face->strike_through_color);
x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
- decoration_width, h);
+ decoration_width, h, false);
XSetForeground (display, s->gc, xgcv.foreground);
}
}
@@ -4667,7 +4739,8 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
x_end_cr_clip (f);
#else
#ifndef USE_GTK
- if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ if (FRAME_X_DOUBLE_BUFFERED_P (f)
+ || f->alpha_background != 1.0)
#endif
{
#if defined HAVE_XRENDER && \
@@ -4677,10 +4750,10 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
&& FRAME_CHECK_XR_VERSION (f, 0, 2))
{
XRenderColor xc;
- GC gc = f->output_data.x->reverse_gc;
+ GC gc = f->output_data.x->normal_gc;
x_xr_apply_ext_clip (f, gc);
- x_xrender_color_from_gc_foreground (f, gc, &xc);
+ x_xrender_color_from_gc_background (f, gc, &xc, true);
XRenderFillRectangle (FRAME_X_DISPLAY (f),
PictOpSrc, FRAME_X_PICTURE (f),
&xc, x, y, width, height);
@@ -9392,6 +9465,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f->output_data.x->has_been_visible = true;
}
+ x_update_opaque_region (f);
+
if (not_hidden && iconified)
{
inev.ie.kind = DEICONIFY_EVENT;
@@ -12134,8 +12209,8 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
x += cursor_glyph->pixel_width - width;
x_fill_rectangle (f, gc, x,
- WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
- width, row->height);
+ WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+ width, row->height, false);
}
else /* HBAR_CURSOR */
{
@@ -12156,7 +12231,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
x_fill_rectangle (f, gc, 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);
}
x_reset_clip_rectangles (f, gc);
@@ -15743,6 +15818,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
+ ATOM_REFS_INIT ("_NET_WM_OPAQUE_REGION", Xatom_net_wm_opaque_region)
#ifdef HAVE_XKB
ATOM_REFS_INIT ("Meta", Xatom_Meta)
ATOM_REFS_INIT ("Super", Xatom_Super)
@@ -16279,7 +16355,8 @@ init_xterm (void)
#ifdef HAVE_XRENDER
void
-x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color)
+x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color,
+ bool apply_alpha_background)
{
XGCValues xgcv;
XColor xc;
@@ -16288,26 +16365,47 @@ x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color)
xc.pixel = xgcv.foreground;
x_query_colors (f, &xc, 1);
- color->alpha = 65535;
- color->red = xc.red;
- color->blue = xc.blue;
- color->green = xc.green;
+ if (color->alpha == 65535)
+ {
+ color->red = xc.red;
+ color->blue = xc.blue;
+ color->green = xc.green;
+ }
+ else
+ {
+ color->red = (xc.red * color->alpha) / 65535;
+ color->blue = (xc.blue * color->alpha) / 65535;
+ color->green = (xc.green * color->alpha) / 65535;
+ }
}
void
-x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color)
+x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color,
+ bool apply_alpha_background)
{
XGCValues xgcv;
XColor xc;
XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
- xc.pixel = xgcv.foreground;
+ xc.pixel = xgcv.background;
x_query_colors (f, &xc, 1);
- color->alpha = 65535;
- color->red = xc.red;
- color->blue = xc.blue;
- color->green = xc.green;
+ color->alpha = (apply_alpha_background
+ ? 65535 * f->alpha_background
+ : 65535);
+
+ if (color->alpha == 65535)
+ {
+ color->red = xc.red;
+ color->blue = xc.blue;
+ color->green = xc.green;
+ }
+ else
+ {
+ color->red = (xc.red * color->alpha) / 65535;
+ color->blue = (xc.blue * color->alpha) / 65535;
+ color->green = (xc.green * color->alpha) / 65535;
+ }
}
#endif
diff --git a/src/xterm.h b/src/xterm.h
index aa5bd2caa19..5e17d5b7215 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -496,7 +496,8 @@ struct x_display_info
Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below,
Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar,
- Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea;
+ Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea,
+ Xatom_net_wm_opaque_region;
/* XSettings atoms and windows. */
Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -1242,8 +1243,13 @@ extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t);
#endif
#ifdef HAVE_XRENDER
-extern void x_xrender_color_from_gc_foreground (struct frame *, GC, XRenderColor *);
-extern void x_xrender_color_from_gc_background (struct frame *, GC, XRenderColor *);
+extern void x_xrender_color_from_gc_foreground (struct frame *, GC,
+ XRenderColor *, bool);
+extern void x_xrender_color_from_gc_background (struct frame *, GC,
+ XRenderColor *, bool);
+extern void x_xr_ensure_picture (struct frame *f);
+extern void x_xr_apply_ext_clip (struct frame *f, GC gc);
+extern void x_xr_reset_ext_clip (struct frame *f);
#endif
INLINE int