From 1c969e86f50065985ddf35b7fef62c14aa7688a5 Mon Sep 17 00:00:00 2001
From: Brian Ashworth <bosrsf04@gmail.com>
Date: Mon, 8 Oct 2018 11:40:13 -0400
Subject: Implement bar bindsym

---
 swaybar/bar.c    | 26 ++++++++++++++++++++++++++
 swaybar/config.c | 10 ++++++++++
 swaybar/ipc.c    | 24 ++++++++++++++++++++++++
 3 files changed, 60 insertions(+)

(limited to 'swaybar')

diff --git a/swaybar/bar.c b/swaybar/bar.c
index 3990f1ca..3eeec5d4 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -144,6 +144,22 @@ static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
 	bar->pointer.y = wl_fixed_to_int(surface_y);
 }
 
+static bool check_bindings(struct swaybar *bar, uint32_t x11_button,
+		uint32_t state) {
+	bool released = state == WL_POINTER_BUTTON_STATE_RELEASED;
+	for (int i = 0; i < bar->config->bindings->length; i++) {
+		struct swaybar_binding *binding = bar->config->bindings->items[i];
+		wlr_log(WLR_DEBUG, "Checking [%u, %d] against [%u, %d, %s]",
+				x11_button, released,
+				binding->button, binding->release, binding->command);
+		if (binding->button == x11_button && binding->release == released) {
+			ipc_execute_binding(bar, binding);
+			return true;
+		}
+	}
+	return false;
+}
+
 static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
 		uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
 	struct swaybar *bar = data;
@@ -152,6 +168,11 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
 	if (!sway_assert(output, "button with no active output")) {
 		return;
 	}
+
+	if (check_bindings(bar, wl_button_to_x11_button(button), state)) {
+		return;
+	}
+
 	if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
 		return;
 	}
@@ -180,6 +201,11 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
 		return;
 	}
 
+	if (check_bindings(bar, wl_axis_to_x11_button(axis, value),
+				WL_POINTER_BUTTON_STATE_PRESSED)) {
+		return;
+	}
+
 	struct swaybar_hotspot *hotspot;
 	wl_list_for_each(hotspot, &output->hotspots, link) {
 		double x = pointer->x * output->scale;
diff --git a/swaybar/config.c b/swaybar/config.c
index 4e851cca..c646fe66 100644
--- a/swaybar/config.c
+++ b/swaybar/config.c
@@ -3,6 +3,8 @@
 #include <string.h>
 #include "swaybar/config.h"
 #include "wlr-layer-shell-unstable-v1-client-protocol.h"
+#include "stringop.h"
+#include "list.h"
 
 uint32_t parse_position(const char *position) {
 	uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
@@ -34,6 +36,7 @@ struct swaybar_config *init_config(void) {
 	config->binding_mode_indicator = true;
 	config->wrap_scroll = false;
 	config->workspace_buttons = true;
+	config->bindings = create_list();
 	wl_list_init(&config->outputs);
 
 	/* height */
@@ -74,6 +77,13 @@ void free_config(struct swaybar_config *config) {
 	free(config->font);
 	free(config->mode);
 	free(config->sep_symbol);
+	while (config->bindings->length) {
+		struct swaybar_binding *binding = config->bindings->items[0];
+		list_del(config->bindings, 0);
+		free(binding->command);
+		free(binding);
+	}
+	list_free(config->bindings);
 	struct config_output *coutput, *tmp;
 	wl_list_for_each_safe(coutput, tmp, &config->outputs, link) {
 		wl_list_remove(&coutput->link);
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
index 7c53a44f..70086a36 100644
--- a/swaybar/ipc.c
+++ b/swaybar/ipc.c
@@ -7,6 +7,7 @@
 #include "swaybar/config.h"
 #include "swaybar/ipc.h"
 #include "ipc-client.h"
+#include "list.h"
 
 void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
 	const char *fmt = "workspace \"%s\"";
@@ -154,6 +155,7 @@ static bool ipc_parse_config(
 	json_object *markup, *mode, *hidden_bar, *position, *status_command;
 	json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
 	json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
+	json_object *bindings;
 	json_object_object_get_ex(bar_config, "mode", &mode);
 	json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar);
 	json_object_object_get_ex(bar_config, "position", &position);
@@ -169,6 +171,7 @@ static bool ipc_parse_config(
 	json_object_object_get_ex(bar_config, "colors", &colors);
 	json_object_object_get_ex(bar_config, "outputs", &outputs);
 	json_object_object_get_ex(bar_config, "pango_markup", &markup);
+	json_object_object_get_ex(bar_config, "bindings", &bindings);
 	if (status_command) {
 		free(config->status_command);
 		config->status_command = strdup(json_object_get_string(status_command));
@@ -202,6 +205,21 @@ static bool ipc_parse_config(
 	if (markup) {
 		config->pango_markup = json_object_get_boolean(markup);
 	}
+	if (bindings) {
+		int length = json_object_array_length(bindings);
+		for (int i = 0; i < length; ++i) {
+			json_object *bindobj = json_object_array_get_idx(bindings, i);
+			struct swaybar_binding *binding =
+				calloc(1, sizeof(struct swaybar_binding));
+			binding->button = json_object_get_int(
+					json_object_object_get(bindobj, "input_code"));
+			binding->command = strdup(json_object_get_string(
+					json_object_object_get(bindobj, "command")));
+			binding->release = json_object_get_boolean(
+					json_object_object_get(bindobj, "release"));
+			list_add(config->bindings, binding);
+		}
+	}
 
 	struct config_output *output, *tmp;
 	wl_list_for_each_safe(output, tmp, &config->outputs, link) {
@@ -319,6 +337,12 @@ static void ipc_get_outputs(struct swaybar *bar) {
 	free(res);
 }
 
+void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
+	uint32_t len = strlen(bind->command);
+	free(ipc_single_command(bar->ipc_socketfd,
+			IPC_COMMAND, bind->command, &len));
+}
+
 bool ipc_initialize(struct swaybar *bar, const char *bar_id) {
 	uint32_t len = strlen(bar_id);
 	char *res = ipc_single_command(bar->ipc_socketfd,
-- 
cgit v1.2.3