mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 14:34:07 +01:00
ipc: add query for mode bindings
This commit is contained in:
parent
cffb006feb
commit
c98ef97eed
@ -8,6 +8,8 @@
|
||||
json_object *ipc_json_get_version(void);
|
||||
|
||||
json_object *ipc_json_get_binding_mode(void);
|
||||
json_object *ipc_json_describe_binding(struct sway_binding *binding);
|
||||
json_object *ipc_json_describe_binding_mode(struct sway_mode *mode);
|
||||
|
||||
json_object *ipc_json_describe_disabled_output(struct sway_output *o);
|
||||
json_object *ipc_json_describe_non_desktop_output(struct sway_output_non_desktop *o);
|
||||
|
191
sway/ipc-json.c
191
sway/ipc-json.c
@ -16,6 +16,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-layer-shell-unstable-v1-protocol.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
@ -1319,3 +1320,193 @@ json_object *ipc_json_get_binding_mode(void) {
|
||||
json_object_new_string(config->current_mode->name));
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_binding_flags(uint32_t flags) {
|
||||
json_object *json_flags = json_object_new_array();
|
||||
if (flags & BINDING_RELEASE) {
|
||||
json_object_array_add(json_flags, json_object_new_string("release"));
|
||||
} else if (flags & BINDING_LOCKED) {
|
||||
json_object_array_add(json_flags, json_object_new_string("locked"));
|
||||
} else if (flags & BINDING_BORDER) {
|
||||
json_object_array_add(json_flags, json_object_new_string("border"));
|
||||
} else if (flags & BINDING_CONTENTS) {
|
||||
json_object_array_add(json_flags, json_object_new_string("contents"));
|
||||
} else if (flags & BINDING_TITLEBAR) {
|
||||
json_object_array_add(json_flags, json_object_new_string("titlebar"));
|
||||
} else if (flags & BINDING_CODE) {
|
||||
json_object_array_add(json_flags, json_object_new_string("code"));
|
||||
} else if (flags & BINDING_RELOAD) {
|
||||
json_object_array_add(json_flags, json_object_new_string("reload"));
|
||||
} else if (flags & BINDING_INHIBITED) {
|
||||
json_object_array_add(json_flags, json_object_new_string("inhibited"));
|
||||
} else if (flags & BINDING_NOREPEAT) {
|
||||
json_object_array_add(json_flags, json_object_new_string("norepeat"));
|
||||
}
|
||||
return json_flags;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_switch_binding(struct sway_switch_binding *binding) {
|
||||
json_object *json_binding = json_object_new_object();
|
||||
json_object_object_add(json_binding, "command", json_object_new_string(binding->command));
|
||||
|
||||
json_object *type = NULL;
|
||||
switch (binding->type) {
|
||||
case WLR_SWITCH_TYPE_LID:
|
||||
type = json_object_new_string("lid");
|
||||
break;
|
||||
case WLR_SWITCH_TYPE_TABLET_MODE:
|
||||
type = json_object_new_string("tablet_mode");
|
||||
break;
|
||||
}
|
||||
json_object_object_add(json_binding, "type", type);
|
||||
|
||||
json_object *trigger = NULL;
|
||||
switch (binding->trigger) {
|
||||
case SWAY_SWITCH_TRIGGER_OFF:
|
||||
trigger = json_object_new_string("off");
|
||||
break;
|
||||
case SWAY_SWITCH_TRIGGER_ON:
|
||||
trigger = json_object_new_string("on");
|
||||
break;
|
||||
case SWAY_SWITCH_TRIGGER_TOGGLE:
|
||||
trigger = json_object_new_string("on");
|
||||
break;
|
||||
}
|
||||
json_object_object_add(json_binding, "trigger", trigger);
|
||||
|
||||
json_object *flags = ipc_json_describe_binding_flags(binding->flags);
|
||||
json_object_object_add(json_binding, "flags", flags);
|
||||
|
||||
return json_binding;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_binding(struct sway_binding *binding) {
|
||||
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, "modifiers", modifiers);
|
||||
|
||||
json_object *input_codes = json_object_new_array();
|
||||
int input_code = 0;
|
||||
json_object *symbols = json_object_new_array();
|
||||
json_object *symbol = NULL;
|
||||
|
||||
json_object *binding_flags = ipc_json_describe_binding_flags(binding->flags);
|
||||
json_object_object_add(json_binding, "flags", binding_flags);
|
||||
|
||||
switch (binding->type) {
|
||||
case BINDING_KEYCODE:
|
||||
json_object_object_add(json_binding, "type", json_object_new_string("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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BINDING_KEYSYM:
|
||||
json_object_object_add(json_binding, "type", json_object_new_string("keysym"));
|
||||
goto symbols;
|
||||
case BINDING_MOUSESYM:
|
||||
json_object_object_add(json_binding, "type", json_object_new_string("mousesym"));
|
||||
goto symbols;
|
||||
case BINDING_MOUSECODE:
|
||||
json_object_object_add(json_binding, "type", json_object_new_string("mousecode"));
|
||||
symbols:; // 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
json_object_put(input_codes);
|
||||
json_object_put(symbols);
|
||||
json_object_put(json_binding);
|
||||
return NULL; // do not send any event
|
||||
}
|
||||
|
||||
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_object_add(json_binding, "input_device",
|
||||
json_object_new_string(binding->input));
|
||||
|
||||
return json_binding;
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_binding_mode(struct sway_mode *mode) {
|
||||
json_object *json_mode = json_object_new_object();
|
||||
json_object_object_add(json_mode, "name", json_object_new_string(mode->name));
|
||||
|
||||
json_object *bindings = json_object_new_array();
|
||||
for (int i = 0; i < mode->keysym_bindings->length; i++) {
|
||||
struct sway_binding *binding = mode->keysym_bindings->items[i];
|
||||
json_object *json_binding = ipc_json_describe_binding(binding);
|
||||
if (json_binding) {
|
||||
json_object_array_add(bindings, json_binding);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mode->keycode_bindings->length; i++) {
|
||||
struct sway_binding *binding = mode->keycode_bindings->items[i];
|
||||
json_object *json_binding = ipc_json_describe_binding(binding);
|
||||
if (json_binding) {
|
||||
json_object_array_add(bindings, json_binding);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mode->mouse_bindings->length; i++) {
|
||||
struct sway_binding *binding = mode->mouse_bindings->items[i];
|
||||
json_object *json_binding = ipc_json_describe_binding(binding);
|
||||
if (json_binding) {
|
||||
json_object_array_add(bindings, json_binding);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mode->switch_bindings->length; i++) {
|
||||
struct sway_switch_binding *binding = mode->switch_bindings->items[i];
|
||||
json_object *json_binding = ipc_json_describe_switch_binding(binding);
|
||||
if (json_binding) {
|
||||
json_object_array_add(bindings, json_binding);
|
||||
}
|
||||
}
|
||||
|
||||
json_object_object_add(json_mode, "bindings", bindings);
|
||||
|
||||
return json_mode;
|
||||
}
|
||||
|
@ -399,77 +399,17 @@ 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;
|
||||
|
||||
switch (binding->type) {
|
||||
case 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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BINDING_KEYSYM:
|
||||
case BINDING_MOUSESYM:
|
||||
case BINDING_MOUSECODE:; // 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
json_object *json_binding = ipc_json_describe_binding(binding);
|
||||
if (!json_binding) {
|
||||
sway_log(SWAY_DEBUG, "Unsupported ipc binding event");
|
||||
json_object_put(input_codes);
|
||||
json_object_put(symbols);
|
||||
json_object_put(json_binding);
|
||||
return; // do not send any event
|
||||
}
|
||||
|
||||
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"));
|
||||
// Modifiers are "event_state_mask" in i3 ipc binding event
|
||||
json_object *modifiers = json_object_object_get(json_binding, "modifiers");
|
||||
json_object_get(modifiers);
|
||||
json_object_object_del(json_binding, "modifiers");
|
||||
json_object_object_add(json_binding, "event_state_mask", modifiers);
|
||||
|
||||
json_object *json = json_object_new_object();
|
||||
json_object_object_add(json, "change", json_object_new_string("run"));
|
||||
@ -862,16 +802,39 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
||||
|
||||
case IPC_GET_BINDING_MODES:
|
||||
{
|
||||
json_object *modes = json_object_new_array();
|
||||
for (int i = 0; i < config->modes->length; i++) {
|
||||
struct sway_mode *mode = config->modes->items[i];
|
||||
json_object_array_add(modes, json_object_new_string(mode->name));
|
||||
if (!buf[0]) {
|
||||
json_object *modes = json_object_new_array();
|
||||
for (int i = 0; i < config->modes->length; i++) {
|
||||
struct sway_mode *mode = config->modes->items[i];
|
||||
json_object_array_add(modes, json_object_new_string(mode->name));
|
||||
}
|
||||
const char *json_string = json_object_to_json_string(modes);
|
||||
ipc_send_reply(client, payload_type, json_string,
|
||||
(uint32_t)strlen(json_string));
|
||||
json_object_put(modes); // free
|
||||
goto exit_cleanup;
|
||||
} else {
|
||||
struct sway_mode *mode = NULL;
|
||||
for (int i = 0; i < config->modes->length; i++) {
|
||||
mode = config->modes->items[i];
|
||||
if (strcmp(buf, mode->name) == 0) {
|
||||
break;
|
||||
}
|
||||
mode = NULL;
|
||||
}
|
||||
if (!mode) {
|
||||
const char *error = "{ \"success\": false, \"error\": \"No mode with that name\" }";
|
||||
ipc_send_reply(client, payload_type, error,
|
||||
(uint32_t)strlen(error));
|
||||
goto exit_cleanup;
|
||||
} else {
|
||||
json_object *json_mode = ipc_json_describe_binding_mode(mode);
|
||||
const char *json_string = json_object_to_json_string(json_mode);
|
||||
ipc_send_reply(client, payload_type, json_string, (uint32_t)strlen(json_string));
|
||||
json_object_put(json_mode);
|
||||
goto exit_cleanup;
|
||||
}
|
||||
}
|
||||
const char *json_string = json_object_to_json_string(modes);
|
||||
ipc_send_reply(client, payload_type, json_string,
|
||||
(uint32_t)strlen(json_string));
|
||||
json_object_put(modes); // free
|
||||
goto exit_cleanup;
|
||||
}
|
||||
|
||||
case IPC_GET_BINDING_STATE:
|
||||
|
Loading…
Reference in New Issue
Block a user