Remove ARGB as a window mode

Instead use win_has_alpha to check for alpha channel, window mode is
reserved for determine if the window is possibly transparent.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2018-09-29 19:07:39 +01:00
parent 290cdd2b85
commit 90b6aa16ad
8 changed files with 42 additions and 30 deletions

View File

@ -26,6 +26,7 @@
#endif #endif
#include "common.h" #include "common.h"
#include "win.h"
#include "c2.h" #include "c2.h"
#define C2_MAX_LEVELS 10 #define C2_MAX_LEVELS 10
@ -1398,7 +1399,7 @@ c2_match_once_leaf(session_t *ps, win *w, const c2_l_t *pleaf,
case C2_L_PBDW: tgt = w->g.border_width; break; case C2_L_PBDW: tgt = w->g.border_width; break;
case C2_L_PFULLSCREEN: tgt = win_is_fullscreen(ps, w); break; case C2_L_PFULLSCREEN: tgt = win_is_fullscreen(ps, w); break;
case C2_L_POVREDIR: tgt = w->a.override_redirect; break; case C2_L_POVREDIR: tgt = w->a.override_redirect; break;
case C2_L_PARGB: tgt = (WMODE_ARGB == w->mode); break; case C2_L_PARGB: tgt = win_has_alpha(w); break;
case C2_L_PFOCUSED: tgt = win_is_focused_real(ps, w); break; case C2_L_PFOCUSED: tgt = win_is_focused_real(ps, w); break;
case C2_L_PWMWIN: tgt = w->wmwin; break; case C2_L_PWMWIN: tgt = w->wmwin; break;
case C2_L_PBSHAPED: tgt = w->bounding_shaped; break; case C2_L_PBSHAPED: tgt = w->bounding_shaped; break;

View File

@ -273,9 +273,9 @@ typedef struct {
/// Enumeration type of window painting mode. /// Enumeration type of window painting mode.
typedef enum { typedef enum {
WMODE_TRANS, WMODE_TRANS, // The window body is (potentially) transparent
WMODE_SOLID, WMODE_FRAME_TRANS, // The window body is opaque, but the frame is not
WMODE_ARGB WMODE_SOLID, // The window is opaque including the frame
} winmode_t; } winmode_t;
/// Structure representing needed window updates. /// Structure representing needed window updates.

View File

@ -1511,7 +1511,7 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
newpict, 0, 0, 0, 0, 0, 0, wid, hei); newpict, 0, 0, 0, 0, 0, 0, wid, hei);
// We use an extra PictOpInReverse operation to get correct pixel // We use an extra PictOpInReverse operation to get correct pixel
// alpha. There could be a better solution. // alpha. There could be a better solution.
if (WMODE_ARGB == w->mode) if (win_has_alpha(w))
xcb_render_composite(c, XCB_RENDER_PICT_OP_IN_REVERSE, pict, None, xcb_render_composite(c, XCB_RENDER_PICT_OP_IN_REVERSE, pict, None,
newpict, 0, 0, 0, 0, 0, 0, wid, hei); newpict, 0, 0, 0, 0, 0, 0, wid, hei);
pict = newpict; pict = newpict;

View File

@ -497,13 +497,14 @@ find_win_all(session_t *ps, const Window wid) {
render_(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg) render_(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg)
#endif #endif
bool win_has_alpha(win *);
static inline void static inline void
win_render(session_t *ps, win *w, int x, int y, int wid, int hei, win_render(session_t *ps, win *w, int x, int y, int wid, int hei,
double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg, double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg,
xcb_render_picture_t pict) { xcb_render_picture_t pict) {
const int dx = (w ? w->g.x: 0) + x; const int dx = (w ? w->g.x: 0) + x;
const int dy = (w ? w->g.y: 0) + y; const int dy = (w ? w->g.y: 0) + y;
const bool argb = (w && (WMODE_ARGB == w->mode || ps->o.force_win_blend)); const bool argb = (w && (win_has_alpha(w) || ps->o.force_win_blend));
const bool neg = (w && w->invert_color); const bool neg = (w && w->invert_color);
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg,

View File

@ -281,19 +281,21 @@ bool wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def,
return ret; return ret;
} }
// XXX should distinguish between frame has alpha and window body has alpha
bool win_has_alpha(win *w) {
return w->pictfmt &&
w->pictfmt->type == XCB_RENDER_PICT_TYPE_DIRECT &&
w->pictfmt->direct.alpha_mask;
}
void win_determine_mode(session_t *ps, win *w) { void win_determine_mode(session_t *ps, win *w) {
winmode_t mode = WMODE_SOLID; if (win_has_alpha(w) || w->opacity != OPAQUE) {
w->mode = WMODE_TRANS;
if (w->pictfmt && w->pictfmt->type == XCB_RENDER_PICT_TYPE_DIRECT && } else if (w->frame_opacity) {
w->pictfmt->direct.alpha_mask) { w->mode = WMODE_FRAME_TRANS;
mode = WMODE_ARGB;
} else if (w->opacity != OPAQUE) {
mode = WMODE_TRANS;
} else { } else {
mode = WMODE_SOLID; w->mode = WMODE_SOLID;
} }
w->mode = mode;
} }
/** /**
@ -375,7 +377,7 @@ void win_determine_fade(session_t *ps, win *w) {
else if (ps->o.no_fading_openclose && w->in_openclose) else if (ps->o.no_fading_openclose && w->in_openclose)
w->fade_last = w->fade = false; w->fade_last = w->fade = false;
else if (ps->o.no_fading_destroyed_argb && w->destroyed && else if (ps->o.no_fading_destroyed_argb && w->destroyed &&
WMODE_ARGB == w->mode && w->client_win && w->client_win != w->id) { win_has_alpha(w) && w->client_win && w->client_win != w->id) {
w->fade_last = w->fade = false; w->fade_last = w->fade = false;
} }
// Ignore other possible causes of fading state changes after window // Ignore other possible causes of fading state changes after window

View File

@ -95,3 +95,6 @@ static inline Window
win_get_leader(session_t *ps, win *w) { win_get_leader(session_t *ps, win *w) {
return win_get_leader_raw(ps, w, 0); return win_get_leader_raw(ps, w, 0);
} }
/// check if window has ARGB visual
bool win_has_alpha(win *w);

27
src/x.c
View File

@ -1,3 +1,5 @@
#include <stdbool.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <xcb/xcb_renderutil.h> #include <xcb/xcb_renderutil.h>
@ -96,16 +98,18 @@ bool wid_get_text_prop(session_t *ps, Window wid, Atom prop,
} }
static inline void x_get_server_pictfmts(session_t *ps) { static inline void x_get_server_pictfmts(session_t *ps) {
xcb_connection_t *c = XGetXCBConnection(ps->dpy); if (ps->pictfmts)
xcb_generic_error_t *e = NULL; return;
// Get window picture format xcb_connection_t *c = XGetXCBConnection(ps->dpy);
ps->pictfmts = xcb_generic_error_t *e = NULL;
xcb_render_query_pict_formats_reply(c, // Get window picture format
xcb_render_query_pict_formats(c), &e); ps->pictfmts =
if (e || !ps->pictfmts) { xcb_render_query_pict_formats_reply(c,
printf_errf("(): failed to get pict formats\n"); xcb_render_query_pict_formats(c), &e);
abort(); if (e || !ps->pictfmts) {
} printf_errf("(): failed to get pict formats\n");
abort();
}
} }
xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *ps, xcb_visualid_t visual) { xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *ps, xcb_visualid_t visual) {
@ -116,8 +120,9 @@ xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *ps, xcb_visualid
for(xcb_render_pictforminfo_iterator_t i = for(xcb_render_pictforminfo_iterator_t i =
xcb_render_query_pict_formats_formats_iterator(ps->pictfmts); i.rem; xcb_render_query_pict_formats_formats_iterator(ps->pictfmts); i.rem;
xcb_render_pictforminfo_next(&i)) { xcb_render_pictforminfo_next(&i)) {
if (i.data->id == pv->format) if (i.data->id == pv->format) {
return i.data; return i.data;
}
} }
return NULL; return NULL;
} }

View File

@ -64,5 +64,5 @@ __attribute__((nonnull(1)));
*/ */
xcb_render_picture_t xcb_render_picture_t
x_create_picture(session_t *ps, int wid, int hei, x_create_picture(session_t *ps, int wid, int hei,
xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask, xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr); const xcb_render_create_picture_value_list_t *attr);