From b1f1da432df47806be3b7e61951eed195ca70fc9 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 25 Dec 2015 16:38:11 +0100 Subject: [PATCH] i3bar: explicitly set cursor using libxcursor if available Even if the X11 root window cursor is not set up correctly for some reason, with this fix, users should at least see the correct cursor when the pointer is over i3bar. see issue #2114 --- i3bar/i3bar.mk | 4 ++-- i3bar/src/xcb.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/i3bar/i3bar.mk b/i3bar/i3bar.mk index 737b0b69..5aed1902 100644 --- a/i3bar/i3bar.mk +++ b/i3bar/i3bar.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3bar i3bar_SOURCES := $(wildcard i3bar/src/*.c) i3bar_HEADERS := $(wildcard i3bar/include/*.h) -i3bar_CFLAGS = $(XCB_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) -i3bar_LIBS = $(XCB_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) +i3bar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) +i3bar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) i3bar_OBJECTS := $(i3bar_SOURCES:.c=.o) diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index c6c9846b..5e21e118 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef XCB_COMPAT #include "xcb_compat.h" @@ -34,6 +35,10 @@ #include "common.h" #include "libi3.h" +/** This is the equivalent of XC_left_ptr. I’m not sure why xcb doesn’t have a + * constant for that. */ +#define XCB_CURSOR_LEFT_PTR 68 + /* We save the atoms in an easy to access array, indexed by an enum */ enum { #define ATOM_DO(name) name, @@ -49,6 +54,7 @@ xcb_connection_t *xcb_connection; int screen; xcb_screen_t *root_screen; xcb_window_t xcb_root; +static xcb_cursor_t cursor; /* selection window for tray support */ static xcb_window_t selwin = XCB_NONE; @@ -1206,6 +1212,24 @@ char *init_xcb_early() { colormap = root_screen->default_colormap; visual_type = get_visualtype(root_screen); + xcb_cursor_context_t *cursor_ctx; + if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) == 0) { + cursor = xcb_cursor_load_cursor(cursor_ctx, "left_ptr"); + xcb_cursor_context_free(cursor_ctx); + } else { + cursor = xcb_generate_id(xcb_connection); + i3Font cursor_font = load_font("cursor", false); + xcb_create_glyph_cursor( + xcb_connection, + cursor, + cursor_font.specific.xcb.id, + cursor_font.specific.xcb.id, + XCB_CURSOR_LEFT_PTR, + XCB_CURSOR_LEFT_PTR + 1, + 0, 0, 0, + 65535, 65535, 65535); + } + /* The various watchers to communicate with xcb */ xcb_io = smalloc(sizeof(ev_io)); xcb_prep = smalloc(sizeof(ev_prepare)); @@ -1462,6 +1486,7 @@ void clean_xcb(void) { FREE_SLIST(outputs, i3_output); FREE(outputs); + xcb_free_cursor(xcb_connection, cursor); xcb_flush(xcb_connection); xcb_aux_sync(xcb_connection); xcb_disconnect(xcb_connection); @@ -1605,7 +1630,7 @@ xcb_void_cookie_t config_strut_partial(i3_output *output) { */ void reconfig_windows(bool redraw_bars) { uint32_t mask; - uint32_t values[5]; + uint32_t values[6]; static bool tray_configured = false; i3_output *walk; @@ -1623,7 +1648,7 @@ void reconfig_windows(bool redraw_bars) { xcb_window_t bar_id = xcb_generate_id(xcb_connection); xcb_pixmap_t buffer_id = xcb_generate_id(xcb_connection); xcb_pixmap_t statusline_buffer_id = xcb_generate_id(xcb_connection); - mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; + mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP | XCB_CW_CURSOR; values[0] = colors.bar_bg.colorpixel; values[1] = root_screen->black_pixel; @@ -1645,6 +1670,7 @@ void reconfig_windows(bool redraw_bars) { walk->visible = true; } values[4] = colormap; + values[5] = cursor; xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection, depth,