From 5f52c78aa04326c25c1f178c3612c4b5613b5f85 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 10 Oct 2011 15:53:57 +0100 Subject: [PATCH] Change the root window cursor to 'watch' during startups --- include/xcb.h | 9 +++++++++ include/xcursor.h | 1 + src/main.c | 14 +++----------- src/startup.c | 17 ++++++++++++++++- src/xcb.c | 17 +++++++++++++++++ src/xcursor.c | 8 +++++--- 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/include/xcb.h b/include/xcb.h index 5bc40d2a..65e4e6c3 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -23,6 +23,7 @@ #define XCB_CURSOR_LEFT_PTR 68 #define XCB_CURSOR_SB_H_DOUBLE_ARROW 108 #define XCB_CURSOR_SB_V_DOUBLE_ARROW 116 +#define XCB_CURSOR_WATCH 150 /* from X11/keysymdef.h */ #define XCB_NUM_LOCK 0xff7f @@ -150,4 +151,12 @@ bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom); */ void xcb_warp_pointer_rect(xcb_connection_t *conn, Rect *rect); +/** + * Set the cursor of the root window to the given cursor id. + * This function should only be used if xcursor_supported == false. + * Otherwise, use xcursor_set_root_cursor(). + * + */ +void xcb_set_root_cursor(int cursor); + #endif diff --git a/include/xcursor.h b/include/xcursor.h index e129a36f..f3ff4f25 100644 --- a/include/xcursor.h +++ b/include/xcursor.h @@ -10,6 +10,7 @@ enum xcursor_cursor_t { XCURSOR_CURSOR_POINTER = 0, XCURSOR_CURSOR_RESIZE_HORIZONTAL, XCURSOR_CURSOR_RESIZE_VERTICAL, + XCURSOR_CURSOR_WATCH, XCURSOR_CURSOR_MAX }; diff --git a/src/main.c b/src/main.c index f985810e..610a2c19 100644 --- a/src/main.c +++ b/src/main.c @@ -442,17 +442,9 @@ int main(int argc, char *argv[]) { /* Set a cursor for the root window (otherwise the root window will show no cursor until the first client is launched). */ - if (xcursor_supported) { - xcursor_set_root_cursor(); - } else { - xcb_cursor_t cursor_id = xcb_generate_id(conn); - i3Font cursor_font = load_font("cursor", false); - int xcb_cursor = xcursor_get_xcb_cursor(XCURSOR_CURSOR_POINTER); - xcb_create_glyph_cursor(conn, cursor_id, cursor_font.id, cursor_font.id, - xcb_cursor, xcb_cursor + 1, 0, 0, 0, 65535, 65535, 65535); - xcb_change_window_attributes(conn, root, XCB_CW_CURSOR, &cursor_id); - xcb_free_cursor(conn, cursor_id); - } + if (xcursor_supported) + xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER); + else xcb_set_root_cursor(XCURSOR_CURSOR_POINTER); if (xkb_supported) { int errBase, diff --git a/src/startup.c b/src/startup.c index 4b6c937d..66cb5285 100644 --- a/src/startup.c +++ b/src/startup.c @@ -7,7 +7,9 @@ * * See file LICENSE for license information. * - * startup.c: Startup notification code + * startup.c: Startup notification code. Ensures a startup notification context + * is setup when launching applications. We store the current workspace to open + * windows in that startup notification context on the appropriate workspace. * */ #include @@ -124,6 +126,11 @@ void start_application(const char *command) { exit(0); } wait(0); + + /* Change the pointer of the root window to indicate progress */ + if (xcursor_supported) + xcursor_set_root_cursor(XCURSOR_CURSOR_WATCH); + else xcb_set_root_cursor(XCURSOR_CURSOR_WATCH); } /* @@ -160,6 +167,14 @@ void startup_monitor_event(SnMonitorEvent *event, void *userdata) { /* Delete our internal sequence */ TAILQ_REMOVE(&startup_sequences, sequence, sequences); + + if (TAILQ_EMPTY(&startup_sequences)) { + DLOG("No more startup sequences running, changing root window cursor to default pointer.\n"); + /* Change the pointer of the root window to indicate progress */ + if (xcursor_supported) + xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER); + else xcb_set_root_cursor(XCURSOR_CURSOR_POINTER); + } break; default: /* ignore */ diff --git a/src/xcb.c b/src/xcb.c index 31d78703..32537388 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -341,3 +341,20 @@ void xcb_warp_pointer_rect(xcb_connection_t *conn, Rect *rect) { LOG("warp pointer to: %d %d\n", mid_x, mid_y); xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, mid_x, mid_y); } + +/* + * Set the cursor of the root window to the given cursor id. + * This function should only be used if xcursor_supported == false. + * Otherwise, use xcursor_set_root_cursor(). + * + */ +void xcb_set_root_cursor(int cursor) { + xcb_cursor_t cursor_id = xcb_generate_id(conn); + i3Font cursor_font = load_font("cursor", false); + int xcb_cursor = xcursor_get_xcb_cursor(cursor); + xcb_create_glyph_cursor(conn, cursor_id, cursor_font.id, cursor_font.id, + xcb_cursor, xcb_cursor + 1, 0, 0, 0, 65535, 65535, 65535); + xcb_change_window_attributes(conn, root, XCB_CW_CURSOR, &cursor_id); + xcb_free_cursor(conn, cursor_id); + xcb_flush(conn); +} diff --git a/src/xcursor.c b/src/xcursor.c index 69518c30..5d209b56 100644 --- a/src/xcursor.c +++ b/src/xcursor.c @@ -14,7 +14,8 @@ static Cursor cursors[XCURSOR_CURSOR_MAX]; static const int xcb_cursors[XCURSOR_CURSOR_MAX] = { XCB_CURSOR_LEFT_PTR, XCB_CURSOR_SB_H_DOUBLE_ARROW, - XCB_CURSOR_SB_V_DOUBLE_ARROW + XCB_CURSOR_SB_V_DOUBLE_ARROW, + XCB_CURSOR_WATCH }; static Cursor load_cursor(const char *name) { @@ -28,6 +29,7 @@ void xcursor_load_cursors() { cursors[XCURSOR_CURSOR_POINTER] = load_cursor("left_ptr"); cursors[XCURSOR_CURSOR_RESIZE_HORIZONTAL] = load_cursor("sb_h_double_arrow"); cursors[XCURSOR_CURSOR_RESIZE_VERTICAL] = load_cursor("sb_v_double_arrow"); + cursors[XCURSOR_CURSOR_WATCH] = load_cursor("watch"); } /* @@ -41,9 +43,9 @@ void xcursor_load_cursors() { * races might occur (even though we flush the Xlib connection). * */ -void xcursor_set_root_cursor() { +void xcursor_set_root_cursor(int cursor_id) { XSetWindowAttributes attributes; - attributes.cursor = xcursor_get_cursor(XCURSOR_CURSOR_POINTER); + attributes.cursor = xcursor_get_cursor(cursor_id); XChangeWindowAttributes(xlibdpy, DefaultRootWindow(xlibdpy), CWCursor, &attributes); XFlush(xlibdpy); }