summaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-01-06 07:26:54 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2016-01-06 07:26:54 -0500
commit8f5de70c93b2afaab0dd7d384c58ff3d3007193c (patch)
tree4826eca48ec5d4d2b827477c74de7d500f39f0fa /sway
parentFix whitespaces in cmake config (diff)
parentOnly send modifier event once for active modifiers (diff)
downloadsway-8f5de70c93b2afaab0dd7d384c58ff3d3007193c.tar.gz
sway-8f5de70c93b2afaab0dd7d384c58ff3d3007193c.tar.zst
sway-8f5de70c93b2afaab0dd7d384c58ff3d3007193c.zip
Merge pull request #434 from mikkeloscar/detect-modifier
Send IPC modifier event on bar_modifier up/down
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c58
-rw-r--r--sway/config.c33
-rw-r--r--sway/handlers.c18
-rw-r--r--sway/input_state.c24
-rw-r--r--sway/ipc-server.c18
5 files changed, 108 insertions, 43 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 9cc33b9c..4e5bc712 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -99,22 +99,6 @@ static sway_cmd bar_colors_cmd_urgent_workspace;
99swayc_t *sp_view; 99swayc_t *sp_view;
100int sp_index = 0; 100int sp_index = 0;
101 101
102static struct modifier_key {
103 char *name;
104 uint32_t mod;
105} modifiers[] = {
106 { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT },
107 { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS },
108 { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL },
109 { "Ctrl", WLC_BIT_MOD_CTRL },
110 { XKB_MOD_NAME_ALT, WLC_BIT_MOD_ALT },
111 { "Alt", WLC_BIT_MOD_ALT },
112 { XKB_MOD_NAME_NUM, WLC_BIT_MOD_MOD2 },
113 { "Mod3", WLC_BIT_MOD_MOD3 },
114 { XKB_MOD_NAME_LOGO, WLC_BIT_MOD_LOGO },
115 { "Mod5", WLC_BIT_MOD_MOD5 },
116};
117
118static char *bg_options[] = { 102static char *bg_options[] = {
119 "stretch", 103 "stretch",
120 "center", 104 "center",
@@ -187,16 +171,11 @@ static struct cmd_results *cmd_bindsym(int argc, char **argv) {
187 list_t *split = split_string(argv[0], "+"); 171 list_t *split = split_string(argv[0], "+");
188 for (int i = 0; i < split->length; ++i) { 172 for (int i = 0; i < split->length; ++i) {
189 // Check for a modifier key 173 // Check for a modifier key
190 int j; 174 uint32_t mod;
191 bool is_mod = false; 175 if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
192 for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) { 176 binding->modifiers |= mod;
193 if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { 177 continue;
194 binding->modifiers |= modifiers[j].mod;
195 is_mod = true;
196 break;
197 }
198 } 178 }
199 if (is_mod) continue;
200 // Check for xkb key 179 // Check for xkb key
201 xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); 180 xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE);
202 if (!sym) { 181 if (!sym) {
@@ -408,17 +387,13 @@ static struct cmd_results *cmd_floating_mod(int argc, char **argv) {
408 if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) { 387 if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) {
409 return error; 388 return error;
410 } 389 }
411 int i, j; 390 int i;
412 list_t *split = split_string(argv[0], "+"); 391 list_t *split = split_string(argv[0], "+");
413 config->floating_mod = 0; 392 config->floating_mod = 0;
414 393
415 // set modifier keys 394 // set modifier keys
416 for (i = 0; i < split->length; ++i) { 395 for (i = 0; i < split->length; ++i) {
417 for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) { 396 config->floating_mod |= get_modifier_mask_by_name(split->items[i]);
418 if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
419 config->floating_mod |= modifiers[j].mod;
420 }
421 }
422 } 397 }
423 free_flat_list(split); 398 free_flat_list(split);
424 if (!config->floating_mod) { 399 if (!config->floating_mod) {
@@ -1776,6 +1751,9 @@ static struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
1776 } 1751 }
1777 } 1752 }
1778 1753
1754 // active bar modifiers might have changed.
1755 update_active_bar_modifiers();
1756
1779 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 1757 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
1780} 1758}
1781 1759
@@ -1800,6 +1778,9 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
1800 if (strcmp(old_mode, bar->mode) != 0) { 1778 if (strcmp(old_mode, bar->mode) != 0) {
1801 if (!config->reading) { 1779 if (!config->reading) {
1802 ipc_event_barconfig_update(bar); 1780 ipc_event_barconfig_update(bar);
1781
1782 // active bar modifiers might have changed.
1783 update_active_bar_modifiers();
1803 } 1784 }
1804 sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id); 1785 sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
1805 } 1786 }
@@ -1893,16 +1874,11 @@ static struct cmd_results *bar_cmd_modifier(int argc, char **argv) {
1893 1874
1894 list_t *split = split_string(argv[0], "+"); 1875 list_t *split = split_string(argv[0], "+");
1895 for (int i = 0; i < split->length; ++i) { 1876 for (int i = 0; i < split->length; ++i) {
1896 int j; 1877 uint32_t tmp_mod;
1897 bool is_mod = false; 1878 if ((tmp_mod = get_modifier_mask_by_name(split->items[i])) > 0) {
1898 for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) { 1879 mod |= tmp_mod;
1899 if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { 1880 continue;
1900 mod |= modifiers[j].mod; 1881 } else {
1901 is_mod = true;
1902 break;
1903 }
1904 }
1905 if (!is_mod) {
1906 free_flat_list(split); 1882 free_flat_list(split);
1907 return cmd_results_new(CMD_INVALID, "modifier", "Unknown modifier '%s'", split->items[i]); 1883 return cmd_results_new(CMD_INVALID, "modifier", "Unknown modifier '%s'", split->items[i]);
1908 } 1884 }
diff --git a/sway/config.c b/sway/config.c
index 1973de02..95d8f339 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -103,6 +103,8 @@ static void free_config(struct sway_config *config) {
103 free_output_config(config->output_configs->items[i]); 103 free_output_config(config->output_configs->items[i]);
104 } 104 }
105 list_free(config->output_configs); 105 list_free(config->output_configs);
106
107 list_free(config->active_bar_modifiers);
106 free(config); 108 free(config);
107} 109}
108 110
@@ -145,6 +147,33 @@ static void config_defaults(struct sway_config *config) {
145 config->edge_gaps = true; 147 config->edge_gaps = true;
146 config->gaps_inner = 0; 148 config->gaps_inner = 0;
147 config->gaps_outer = 0; 149 config->gaps_outer = 0;
150
151 config->active_bar_modifiers = create_list();
152}
153
154static int compare_modifiers(const void *left, const void *right) {
155 uint32_t a = *(uint32_t *)left;
156 uint32_t b = *(uint32_t *)right;
157
158 return a - b;
159}
160
161void update_active_bar_modifiers() {
162 if (config->active_bar_modifiers->length > 0) {
163 list_free(config->active_bar_modifiers);
164 config->active_bar_modifiers = create_list();
165 }
166
167 struct bar_config *bar;
168 int i;
169 for (i = 0; i < config->bars->length; ++i) {
170 bar = config->bars->items[i];
171 if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) {
172 if (list_seq_find(config->active_bar_modifiers, compare_modifiers, &bar->modifier) < 0) {
173 list_add(config->active_bar_modifiers, &bar->modifier);
174 }
175 }
176 }
148} 177}
149 178
150static char *get_config_path(void) { 179static char *get_config_path(void) {
@@ -215,6 +244,8 @@ bool load_config(const char *file) {
215 } 244 }
216 fclose(f); 245 fclose(f);
217 246
247 update_active_bar_modifiers();
248
218 return config_load_success; 249 return config_load_success;
219} 250}
220 251
@@ -695,7 +726,7 @@ struct bar_config *default_bar_config(void) {
695 bar = malloc(sizeof(struct bar_config)); 726 bar = malloc(sizeof(struct bar_config));
696 bar->mode = strdup("dock"); 727 bar->mode = strdup("dock");
697 bar->hidden_state = strdup("hide"); 728 bar->hidden_state = strdup("hide");
698 bar->modifier = 0; 729 bar->modifier = WLC_BIT_MOD_LOGO;
699 bar->outputs = NULL; 730 bar->outputs = NULL;
700 bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; 731 bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM;
701 bar->bindings = create_list(); 732 bar->bindings = create_list();
diff --git a/sway/handlers.c b/sway/handlers.c
index 3cc5cf3e..470f3c95 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -20,6 +20,7 @@
20#include "resize.h" 20#include "resize.h"
21#include "extensions.h" 21#include "extensions.h"
22#include "criteria.h" 22#include "criteria.h"
23#include "ipc-server.h"
23 24
24// Event should be sent to client 25// Event should be sent to client
25#define EVENT_PASSTHROUGH false 26#define EVENT_PASSTHROUGH false
@@ -391,6 +392,23 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
391 } 392 }
392 } 393 }
393 } 394 }
395
396 // handle bar modifiers pressed/released
397 uint32_t modifier;
398 for (i = 0; i < config->active_bar_modifiers->length; ++i) {
399 modifier = *(uint32_t *)config->active_bar_modifiers->items[i];
400
401 switch (modifier_state_changed(modifiers->mods, modifier)) {
402 case MOD_STATE_PRESSED:
403 ipc_event_modifier(modifier, "pressed");
404 break;
405 case MOD_STATE_RELEASED:
406 ipc_event_modifier(modifier, "released");
407 break;
408 }
409 }
410 // update modifiers state
411 modifiers_state_update(modifiers->mods);
394 return EVENT_PASSTHROUGH; 412 return EVENT_PASSTHROUGH;
395} 413}
396 414
diff --git a/sway/input_state.c b/sway/input_state.c
index 58619d1f..2f40b6c2 100644
--- a/sway/input_state.c
+++ b/sway/input_state.c
@@ -22,12 +22,36 @@ struct key_state {
22 22
23static struct key_state key_state_array[KEY_STATE_MAX_LENGTH]; 23static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
24 24
25static uint32_t modifiers_state;
26
25void input_init(void) { 27void input_init(void) {
26 int i; 28 int i;
27 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { 29 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
28 struct key_state none = { 0, 0, 0 }; 30 struct key_state none = { 0, 0, 0 };
29 key_state_array[i] = none; 31 key_state_array[i] = none;
30 } 32 }
33
34 modifiers_state = 0;
35}
36
37uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod) {
38 if ((new_state & mod) != 0) { // pressed
39 if ((modifiers_state & mod) != 0) { // already pressed
40 return MOD_STATE_UNCHANGED;
41 } else { // pressed
42 return MOD_STATE_PRESSED;
43 }
44 } else { // not pressed
45 if ((modifiers_state & mod) != 0) { // released
46 return MOD_STATE_RELEASED;
47 } else { // already released
48 return MOD_STATE_UNCHANGED;
49 }
50 }
51}
52
53void modifiers_state_update(uint32_t new_state) {
54 modifiers_state = new_state;
31} 55}
32 56
33static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) { 57static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index ed3977d5..f3a4647b 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -19,6 +19,7 @@
19#include "commands.h" 19#include "commands.h"
20#include "list.h" 20#include "list.h"
21#include "stringop.h" 21#include "stringop.h"
22#include "util.h"
22 23
23static int ipc_socket = -1; 24static int ipc_socket = -1;
24static struct wlc_event_source *ipc_event_source = NULL; 25static struct wlc_event_source *ipc_event_source = NULL;
@@ -295,6 +296,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
295 client->subscribed_events |= IPC_EVENT_BARCONFIG_UPDATE; 296 client->subscribed_events |= IPC_EVENT_BARCONFIG_UPDATE;
296 } else if (strcmp(event_type, "mode") == 0) { 297 } else if (strcmp(event_type, "mode") == 0) {
297 client->subscribed_events |= IPC_EVENT_MODE; 298 client->subscribed_events |= IPC_EVENT_MODE;
299 } else if (strcmp(event_type, "modifier") == 0) {
300 client->subscribed_events |= IPC_EVENT_MODIFIER;
298 } else { 301 } else {
299 ipc_send_reply(client, "{\"success\": false}", 18); 302 ipc_send_reply(client, "{\"success\": false}", 18);
300 ipc_client_disconnect(client); 303 ipc_client_disconnect(client);
@@ -508,7 +511,7 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
508 json_object_object_add(json, "tray_output", NULL); 511 json_object_object_add(json, "tray_output", NULL);
509 json_object_object_add(json, "mode", json_object_new_string(bar->mode)); 512 json_object_object_add(json, "mode", json_object_new_string(bar->mode));
510 json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); 513 json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
511 //json_object_object_add(json, "modifier", json_object_new_string(bar->modifier)); // TODO: Fix modifier 514 json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
512 switch (bar->position) { 515 switch (bar->position) {
513 case DESKTOP_SHELL_PANEL_POSITION_TOP: 516 case DESKTOP_SHELL_PANEL_POSITION_TOP:
514 json_object_object_add(json, "position", json_object_new_string("top")); 517 json_object_object_add(json, "position", json_object_new_string("top"));
@@ -617,3 +620,16 @@ void ipc_event_mode(const char *mode) {
617 620
618 json_object_put(obj); // free 621 json_object_put(obj); // free
619} 622}
623
624void ipc_event_modifier(uint32_t modifier, const char *state) {
625 json_object *obj = json_object_new_object();
626 json_object_object_add(obj, "change", json_object_new_string(state));
627
628 const char *modifier_name = get_modifier_name_by_mask(modifier);
629 json_object_object_add(obj, "modifier", json_object_new_string(modifier_name));
630
631 const char *json_string = json_object_to_json_string(obj);
632 ipc_send_event(json_string, IPC_EVENT_MODIFIER);
633
634 json_object_put(obj); // free
635}