diff options
author | Ryan Walklin <ryan@testtoast.com> | 2019-03-20 14:47:29 +1100 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2019-03-19 23:58:47 -0400 |
commit | bdb402404cd6d54242b0b1dc2360cfc5679e52f2 (patch) | |
tree | 5a355e025c24b3de0bc69db4b8cc9d002bbd1167 /sway/input/switch.c | |
parent | Clean up focus follows mouse logic (diff) | |
download | sway-bdb402404cd6d54242b0b1dc2360cfc5679e52f2.tar.gz sway-bdb402404cd6d54242b0b1dc2360cfc5679e52f2.tar.zst sway-bdb402404cd6d54242b0b1dc2360cfc5679e52f2.zip |
Support WLR_INPUT_DEVICE_SWITCH in sway
This commit adds support for laptop lid and tablet
mode switches as provided by evdev/libinput and
handled by wlroots.
Adds a new bindswitch command with syntax:
bindswitch <switch>:<state> <command>
Where <switch> is one of:
tablet for WLR_SWITCH_TYPE_TABLET_MODE
lid for WLR_SWITCH_TYPE_LID
<state> is one of:
on for WLR_SWITCH_STATE_ON
off for WLR_SWITCH_STATE_OFF
toggle for WLR_SWITCH_STATE_TOGGLE
(Note that WLR_SWITCH_STATE_TOGGLE doesn't map to
libinput and will trigger at both on and off events)
Diffstat (limited to 'sway/input/switch.c')
-rw-r--r-- | sway/input/switch.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/sway/input/switch.c b/sway/input/switch.c new file mode 100644 index 00000000..d56e6525 --- /dev/null +++ b/sway/input/switch.c | |||
@@ -0,0 +1,85 @@ | |||
1 | #include "sway/config.h" | ||
2 | #include "sway/desktop/transaction.h" | ||
3 | #include "sway/input/switch.h" | ||
4 | #include <wlr/types/wlr_idle.h> | ||
5 | #include "log.h" | ||
6 | |||
7 | struct sway_switch *sway_switch_create(struct sway_seat *seat, | ||
8 | struct sway_seat_device *device) { | ||
9 | struct sway_switch *switch_device = | ||
10 | calloc(1, sizeof(struct sway_switch)); | ||
11 | if (!sway_assert(switch_device, "could not allocate switch")) { | ||
12 | return NULL; | ||
13 | } | ||
14 | device->switch_device = switch_device; | ||
15 | switch_device->seat_device = device; | ||
16 | wl_list_init(&switch_device->switch_toggle.link); | ||
17 | sway_log(SWAY_DEBUG, "Allocated switch for device"); | ||
18 | |||
19 | return switch_device; | ||
20 | } | ||
21 | |||
22 | static void handle_switch_toggle(struct wl_listener *listener, void *data) { | ||
23 | struct sway_switch *sway_switch = | ||
24 | wl_container_of(listener, sway_switch, switch_toggle); | ||
25 | struct sway_seat* seat = sway_switch->seat_device->sway_seat; | ||
26 | struct wlr_seat *wlr_seat = seat->wlr_seat; | ||
27 | struct wlr_input_device *wlr_device = | ||
28 | sway_switch->seat_device->input_device->wlr_device; | ||
29 | |||
30 | wlr_idle_notify_activity(server.idle, wlr_seat); | ||
31 | bool input_inhibited = seat->exclusive_client != NULL; | ||
32 | |||
33 | char *device_identifier = input_device_get_identifier(wlr_device); | ||
34 | |||
35 | struct wlr_event_switch_toggle *event = data; | ||
36 | enum wlr_switch_type type = event->switch_type; | ||
37 | enum wlr_switch_state state = event->switch_state; | ||
38 | sway_log(SWAY_DEBUG, "%s: type %d state %d", device_identifier, type, state); | ||
39 | |||
40 | list_t *bindings = config->current_mode->switch_bindings; | ||
41 | for (int i = 0; i < bindings->length; ++i) { | ||
42 | struct sway_switch_binding *binding = bindings->items[i]; | ||
43 | if (binding->type != type) { | ||
44 | continue; | ||
45 | } | ||
46 | if (binding->state != WLR_SWITCH_STATE_TOGGLE && | ||
47 | binding->state != state) { | ||
48 | continue; | ||
49 | } | ||
50 | bool binding_locked = binding->flags & BINDING_LOCKED; | ||
51 | if (!binding_locked && input_inhibited) { | ||
52 | continue; | ||
53 | } | ||
54 | |||
55 | struct sway_binding *dummy_binding = calloc(1, sizeof(struct sway_binding)); | ||
56 | dummy_binding->type = BINDING_SWITCH; | ||
57 | dummy_binding->flags = binding->flags; | ||
58 | dummy_binding->command = binding->command; | ||
59 | |||
60 | seat_execute_command(seat, dummy_binding); | ||
61 | free(dummy_binding); | ||
62 | } | ||
63 | |||
64 | transaction_commit_dirty(); | ||
65 | |||
66 | free(device_identifier); | ||
67 | } | ||
68 | |||
69 | void sway_switch_configure(struct sway_switch *sway_switch) { | ||
70 | struct wlr_input_device *wlr_device = | ||
71 | sway_switch->seat_device->input_device->wlr_device; | ||
72 | wl_list_remove(&sway_switch->switch_toggle.link); | ||
73 | wl_signal_add(&wlr_device->switch_device->events.toggle, | ||
74 | &sway_switch->switch_toggle); | ||
75 | sway_switch->switch_toggle.notify = handle_switch_toggle; | ||
76 | sway_log(SWAY_DEBUG, "Configured switch for device"); | ||
77 | } | ||
78 | |||
79 | void sway_switch_destroy(struct sway_switch *sway_switch) { | ||
80 | if (!sway_switch) { | ||
81 | return; | ||
82 | } | ||
83 | wl_list_remove(&sway_switch->switch_toggle.link); | ||
84 | free(sway_switch); | ||
85 | } | ||