aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Ashworth <bosrsf04@gmail.com>2019-07-17 17:12:20 -0400
committerSimon Ser <contact@emersion.fr>2019-07-23 20:45:46 +0300
commit6effca7b61e87c7d17885d007d94e556a0137651 (patch)
tree686cc1e219d8236f8c9864c9992b3cb6b44c9583
parent36aa67e549609ce6c786c382f14ab866536cac47 (diff)
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
-rw-r--r--include/ipc.h1
-rw-r--r--include/sway/input/keyboard.h1
-rw-r--r--include/sway/ipc-server.h2
-rw-r--r--sway/input/input-manager.c5
-rw-r--r--sway/input/keyboard.c28
-rw-r--r--sway/ipc-server.c17
-rw-r--r--sway/sway-ipc.7.scd53
7 files changed, 107 insertions, 0 deletions
diff --git a/include/ipc.h b/include/ipc.h
index 6063f69c..7ae21ab3 100644
--- a/include/ipc.h
+++ b/include/ipc.h
@@ -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
diff --git a/include/sway/input/keyboard.h b/include/sway/input/keyboard.h
index 90214af9..1ff63c94 100644
--- a/include/sway/input/keyboard.h
+++ b/include/sway/input/keyboard.h
@@ -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;
diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h
index 3c43f74d..bc4f781a 100644
--- a/include/sway/ipc-server.h
+++ b/include/sway/ipc-server.h
@@ -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
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 4fd980c4..dd84a0b3 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -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) {
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 1f7ed849..328458fa 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -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) {
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index ca1c1b12..773e90fd 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -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));
diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd
index 3657dcd6..4688e46d 100644
--- a/sway/sway-ipc.7.scd
+++ b/sway/sway-ipc.7.scd
@@ -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)