Make i3 send arguments as command to a running i3 instance (like i3-msg)
From i3 --help: If you pass plain text arguments, i3 will interpret them as a command to send to a currently running i3 (like i3-msg). This allows you to use nice and logical commands, such as: i3 border none i3 floating toggle i3 kill window
This commit is contained in:
parent
4243a4053e
commit
b755397687
70
src/main.c
70
src/main.c
|
@ -3,6 +3,9 @@
|
||||||
*/
|
*/
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
|
||||||
#include "sd-daemon.h"
|
#include "sd-daemon.h"
|
||||||
|
@ -281,10 +284,77 @@ int main(int argc, char *argv[]) {
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "\t--get-socketpath\n"
|
fprintf(stderr, "\t--get-socketpath\n"
|
||||||
"\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
|
"\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
|
||||||
|
"to send to a currently running i3 (like i3-msg). This allows you to\n"
|
||||||
|
"use nice and logical commands, such as:\n"
|
||||||
|
"\n"
|
||||||
|
"\ti3 border none\n"
|
||||||
|
"\ti3 floating toggle\n"
|
||||||
|
"\ti3 kill window\n"
|
||||||
|
"\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the user passes more arguments, we act like i3-msg would: Just send
|
||||||
|
* the arguments as an IPC message to i3. This allows for nice semantic
|
||||||
|
* commands such as 'i3 border none'. */
|
||||||
|
if (optind < argc) {
|
||||||
|
/* We enable verbose mode so that the user knows what’s going on.
|
||||||
|
* This should make it easier to find mistakes when the user passes
|
||||||
|
* arguments by mistake. */
|
||||||
|
set_verbosity(true);
|
||||||
|
|
||||||
|
LOG("Additional arguments passed. Sending them as a command to i3.\n");
|
||||||
|
char *payload = NULL;
|
||||||
|
while (optind < argc) {
|
||||||
|
if (!payload) {
|
||||||
|
payload = sstrdup(argv[optind]);
|
||||||
|
} else {
|
||||||
|
char *both;
|
||||||
|
if (asprintf(&both, "%s %s", payload, argv[optind]) == -1)
|
||||||
|
err(EXIT_FAILURE, "asprintf");
|
||||||
|
free(payload);
|
||||||
|
payload = both;
|
||||||
|
}
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
LOG("Command is: %s (%d bytes)\n", payload, strlen(payload));
|
||||||
|
char *socket_path = socket_path_from_x11();
|
||||||
|
if (!socket_path) {
|
||||||
|
ELOG("Could not get i3 IPC socket path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||||
|
if (sockfd == -1)
|
||||||
|
err(EXIT_FAILURE, "Could not create socket");
|
||||||
|
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
addr.sun_family = AF_LOCAL;
|
||||||
|
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
|
||||||
|
if (connect(sockfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0)
|
||||||
|
err(EXIT_FAILURE, "Could not connect to i3");
|
||||||
|
|
||||||
|
if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_COMMAND,
|
||||||
|
(uint8_t*)payload) == -1)
|
||||||
|
err(EXIT_FAILURE, "IPC: write()");
|
||||||
|
|
||||||
|
uint32_t reply_length;
|
||||||
|
uint8_t *reply;
|
||||||
|
int ret;
|
||||||
|
if ((ret = ipc_recv_message(sockfd, I3_IPC_MESSAGE_TYPE_COMMAND,
|
||||||
|
&reply_length, &reply)) != 0) {
|
||||||
|
if (ret == -1)
|
||||||
|
err(EXIT_FAILURE, "IPC: read()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("%.*s\n", reply_length, reply);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LOG("i3 (tree) version " I3_VERSION " starting\n");
|
LOG("i3 (tree) version " I3_VERSION " starting\n");
|
||||||
|
|
||||||
conn = xcb_connect(NULL, &screens);
|
conn = xcb_connect(NULL, &screens);
|
||||||
|
|
Loading…
Reference in New Issue