diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 31 | ||||
-rw-r--r-- | swaybar/config.c | 16 | ||||
-rw-r--r-- | swaybar/ipc.c | 26 |
3 files changed, 73 insertions, 0 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index 3990f1ca..5b7fea71 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -144,6 +144,19 @@ static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, | |||
144 | bar->pointer.y = wl_fixed_to_int(surface_y); | 144 | bar->pointer.y = wl_fixed_to_int(surface_y); |
145 | } | 145 | } |
146 | 146 | ||
147 | static bool check_bindings(struct swaybar *bar, uint32_t x11_button, | ||
148 | uint32_t state) { | ||
149 | bool released = state == WL_POINTER_BUTTON_STATE_RELEASED; | ||
150 | for (int i = 0; i < bar->config->bindings->length; i++) { | ||
151 | struct swaybar_binding *binding = bar->config->bindings->items[i]; | ||
152 | if (binding->button == x11_button && binding->release == released) { | ||
153 | ipc_execute_binding(bar, binding); | ||
154 | return true; | ||
155 | } | ||
156 | } | ||
157 | return false; | ||
158 | } | ||
159 | |||
147 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | 160 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, |
148 | uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { | 161 | uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { |
149 | struct swaybar *bar = data; | 162 | struct swaybar *bar = data; |
@@ -152,6 +165,11 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | |||
152 | if (!sway_assert(output, "button with no active output")) { | 165 | if (!sway_assert(output, "button with no active output")) { |
153 | return; | 166 | return; |
154 | } | 167 | } |
168 | |||
169 | if (check_bindings(bar, wl_button_to_x11_button(button), state)) { | ||
170 | return; | ||
171 | } | ||
172 | |||
155 | if (state != WL_POINTER_BUTTON_STATE_PRESSED) { | 173 | if (state != WL_POINTER_BUTTON_STATE_PRESSED) { |
156 | return; | 174 | return; |
157 | } | 175 | } |
@@ -180,6 +198,15 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | |||
180 | return; | 198 | return; |
181 | } | 199 | } |
182 | 200 | ||
201 | // If there is a button press binding, execute it, skip default behavior, | ||
202 | // and check button release bindings | ||
203 | if (check_bindings(bar, wl_axis_to_x11_button(axis, value), | ||
204 | WL_POINTER_BUTTON_STATE_PRESSED)) { | ||
205 | check_bindings(bar, wl_axis_to_x11_button(axis, value), | ||
206 | WL_POINTER_BUTTON_STATE_RELEASED); | ||
207 | return; | ||
208 | } | ||
209 | |||
183 | struct swaybar_hotspot *hotspot; | 210 | struct swaybar_hotspot *hotspot; |
184 | wl_list_for_each(hotspot, &output->hotspots, link) { | 211 | wl_list_for_each(hotspot, &output->hotspots, link) { |
185 | double x = pointer->x * output->scale; | 212 | double x = pointer->x * output->scale; |
@@ -247,6 +274,10 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | |||
247 | } | 274 | } |
248 | 275 | ||
249 | ipc_send_workspace_command(bar, new->name); | 276 | ipc_send_workspace_command(bar, new->name); |
277 | |||
278 | // Check button release bindings | ||
279 | check_bindings(bar, wl_axis_to_x11_button(axis, value), | ||
280 | WL_POINTER_BUTTON_STATE_RELEASED); | ||
250 | } | 281 | } |
251 | 282 | ||
252 | static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { | 283 | static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { |
diff --git a/swaybar/config.c b/swaybar/config.c index 4e851cca..09d40c24 100644 --- a/swaybar/config.c +++ b/swaybar/config.c | |||
@@ -3,6 +3,8 @@ | |||
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include "swaybar/config.h" | 4 | #include "swaybar/config.h" |
5 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 5 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
6 | #include "stringop.h" | ||
7 | #include "list.h" | ||
6 | 8 | ||
7 | uint32_t parse_position(const char *position) { | 9 | uint32_t parse_position(const char *position) { |
8 | uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | | 10 | uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | |
@@ -34,6 +36,7 @@ struct swaybar_config *init_config(void) { | |||
34 | config->binding_mode_indicator = true; | 36 | config->binding_mode_indicator = true; |
35 | config->wrap_scroll = false; | 37 | config->wrap_scroll = false; |
36 | config->workspace_buttons = true; | 38 | config->workspace_buttons = true; |
39 | config->bindings = create_list(); | ||
37 | wl_list_init(&config->outputs); | 40 | wl_list_init(&config->outputs); |
38 | 41 | ||
39 | /* height */ | 42 | /* height */ |
@@ -69,11 +72,24 @@ struct swaybar_config *init_config(void) { | |||
69 | return config; | 72 | return config; |
70 | } | 73 | } |
71 | 74 | ||
75 | static void free_binding(struct swaybar_binding *binding) { | ||
76 | if (!binding) { | ||
77 | return; | ||
78 | } | ||
79 | free(binding->command); | ||
80 | free(binding); | ||
81 | } | ||
82 | |||
72 | void free_config(struct swaybar_config *config) { | 83 | void free_config(struct swaybar_config *config) { |
73 | free(config->status_command); | 84 | free(config->status_command); |
74 | free(config->font); | 85 | free(config->font); |
75 | free(config->mode); | 86 | free(config->mode); |
76 | free(config->sep_symbol); | 87 | free(config->sep_symbol); |
88 | for (int i = 0; i < config->bindings->length; i++) { | ||
89 | struct swaybar_binding *binding = config->bindings->items[i]; | ||
90 | free_binding(binding); | ||
91 | } | ||
92 | list_free(config->bindings); | ||
77 | struct config_output *coutput, *tmp; | 93 | struct config_output *coutput, *tmp; |
78 | wl_list_for_each_safe(coutput, tmp, &config->outputs, link) { | 94 | wl_list_for_each_safe(coutput, tmp, &config->outputs, link) { |
79 | wl_list_remove(&coutput->link); | 95 | wl_list_remove(&coutput->link); |
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 7c53a44f..a67814c1 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "swaybar/config.h" | 7 | #include "swaybar/config.h" |
8 | #include "swaybar/ipc.h" | 8 | #include "swaybar/ipc.h" |
9 | #include "ipc-client.h" | 9 | #include "ipc-client.h" |
10 | #include "list.h" | ||
10 | 11 | ||
11 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws) { | 12 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws) { |
12 | const char *fmt = "workspace \"%s\""; | 13 | const char *fmt = "workspace \"%s\""; |
@@ -154,6 +155,7 @@ static bool ipc_parse_config( | |||
154 | json_object *markup, *mode, *hidden_bar, *position, *status_command; | 155 | json_object *markup, *mode, *hidden_bar, *position, *status_command; |
155 | json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; | 156 | json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; |
156 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; | 157 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; |
158 | json_object *bindings; | ||
157 | json_object_object_get_ex(bar_config, "mode", &mode); | 159 | json_object_object_get_ex(bar_config, "mode", &mode); |
158 | json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); | 160 | json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); |
159 | json_object_object_get_ex(bar_config, "position", &position); | 161 | json_object_object_get_ex(bar_config, "position", &position); |
@@ -169,6 +171,7 @@ static bool ipc_parse_config( | |||
169 | json_object_object_get_ex(bar_config, "colors", &colors); | 171 | json_object_object_get_ex(bar_config, "colors", &colors); |
170 | json_object_object_get_ex(bar_config, "outputs", &outputs); | 172 | json_object_object_get_ex(bar_config, "outputs", &outputs); |
171 | json_object_object_get_ex(bar_config, "pango_markup", &markup); | 173 | json_object_object_get_ex(bar_config, "pango_markup", &markup); |
174 | json_object_object_get_ex(bar_config, "bindings", &bindings); | ||
172 | if (status_command) { | 175 | if (status_command) { |
173 | free(config->status_command); | 176 | free(config->status_command); |
174 | config->status_command = strdup(json_object_get_string(status_command)); | 177 | config->status_command = strdup(json_object_get_string(status_command)); |
@@ -202,6 +205,21 @@ static bool ipc_parse_config( | |||
202 | if (markup) { | 205 | if (markup) { |
203 | config->pango_markup = json_object_get_boolean(markup); | 206 | config->pango_markup = json_object_get_boolean(markup); |
204 | } | 207 | } |
208 | if (bindings) { | ||
209 | int length = json_object_array_length(bindings); | ||
210 | for (int i = 0; i < length; ++i) { | ||
211 | json_object *bindobj = json_object_array_get_idx(bindings, i); | ||
212 | struct swaybar_binding *binding = | ||
213 | calloc(1, sizeof(struct swaybar_binding)); | ||
214 | binding->button = json_object_get_int( | ||
215 | json_object_object_get(bindobj, "input_code")); | ||
216 | binding->command = strdup(json_object_get_string( | ||
217 | json_object_object_get(bindobj, "command"))); | ||
218 | binding->release = json_object_get_boolean( | ||
219 | json_object_object_get(bindobj, "release")); | ||
220 | list_add(config->bindings, binding); | ||
221 | } | ||
222 | } | ||
205 | 223 | ||
206 | struct config_output *output, *tmp; | 224 | struct config_output *output, *tmp; |
207 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { | 225 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { |
@@ -319,6 +337,14 @@ static void ipc_get_outputs(struct swaybar *bar) { | |||
319 | free(res); | 337 | free(res); |
320 | } | 338 | } |
321 | 339 | ||
340 | void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { | ||
341 | wlr_log(WLR_DEBUG, "Executing binding for button %u (release=%d): `%s`", | ||
342 | bind->button, bind->release, bind->command); | ||
343 | uint32_t len = strlen(bind->command); | ||
344 | free(ipc_single_command(bar->ipc_socketfd, | ||
345 | IPC_COMMAND, bind->command, &len)); | ||
346 | } | ||
347 | |||
322 | bool ipc_initialize(struct swaybar *bar, const char *bar_id) { | 348 | bool ipc_initialize(struct swaybar *bar, const char *bar_id) { |
323 | uint32_t len = strlen(bar_id); | 349 | uint32_t len = strlen(bar_id); |
324 | char *res = ipc_single_command(bar->ipc_socketfd, | 350 | char *res = ipc_single_command(bar->ipc_socketfd, |