forked from external/yambar
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:
parent
dc7fde335e
commit
85d1971ac3
1 changed files with 37 additions and 10 deletions
47
modules/i3.c
47
modules/i3.c
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue