Default to only use ARGB visual for ARGB client windows

Don't use the same visual for all windows.

And add a --full-argb option to force ARGB visual for all windows, which
is the current default behavior.

Fixes #2408
This commit is contained in:
Yuxuan Shui 2024-04-13 11:48:36 +01:00
parent 8b1f8958b4
commit b013e9aeaf
15 changed files with 106 additions and 52 deletions

View File

@ -693,21 +693,23 @@ main(int argc, char **argv)
if(xcb_connection_has_error(globalconf.connection))
fatal("cannot open display (error %d)", xcb_connection_has_error(globalconf.connection));
if (!(default_init_flags & INIT_FLAG_ARGB))
globalconf.argb_mode = ARGB_MODE_DISABLED;
else if (default_init_flags & INIT_FLAG_FULL_ARGB)
globalconf.argb_mode = ARGB_MODE_FULL;
else
globalconf.argb_mode = ARGB_MODE_ENABLED;
globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen);
globalconf.default_visual = draw_default_visual(globalconf.screen);
if(default_init_flags & INIT_FLAG_ARGB)
globalconf.visual = draw_argb_visual(globalconf.screen);
if(!globalconf.visual)
globalconf.visual = globalconf.default_visual;
globalconf.default_depth = draw_visual_depth(globalconf.screen, globalconf.visual->visual_id);
globalconf.default_cmap = globalconf.screen->default_colormap;
if(globalconf.default_depth != globalconf.screen->root_depth)
globalconf.screen_visual = draw_default_visual(globalconf.screen);
globalconf.screen_depth = draw_visual_depth(globalconf.screen, globalconf.screen_visual->visual_id);
globalconf.screen_cmap = globalconf.screen->default_colormap;
if (globalconf.argb_mode != ARGB_MODE_DISABLED)
{
// We need our own color map if we aren't using the default depth
globalconf.default_cmap = xcb_generate_id(globalconf.connection);
globalconf.argb_visual = draw_argb_visual(globalconf.screen);
globalconf.argb_cmap = xcb_generate_id(globalconf.connection);
xcb_create_colormap(globalconf.connection, XCB_COLORMAP_ALLOC_NONE,
globalconf.default_cmap, globalconf.screen->root,
globalconf.visual->visual_id);
globalconf.argb_cmap, globalconf.screen->root,
globalconf.argb_visual->visual_id);
}
#ifdef WITH_XCB_ERRORS
@ -815,10 +817,10 @@ main(int argc, char **argv)
* The window_no_focus is used for "nothing has the input focus". */
globalconf.focus.window_no_focus = xcb_generate_id(globalconf.connection);
globalconf.gc = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth,
xcb_create_window(globalconf.connection, globalconf.screen_depth,
globalconf.focus.window_no_focus, globalconf.screen->root,
-1, -1, 1, 1, 0,
XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
XCB_COPY_FROM_PARENT, globalconf.screen_visual->visual_id,
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP,
(const uint32_t [])
@ -826,7 +828,7 @@ main(int argc, char **argv)
globalconf.screen->black_pixel,
globalconf.screen->black_pixel,
1,
globalconf.default_cmap
globalconf.screen_cmap
});
xwindow_set_class_instance(globalconf.focus.window_no_focus);
xwindow_set_name_static(globalconf.focus.window_no_focus, "Awesome no input window");

View File

@ -159,7 +159,7 @@ color_init_unchecked(color_t *color, const char *colstr, ssize_t len, xcb_visual
return req;
}
req.cookie_hexa = xcb_alloc_color_unchecked(globalconf.connection,
globalconf.default_cmap,
globalconf.screen_cmap,
RGB_8TO16(red),
RGB_8TO16(green),
RGB_8TO16(blue));

4
draw.c
View File

@ -242,10 +242,10 @@ uint8_t draw_visual_depth(const xcb_screen_t *s, xcb_visualid_t vis)
void draw_test_cairo_xcb(void)
{
xcb_pixmap_t pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, pixmap,
xcb_create_pixmap(globalconf.connection, globalconf.screen_depth, pixmap,
globalconf.screen->root, 1, 1);
cairo_surface_t *surface = cairo_xcb_surface_create(globalconf.connection,
pixmap, globalconf.visual, 1, 1);
pixmap, globalconf.screen_visual, 1, 1);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
fatal("Could not set up display: got cairo surface with status %s",
cairo_status_to_string(cairo_surface_status(surface)));

View File

@ -77,6 +77,15 @@ ARRAY_TYPE(xproperty_t, xproperty)
DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING)
DO_ARRAY(xcb_window_t, window, DO_NOTHING)
enum argb_mode {
/** No window will be created with an ARGB visual */
ARGB_MODE_DISABLED = 0,
/** Client window with an ARGB visual will be reparented an ARGB window */
ARGB_MODE_ENABLED,
/** All windows will be created with an ARGB visual */
ARGB_MODE_FULL
};
/** Main configuration structure */
typedef struct
{
@ -185,20 +194,24 @@ typedef struct
} systray;
/** The monitor of startup notifications */
SnMonitorContext *snmonitor;
/** The visual, used to draw */
xcb_visualtype_t *visual;
/** The screen's default visual */
xcb_visualtype_t *default_visual;
xcb_visualtype_t *screen_visual;
/** An ARGB visual */
xcb_visualtype_t *argb_visual;
/** The screen's information */
xcb_screen_t *screen;
/** A graphic context. */
xcb_gcontext_t gc;
/** Our default depth */
uint8_t default_depth;
/** Our default color map */
xcb_colormap_t default_cmap;
/** The screen's depth */
uint8_t screen_depth;
/** The screen's default color map */
xcb_colormap_t screen_cmap;
/** ARGB color map */
xcb_colormap_t argb_cmap;
/** Do we have to reban clients? */
bool need_lazy_banning;
/** Should we use ARGB visual for all windows? */
enum argb_mode argb_mode;
/** Tag list */
tag_array_t tags;
/** List of registered xproperties */

View File

@ -1891,8 +1891,8 @@ client_get_nofocus_window(client_t *c)
{
if (c->nofocus_window == XCB_NONE) {
c->nofocus_window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth, c->nofocus_window, c->frame_window,
-2, -2, 1, 1, 0, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
xcb_create_window(globalconf.connection, globalconf.screen_depth, c->nofocus_window, c->frame_window,
-2, -2, 1, 1, 0, XCB_COPY_FROM_PARENT, globalconf.screen_visual->visual_id,
0, NULL);
xcb_map_window(globalconf.connection, c->nofocus_window);
xwindow_grabkeys(c->nofocus_window, &c->keys);
@ -2137,17 +2137,26 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at
client_t *c = client_new(L);
xcb_screen_t *s = globalconf.screen;
uint8_t depth = globalconf.screen_depth, window_depth = draw_visual_depth(globalconf.screen, wattr->visual);
xcb_colormap_t cmap = globalconf.screen_cmap;
c->border_width_callback = (void (*) (void *, uint16_t, uint16_t)) border_width_callback;
/* consider the window banned */
c->isbanned = true;
/* Store window and visual */
c->window = w;
c->visualtype = draw_find_visual(globalconf.screen, wattr->visual);
c->client_visualtype = draw_find_visual(globalconf.screen, wattr->visual);
c->frame_window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth, c->frame_window, s->root,
c->visualtype = globalconf.screen_visual;
if ((globalconf.argb_mode == ARGB_MODE_FULL || window_depth == 32) && globalconf.argb_mode != ARGB_MODE_DISABLED)
{
c->visualtype = globalconf.argb_visual;
depth = 32;
cmap = globalconf.argb_cmap;
}
xcb_create_window(globalconf.connection, depth, c->frame_window, s->root,
wgeom->x, wgeom->y, wgeom->width, wgeom->height,
wgeom->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
wgeom->border_width, XCB_COPY_FROM_PARENT, c->visualtype->visual_id,
XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_WIN_GRAVITY
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
(const uint32_t [])
@ -2157,7 +2166,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at
XCB_GRAVITY_NORTH_WEST,
1,
FRAME_SELECT_INPUT_EVENT_MASK,
globalconf.default_cmap
cmap
});
/* The client may already be mapped, thus we must be sure that we don't send
@ -3195,7 +3204,7 @@ client_set_icon_from_pixmaps(client_t *c, xcb_pixmap_t icon, xcb_pixmap_t mask)
s_icon = cairo_xcb_surface_create_for_bitmap(globalconf.connection,
globalconf.screen, icon, geom_icon_r->width, geom_icon_r->height);
else
s_icon = cairo_xcb_surface_create(globalconf.connection, icon, globalconf.default_visual,
s_icon = cairo_xcb_surface_create(globalconf.connection, icon, globalconf.screen_visual,
geom_icon_r->width, geom_icon_r->height);
result = s_icon;
@ -3568,21 +3577,28 @@ client_refresh_partial(client_t *c, int16_t x, int16_t y, uint16_t width, uint16
static drawable_t *
titlebar_get_drawable(lua_State *L, client_t *c, int cl_idx, client_titlebar_t bar)
{
uint8_t depth = globalconf.screen_depth;
xcb_visualtype_t *visual = globalconf.screen_visual;
if (globalconf.argb_mode == ARGB_MODE_FULL)
{
visual = globalconf.argb_visual;
depth = 32;
}
if (c->titlebar[bar].drawable == NULL)
{
cl_idx = luaA_absindex(L, cl_idx);
switch (bar) {
case CLIENT_TITLEBAR_TOP:
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_top, c);
drawable_allocator(L, depth, visual, (drawable_refresh_callback *) client_refresh_titlebar_top, c);
break;
case CLIENT_TITLEBAR_BOTTOM:
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_bottom, c);
drawable_allocator(L, depth, visual, (drawable_refresh_callback *) client_refresh_titlebar_bottom, c);
break;
case CLIENT_TITLEBAR_RIGHT:
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_right, c);
drawable_allocator(L, depth, visual, (drawable_refresh_callback *) client_refresh_titlebar_right, c);
break;
case CLIENT_TITLEBAR_LEFT:
drawable_allocator(L, (drawable_refresh_callback *) client_refresh_titlebar_left, c);
drawable_allocator(L, depth, visual, (drawable_refresh_callback *) client_refresh_titlebar_left, c);
break;
default:
fatal("Unknown titlebar kind %d\n", (int) bar);
@ -4022,7 +4038,7 @@ luaA_client_get_content(lua_State *L, client_t *c)
height -= c->titlebar[CLIENT_TITLEBAR_TOP].size + c->titlebar[CLIENT_TITLEBAR_BOTTOM].size;
surface = cairo_xcb_surface_create(globalconf.connection, c->window,
c->visualtype, width, height);
c->client_visualtype, width, height);
/* lua has to make sure to free the ref or we have a leak */
lua_pushlightuserdata(L, surface);

View File

@ -173,7 +173,7 @@ struct client_t
/** Size hints */
xcb_size_hints_t size_hints;
/** The visualtype that c->window uses */
xcb_visualtype_t *visualtype;
xcb_visualtype_t *client_visualtype;
/** Do we honor the client's size hints? */
bool size_hints_honor;
/** Machine the client is running on. */

View File

@ -105,7 +105,7 @@ static lua_class_t drawable_class;
LUA_OBJECT_FUNCS(drawable_class, drawable_t, drawable)
drawable_t *
drawable_allocator(lua_State *L, drawable_refresh_callback *callback, void *data)
drawable_allocator(lua_State *L, uint8_t depth, xcb_visualtype_t *visual, drawable_refresh_callback *callback, void *data)
{
drawable_t *d = drawable_new(L);
d->refresh_callback = callback;
@ -113,6 +113,8 @@ drawable_allocator(lua_State *L, drawable_refresh_callback *callback, void *data
d->refreshed = false;
d->surface = NULL;
d->pixmap = XCB_NONE;
d->depth = depth;
d->visual = visual;
return d;
}
@ -147,10 +149,10 @@ drawable_set_geometry(lua_State *L, int didx, area_t geom)
if (area_changed && geom.width > 0 && geom.height > 0)
{
d->pixmap = xcb_generate_id(globalconf.connection);
xcb_create_pixmap(globalconf.connection, globalconf.default_depth, d->pixmap,
xcb_create_pixmap(globalconf.connection, d->depth, d->pixmap,
globalconf.screen->root, geom.width, geom.height);
d->surface = cairo_xcb_surface_create(globalconf.connection,
d->pixmap, globalconf.visual,
d->pixmap, d->visual,
geom.width, geom.height);
luaA_object_emit_signal(L, didx, "property::surface", 0);
}

View File

@ -44,10 +44,14 @@ struct drawable_t
drawable_refresh_callback *refresh_callback;
/** Data for refresh callback. */
void *refresh_data;
/** Drawable depth */
uint8_t depth;
/** Drawable visual */
xcb_visualtype_t *visual;
};
typedef struct drawable_t drawable_t;
drawable_t *drawable_allocator(lua_State *, drawable_refresh_callback *, void *);
drawable_t *drawable_allocator(lua_State *, uint8_t depth, xcb_visualtype_t *visual, drawable_refresh_callback *, void *);
void drawable_set_geometry(lua_State *, int, area_t);
void drawable_class_setup(lua_State *);

View File

@ -416,6 +416,15 @@ drawin_allocator(lua_State *L)
{
xcb_screen_t *s = globalconf.screen;
drawin_t *w = drawin_new(L);
uint8_t depth = globalconf.screen_depth;
xcb_visualtype_t *visual = globalconf.screen_visual;
xcb_colormap_t cmap = globalconf.screen_cmap;
if (globalconf.argb_mode == ARGB_MODE_FULL)
{
visual = globalconf.argb_visual;
cmap = globalconf.argb_cmap;
depth = 32;
}
w->visible = false;
@ -425,15 +434,16 @@ drawin_allocator(lua_State *L)
w->geometry.height = 1;
w->geometry_dirty = false;
w->type = _NET_WM_WINDOW_TYPE_NORMAL;
w->visualtype = visual;
drawable_allocator(L, (drawable_refresh_callback *) drawin_refresh_pixmap, w);
drawable_allocator(L, depth, visual, (drawable_refresh_callback *) drawin_refresh_pixmap, w);
w->drawable = luaA_object_ref_item(L, -2, -1);
w->window = xcb_generate_id(globalconf.connection);
xcb_create_window(globalconf.connection, globalconf.default_depth, w->window, s->root,
xcb_create_window(globalconf.connection, depth, w->window, s->root,
w->geometry.x, w->geometry.y,
w->geometry.width, w->geometry.height,
w->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
w->border_width, XCB_COPY_FROM_PARENT, visual->visual_id,
XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP
| XCB_CW_CURSOR,
@ -448,7 +458,7 @@ drawin_allocator(lua_State *L)
| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_BUTTON_PRESS
| XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_PROPERTY_CHANGE,
globalconf.default_cmap,
cmap,
xcursor_new(globalconf.cursor_ctx, xcursor_font_fromstr(w->cursor))
});
xwindow_set_class_instance(w->window);

View File

@ -195,7 +195,7 @@ luaA_window_set_border_color(lua_State *L, window_t *window)
const char *color_name = luaL_checklstring(L, -1, &len);
if(color_name &&
color_init_reply(color_init_unchecked(&window->border_color, color_name, len, globalconf.visual)))
color_init_reply(color_init_unchecked(&window->border_color, color_name, len, window->visualtype)))
{
window->border_need_update = true;
luaA_object_emit_signal(L, -3, "property::border_color", 0);

View File

@ -69,6 +69,8 @@ typedef enum
color_t border_color; \
/** Border width */ \
uint16_t border_width; \
/** The visual type */ \
xcb_visualtype_t *visualtype; \
/** The window type */ \
window_type_t type; \
/** The border width callback */ \

View File

@ -418,6 +418,7 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
{ "screen" , ARG , NULL, 'm' },
{ "api-level" , ARG , NULL, 'l' },
{ "reap" , ARG , NULL, '\1' },
{ "full-argb" , NO_ARG, NULL, 'A' },
{ NULL , NO_ARG, NULL, 0 }
};
@ -467,6 +468,9 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
globalconf.had_overriden_depth = true;
(*init_flags) &= ~INIT_FLAG_ARGB;
break;
case 'A':
(*init_flags) |= INIT_FLAG_FULL_ARGB | INIT_FLAG_ARGB;
break;
case 'r':
(*init_flags) |= INIT_FLAG_REPLACE_WM;
break;

View File

@ -32,6 +32,7 @@ typedef enum {
INIT_FLAG_AUTO_SCREEN = 0x1 << 3,
INIT_FLAG_ALLOW_FALLBACK = 0x1 << 4,
INIT_FLAG_FORCE_CMD_ARGS = 0x1 << 5,
INIT_FLAG_FULL_ARGB = 0x1 << 6,
} awesome_init_config_t;
char *options_detect_shebang(int argc, char **argv);

8
root.c
View File

@ -193,13 +193,13 @@ root_update_wallpaper(void)
}
/* Only the default visual makes sense, so just the default depth */
if (geom_r->depth != draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id))
if (geom_r->depth != draw_visual_depth(globalconf.screen, globalconf.screen_visual->visual_id))
warn("Got a pixmap with depth %d, but the default depth is %d, continuing anyway",
geom_r->depth, draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id));
geom_r->depth, draw_visual_depth(globalconf.screen, globalconf.screen_visual->visual_id));
globalconf.wallpaper = cairo_xcb_surface_create(globalconf.connection,
*rootpix,
globalconf.default_visual,
globalconf.screen_visual,
geom_r->width,
geom_r->height);
@ -530,7 +530,7 @@ luaA_root_get_content(lua_State *L)
surface = cairo_xcb_surface_create(globalconf.connection,
globalconf.screen->root,
globalconf.default_visual,
globalconf.screen_visual,
globalconf.screen->width_in_pixels,
globalconf.screen->height_in_pixels);

View File

@ -372,7 +372,7 @@ luaA_systray(lua_State *L)
color_t bg_color;
bool force_redraw = false;
if(color_init_reply(color_init_unchecked(&bg_color, bg, bg_len, globalconf.default_visual))
if(color_init_reply(color_init_unchecked(&bg_color, bg, bg_len, globalconf.screen_visual))
&& globalconf.systray.background_pixel != bg_color.pixel)
{
uint32_t config_back[] = { bg_color.pixel };