ipc: add an input event
This adds an ipc event related to input devices. Currently the following changes are supported: - added: when an input device becomes available - removed: when an input device is no longer available - xkb_keymap_changed: (keyboards only) the keymap changed - xkb_layout_changed: (keyboards only) the effective layout changed
This commit is contained in:
parent
36aa67e549
commit
6effca7b61
|
@ -34,6 +34,7 @@ enum ipc_command_type {
|
|||
|
||||
// sway-specific event types
|
||||
IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20),
|
||||
IPC_EVENT_INPUT = ((1<<31) | 21),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,7 @@ struct sway_keyboard {
|
|||
struct sway_seat_device *seat_device;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
xkb_layout_index_t effective_layout;
|
||||
|
||||
struct wl_listener keyboard_key;
|
||||
struct wl_listener keyboard_modifiers;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _SWAY_IPC_SERVER_H
|
||||
#include <sys/socket.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "ipc.h"
|
||||
|
||||
|
@ -19,5 +20,6 @@ void ipc_event_bar_state_update(struct bar_config *bar);
|
|||
void ipc_event_mode(const char *mode, bool pango);
|
||||
void ipc_event_shutdown(const char *reason);
|
||||
void ipc_event_binding(struct sway_binding *binding);
|
||||
void ipc_event_input(const char *change, struct sway_input_device *device);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/server.h"
|
||||
#include "stringop.h"
|
||||
#include "list.h"
|
||||
|
@ -584,6 +585,8 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) {
|
|||
seat_remove_device(seat, input_device);
|
||||
}
|
||||
|
||||
ipc_event_input("removed", input_device);
|
||||
|
||||
wl_list_remove(&input_device->link);
|
||||
wl_list_remove(&input_device->device_destroy.link);
|
||||
free(input_device->identifier);
|
||||
|
@ -656,6 +659,8 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
|
|||
"device '%s' is not configured on any seats",
|
||||
input_device->identifier);
|
||||
}
|
||||
|
||||
ipc_event_input("added", input_device);
|
||||
}
|
||||
|
||||
static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
|
||||
|
|
|
@ -473,6 +473,11 @@ static void handle_keyboard_modifiers(struct wl_listener *listener,
|
|||
|
||||
uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
|
||||
determine_bar_visibility(modifiers);
|
||||
|
||||
if (wlr_device->keyboard->modifiers.group != keyboard->effective_layout) {
|
||||
keyboard->effective_layout = wlr_device->keyboard->modifiers.group;
|
||||
ipc_event_input("xkb_layout", keyboard->seat_device->input_device);
|
||||
}
|
||||
}
|
||||
|
||||
struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
|
||||
|
@ -603,8 +608,23 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||
}
|
||||
}
|
||||
|
||||
bool keymap_changed = false;
|
||||
bool effective_layout_changed = keyboard->effective_layout != 0;
|
||||
if (keyboard->keymap) {
|
||||
char *old_keymap_string = xkb_keymap_get_as_string(keyboard->keymap,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||
char *new_keymap_string = xkb_keymap_get_as_string(keymap,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||
keymap_changed = strcmp(old_keymap_string, new_keymap_string);
|
||||
free(old_keymap_string);
|
||||
free(new_keymap_string);
|
||||
} else {
|
||||
keymap_changed = true;
|
||||
}
|
||||
|
||||
xkb_keymap_unref(keyboard->keymap);
|
||||
keyboard->keymap = keymap;
|
||||
keyboard->effective_layout = 0;
|
||||
wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
|
||||
|
||||
xkb_mod_mask_t locked_mods = 0;
|
||||
|
@ -654,6 +674,14 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||
wl_signal_add(&wlr_device->keyboard->events.modifiers,
|
||||
&keyboard->keyboard_modifiers);
|
||||
keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
|
||||
|
||||
if (keymap_changed) {
|
||||
ipc_event_input("xkb_keymap",
|
||||
keyboard->seat_device->input_device);
|
||||
} else if (effective_layout_changed) {
|
||||
ipc_event_input("xkb_layout",
|
||||
keyboard->seat_device->input_device);
|
||||
}
|
||||
}
|
||||
|
||||
void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
|
||||
|
|
|
@ -487,6 +487,21 @@ static void ipc_event_tick(const char *payload) {
|
|||
json_object_put(json);
|
||||
}
|
||||
|
||||
void ipc_event_input(const char *change, struct sway_input_device *device) {
|
||||
if (!ipc_has_event_listeners(IPC_EVENT_INPUT)) {
|
||||
return;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "Sending input event");
|
||||
|
||||
json_object *json = json_object_new_object();
|
||||
json_object_object_add(json, "change", json_object_new_string(change));
|
||||
json_object_object_add(json, "input", ipc_json_describe_input(device));
|
||||
|
||||
const char *json_string = json_object_to_json_string(json);
|
||||
ipc_send_event(json_string, IPC_EVENT_INPUT);
|
||||
json_object_put(json);
|
||||
}
|
||||
|
||||
int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) {
|
||||
struct ipc_client *client = data;
|
||||
|
||||
|
@ -716,6 +731,8 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
|||
} else if (strcmp(event_type, "tick") == 0) {
|
||||
client->subscribed_events |= event_mask(IPC_EVENT_TICK);
|
||||
is_tick = true;
|
||||
} else if (strcmp(event_type, "input") == 0) {
|
||||
client->subscribed_events |= event_mask(IPC_EVENT_INPUT);
|
||||
} else {
|
||||
const char msg[] = "{\"success\": false}";
|
||||
ipc_send_reply(client, payload_type, msg, strlen(msg));
|
||||
|
|
|
@ -1371,6 +1371,9 @@ available:
|
|||
|- 0x80000014
|
||||
: bar_status_update
|
||||
: Send when the visibility of a bar should change due to a modifier
|
||||
|- 0x80000015
|
||||
: input
|
||||
: Sent when something related to input devices changes
|
||||
|
||||
|
||||
## 0x80000000. WORKSPACE
|
||||
|
@ -1702,6 +1705,56 @@ event is a single object with the following properties:
|
|||
}
|
||||
```
|
||||
|
||||
## 0x80000015. INPUT
|
||||
|
||||
Sent when something related to the input devices changes. The event is a single
|
||||
object with the following properties:
|
||||
|
||||
[- *PROPERTY*
|
||||
:- *DATA TYPE*
|
||||
:- *DESCRIPTION*
|
||||
|- change
|
||||
: string
|
||||
:[ What has changed
|
||||
|- input
|
||||
: object
|
||||
: An object representing the input that is identical the ones GET_INPUTS gives
|
||||
|
||||
The following change types are currently available:
|
||||
[- *TYPE*
|
||||
:- *DESCRIPTION*
|
||||
|- added
|
||||
:[ The input device became available
|
||||
|- removed
|
||||
: The input device is no longer available
|
||||
|- xkb_keymap
|
||||
: (Keyboards only) The keymap for the keyboard has changed
|
||||
|- xkb_layout
|
||||
: (Keyboards only) The effective layout in the keymap has changed
|
||||
|
||||
*Example Event:*
|
||||
```
|
||||
{
|
||||
"change": "xkb_layout",
|
||||
"input": {
|
||||
"identifier": "1:1:AT_Translated_Set_2_keyboard",
|
||||
"name": "AT Translated Set 2 keyboard",
|
||||
"vendor": 1,
|
||||
"product": 1,
|
||||
"type": "keyboard",
|
||||
"xkb_layout_names": [
|
||||
"English (US)",
|
||||
"English (Dvorak)"
|
||||
],
|
||||
"xkb_active_layout_index": 1,
|
||||
"xkb_active_layout_name": "English (Dvorak)",
|
||||
"libinput": {
|
||||
"send_events": "enabled"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*sway*(1) *sway*(5) *sway-bar*(5) *swaymsg*(1) *sway-input*(5) *sway-output*(5)
|
||||
|
|
Loading…
Reference in a new issue