mirror of
https://github.com/swaywm/sway.git
synced 2026-04-29 06:46:22 -04:00
Add get_bindings IPC interface
The new get_bindings IPC interface (IPC_GET_BINDINGS) allows swaymsg (and other IPC clients) to interrogate sway's input bindings for all configured binding modes. The output of get_bindings is a JSON object mapping each configured binding mode (e.g. "default", "resize", etc.) to an array of binding objects. The binding JSON objects are of the same form as those in IPC_EVENT_BINDING. N.B. a big chunk of code from ipc_event_binding() is moved to a new ipc_json_describe_binding() function which services both the new IPC_GET_BINDINGS as well as the existing IPC_EVENT_BINDING commands. Signed-off-by: Peter Grayson <pete@jpgrayson.net>
This commit is contained in:
parent
b7fe5097e9
commit
331bcac3ea
10 changed files with 124 additions and 62 deletions
|
|
@ -12,6 +12,7 @@
|
|||
#include "sway/output.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/keyboard.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/types/wlr_box.h>
|
||||
|
|
@ -1103,3 +1104,95 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
|
|||
#endif
|
||||
return json;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_binding(struct sway_binding *binding) {
|
||||
if (!sway_assert(binding, "Binding must not be NULL")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_object *json_binding = json_object_new_object();
|
||||
json_object_object_add(json_binding, "command", json_object_new_string(binding->command));
|
||||
|
||||
const char *names[10];
|
||||
int len = get_modifier_names(names, binding->modifiers);
|
||||
json_object *modifiers = json_object_new_array();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
json_object_array_add(modifiers, json_object_new_string(names[i]));
|
||||
}
|
||||
json_object_object_add(json_binding, "event_state_mask", modifiers);
|
||||
|
||||
json_object *input_codes = json_object_new_array();
|
||||
int input_code = 0;
|
||||
json_object *symbols = json_object_new_array();
|
||||
json_object *symbol = NULL;
|
||||
|
||||
if (binding->type == BINDING_KEYCODE) { // bindcode: populate input_codes
|
||||
uint32_t keycode;
|
||||
for (int i = 0; i < binding->keys->length; ++i) {
|
||||
keycode = *(uint32_t *)binding->keys->items[i];
|
||||
json_object_array_add(input_codes, json_object_new_int(keycode));
|
||||
if (i == 0) {
|
||||
input_code = keycode;
|
||||
}
|
||||
}
|
||||
} else { // bindsym/mouse: populate symbols
|
||||
uint32_t keysym;
|
||||
char buffer[64];
|
||||
for (int i = 0; i < binding->keys->length; ++i) {
|
||||
keysym = *(uint32_t *)binding->keys->items[i];
|
||||
if (keysym >= BTN_LEFT && keysym <= BTN_LEFT + 8) {
|
||||
snprintf(buffer, 64, "button%u", keysym - BTN_LEFT + 1);
|
||||
} else if (xkb_keysym_get_name(keysym, buffer, 64) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_object *str = json_object_new_string(buffer);
|
||||
if (i == 0) {
|
||||
// str is owned by both symbol and symbols. Make sure
|
||||
// to bump the ref count.
|
||||
json_object_array_add(symbols, json_object_get(str));
|
||||
symbol = str;
|
||||
} else {
|
||||
json_object_array_add(symbols, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_object_object_add(json_binding, "input_codes", input_codes);
|
||||
json_object_object_add(json_binding, "input_code", json_object_new_int(input_code));
|
||||
json_object_object_add(json_binding, "symbols", symbols);
|
||||
json_object_object_add(json_binding, "symbol", symbol);
|
||||
|
||||
bool mouse = binding->type == BINDING_MOUSECODE ||
|
||||
binding->type == BINDING_MOUSESYM;
|
||||
json_object_object_add(json_binding, "input_type", mouse
|
||||
? json_object_new_string("mouse")
|
||||
: json_object_new_string("keyboard"));
|
||||
|
||||
return json_binding;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_mode_bindings(struct sway_mode * mode) {
|
||||
if (!sway_assert(mode, "Mode must not be NULL")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_object *json_bindings = json_object_new_array();
|
||||
|
||||
for (int i = 0; i < mode->keysym_bindings->length; i++) {
|
||||
json_object_array_add(json_bindings,
|
||||
ipc_json_describe_binding(mode->keysym_bindings->items[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < mode->keycode_bindings->length; i++) {
|
||||
json_object_array_add(json_bindings,
|
||||
ipc_json_describe_binding(mode->keycode_bindings->items[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < mode->mouse_bindings->length; i++) {
|
||||
json_object_array_add(json_bindings,
|
||||
ipc_json_describe_binding(mode->mouse_bindings->items[i]));
|
||||
}
|
||||
|
||||
return json_bindings;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/keyboard.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
|
@ -394,68 +393,10 @@ void ipc_event_binding(struct sway_binding *binding) {
|
|||
}
|
||||
sway_log(SWAY_DEBUG, "Sending binding event");
|
||||
|
||||
json_object *json_binding = json_object_new_object();
|
||||
json_object_object_add(json_binding, "command", json_object_new_string(binding->command));
|
||||
|
||||
const char *names[10];
|
||||
int len = get_modifier_names(names, binding->modifiers);
|
||||
json_object *modifiers = json_object_new_array();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
json_object_array_add(modifiers, json_object_new_string(names[i]));
|
||||
}
|
||||
json_object_object_add(json_binding, "event_state_mask", modifiers);
|
||||
|
||||
json_object *input_codes = json_object_new_array();
|
||||
int input_code = 0;
|
||||
json_object *symbols = json_object_new_array();
|
||||
json_object *symbol = NULL;
|
||||
|
||||
if (binding->type == BINDING_KEYCODE) { // bindcode: populate input_codes
|
||||
uint32_t keycode;
|
||||
for (int i = 0; i < binding->keys->length; ++i) {
|
||||
keycode = *(uint32_t *)binding->keys->items[i];
|
||||
json_object_array_add(input_codes, json_object_new_int(keycode));
|
||||
if (i == 0) {
|
||||
input_code = keycode;
|
||||
}
|
||||
}
|
||||
} else { // bindsym/mouse: populate symbols
|
||||
uint32_t keysym;
|
||||
char buffer[64];
|
||||
for (int i = 0; i < binding->keys->length; ++i) {
|
||||
keysym = *(uint32_t *)binding->keys->items[i];
|
||||
if (keysym >= BTN_LEFT && keysym <= BTN_LEFT + 8) {
|
||||
snprintf(buffer, 64, "button%u", keysym - BTN_LEFT + 1);
|
||||
} else if (xkb_keysym_get_name(keysym, buffer, 64) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_object *str = json_object_new_string(buffer);
|
||||
if (i == 0) {
|
||||
// str is owned by both symbol and symbols. Make sure
|
||||
// to bump the ref count.
|
||||
json_object_array_add(symbols, json_object_get(str));
|
||||
symbol = str;
|
||||
} else {
|
||||
json_object_array_add(symbols, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_object_object_add(json_binding, "input_codes", input_codes);
|
||||
json_object_object_add(json_binding, "input_code", json_object_new_int(input_code));
|
||||
json_object_object_add(json_binding, "symbols", symbols);
|
||||
json_object_object_add(json_binding, "symbol", symbol);
|
||||
|
||||
bool mouse = binding->type == BINDING_MOUSECODE ||
|
||||
binding->type == BINDING_MOUSESYM;
|
||||
json_object_object_add(json_binding, "input_type", mouse
|
||||
? json_object_new_string("mouse")
|
||||
: json_object_new_string("keyboard"));
|
||||
|
||||
json_object *json = json_object_new_object();
|
||||
json_object_object_add(json, "change", json_object_new_string("run"));
|
||||
json_object_object_add(json, "binding", json_binding);
|
||||
json_object_object_add(json, "binding", ipc_json_describe_binding(binding));
|
||||
|
||||
const char *json_string = json_object_to_json_string(json);
|
||||
ipc_send_event(json_string, IPC_EVENT_BINDING);
|
||||
json_object_put(json);
|
||||
|
|
@ -836,6 +777,21 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
|||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
case IPC_GET_BINDINGS:
|
||||
{
|
||||
json_object *modes = json_object_new_object();
|
||||
for (int i = 0; i < config->modes->length; i++) {
|
||||
struct sway_mode *mode = config->modes->items[i];
|
||||
json_object_object_add(
|
||||
modes, mode->name, ipc_json_describe_mode_bindings(mode));
|
||||
}
|
||||
const char *json_string = json_object_to_json_string(modes);
|
||||
client_valid =
|
||||
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
|
||||
json_object_put(modes); // free
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
case IPC_GET_CONFIG:
|
||||
{
|
||||
json_object *json = json_object_new_object();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue