module/i3: read socket path from root window's I3_SOCKET_PATH property

This way, we don't have to execute another process just to get the
path.
This commit is contained in:
Daniel Eklöf 2019-01-16 17:22:13 +01:00
parent dc7fde335e
commit 85d1971ac3

View file

@ -10,7 +10,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <xcb/xcb.h>
#include <i3/ipc.h> #include <i3/ipc.h>
#include <json-c/json_tokener.h> #include <json-c/json_tokener.h>
#include <json-c/json_util.h> #include <json-c/json_util.h>
#include <json-c/linkhash.h> #include <json-c/linkhash.h>
@ -21,8 +23,8 @@
#include "../bar.h" #include "../bar.h"
#include "../config.h" #include "../config.h"
#include "../config-verify.h" #include "../config-verify.h"
#include "../particles/dynlist.h" #include "../particles/dynlist.h"
#include "../xcb.h"
struct ws_content { struct ws_content {
char *name; char *name;
@ -374,19 +376,44 @@ run(struct module *mod)
struct sockaddr_un addr = {.sun_family = AF_UNIX}; struct sockaddr_un addr = {.sun_family = AF_UNIX};
{ {
FILE *out = popen("i3 --get-socketpath", "r"); xcb_connection_t *conn = xcb_connect(NULL, NULL);
if (out == NULL) {
LOG_ERRNO("failed to execute 'i3 --get-socketpath'"); const xcb_setup_t *setup = xcb_get_setup(conn);
xcb_screen_t *screen = xcb_setup_roots_iterator(setup).data;
xcb_atom_t atom = get_atom(conn, "I3_SOCKET_PATH");
assert(atom != XCB_ATOM_NONE);
xcb_get_property_cookie_t cookie
= xcb_get_property_unchecked(
conn, false, screen->root, atom,
XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof(addr.sun_path));
xcb_generic_error_t *err;
xcb_get_property_reply_t *reply =
xcb_get_property_reply(conn, cookie, &err);
if (err != NULL) {
LOG_ERR("failed to get i3 socket path: %s", xcb_error(err));
free(err);
free(reply);
return 1; return 1;
} }
fgets(addr.sun_path, sizeof(addr.sun_path), out); const int len = xcb_get_property_value_length(reply);
pclose(out); assert(len < sizeof(addr.sun_path));
/* Strip newline */ if (len == 0) {
ssize_t len = strlen(addr.sun_path); LOG_ERR("failed to get i3 socket path: empty reply");
if (addr.sun_path[len - 1] == '\n') free(reply);
addr.sun_path[len - 1] = '\0'; return 1;
}
memcpy(addr.sun_path, xcb_get_property_value(reply), len);
addr.sun_path[len] = '\0';
free(reply);
xcb_disconnect(conn);
} }
int sock = socket(AF_UNIX, SOCK_STREAM, 0); int sock = socket(AF_UNIX, SOCK_STREAM, 0);