mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -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
|
|
@ -15,6 +15,7 @@ _swaymsg()
|
|||
'get_bar_config'
|
||||
'get_version'
|
||||
'get_binding_modes'
|
||||
'get_bindings'
|
||||
'get_config'
|
||||
'send_tick'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ complete -c swaymsg -s t -l type -fra 'get_marks' --description "Get a JSON-enco
|
|||
complete -c swaymsg -s t -l type -fra 'get_bar_config' --description "Get a JSON-encoded configuration for swaybar."
|
||||
complete -c swaymsg -s t -l type -fra 'get_version' --description "Get JSON-encoded version information for the running instance of sway."
|
||||
complete -c swaymsg -s t -l type -fra 'get_binding_modes' --description "Gets a JSON-encoded list of currently configured binding modes."
|
||||
complete -c swaymsg -s t -l type -fra 'get_bindings' --description "Gets a JSON-encoded object mapping binding modes to their keyboard and mouse bindings."
|
||||
complete -c swaymsg -s t -l type -fra 'get_config' --description "Gets a JSON-encoded copy of the current configuration."
|
||||
complete -c swaymsg -s t -l type -fra 'get_seats' --description "Gets a JSON-encoded list of all seats, its properties and all assigned devices."
|
||||
complete -c swaymsg -s t -l type -fra 'send_tick' --description "Sends a tick event to all subscribed clients."
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ types=(
|
|||
'get_bar_config'
|
||||
'get_version'
|
||||
'get_binding_modes'
|
||||
'get_bindings'
|
||||
'get_config'
|
||||
'send_tick'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ enum ipc_command_type {
|
|||
// sway-specific command types
|
||||
IPC_GET_INPUTS = 100,
|
||||
IPC_GET_SEATS = 101,
|
||||
IPC_GET_BINDINGS = 102,
|
||||
|
||||
// Events sent from sway to clients. Events have the highest bits set.
|
||||
IPC_EVENT_WORKSPACE = ((1<<31) | 0),
|
||||
|
|
|
|||
|
|
@ -354,9 +354,10 @@ enum ipc_feature {
|
|||
IPC_FEATURE_EVENT_BINDING = 4096,
|
||||
IPC_FEATURE_EVENT_INPUT = 8192,
|
||||
IPC_FEATURE_GET_SEATS = 16384,
|
||||
IPC_FEATURE_GET_BINDINGS = 32768,
|
||||
|
||||
IPC_FEATURE_ALL_COMMANDS =
|
||||
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384,
|
||||
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384 | 32768,
|
||||
IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
|
||||
|
||||
IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
|
||||
|
|
|
|||
|
|
@ -12,5 +12,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node);
|
|||
json_object *ipc_json_describe_input(struct sway_input_device *device);
|
||||
json_object *ipc_json_describe_seat(struct sway_seat *seat);
|
||||
json_object *ipc_json_describe_bar_config(struct bar_config *bar);
|
||||
json_object *ipc_json_describe_binding(struct sway_binding *binding);
|
||||
json_object *ipc_json_describe_mode_bindings(struct sway_mode *mode);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -417,6 +417,8 @@ int main(int argc, char **argv) {
|
|||
type = IPC_GET_VERSION;
|
||||
} else if (strcasecmp(cmdtype, "get_binding_modes") == 0) {
|
||||
type = IPC_GET_BINDING_MODES;
|
||||
} else if (strcasecmp(cmdtype, "get_bindings") == 0) {
|
||||
type = IPC_GET_BINDINGS;
|
||||
} else if (strcasecmp(cmdtype, "get_config") == 0) {
|
||||
type = IPC_GET_CONFIG;
|
||||
} else if (strcasecmp(cmdtype, "send_tick") == 0) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ _swaymsg_ [options...] [message]
|
|||
*get\_binding\_modes*
|
||||
Gets a JSON-encoded list of currently configured binding modes.
|
||||
|
||||
*get\_bindings*
|
||||
Gets a JSON-encoded object mapping binding modes to their keyboard and
|
||||
mouse bindings.
|
||||
|
||||
*get\_config*
|
||||
Gets a JSON-encoded copy of the current configuration.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue