X-Git-Url: https://git.sur5r.net/?p=i3%2Fi3;a=blobdiff_plain;f=src%2Fmain.c;h=5d6a68b9689f611cdd2d8f6f7dcb416cbd795da9;hp=d5d4dcef1349c682371f653621c9610803d8857c;hb=HEAD;hpb=e26fd91cf868824726d74db7388d05736e1fd7da diff --git a/src/main.c b/src/main.c index d5d4dcef..5d6a68b9 100644 --- a/src/main.c +++ b/src/main.c @@ -32,15 +32,13 @@ * RLIM_INFINITY for i3 debugging versions. */ struct rlimit original_rlimit_core; -/** The number of file descriptors passed via socket activation. */ +/* The number of file descriptors passed via socket activation. */ int listen_fds; /* We keep the xcb_prepare watcher around to be able to enable and disable it * temporarily for drag_pointer(). */ static struct ev_prepare *xcb_prepare; -extern Con *focused; - char **start_argv; xcb_connection_t *conn; @@ -162,13 +160,6 @@ void main_set_x11_cb(bool enable) { * */ static void i3_exit(void) { -/* We need ev >= 4 for the following code. Since it is not *that* important (it - * only makes sure that there are no i3-nagbar instances left behind) we still - * support old systems with libev 3. */ -#if EV_VERSION_MAJOR >= 4 - ev_loop_destroy(main_loop); -#endif - if (*shmlogname != '\0') { fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname); fflush(stderr); @@ -176,6 +167,18 @@ static void i3_exit(void) { } ipc_shutdown(SHUTDOWN_REASON_EXIT); unlink(config.ipc_socket_path); + xcb_disconnect(conn); + +/* We need ev >= 4 for the following code. Since it is not *that* important (it + * only makes sure that there are no i3-nagbar instances left behind) we still + * support old systems with libev 3. */ +#if EV_VERSION_MAJOR >= 4 + ev_loop_destroy(main_loop); +#endif + +#ifdef I3_ASAN_ENABLED + __lsan_do_leak_check(); +#endif } /* @@ -643,8 +646,16 @@ int main(int argc, char *argv[]) { /* Setting both, XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE and * XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED, will lead to the * X server sending us the full XKB state in KeyPress and KeyRelease: - * https://sources.debian.net/src/xorg-server/2:1.17.2-1.1/xkb/xkbEvents.c/?hl=927#L927 + * https://cgit.freedesktop.org/xorg/xserver/tree/xkb/xkbEvents.c?h=xorg-server-1.20.0#n927 + * + * XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT enable detectable autorepeat: + * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat + * This affects bindings using the --release flag: instead of getting multiple KeyRelease + * events we get only one event when the key is physically released by the user. */ + const uint32_t mask = XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE | + XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED | + XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT; xcb_xkb_per_client_flags_reply_t *pcf_reply; /* The last three parameters are unset because they are only relevant * when using a feature called “automatic reset of boolean controls”: @@ -655,20 +666,24 @@ int main(int argc, char *argv[]) { xcb_xkb_per_client_flags( conn, XCB_XKB_ID_USE_CORE_KBD, - XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE | XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED, - XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE | XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED, + mask, + mask, 0 /* uint32_t ctrlsToChange */, 0 /* uint32_t autoCtrls */, 0 /* uint32_t autoCtrlsValues */), NULL); - if (pcf_reply == NULL || - !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE)) { - ELOG("Could not set XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE\n"); - } - if (pcf_reply == NULL || - !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED)) { - ELOG("Could not set XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED\n"); - } + +#define PCF_REPLY_ERROR(_value) \ + do { \ + if (pcf_reply == NULL || !(pcf_reply->value & (_value))) { \ + ELOG("Could not set " #_value "\n"); \ + } \ + } while (0) + + PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE); + PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED); + PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT); + free(pcf_reply); xkb_base = extreply->first_event; }