From 843e2ad2c140288733110691f7dc8252fbe4dc16 Mon Sep 17 00:00:00 2001
From: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Tue, 5 Jan 2016 23:18:59 +0100
Subject: Only send modifier event once for active modifiers

This makes sure that a modifier event is only sent for active bar
modifiers, and that it is only sent once for each of those modifiers.

An active bar modifier is a modifier defined for a bar with `mode hide`
and `hidden_state hide`.
---
 sway/commands.c |  6 ++++++
 sway/config.c   | 31 +++++++++++++++++++++++++++++++
 sway/handlers.c | 23 +++++++++++------------
 3 files changed, 48 insertions(+), 12 deletions(-)

(limited to 'sway')

diff --git a/sway/commands.c b/sway/commands.c
index 963d8f12..3a4079e4 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -1751,6 +1751,9 @@ static struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
 		}
 	}
 
+	// active bar modifiers might have changed.
+	update_active_bar_modifiers();
+
 	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 }
 
@@ -1775,6 +1778,9 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
 	if (strcmp(old_mode, bar->mode) != 0) {
 		if (!config->reading) {
 			ipc_event_barconfig_update(bar);
+
+			// active bar modifiers might have changed.
+			update_active_bar_modifiers();
 		}
 		sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
 	}
diff --git a/sway/config.c b/sway/config.c
index 87b1342d..95d8f339 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -103,6 +103,8 @@ static void free_config(struct sway_config *config) {
 		free_output_config(config->output_configs->items[i]);
 	}
 	list_free(config->output_configs);
+
+	list_free(config->active_bar_modifiers);
 	free(config);
 }
 
@@ -145,6 +147,33 @@ static void config_defaults(struct sway_config *config) {
 	config->edge_gaps = true;
 	config->gaps_inner = 0;
 	config->gaps_outer = 0;
+
+	config->active_bar_modifiers = create_list();
+}
+
+static int compare_modifiers(const void *left, const void *right) {
+	uint32_t a = *(uint32_t *)left;
+	uint32_t b = *(uint32_t *)right;
+
+	return a - b;
+}
+
+void update_active_bar_modifiers() {
+	if (config->active_bar_modifiers->length > 0) {
+		list_free(config->active_bar_modifiers);
+		config->active_bar_modifiers = create_list();
+	}
+
+	struct bar_config *bar;
+	int i;
+	for (i = 0; i < config->bars->length; ++i) {
+		bar = config->bars->items[i];
+		if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) {
+			if (list_seq_find(config->active_bar_modifiers, compare_modifiers, &bar->modifier) < 0) {
+				list_add(config->active_bar_modifiers, &bar->modifier);
+			}
+		}
+	}
 }
 
 static char *get_config_path(void) {
@@ -215,6 +244,8 @@ bool load_config(const char *file) {
 	}
 	fclose(f);
 
+	update_active_bar_modifiers();
+
 	return config_load_success;
 }
 
diff --git a/sway/handlers.c b/sway/handlers.c
index 4cbec0ab..db3a0206 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -390,18 +390,17 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
 	}
 
 	// handle bar modifiers pressed/released
-	struct bar_config *bar;
-	for (i = 0; i < config->bars->length; ++i) {
-		bar = config->bars->items[i];
-		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;
-			}
+	uint32_t modifier;
+	for (i = 0; i < config->active_bar_modifiers->length; ++i) {
+		modifier = *(uint32_t *)config->active_bar_modifiers->items[i];
+
+		switch (modifier_state_changed(modifiers->mods, modifier)) {
+		case MOD_STATE_PRESSED:
+			ipc_event_modifier(modifier, "pressed");
+			break;
+		case MOD_STATE_RELEASED:
+			ipc_event_modifier(modifier, "released");
+			break;
 		}
 	}
 	// update modifiers state
-- 
cgit v1.2.3