mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 22:43:58 +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_version(void);
|
||||||
|
|
||||||
json_object *ipc_json_get_binding_mode(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_disabled_output(struct sway_output *o);
|
||||||
json_object *ipc_json_describe_non_desktop_output(struct sway_output_non_desktop *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/output.h"
|
||||||
#include "sway/input/input-manager.h"
|
#include "sway/input/input-manager.h"
|
||||||
#include "sway/input/cursor.h"
|
#include "sway/input/cursor.h"
|
||||||
|
#include "sway/input/keyboard.h"
|
||||||
#include "sway/input/seat.h"
|
#include "sway/input/seat.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
||||||
#include "sway/desktop/idle_inhibit_v1.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));
|
json_object_new_string(config->current_mode->name));
|
||||||
return current_mode;
|
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");
|
sway_log(SWAY_DEBUG, "Sending binding event");
|
||||||
|
|
||||||
json_object *json_binding = json_object_new_object();
|
json_object *json_binding = ipc_json_describe_binding(binding);
|
||||||
json_object_object_add(json_binding, "command", json_object_new_string(binding->command));
|
if (!json_binding) {
|
||||||
|
|
||||||
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:
|
|
||||||
sway_log(SWAY_DEBUG, "Unsupported ipc binding event");
|
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
|
return; // do not send any event
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object_object_add(json_binding, "input_codes", input_codes);
|
// Modifiers are "event_state_mask" in i3 ipc binding event
|
||||||
json_object_object_add(json_binding, "input_code", json_object_new_int(input_code));
|
json_object *modifiers = json_object_object_get(json_binding, "modifiers");
|
||||||
json_object_object_add(json_binding, "symbols", symbols);
|
json_object_get(modifiers);
|
||||||
json_object_object_add(json_binding, "symbol", symbol);
|
json_object_object_del(json_binding, "modifiers");
|
||||||
|
json_object_object_add(json_binding, "event_state_mask", modifiers);
|
||||||
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 *json = json_object_new_object();
|
||||||
json_object_object_add(json, "change", json_object_new_string("run"));
|
json_object_object_add(json, "change", json_object_new_string("run"));
|
||||||
@ -862,6 +802,7 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
|||||||
|
|
||||||
case IPC_GET_BINDING_MODES:
|
case IPC_GET_BINDING_MODES:
|
||||||
{
|
{
|
||||||
|
if (!buf[0]) {
|
||||||
json_object *modes = json_object_new_array();
|
json_object *modes = json_object_new_array();
|
||||||
for (int i = 0; i < config->modes->length; i++) {
|
for (int i = 0; i < config->modes->length; i++) {
|
||||||
struct sway_mode *mode = config->modes->items[i];
|
struct sway_mode *mode = config->modes->items[i];
|
||||||
@ -872,6 +813,28 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
|||||||
(uint32_t)strlen(json_string));
|
(uint32_t)strlen(json_string));
|
||||||
json_object_put(modes); // free
|
json_object_put(modes); // free
|
||||||
goto exit_cleanup;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPC_GET_BINDING_STATE:
|
case IPC_GET_BINDING_STATE:
|
||||||
|
Loading…
Reference in New Issue
Block a user