From c20c63b677c03b17441f0d135b5325e23d65f38d Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Tue, 5 Jan 2016 02:20:20 +0100 Subject: [PATCH] Send IPC modifier event on bar_modifier up/down Detects when a bar modifier key is pressed/released and sends a modifier IPC event to any listeners (usually swaybars). This way a swaybar can listen on the modifier event and hide/show the bar accordingly (not implemented yet) The modifier event looks like this: { "change": "pressed", // or released "modifier": "Mod4" } --- include/ipc-server.h | 6 ++++++ include/ipc.h | 1 + sway/commands.c | 2 +- sway/handlers.c | 17 ++++++++++------- sway/ipc-server.c | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/include/ipc-server.h b/include/ipc-server.h index 049750930..47026bfdc 100644 --- a/include/ipc-server.h +++ b/include/ipc-server.h @@ -15,6 +15,12 @@ void ipc_event_barconfig_update(struct bar_config *bar); * Send IPC mode event to all listening clients */ void ipc_event_mode(const char *mode); +/** + * Sends an IPC modifier event to all listening clients. The modifier event + * includes a key 'change' with the value of state and a key 'modifier' with + * the name of that modifier. + */ +void ipc_event_modifier(uint32_t modifier, const char *state); const char *swayc_type_string(enum swayc_types type); #endif diff --git a/include/ipc.h b/include/ipc.h index e0b3b7364..565935295 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -17,6 +17,7 @@ enum ipc_command_type { IPC_EVENT_WINDOW = (1 << 31 | 3), IPC_EVENT_BARCONFIG_UPDATE = (1 << 31 | 4), IPC_EVENT_BINDING = (1 << 31 | 5), + IPC_EVENT_MODIFIER = (1 << 31 | 6), IPC_SWAY_GET_PIXELS = 0x81 }; diff --git a/sway/commands.c b/sway/commands.c index 38019be5f..f748a9698 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1897,7 +1897,7 @@ static struct cmd_results *bar_cmd_modifier(int argc, char **argv) { bool is_mod = false; for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) { if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { - mod |= modifiers[j].mod; + mod = modifiers[j].mod; is_mod = true; break; } diff --git a/sway/handlers.c b/sway/handlers.c index 5e5234681..4cbec0abc 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -20,6 +20,7 @@ #include "resize.h" #include "extensions.h" #include "criteria.h" +#include "ipc-server.h" // Event should be sent to client #define EVENT_PASSTHROUGH false @@ -392,13 +393,15 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier struct bar_config *bar; for (i = 0; i < config->bars->length; ++i) { bar = config->bars->items[i]; - switch (modifier_state_changed(modifiers->mods, bar->modifier)) { - case MOD_STATE_PRESSED: - sway_log(L_INFO, "pressed!!!"); - break; - case MOD_STATE_RELEASED: - sway_log(L_INFO, "released!!!"); - break; + if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) { + switch (modifier_state_changed(modifiers->mods, bar->modifier)) { + case MOD_STATE_PRESSED: + ipc_event_modifier(bar->modifier, "pressed"); + break; + case MOD_STATE_RELEASED: + ipc_event_modifier(bar->modifier, "released"); + break; + } } } // update modifiers state diff --git a/sway/ipc-server.c b/sway/ipc-server.c index ed3977d51..da3d52e31 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -35,6 +35,22 @@ struct ipc_client { enum ipc_command_type subscribed_events; }; +static struct modifier_key { + char *name; + uint32_t mod; +} modifiers[] = { + { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT }, + { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS }, + { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL }, + { "Ctrl", WLC_BIT_MOD_CTRL }, + { XKB_MOD_NAME_ALT, WLC_BIT_MOD_ALT }, + { "Alt", WLC_BIT_MOD_ALT }, + { XKB_MOD_NAME_NUM, WLC_BIT_MOD_MOD2 }, + { "Mod3", WLC_BIT_MOD_MOD3 }, + { XKB_MOD_NAME_LOGO, WLC_BIT_MOD_LOGO }, + { "Mod5", WLC_BIT_MOD_MOD5 }, +}; + struct sockaddr_un *ipc_user_sockaddr(void); int ipc_handle_connection(int fd, uint32_t mask, void *data); int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data); @@ -295,6 +311,8 @@ void ipc_client_handle_command(struct ipc_client *client) { client->subscribed_events |= IPC_EVENT_BARCONFIG_UPDATE; } else if (strcmp(event_type, "mode") == 0) { client->subscribed_events |= IPC_EVENT_MODE; + } else if (strcmp(event_type, "modifier") == 0) { + client->subscribed_events |= IPC_EVENT_MODIFIER; } else { ipc_send_reply(client, "{\"success\": false}", 18); ipc_client_disconnect(client); @@ -617,3 +635,24 @@ void ipc_event_mode(const char *mode) { json_object_put(obj); // free } + +void ipc_event_modifier(uint32_t modifier, const char *state) { + json_object *obj = json_object_new_object(); + json_object_object_add(obj, "change", json_object_new_string(state)); + + const char *modifier_name = NULL; + int i; + for (i = 0; i < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++i) { + if (modifiers[i].mod == modifier) { + modifier_name = modifiers[i].name; + break; + } + } + + json_object_object_add(obj, "modifier", json_object_new_string(modifier_name)); + + const char *json_string = json_object_to_json_string(obj); + ipc_send_event(json_string, IPC_EVENT_MODIFIER); + + json_object_put(obj); // free +}