diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 10 | ||||
-rw-r--r-- | include/sway/input/cursor.h | 2 | ||||
-rw-r--r-- | include/swaybar/config.h | 10 | ||||
-rw-r--r-- | include/swaybar/input.h | 15 | ||||
-rw-r--r-- | sway/commands/bar.c | 1 | ||||
-rw-r--r-- | sway/commands/bar/bind.c | 22 | ||||
-rw-r--r-- | sway/commands/bar/tray_bind.c | 97 | ||||
-rw-r--r-- | sway/commands/bar/tray_bindsym.c | 55 | ||||
-rw-r--r-- | sway/config/bar.c | 7 | ||||
-rw-r--r-- | sway/input/cursor.c | 16 | ||||
-rw-r--r-- | sway/ipc-json.c | 19 | ||||
-rw-r--r-- | sway/meson.build | 2 | ||||
-rw-r--r-- | sway/sway-bar.5.scd | 20 | ||||
-rw-r--r-- | swaybar/config.c | 20 | ||||
-rw-r--r-- | swaybar/i3bar.c | 25 | ||||
-rw-r--r-- | swaybar/input.c | 25 | ||||
-rw-r--r-- | swaybar/ipc.c | 12 | ||||
-rw-r--r-- | swaybar/tray/item.c | 15 |
19 files changed, 230 insertions, 144 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 68487879..7672a3fd 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -207,6 +207,7 @@ sway_cmd bar_cmd_pango_markup; | |||
207 | sway_cmd bar_cmd_strip_workspace_numbers; | 207 | sway_cmd bar_cmd_strip_workspace_numbers; |
208 | sway_cmd bar_cmd_strip_workspace_name; | 208 | sway_cmd bar_cmd_strip_workspace_name; |
209 | sway_cmd bar_cmd_swaybar_command; | 209 | sway_cmd bar_cmd_swaybar_command; |
210 | sway_cmd bar_cmd_tray_bindcode; | ||
210 | sway_cmd bar_cmd_tray_bindsym; | 211 | sway_cmd bar_cmd_tray_bindsym; |
211 | sway_cmd bar_cmd_tray_output; | 212 | sway_cmd bar_cmd_tray_output; |
212 | sway_cmd bar_cmd_tray_padding; | 213 | sway_cmd bar_cmd_tray_padding; |
diff --git a/include/sway/config.h b/include/sway/config.h index 96fe899b..978606a6 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -260,7 +260,7 @@ struct bar_config { | |||
260 | 260 | ||
261 | #if HAVE_TRAY | 261 | #if HAVE_TRAY |
262 | char *icon_theme; | 262 | char *icon_theme; |
263 | const char *tray_bindings[10]; // mouse buttons 0-9 | 263 | struct wl_list tray_bindings; // struct tray_binding::link |
264 | list_t *tray_outputs; // char * | 264 | list_t *tray_outputs; // char * |
265 | int tray_padding; | 265 | int tray_padding; |
266 | #endif | 266 | #endif |
@@ -272,6 +272,14 @@ struct bar_binding { | |||
272 | char *command; | 272 | char *command; |
273 | }; | 273 | }; |
274 | 274 | ||
275 | #if HAVE_TRAY | ||
276 | struct tray_binding { | ||
277 | uint32_t button; | ||
278 | const char *command; | ||
279 | struct wl_list link; // struct tray_binding::link | ||
280 | }; | ||
281 | #endif | ||
282 | |||
275 | struct border_colors { | 283 | struct border_colors { |
276 | float border[4]; | 284 | float border[4]; |
277 | float background[4]; | 285 | float background[4]; |
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 77aa0ea1..abd72783 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -103,4 +103,6 @@ uint32_t get_mouse_bindcode(const char *name, char **error); | |||
103 | // Considers both bindsym and bindcode | 103 | // Considers both bindsym and bindcode |
104 | uint32_t get_mouse_button(const char *name, char **error); | 104 | uint32_t get_mouse_button(const char *name, char **error); |
105 | 105 | ||
106 | const char *get_mouse_button_name(uint32_t button); | ||
107 | |||
106 | #endif | 108 | #endif |
diff --git a/include/swaybar/config.h b/include/swaybar/config.h index add0a1cf..ec042e51 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h | |||
@@ -70,13 +70,21 @@ struct swaybar_config { | |||
70 | 70 | ||
71 | #if HAVE_TRAY | 71 | #if HAVE_TRAY |
72 | char *icon_theme; | 72 | char *icon_theme; |
73 | char *tray_bindings[10]; // mouse buttons 0-9 | 73 | struct wl_list tray_bindings; // struct tray_binding::link |
74 | bool tray_hidden; | 74 | bool tray_hidden; |
75 | list_t *tray_outputs; // char * | 75 | list_t *tray_outputs; // char * |
76 | int tray_padding; | 76 | int tray_padding; |
77 | #endif | 77 | #endif |
78 | }; | 78 | }; |
79 | 79 | ||
80 | #if HAVE_TRAY | ||
81 | struct tray_binding { | ||
82 | uint32_t button; | ||
83 | char *command; | ||
84 | struct wl_list link; // struct tray_binding::link | ||
85 | }; | ||
86 | #endif | ||
87 | |||
80 | struct swaybar_config *init_config(void); | 88 | struct swaybar_config *init_config(void); |
81 | void free_config(struct swaybar_config *config); | 89 | void free_config(struct swaybar_config *config); |
82 | uint32_t parse_position(const char *position); | 90 | uint32_t parse_position(const char *position); |
diff --git a/include/swaybar/input.h b/include/swaybar/input.h index 4b46b0de..d76cd551 100644 --- a/include/swaybar/input.h +++ b/include/swaybar/input.h | |||
@@ -22,19 +22,6 @@ struct swaybar_pointer { | |||
22 | uint32_t serial; | 22 | uint32_t serial; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | enum x11_button { | ||
26 | NONE, | ||
27 | LEFT, | ||
28 | MIDDLE, | ||
29 | RIGHT, | ||
30 | SCROLL_UP, | ||
31 | SCROLL_DOWN, | ||
32 | SCROLL_LEFT, | ||
33 | SCROLL_RIGHT, | ||
34 | BACK, | ||
35 | FORWARD, | ||
36 | }; | ||
37 | |||
38 | enum hotspot_event_handling { | 25 | enum hotspot_event_handling { |
39 | HOTSPOT_IGNORE, | 26 | HOTSPOT_IGNORE, |
40 | HOTSPOT_PROCESS, | 27 | HOTSPOT_PROCESS, |
@@ -54,6 +41,8 @@ extern const struct wl_seat_listener seat_listener; | |||
54 | 41 | ||
55 | void update_cursor(struct swaybar *bar); | 42 | void update_cursor(struct swaybar *bar); |
56 | 43 | ||
44 | uint32_t event_to_x11_button(uint32_t event); | ||
45 | |||
57 | void free_hotspots(struct wl_list *list); | 46 | void free_hotspots(struct wl_list *list); |
58 | 47 | ||
59 | #endif | 48 | #endif |
diff --git a/sway/commands/bar.c b/sway/commands/bar.c index b19d9574..2cfc538f 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c | |||
@@ -28,6 +28,7 @@ static struct cmd_handler bar_handlers[] = { | |||
28 | { "status_padding", bar_cmd_status_padding }, | 28 | { "status_padding", bar_cmd_status_padding }, |
29 | { "strip_workspace_name", bar_cmd_strip_workspace_name }, | 29 | { "strip_workspace_name", bar_cmd_strip_workspace_name }, |
30 | { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, | 30 | { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, |
31 | { "tray_bindcode", bar_cmd_tray_bindcode }, | ||
31 | { "tray_bindsym", bar_cmd_tray_bindsym }, | 32 | { "tray_bindsym", bar_cmd_tray_bindsym }, |
32 | { "tray_output", bar_cmd_tray_output }, | 33 | { "tray_output", bar_cmd_tray_output }, |
33 | { "tray_padding", bar_cmd_tray_padding }, | 34 | { "tray_padding", bar_cmd_tray_padding }, |
diff --git a/sway/commands/bar/bind.c b/sway/commands/bar/bind.c index 71adced8..4b0be804 100644 --- a/sway/commands/bar/bind.c +++ b/sway/commands/bar/bind.c | |||
@@ -46,27 +46,7 @@ static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code) { | |||
46 | free_bar_binding(binding); | 46 | free_bar_binding(binding); |
47 | return cmd_results_new(CMD_INVALID, "Unknown button %s", argv[0]); | 47 | return cmd_results_new(CMD_INVALID, "Unknown button %s", argv[0]); |
48 | } | 48 | } |
49 | 49 | const char *name = get_mouse_button_name(binding->button); | |
50 | const char *name = libevdev_event_code_get_name(EV_KEY, binding->button); | ||
51 | if (!name) { | ||
52 | switch (binding->button) { | ||
53 | case SWAY_SCROLL_UP: | ||
54 | name = "SWAY_SCROLL_UP"; | ||
55 | break; | ||
56 | case SWAY_SCROLL_DOWN: | ||
57 | name = "SWAY_SCROLL_DOWN"; | ||
58 | break; | ||
59 | case SWAY_SCROLL_LEFT: | ||
60 | name = "SWAY_SCROLL_LEFT"; | ||
61 | break; | ||
62 | case SWAY_SCROLL_RIGHT: | ||
63 | name = "SWAY_SCROLL_RIGHT"; | ||
64 | break; | ||
65 | default: | ||
66 | // Unreachable | ||
67 | break; | ||
68 | } | ||
69 | } | ||
70 | 50 | ||
71 | binding->command = join_args(argv + 1, argc - 1); | 51 | binding->command = join_args(argv + 1, argc - 1); |
72 | 52 | ||
diff --git a/sway/commands/bar/tray_bind.c b/sway/commands/bar/tray_bind.c new file mode 100644 index 00000000..48a15462 --- /dev/null +++ b/sway/commands/bar/tray_bind.c | |||
@@ -0,0 +1,97 @@ | |||
1 | #include <strings.h> | ||
2 | #include "config.h" | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/input/cursor.h" | ||
6 | #include "log.h" | ||
7 | |||
8 | static struct cmd_results *tray_bind(int argc, char **argv, bool code) { | ||
9 | #if HAVE_TRAY | ||
10 | const char *command = code ? "bar tray_bindcode" : "bar tray_bindsym"; | ||
11 | struct cmd_results *error = NULL; | ||
12 | if ((error = checkarg(argc, command, EXPECTED_EQUAL_TO, 2))) { | ||
13 | return error; | ||
14 | } | ||
15 | if (!config->current_bar) { | ||
16 | return cmd_results_new(CMD_FAILURE, "No bar defined."); | ||
17 | } | ||
18 | |||
19 | struct tray_binding *binding = calloc(1, sizeof(struct tray_binding)); | ||
20 | if (!binding) { | ||
21 | return cmd_results_new(CMD_FAILURE, "Unable to allocate tray binding"); | ||
22 | } | ||
23 | |||
24 | char *message = NULL; | ||
25 | if (code) { | ||
26 | binding->button = get_mouse_bindcode(argv[0], &message); | ||
27 | } else { | ||
28 | binding->button = get_mouse_bindsym(argv[0], &message); | ||
29 | } | ||
30 | if (message) { | ||
31 | free(binding); | ||
32 | error = cmd_results_new(CMD_INVALID, message); | ||
33 | free(message); | ||
34 | return error; | ||
35 | } else if (!binding->button) { | ||
36 | free(binding); | ||
37 | return cmd_results_new(CMD_INVALID, "Unknown button %s", argv[0]); | ||
38 | } | ||
39 | const char *name = get_mouse_button_name(binding->button); | ||
40 | |||
41 | static const char *commands[] = { | ||
42 | "ContextMenu", | ||
43 | "Activate", | ||
44 | "SecondaryActivate", | ||
45 | "ScrollDown", | ||
46 | "ScrollLeft", | ||
47 | "ScrollRight", | ||
48 | "ScrollUp", | ||
49 | "nop" | ||
50 | }; | ||
51 | |||
52 | for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) { | ||
53 | if (strcasecmp(argv[1], commands[i]) == 0) { | ||
54 | binding->command = commands[i]; | ||
55 | } | ||
56 | } | ||
57 | if (!binding->command) { | ||
58 | return cmd_results_new(CMD_INVALID, "[Bar %s] Invalid tray command %s", | ||
59 | config->current_bar->id, argv[1]); | ||
60 | } | ||
61 | |||
62 | bool overwritten = false; | ||
63 | struct tray_binding *other = NULL; | ||
64 | wl_list_for_each(other, &config->current_bar->tray_bindings, link) { | ||
65 | if (other->button == binding->button) { | ||
66 | overwritten = true; | ||
67 | other->command = binding->command; | ||
68 | free(binding); | ||
69 | binding = other; | ||
70 | wlr_log(WLR_DEBUG, | ||
71 | "[bar %s] Updated tray binding for %u (%s) to %s", | ||
72 | config->current_bar->id, binding->button, name, | ||
73 | binding->command); | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | if (!overwritten) { | ||
78 | wl_list_insert(&config->current_bar->tray_bindings, &binding->link); | ||
79 | wlr_log(WLR_DEBUG, "[bar %s] Added tray binding for %u (%s) to %s", | ||
80 | config->current_bar->id, binding->button, name, | ||
81 | binding->command); | ||
82 | } | ||
83 | |||
84 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
85 | #else | ||
86 | return cmd_results_new(CMD_INVALID, | ||
87 | "Sway has been compiled without tray support"); | ||
88 | #endif | ||
89 | } | ||
90 | |||
91 | struct cmd_results *bar_cmd_tray_bindcode(int argc, char **argv) { | ||
92 | return tray_bind(argc, argv, true); | ||
93 | } | ||
94 | |||
95 | struct cmd_results *bar_cmd_tray_bindsym(int argc, char **argv) { | ||
96 | return tray_bind(argc, argv, false); | ||
97 | } | ||
diff --git a/sway/commands/bar/tray_bindsym.c b/sway/commands/bar/tray_bindsym.c deleted file mode 100644 index 4e57e35e..00000000 --- a/sway/commands/bar/tray_bindsym.c +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | #include <strings.h> | ||
2 | #include "config.h" | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | #include "log.h" | ||
6 | |||
7 | struct cmd_results *bar_cmd_tray_bindsym(int argc, char **argv) { | ||
8 | #if HAVE_TRAY | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "tray_bindsym", EXPECTED_EQUAL_TO, 2))) { | ||
11 | return error; | ||
12 | } | ||
13 | |||
14 | if (!config->current_bar) { | ||
15 | return cmd_results_new(CMD_FAILURE, "No bar defined."); | ||
16 | } | ||
17 | |||
18 | int button = 0; | ||
19 | if (strncasecmp(argv[0], "button", strlen("button")) == 0 && | ||
20 | strlen(argv[0]) == strlen("button0")) { | ||
21 | button = argv[0][strlen("button")] - '0'; | ||
22 | } | ||
23 | if (button < 1 || button > 9) { | ||
24 | return cmd_results_new(CMD_FAILURE, | ||
25 | "[Bar %s] Only buttons 1 to 9 are supported", | ||
26 | config->current_bar->id); | ||
27 | } | ||
28 | |||
29 | static const char *commands[] = { | ||
30 | "ContextMenu", | ||
31 | "Activate", | ||
32 | "SecondaryActivate", | ||
33 | "ScrollDown", | ||
34 | "ScrollLeft", | ||
35 | "ScrollRight", | ||
36 | "ScrollUp", | ||
37 | "nop" | ||
38 | }; | ||
39 | |||
40 | for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) { | ||
41 | if (strcasecmp(argv[1], commands[i]) == 0) { | ||
42 | wlr_log(WLR_DEBUG, "[Bar %s] Binding button %d to %s", | ||
43 | config->current_bar->id, button, commands[i]); | ||
44 | config->current_bar->tray_bindings[button] = commands[i]; | ||
45 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | return cmd_results_new(CMD_INVALID, | ||
50 | "[Bar %s] Invalid command %s", config->current_bar->id, argv[1]); | ||
51 | #else | ||
52 | return cmd_results_new(CMD_INVALID, | ||
53 | "Sway has been compiled without tray support"); | ||
54 | #endif | ||
55 | } | ||
diff --git a/sway/config/bar.c b/sway/config/bar.c index 701bf051..b1aa2313 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c | |||
@@ -81,6 +81,12 @@ void free_bar_config(struct bar_config *bar) { | |||
81 | #if HAVE_TRAY | 81 | #if HAVE_TRAY |
82 | list_free_items_and_destroy(bar->tray_outputs); | 82 | list_free_items_and_destroy(bar->tray_outputs); |
83 | free(bar->icon_theme); | 83 | free(bar->icon_theme); |
84 | |||
85 | struct tray_binding *tray_bind = NULL, *tmp_tray_bind = NULL; | ||
86 | wl_list_for_each_safe(tray_bind, tmp_tray_bind, &bar->tray_bindings, link) { | ||
87 | wl_list_remove(&tray_bind->link); | ||
88 | free(tray_bind); | ||
89 | } | ||
84 | #endif | 90 | #endif |
85 | free(bar); | 91 | free(bar); |
86 | } | 92 | } |
@@ -174,6 +180,7 @@ struct bar_config *default_bar_config(void) { | |||
174 | 180 | ||
175 | #if HAVE_TRAY | 181 | #if HAVE_TRAY |
176 | bar->tray_padding = 2; | 182 | bar->tray_padding = 2; |
183 | wl_list_init(&bar->tray_bindings); | ||
177 | #endif | 184 | #endif |
178 | 185 | ||
179 | list_add(config->bars, bar); | 186 | list_add(config->bars, bar); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 731e82ad..5eb44412 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -1237,3 +1237,19 @@ uint32_t get_mouse_button(const char *name, char **error) { | |||
1237 | } | 1237 | } |
1238 | return button; | 1238 | return button; |
1239 | } | 1239 | } |
1240 | |||
1241 | const char *get_mouse_button_name(uint32_t button) { | ||
1242 | const char *name = libevdev_event_code_get_name(EV_KEY, button); | ||
1243 | if (!name) { | ||
1244 | if (button == SWAY_SCROLL_UP) { | ||
1245 | name = "SWAY_SCROLL_UP"; | ||
1246 | } else if (button == SWAY_SCROLL_DOWN) { | ||
1247 | name = "SWAY_SCROLL_DOWN"; | ||
1248 | } else if (button == SWAY_SCROLL_LEFT) { | ||
1249 | name = "SWAY_SCROLL_LEFT"; | ||
1250 | } else if (button == SWAY_SCROLL_RIGHT) { | ||
1251 | name = "SWAY_SCROLL_RIGHT"; | ||
1252 | } | ||
1253 | } | ||
1254 | return name; | ||
1255 | } | ||
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 6e5ba4fd..d72fc5db 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -852,15 +852,16 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { | |||
852 | } | 852 | } |
853 | 853 | ||
854 | json_object *tray_bindings = json_object_new_array(); | 854 | json_object *tray_bindings = json_object_new_array(); |
855 | for (int i = 0; i < 10; ++i) { | 855 | struct tray_binding *tray_bind = NULL; |
856 | if (bar->tray_bindings[i]) { | 856 | wl_list_for_each(tray_bind, &bar->tray_bindings, link) { |
857 | json_object *bind = json_object_new_object(); | 857 | json_object *bind = json_object_new_object(); |
858 | json_object_object_add(bind, "input_code", | 858 | json_object_object_add(bind, "input_code", |
859 | json_object_new_int(i)); | 859 | json_object_new_int(event_to_x11_button(tray_bind->button))); |
860 | json_object_object_add(bind, "command", | 860 | json_object_object_add(bind, "event_code", |
861 | json_object_new_string(bar->tray_bindings[i])); | 861 | json_object_new_int(tray_bind->button)); |
862 | json_object_array_add(tray_bindings, bind); | 862 | json_object_object_add(bind, "command", |
863 | } | 863 | json_object_new_string(tray_bind->command)); |
864 | json_object_array_add(tray_bindings, bind); | ||
864 | } | 865 | } |
865 | if (json_object_array_length(tray_bindings) > 0) { | 866 | if (json_object_array_length(tray_bindings) > 0) { |
866 | json_object_object_add(json, "tray_bindings", tray_bindings); | 867 | json_object_object_add(json, "tray_bindings", tray_bindings); |
diff --git a/sway/meson.build b/sway/meson.build index c2ed6298..0a08ee74 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -127,7 +127,7 @@ sway_sources = files( | |||
127 | 'commands/bar/strip_workspace_numbers.c', | 127 | 'commands/bar/strip_workspace_numbers.c', |
128 | 'commands/bar/strip_workspace_name.c', | 128 | 'commands/bar/strip_workspace_name.c', |
129 | 'commands/bar/swaybar_command.c', | 129 | 'commands/bar/swaybar_command.c', |
130 | 'commands/bar/tray_bindsym.c', | 130 | 'commands/bar/tray_bind.c', |
131 | 'commands/bar/tray_output.c', | 131 | 'commands/bar/tray_output.c', |
132 | 'commands/bar/tray_padding.c', | 132 | 'commands/bar/tray_padding.c', |
133 | 'commands/bar/workspace_buttons.c', | 133 | 'commands/bar/workspace_buttons.c', |
diff --git a/sway/sway-bar.5.scd b/sway/sway-bar.5.scd index 3f6b4298..9a6397e3 100644 --- a/sway/sway-bar.5.scd +++ b/sway/sway-bar.5.scd | |||
@@ -115,13 +115,19 @@ Sway allows configuring swaybar in the sway configuration file. | |||
115 | Swaybar provides a system tray where third-party applications may place icons. | 115 | Swaybar provides a system tray where third-party applications may place icons. |
116 | The following commands configure the tray. | 116 | The following commands configure the tray. |
117 | 117 | ||
118 | The _button_ argument in all cases is a platform-specific button code. On Linux | 118 | *tray\_bindcode* <event-code> |
119 | you can find a list of these at linux/input-event-codes.h. | 119 | ContextMenu|Activate|SecondaryActivate|ScrollDown|ScrollLeft|ScrollRight|ScrollUp|nop |
120 | 120 | Executes the action when the mouse button has been pressed. The buttons can | |
121 | *tray\_bindsym* button<n> ContextMenu|Activate|SecondaryActivate|ScrollDown|ScrollLeft|ScrollRight|ScrollUp|nop | 121 | be given as an event code, which can be obtained from `libinput debug-events`. |
122 | Binds mouse button _n_ (1 to 9) to the specified action. Use the command | 122 | To disable the default behavior for a button, use the command _nop_. |
123 | _nop_ to disable the default action (Activate for button 1, ContextMenu for | 123 | |
124 | button 2 and SecondaryActivate for button 3). | 124 | *tray\_bindsym* button[1-9]|<event-name> |
125 | ContextMenu|Activate|SecondaryActivate|ScrollDown|ScrollLeft|ScrollRight|ScrollUp|nop | ||
126 | Executes the action when the mouse button has been pressed. The buttons can | ||
127 | be given as a x11 button number or an event name, which can be obtained | ||
128 | from `libinput debug-events`. Use the command _nop_ to disable the default | ||
129 | action (Activate for button1, ContextMenu for button2 and SecondaryActivate | ||
130 | for button3). | ||
125 | 131 | ||
126 | *tray\_padding* <px> [px] | 132 | *tray\_padding* <px> [px] |
127 | Sets the pixel padding of the system tray. This padding will surround the | 133 | Sets the pixel padding of the system tray. This padding will surround the |
diff --git a/swaybar/config.c b/swaybar/config.c index d4cc9b1a..0071c7f9 100644 --- a/swaybar/config.c +++ b/swaybar/config.c | |||
@@ -78,6 +78,7 @@ struct swaybar_config *init_config(void) { | |||
78 | 78 | ||
79 | #if HAVE_TRAY | 79 | #if HAVE_TRAY |
80 | config->tray_padding = 2; | 80 | config->tray_padding = 2; |
81 | wl_list_init(&config->tray_bindings); | ||
81 | #endif | 82 | #endif |
82 | 83 | ||
83 | return config; | 84 | return config; |
@@ -91,6 +92,16 @@ static void free_binding(struct swaybar_binding *binding) { | |||
91 | free(binding); | 92 | free(binding); |
92 | } | 93 | } |
93 | 94 | ||
95 | #if HAVE_TRAY | ||
96 | static void free_tray_binding(struct tray_binding *binding) { | ||
97 | if (!binding) { | ||
98 | return; | ||
99 | } | ||
100 | free(binding->command); | ||
101 | free(binding); | ||
102 | } | ||
103 | #endif | ||
104 | |||
94 | void free_config(struct swaybar_config *config) { | 105 | void free_config(struct swaybar_config *config) { |
95 | free(config->status_command); | 106 | free(config->status_command); |
96 | free(config->font); | 107 | free(config->font); |
@@ -111,9 +122,14 @@ void free_config(struct swaybar_config *config) { | |||
111 | } | 122 | } |
112 | #if HAVE_TRAY | 123 | #if HAVE_TRAY |
113 | list_free_items_and_destroy(config->tray_outputs); | 124 | list_free_items_and_destroy(config->tray_outputs); |
114 | for (int i = 0; i < 10; ++i) { | 125 | |
115 | free(config->tray_bindings[i]); | 126 | struct tray_binding *tray_bind = NULL, *tmp_tray_bind = NULL; |
127 | wl_list_for_each_safe(tray_bind, tmp_tray_bind, &config->tray_bindings, | ||
128 | link) { | ||
129 | wl_list_remove(&tray_bind->link); | ||
130 | free_tray_binding(tray_bind); | ||
116 | } | 131 | } |
132 | |||
117 | free(config->icon_theme); | 133 | free(config->icon_theme); |
118 | #endif | 134 | #endif |
119 | free(config); | 135 | free(config); |
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 116c8f6e..8bca1bf9 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c | |||
@@ -259,31 +259,6 @@ bool i3bar_handle_readable(struct status_line *status) { | |||
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | static uint32_t event_to_x11_button(uint32_t event) { | ||
263 | switch (event) { | ||
264 | case BTN_LEFT: | ||
265 | return 1; | ||
266 | case BTN_MIDDLE: | ||
267 | return 2; | ||
268 | case BTN_RIGHT: | ||
269 | return 3; | ||
270 | case SWAY_SCROLL_UP: | ||
271 | return 4; | ||
272 | case SWAY_SCROLL_DOWN: | ||
273 | return 5; | ||
274 | case SWAY_SCROLL_LEFT: | ||
275 | return 6; | ||
276 | case SWAY_SCROLL_RIGHT: | ||
277 | return 7; | ||
278 | case BTN_SIDE: | ||
279 | return 8; | ||
280 | case BTN_EXTRA: | ||
281 | return 9; | ||
282 | default: | ||
283 | return 0; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, | 262 | enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, |
288 | struct i3bar_block *block, int x, int y, int rx, int ry, int w, int h, | 263 | struct i3bar_block *block, int x, int y, int rx, int ry, int w, int h, |
289 | uint32_t button) { | 264 | uint32_t button) { |
diff --git a/swaybar/input.c b/swaybar/input.c index bdd55e58..998b186f 100644 --- a/swaybar/input.c +++ b/swaybar/input.c | |||
@@ -22,6 +22,31 @@ void free_hotspots(struct wl_list *list) { | |||
22 | } | 22 | } |
23 | } | 23 | } |
24 | 24 | ||
25 | uint32_t event_to_x11_button(uint32_t event) { | ||
26 | switch (event) { | ||
27 | case BTN_LEFT: | ||
28 | return 1; | ||
29 | case BTN_MIDDLE: | ||
30 | return 2; | ||
31 | case BTN_RIGHT: | ||
32 | return 3; | ||
33 | case SWAY_SCROLL_UP: | ||
34 | return 4; | ||
35 | case SWAY_SCROLL_DOWN: | ||
36 | return 5; | ||
37 | case SWAY_SCROLL_LEFT: | ||
38 | return 6; | ||
39 | case SWAY_SCROLL_RIGHT: | ||
40 | return 7; | ||
41 | case BTN_SIDE: | ||
42 | return 8; | ||
43 | case BTN_EXTRA: | ||
44 | return 9; | ||
45 | default: | ||
46 | return 0; | ||
47 | } | ||
48 | } | ||
49 | |||
25 | static uint32_t wl_axis_to_button(uint32_t axis, wl_fixed_t value) { | 50 | static uint32_t wl_axis_to_button(uint32_t axis, wl_fixed_t value) { |
26 | bool negative = wl_fixed_to_double(value) < 0; | 51 | bool negative = wl_fixed_to_double(value) < 0; |
27 | switch (axis) { | 52 | switch (axis) { |
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 097f9161..0dc39439 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -313,11 +313,13 @@ static bool ipc_parse_config( | |||
313 | int length = json_object_array_length(tray_bindings); | 313 | int length = json_object_array_length(tray_bindings); |
314 | for (int i = 0; i < length; ++i) { | 314 | for (int i = 0; i < length; ++i) { |
315 | json_object *bind = json_object_array_get_idx(tray_bindings, i); | 315 | json_object *bind = json_object_array_get_idx(tray_bindings, i); |
316 | json_object *button, *command; | 316 | struct tray_binding *binding = |
317 | json_object_object_get_ex(bind, "input_code", &button); | 317 | calloc(1, sizeof(struct tray_binding)); |
318 | json_object_object_get_ex(bind, "command", &command); | 318 | binding->button = json_object_get_int( |
319 | config->tray_bindings[json_object_get_int(button)] = | 319 | json_object_object_get(bind, "event_code")); |
320 | strdup(json_object_get_string(command)); | 320 | binding->command = strdup(json_object_get_string( |
321 | json_object_object_get(bind, "command"))); | ||
322 | wl_list_insert(&config->tray_bindings, &binding->link); | ||
321 | } | 323 | } |
322 | } | 324 | } |
323 | 325 | ||
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c index 0833dcb9..9056331e 100644 --- a/swaybar/tray/item.c +++ b/swaybar/tray/item.c | |||
@@ -301,8 +301,15 @@ void destroy_sni(struct swaybar_sni *sni) { | |||
301 | } | 301 | } |
302 | 302 | ||
303 | static void handle_click(struct swaybar_sni *sni, int x, int y, | 303 | static void handle_click(struct swaybar_sni *sni, int x, int y, |
304 | enum x11_button button, int delta) { | 304 | uint32_t button, int delta) { |
305 | const char *method = sni->tray->bar->config->tray_bindings[button]; | 305 | const char *method = NULL; |
306 | struct tray_binding *binding = NULL; | ||
307 | wl_list_for_each(binding, &sni->tray->bar->config->tray_bindings, link) { | ||
308 | if (binding->button == button) { | ||
309 | method = binding->command; | ||
310 | break; | ||
311 | } | ||
312 | } | ||
306 | if (!method) { | 313 | if (!method) { |
307 | static const char *default_bindings[10] = { | 314 | static const char *default_bindings[10] = { |
308 | "nop", | 315 | "nop", |
@@ -316,7 +323,7 @@ static void handle_click(struct swaybar_sni *sni, int x, int y, | |||
316 | "nop", | 323 | "nop", |
317 | "nop" | 324 | "nop" |
318 | }; | 325 | }; |
319 | method = default_bindings[button]; | 326 | method = default_bindings[event_to_x11_button(button)]; |
320 | } | 327 | } |
321 | if (strcmp(method, "nop") == 0) { | 328 | if (strcmp(method, "nop") == 0) { |
322 | return; | 329 | return; |
@@ -345,7 +352,7 @@ static int cmp_sni_id(const void *item, const void *cmp_to) { | |||
345 | 352 | ||
346 | static enum hotspot_event_handling icon_hotspot_callback( | 353 | static enum hotspot_event_handling icon_hotspot_callback( |
347 | struct swaybar_output *output, struct swaybar_hotspot *hotspot, | 354 | struct swaybar_output *output, struct swaybar_hotspot *hotspot, |
348 | int x, int y, enum x11_button button, void *data) { | 355 | int x, int y, uint32_t button, void *data) { |
349 | wlr_log(WLR_DEBUG, "Clicked on %s", (char *)data); | 356 | wlr_log(WLR_DEBUG, "Clicked on %s", (char *)data); |
350 | 357 | ||
351 | struct swaybar_tray *tray = output->bar->tray; | 358 | struct swaybar_tray *tray = output->bar->tray; |