Implement support for chosing a 32 bit visual (necessary for pseudo-transparency) (Thanks darkraven)
You need to specify the --enable-32bit-visual flag when starting i3. This is done because everything feels sluggish on my system when using a 32 bit visual instead of a 24 bit visual. Fast > fancy.
This commit is contained in:
parent
19f3f84d29
commit
58ecd14900
|
@ -50,7 +50,14 @@ extern TAILQ_HEAD(ws_assignments_head, Workspace_Assignment) ws_assignments;
|
||||||
extern TAILQ_HEAD(assignments_head, Assignment) assignments;
|
extern TAILQ_HEAD(assignments_head, Assignment) assignments;
|
||||||
extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
|
extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
|
||||||
extern xcb_screen_t *root_screen;
|
extern xcb_screen_t *root_screen;
|
||||||
|
|
||||||
|
/* Color depth, visual id and colormap to use when creating windows and
|
||||||
|
* pixmaps. Will use 32 bit depth and an appropriate visual, if available,
|
||||||
|
* otherwise the root window’s default (usually 24 bit TrueColor). */
|
||||||
extern uint8_t root_depth;
|
extern uint8_t root_depth;
|
||||||
|
extern xcb_visualid_t visual_id;
|
||||||
|
extern xcb_colormap_t colormap;
|
||||||
|
|
||||||
extern bool xcursor_supported, xkb_supported;
|
extern bool xcursor_supported, xkb_supported;
|
||||||
extern xcb_window_t root;
|
extern xcb_window_t root;
|
||||||
extern struct ev_loop *main_loop;
|
extern struct ev_loop *main_loop;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* vim:ts=4:sw=4:expandtab
|
* vim:ts=4:sw=4:expandtab
|
||||||
*
|
*
|
||||||
* i3 - an improved dynamic tiling window manager
|
* i3 - an improved dynamic tiling window manager
|
||||||
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
|
* © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -32,5 +32,7 @@ uint32_t get_colorpixel(const char *hex) {
|
||||||
uint8_t g = strtol(strgroups[1], NULL, 16);
|
uint8_t g = strtol(strgroups[1], NULL, 16);
|
||||||
uint8_t b = strtol(strgroups[2], NULL, 16);
|
uint8_t b = strtol(strgroups[2], NULL, 16);
|
||||||
|
|
||||||
return (r << 16 | g << 8 | b);
|
/* We set the first 8 bits high to have 100% opacity in case of a 32 bit
|
||||||
|
* color depth visual. */
|
||||||
|
return (0xFF << 24) | (r << 16 | g << 8 | b);
|
||||||
}
|
}
|
||||||
|
|
64
src/main.c
64
src/main.c
|
@ -53,7 +53,13 @@ xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
|
||||||
|
|
||||||
xcb_screen_t *root_screen;
|
xcb_screen_t *root_screen;
|
||||||
xcb_window_t root;
|
xcb_window_t root;
|
||||||
|
|
||||||
|
/* Color depth, visual id and colormap to use when creating windows and
|
||||||
|
* pixmaps. Will use 32 bit depth and an appropriate visual, if available,
|
||||||
|
* otherwise the root window’s default (usually 24 bit TrueColor). */
|
||||||
uint8_t root_depth;
|
uint8_t root_depth;
|
||||||
|
xcb_visualid_t visual_id;
|
||||||
|
xcb_colormap_t colormap;
|
||||||
|
|
||||||
struct ev_loop *main_loop;
|
struct ev_loop *main_loop;
|
||||||
|
|
||||||
|
@ -244,6 +250,7 @@ int main(int argc, char *argv[]) {
|
||||||
bool delete_layout_path = false;
|
bool delete_layout_path = false;
|
||||||
bool force_xinerama = false;
|
bool force_xinerama = false;
|
||||||
bool disable_signalhandler = false;
|
bool disable_signalhandler = false;
|
||||||
|
bool enable_32bit_visual = false;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"no-autostart", no_argument, 0, 'a'},
|
{"no-autostart", no_argument, 0, 'a'},
|
||||||
{"config", required_argument, 0, 'c'},
|
{"config", required_argument, 0, 'c'},
|
||||||
|
@ -258,9 +265,12 @@ int main(int argc, char *argv[]) {
|
||||||
{"shmlog_size", required_argument, 0, 0},
|
{"shmlog_size", required_argument, 0, 0},
|
||||||
{"get-socketpath", no_argument, 0, 0},
|
{"get-socketpath", no_argument, 0, 0},
|
||||||
{"get_socketpath", no_argument, 0, 0},
|
{"get_socketpath", no_argument, 0, 0},
|
||||||
|
{"enable-32bit-visual", no_argument, 0, 0},
|
||||||
|
{"enable_32bit_visual", no_argument, 0, 0},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
int option_index = 0, opt;
|
int option_index = 0, opt;
|
||||||
|
xcb_void_cookie_t colormap_cookie;
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
|
@ -358,6 +368,11 @@ int main(int argc, char *argv[]) {
|
||||||
layout_path = sstrdup(optarg);
|
layout_path = sstrdup(optarg);
|
||||||
delete_layout_path = true;
|
delete_layout_path = true;
|
||||||
break;
|
break;
|
||||||
|
} else if (strcmp(long_options[option_index].name, "enable_32bit_visual") == 0 ||
|
||||||
|
strcmp(long_options[option_index].name, "enable-32bit-visual") == 0) {
|
||||||
|
LOG("Enabling 32 bit visual (if available)\n");
|
||||||
|
enable_32bit_visual = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
|
@ -384,6 +399,10 @@ int main(int argc, char *argv[]) {
|
||||||
"\tto 0 disables SHM logging entirely.\n"
|
"\tto 0 disables SHM logging entirely.\n"
|
||||||
"\tThe default is %d bytes.\n", shmlog_size);
|
"\tThe default is %d bytes.\n", shmlog_size);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "\t--enable-32bit-visual\n"
|
||||||
|
"\tMakes i3 use a 32 bit visual, if available. Necessary for\n"
|
||||||
|
"\tpseudo-transparency with xcompmgr.\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
|
fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
|
||||||
"to send to a currently running i3 (like i3-msg). This allows you to\n"
|
"to send to a currently running i3 (like i3-msg). This allows you to\n"
|
||||||
"use nice and logical commands, such as:\n"
|
"use nice and logical commands, such as:\n"
|
||||||
|
@ -494,7 +513,38 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
root_screen = xcb_aux_get_screen(conn, conn_screen);
|
root_screen = xcb_aux_get_screen(conn, conn_screen);
|
||||||
root = root_screen->root;
|
root = root_screen->root;
|
||||||
|
|
||||||
|
/* By default, we use the same depth and visual as the root window, which
|
||||||
|
* usually is TrueColor (24 bit depth) and the corresponding visual.
|
||||||
|
* However, we also check if a 32 bit depth and visual are available (for
|
||||||
|
* transparency) and use it if so. */
|
||||||
root_depth = root_screen->root_depth;
|
root_depth = root_screen->root_depth;
|
||||||
|
visual_id = root_screen->root_visual;
|
||||||
|
colormap = root_screen->default_colormap;
|
||||||
|
|
||||||
|
if (enable_32bit_visual) {
|
||||||
|
xcb_depth_iterator_t depth_iter;
|
||||||
|
xcb_visualtype_iterator_t visual_iter;
|
||||||
|
for (depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
|
||||||
|
depth_iter.rem;
|
||||||
|
xcb_depth_next(&depth_iter)) {
|
||||||
|
if (depth_iter.data->depth != 32)
|
||||||
|
continue;
|
||||||
|
visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
|
||||||
|
if (!visual_iter.rem)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
visual_id = visual_iter.data->visual_id;
|
||||||
|
root_depth = depth_iter.data->depth;
|
||||||
|
colormap = xcb_generate_id(conn);
|
||||||
|
colormap_cookie = xcb_create_colormap_checked(conn, XCB_COLORMAP_ALLOC_NONE, colormap, root, visual_id);
|
||||||
|
DLOG("Found a visual with 32 bit depth.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
|
||||||
|
|
||||||
xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
|
xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
|
||||||
xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
|
xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
|
||||||
|
|
||||||
|
@ -524,6 +574,20 @@ int main(int argc, char *argv[]) {
|
||||||
cookie = xcb_change_window_attributes_checked(conn, root, mask, values);
|
cookie = xcb_change_window_attributes_checked(conn, root, mask, values);
|
||||||
check_error(conn, cookie, "Another window manager seems to be running");
|
check_error(conn, cookie, "Another window manager seems to be running");
|
||||||
|
|
||||||
|
/* By now we already checked for replies once, so let’s see if colormap
|
||||||
|
* creation worked (if requested). */
|
||||||
|
if (colormap != root_screen->default_colormap) {
|
||||||
|
xcb_generic_error_t *error = xcb_request_check(conn, colormap_cookie);
|
||||||
|
if (error != NULL) {
|
||||||
|
ELOG("Could not create ColorMap for 32 bit visual, falling back to X11 default.\n");
|
||||||
|
root_depth = root_screen->root_depth;
|
||||||
|
visual_id = root_screen->root_visual;
|
||||||
|
colormap = root_screen->default_colormap;
|
||||||
|
DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
|
||||||
|
free(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
|
xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
|
||||||
if (greply == NULL) {
|
if (greply == NULL) {
|
||||||
ELOG("Could not get geometry of the root window, exiting\n");
|
ELOG("Could not get geometry of the root window, exiting\n");
|
||||||
|
|
19
src/x.c
19
src/x.c
|
@ -90,15 +90,28 @@ void x_con_init(Con *con) {
|
||||||
* get the initial geometry right */
|
* get the initial geometry right */
|
||||||
|
|
||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t values[2];
|
uint32_t values[5];
|
||||||
|
|
||||||
|
/* We explicitly set a background color and border color (even though we
|
||||||
|
* don’t even have a border) because the X11 server requires us to when
|
||||||
|
* using 32 bit color depths, see
|
||||||
|
* http://stackoverflow.com/questions/3645632 */
|
||||||
|
mask |= XCB_CW_BACK_PIXEL;
|
||||||
|
values[0] = root_screen->black_pixel;
|
||||||
|
|
||||||
|
mask |= XCB_CW_BORDER_PIXEL;
|
||||||
|
values[1] = root_screen->black_pixel;
|
||||||
|
|
||||||
/* our own frames should not be managed */
|
/* our own frames should not be managed */
|
||||||
mask |= XCB_CW_OVERRIDE_REDIRECT;
|
mask |= XCB_CW_OVERRIDE_REDIRECT;
|
||||||
values[0] = 1;
|
values[2] = 1;
|
||||||
|
|
||||||
/* see include/xcb.h for the FRAME_EVENT_MASK */
|
/* see include/xcb.h for the FRAME_EVENT_MASK */
|
||||||
mask |= XCB_CW_EVENT_MASK;
|
mask |= XCB_CW_EVENT_MASK;
|
||||||
values[1] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
|
values[3] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
|
||||||
|
|
||||||
|
mask |= XCB_CW_COLORMAP;
|
||||||
|
values[4] = colormap;
|
||||||
|
|
||||||
Rect dims = { -15, -15, 10, 10 };
|
Rect dims = { -15, -15, 10, 10 };
|
||||||
con->frame = create_window(conn, dims, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER, false, mask, values);
|
con->frame = create_window(conn, dims, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER, false, mask, values);
|
||||||
|
|
15
src/xcb.c
15
src/xcb.c
|
@ -20,8 +20,17 @@ xcb_window_t create_window(xcb_connection_t *conn, Rect dims, uint16_t window_cl
|
||||||
enum xcursor_cursor_t cursor, bool map, uint32_t mask, uint32_t *values) {
|
enum xcursor_cursor_t cursor, bool map, uint32_t mask, uint32_t *values) {
|
||||||
xcb_window_t result = xcb_generate_id(conn);
|
xcb_window_t result = xcb_generate_id(conn);
|
||||||
|
|
||||||
/* If the window class is XCB_WINDOW_CLASS_INPUT_ONLY, depth has to be 0 */
|
/* By default, the color depth determined in src/main.c is used (32 bit if
|
||||||
uint16_t depth = (window_class == XCB_WINDOW_CLASS_INPUT_ONLY ? 0 : XCB_COPY_FROM_PARENT);
|
* available, otherwise the X11 root window’s default depth). */
|
||||||
|
uint16_t depth = root_depth;
|
||||||
|
xcb_visualid_t visual = visual_id;
|
||||||
|
|
||||||
|
/* If the window class is XCB_WINDOW_CLASS_INPUT_ONLY, we copy depth and
|
||||||
|
* visual id from the parent window. */
|
||||||
|
if (window_class == XCB_WINDOW_CLASS_INPUT_ONLY) {
|
||||||
|
depth = XCB_COPY_FROM_PARENT;
|
||||||
|
visual = XCB_COPY_FROM_PARENT;
|
||||||
|
}
|
||||||
|
|
||||||
xcb_create_window(conn,
|
xcb_create_window(conn,
|
||||||
depth,
|
depth,
|
||||||
|
@ -30,7 +39,7 @@ xcb_window_t create_window(xcb_connection_t *conn, Rect dims, uint16_t window_cl
|
||||||
dims.x, dims.y, dims.width, dims.height, /* dimensions */
|
dims.x, dims.y, dims.width, dims.height, /* dimensions */
|
||||||
0, /* border = 0, we draw our own */
|
0, /* border = 0, we draw our own */
|
||||||
window_class,
|
window_class,
|
||||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
|
visual,
|
||||||
mask,
|
mask,
|
||||||
values);
|
values);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue