From 7727c9efbc105269befe06a5bb12d2019c52515e Mon Sep 17 00:00:00 2001
From: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Tue, 5 Jan 2016 00:49:11 +0100
Subject: [PATCH] Detect bar modifier pressed/released

---
 include/input_state.h | 20 ++++++++++++++++++++
 sway/config.c         |  2 +-
 sway/handlers.c       | 16 ++++++++++++++++
 sway/input_state.c    | 24 ++++++++++++++++++++++++
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/include/input_state.h b/include/input_state.h
index a1f238e1..79e27d91 100644
--- a/include/input_state.h
+++ b/include/input_state.h
@@ -60,6 +60,12 @@ extern struct pointer_state {
 	int mode;
 } pointer_state;
 
+enum modifier_state {
+	MOD_STATE_UNCHANGED = 0,
+	MOD_STATE_PRESSED = 1,
+	MOD_STATE_RELEASED = 2
+};
+
 void pointer_position_set(struct wlc_origin *new_origin, bool force_focus);
 void center_pointer_on(swayc_t *view);
 
@@ -75,5 +81,19 @@ void pointer_mode_reset(void);
 
 void input_init(void);
 
+/**
+ * Check if state of mod changed from current state to new_state.
+ *
+ * Returns MOD_STATE_UNCHANGED if the state didn't change, MOD_STATE_PRESSED if
+ * the state changed to pressed and MOD_STATE_RELEASED if the state changed to
+ * released.
+ */
+uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod);
+
+/**
+ * Update the current modifiers state to new_state.
+ */
+void modifiers_state_update(uint32_t new_state);
+
 #endif
 
diff --git a/sway/config.c b/sway/config.c
index 1973de02..87b1342d 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -695,7 +695,7 @@ struct bar_config *default_bar_config(void) {
 	bar = malloc(sizeof(struct bar_config));
 	bar->mode = strdup("dock");
 	bar->hidden_state = strdup("hide");
-	bar->modifier = 0;
+	bar->modifier = WLC_BIT_MOD_LOGO;
 	bar->outputs = NULL;
 	bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM;
 	bar->bindings = create_list();
diff --git a/sway/handlers.c b/sway/handlers.c
index 6c6d0e60..5e523468 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -387,6 +387,22 @@ 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];
+		switch (modifier_state_changed(modifiers->mods, bar->modifier)) {
+		case MOD_STATE_PRESSED:
+			sway_log(L_INFO, "pressed!!!");
+			break;
+		case MOD_STATE_RELEASED:
+			sway_log(L_INFO, "released!!!");
+			break;
+		}
+	}
+	// update modifiers state
+	modifiers_state_update(modifiers->mods);
 	return EVENT_PASSTHROUGH;
 }
 
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 {
 
 static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
 
+static uint32_t modifiers_state;
+
 void input_init(void) {
 	int i;
 	for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
 		struct key_state none = { 0, 0, 0 };
 		key_state_array[i] = none;
 	}
+
+	modifiers_state = 0;
+}
+
+uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod) {
+	if ((new_state & mod) != 0) { // pressed
+		if ((modifiers_state & mod) != 0) { // already pressed
+			return MOD_STATE_UNCHANGED;
+		} else { // pressed
+			return MOD_STATE_PRESSED;
+		}
+	} else { // not pressed
+		if ((modifiers_state & mod) != 0) { // released
+			return MOD_STATE_RELEASED;
+		} else { // already released
+			return MOD_STATE_UNCHANGED;
+		}
+	}
+}
+
+void modifiers_state_update(uint32_t new_state) {
+	modifiers_state = new_state;
 }
 
 static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {