Change the root window cursor to 'watch' during startups

This commit is contained in:
Michael Stapelberg 2011-10-10 15:53:57 +01:00
parent ad9ffcc917
commit 5f52c78aa0
6 changed files with 51 additions and 15 deletions

View File

@ -23,6 +23,7 @@
#define XCB_CURSOR_LEFT_PTR 68 #define XCB_CURSOR_LEFT_PTR 68
#define XCB_CURSOR_SB_H_DOUBLE_ARROW 108 #define XCB_CURSOR_SB_H_DOUBLE_ARROW 108
#define XCB_CURSOR_SB_V_DOUBLE_ARROW 116 #define XCB_CURSOR_SB_V_DOUBLE_ARROW 116
#define XCB_CURSOR_WATCH 150
/* from X11/keysymdef.h */ /* from X11/keysymdef.h */
#define XCB_NUM_LOCK 0xff7f #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); 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 #endif

View File

@ -10,6 +10,7 @@ enum xcursor_cursor_t {
XCURSOR_CURSOR_POINTER = 0, XCURSOR_CURSOR_POINTER = 0,
XCURSOR_CURSOR_RESIZE_HORIZONTAL, XCURSOR_CURSOR_RESIZE_HORIZONTAL,
XCURSOR_CURSOR_RESIZE_VERTICAL, XCURSOR_CURSOR_RESIZE_VERTICAL,
XCURSOR_CURSOR_WATCH,
XCURSOR_CURSOR_MAX XCURSOR_CURSOR_MAX
}; };

View File

@ -442,17 +442,9 @@ int main(int argc, char *argv[]) {
/* Set a cursor for the root window (otherwise the root window will show no /* Set a cursor for the root window (otherwise the root window will show no
cursor until the first client is launched). */ cursor until the first client is launched). */
if (xcursor_supported) { if (xcursor_supported)
xcursor_set_root_cursor(); xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER);
} else { else xcb_set_root_cursor(XCURSOR_CURSOR_POINTER);
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 (xkb_supported) { if (xkb_supported) {
int errBase, int errBase,

View File

@ -7,7 +7,9 @@
* *
* See file LICENSE for license information. * 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 <sys/types.h> #include <sys/types.h>
@ -124,6 +126,11 @@ void start_application(const char *command) {
exit(0); exit(0);
} }
wait(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 */ /* Delete our internal sequence */
TAILQ_REMOVE(&startup_sequences, sequence, sequences); 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; break;
default: default:
/* ignore */ /* ignore */

View File

@ -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); 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); 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);
}

View File

@ -14,7 +14,8 @@ static Cursor cursors[XCURSOR_CURSOR_MAX];
static const int xcb_cursors[XCURSOR_CURSOR_MAX] = { static const int xcb_cursors[XCURSOR_CURSOR_MAX] = {
XCB_CURSOR_LEFT_PTR, XCB_CURSOR_LEFT_PTR,
XCB_CURSOR_SB_H_DOUBLE_ARROW, 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) { 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_POINTER] = load_cursor("left_ptr");
cursors[XCURSOR_CURSOR_RESIZE_HORIZONTAL] = load_cursor("sb_h_double_arrow"); 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_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). * 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; XSetWindowAttributes attributes;
attributes.cursor = xcursor_get_cursor(XCURSOR_CURSOR_POINTER); attributes.cursor = xcursor_get_cursor(cursor_id);
XChangeWindowAttributes(xlibdpy, DefaultRootWindow(xlibdpy), CWCursor, &attributes); XChangeWindowAttributes(xlibdpy, DefaultRootWindow(xlibdpy), CWCursor, &attributes);
XFlush(xlibdpy); XFlush(xlibdpy);
} }