mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master' into atomic
This commit is contained in:
		
						commit
						645bf446fa
					
				
					 7 changed files with 142 additions and 118 deletions
				
			
		| 
						 | 
					@ -144,5 +144,6 @@ struct pool_buffer *get_next_buffer(struct wl_shm *shm,
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						buffer->busy = true;
 | 
				
			||||||
	return buffer;
 | 
						return buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ struct sway_binding {
 | 
				
			||||||
	bool release;
 | 
						bool release;
 | 
				
			||||||
	bool locked;
 | 
						bool locked;
 | 
				
			||||||
	bool bindcode;
 | 
						bool bindcode;
 | 
				
			||||||
	list_t *keys;
 | 
						list_t *keys; // sorted in ascending order
 | 
				
			||||||
	uint32_t modifiers;
 | 
						uint32_t modifiers;
 | 
				
			||||||
	char *command;
 | 
						char *command;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,9 @@ struct sway_shortcut_state {
 | 
				
			||||||
	 * including duplicates when a keycode generates multiple key ids.
 | 
						 * including duplicates when a keycode generates multiple key ids.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	uint32_t pressed_keycodes[SWAY_KEYBOARD_PRESSED_KEYS_CAP];
 | 
						uint32_t pressed_keycodes[SWAY_KEYBOARD_PRESSED_KEYS_CAP];
 | 
				
			||||||
	int last_key_index;
 | 
						uint32_t last_keycode;
 | 
				
			||||||
 | 
						uint32_t last_raw_modifiers;
 | 
				
			||||||
 | 
						size_t npressed;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_keyboard {
 | 
					struct sway_keyboard {
 | 
				
			||||||
| 
						 | 
					@ -36,7 +38,6 @@ struct sway_keyboard {
 | 
				
			||||||
	struct sway_shortcut_state state_keysyms_raw;
 | 
						struct sway_shortcut_state state_keysyms_raw;
 | 
				
			||||||
	struct sway_shortcut_state state_keycodes;
 | 
						struct sway_shortcut_state state_keycodes;
 | 
				
			||||||
	struct sway_binding *held_binding;
 | 
						struct sway_binding *held_binding;
 | 
				
			||||||
	uint32_t last_modifiers;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
					struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ void free_sway_binding(struct sway_binding *binding) {
 | 
				
			||||||
 * Note that keyboard layout is not considered, so the bindings might actually
 | 
					 * Note that keyboard layout is not considered, so the bindings might actually
 | 
				
			||||||
 * not be equivalent on some layouts.
 | 
					 * not be equivalent on some layouts.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool binding_key_compare(struct sway_binding *binding_a,
 | 
					static bool binding_key_compare(struct sway_binding *binding_a,
 | 
				
			||||||
		struct sway_binding *binding_b) {
 | 
							struct sway_binding *binding_b) {
 | 
				
			||||||
	if (binding_a->release != binding_b->release) {
 | 
						if (binding_a->release != binding_b->release) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -50,18 +50,12 @@ bool binding_key_compare(struct sway_binding *binding_a,
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Keys are sorted
 | 
				
			||||||
	int keys_len = binding_a->keys->length;
 | 
						int keys_len = binding_a->keys->length;
 | 
				
			||||||
	for (int i = 0; i < keys_len; ++i) {
 | 
						for (int i = 0; i < keys_len; ++i) {
 | 
				
			||||||
		uint32_t key_a = *(uint32_t*)binding_a->keys->items[i];
 | 
							uint32_t key_a = *(uint32_t *)binding_a->keys->items[i];
 | 
				
			||||||
		bool found = false;
 | 
							uint32_t key_b = *(uint32_t *)binding_b->keys->items[i];
 | 
				
			||||||
		for (int j = 0; j < keys_len; ++j) {
 | 
							if (key_a != key_b) {
 | 
				
			||||||
			uint32_t key_b = *(uint32_t*)binding_b->keys->items[j];
 | 
					 | 
				
			||||||
			if (key_b == key_a) {
 | 
					 | 
				
			||||||
				found = true;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (!found) {
 | 
					 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -69,6 +63,12 @@ bool binding_key_compare(struct sway_binding *binding_a,
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) {
 | 
				
			||||||
 | 
						uint32_t key_a = **(uint32_t **)keyp_a;
 | 
				
			||||||
 | 
						uint32_t key_b = **(uint32_t **)keyp_b;
 | 
				
			||||||
 | 
						return (key_a < key_b) ? -1 : ((key_a > key_b) ? 1 : 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
					static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
				
			||||||
		bool bindcode) {
 | 
							bool bindcode) {
 | 
				
			||||||
	const char *bindtype = bindcode ? "bindcode" : "bindsym";
 | 
						const char *bindtype = bindcode ? "bindcode" : "bindsym";
 | 
				
			||||||
| 
						 | 
					@ -169,6 +169,9 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
				
			||||||
	free_flat_list(split);
 | 
						free_flat_list(split);
 | 
				
			||||||
	binding->order = binding_order++;
 | 
						binding->order = binding_order++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// sort ascending
 | 
				
			||||||
 | 
						list_qsort(binding->keys, key_qsort_cmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_t *mode_bindings;
 | 
						list_t *mode_bindings;
 | 
				
			||||||
	if (bindcode) {
 | 
						if (bindcode) {
 | 
				
			||||||
		mode_bindings = config->current_mode->keycode_bindings;
 | 
							mode_bindings = config->current_mode->keycode_bindings;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -285,10 +285,10 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
 | 
				
			||||||
		intersects = get_view_box(&data->root_geo, data->output, data->view,
 | 
							intersects = get_view_box(&data->root_geo, data->output, data->view,
 | 
				
			||||||
				sx, sy, &box);
 | 
									sx, sy, &box);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (!wlr_surface_has_buffer(surface)) {
 | 
							texture = wlr_surface_get_texture(surface);
 | 
				
			||||||
 | 
							if (texture == NULL) {
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		texture = surface->texture;
 | 
					 | 
				
			||||||
		intersects = get_surface_box(&data->root_geo, data->output, surface,
 | 
							intersects = get_surface_box(&data->root_geo, data->output, surface,
 | 
				
			||||||
				sx, sy, &box);
 | 
									sx, sy, &box);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,85 +10,111 @@
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Update the shortcut model state in response to new input
 | 
					 * Remove all key ids associated to a keycode from the list of pressed keys
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void update_shortcut_state(struct sway_shortcut_state *state,
 | 
					static void state_erase_key(struct sway_shortcut_state *state,
 | 
				
			||||||
		struct wlr_event_keyboard_key *event, uint32_t new_key,
 | 
							uint32_t keycode) {
 | 
				
			||||||
		bool last_key_was_a_modifier) {
 | 
						size_t j = 0;
 | 
				
			||||||
	if (event->state == WLR_KEY_PRESSED) {
 | 
						for (size_t i = 0; i < state->npressed; ++i) {
 | 
				
			||||||
		if (last_key_was_a_modifier && state->last_key_index >= 0) {
 | 
							if (i > j) {
 | 
				
			||||||
			// Last pressed key before this one was a modifier
 | 
								state->pressed_keys[j] = state->pressed_keys[i];
 | 
				
			||||||
			state->pressed_keycodes[state->last_key_index] = 0;
 | 
								state->pressed_keycodes[j] = state->pressed_keycodes[i];
 | 
				
			||||||
			state->pressed_keys[state->last_key_index] = 0;
 | 
					 | 
				
			||||||
			state->last_key_index = -1;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (state->pressed_keycodes[i] != keycode) {
 | 
				
			||||||
		// Add current key to set; there may be duplicates
 | 
								++j;
 | 
				
			||||||
		for (size_t i = 0; i < SWAY_KEYBOARD_PRESSED_KEYS_CAP; ++i) {
 | 
					 | 
				
			||||||
			if (!state->pressed_keys[i]) {
 | 
					 | 
				
			||||||
				state->pressed_keys[i] = new_key;
 | 
					 | 
				
			||||||
				state->pressed_keycodes[i] = event->keycode;
 | 
					 | 
				
			||||||
				state->last_key_index = i;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		for (size_t i = 0; i < SWAY_KEYBOARD_PRESSED_KEYS_CAP; ++i) {
 | 
					 | 
				
			||||||
			// The same keycode may match multiple keysyms.
 | 
					 | 
				
			||||||
			if (state->pressed_keycodes[i] == event->keycode) {
 | 
					 | 
				
			||||||
				state->pressed_keys[i] = 0;
 | 
					 | 
				
			||||||
				state->pressed_keycodes[i] = 0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						while(state->npressed > j) {
 | 
				
			||||||
 | 
							--state->npressed;
 | 
				
			||||||
 | 
							state->pressed_keys[state->npressed] = 0;
 | 
				
			||||||
 | 
							state->pressed_keycodes[state->npressed] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 * Add a key id (with associated keycode) to the list of pressed keys,
 | 
				
			||||||
 * Returns a binding which matches the shortcut model state (ignoring the
 | 
					 * if the list is not full.
 | 
				
			||||||
 * `release` flag).
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static struct sway_binding *get_active_binding(
 | 
					static void state_add_key(struct sway_shortcut_state *state,
 | 
				
			||||||
		struct sway_shortcut_state *state, list_t *bindings,
 | 
							uint32_t keycode, uint32_t key_id) {
 | 
				
			||||||
		uint32_t modifiers, bool locked) {
 | 
						if (state->npressed >= SWAY_KEYBOARD_PRESSED_KEYS_CAP) {
 | 
				
			||||||
	int npressed_keys = 0;
 | 
							return;
 | 
				
			||||||
	for (size_t i = 0; i < SWAY_KEYBOARD_PRESSED_KEYS_CAP; ++i) {
 | 
					 | 
				
			||||||
		if (state->pressed_keys[i]) {
 | 
					 | 
				
			||||||
			++npressed_keys;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						size_t i = 0;
 | 
				
			||||||
 | 
						while (i < state->npressed && state->pressed_keys[i] < key_id) {
 | 
				
			||||||
 | 
							++i;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size_t j = state->npressed;
 | 
				
			||||||
 | 
						while (j > i) {
 | 
				
			||||||
 | 
							state->pressed_keys[j] = state->pressed_keys[j - 1];
 | 
				
			||||||
 | 
							state->pressed_keycodes[j] = state->pressed_keycodes[j - 1];
 | 
				
			||||||
 | 
							--j;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						state->pressed_keys[i] = key_id;
 | 
				
			||||||
 | 
						state->pressed_keycodes[i] = keycode;
 | 
				
			||||||
 | 
						state->npressed++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Update the shortcut model state in response to new input
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void update_shortcut_state(struct sway_shortcut_state *state,
 | 
				
			||||||
 | 
							struct wlr_event_keyboard_key *event, uint32_t new_key,
 | 
				
			||||||
 | 
							uint32_t raw_modifiers) {
 | 
				
			||||||
 | 
						bool last_key_was_a_modifier = raw_modifiers != state->last_raw_modifiers;
 | 
				
			||||||
 | 
						state->last_raw_modifiers = raw_modifiers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (event->state == WLR_KEY_PRESSED) {
 | 
				
			||||||
 | 
							if (last_key_was_a_modifier && state->last_keycode) {
 | 
				
			||||||
 | 
								// Last pressed key before this one was a modifier
 | 
				
			||||||
 | 
								state_erase_key(state, state->last_keycode);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Add current key to set; there may be duplicates
 | 
				
			||||||
 | 
							state_add_key(state, event->keycode, new_key);
 | 
				
			||||||
 | 
							state->last_keycode = event->keycode;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							state_erase_key(state, event->keycode);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * If one exists, finds a binding which matches the shortcut model state,
 | 
				
			||||||
 | 
					 * current modifiers, release state, and locked state.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void get_active_binding(const struct sway_shortcut_state *state,
 | 
				
			||||||
 | 
							list_t *bindings, struct sway_binding **current_binding,
 | 
				
			||||||
 | 
							uint32_t modifiers, bool release, bool locked) {
 | 
				
			||||||
	for (int i = 0; i < bindings->length; ++i) {
 | 
						for (int i = 0; i < bindings->length; ++i) {
 | 
				
			||||||
		struct sway_binding *binding = bindings->items[i];
 | 
							struct sway_binding *binding = bindings->items[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (modifiers ^ binding->modifiers ||
 | 
							if (modifiers ^ binding->modifiers ||
 | 
				
			||||||
				npressed_keys != binding->keys->length ||
 | 
									state->npressed != (size_t)binding->keys->length ||
 | 
				
			||||||
				locked > binding->locked) {
 | 
									locked > binding->locked ||
 | 
				
			||||||
 | 
									release != binding->release) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool match = true;
 | 
							bool match = true;
 | 
				
			||||||
		for (int j = 0; j < binding->keys->length; ++j) {
 | 
							for (size_t j = 0; j < state->npressed; j++) {
 | 
				
			||||||
			uint32_t key = *(uint32_t *)binding->keys->items[j];
 | 
								uint32_t key = *(uint32_t *)binding->keys->items[j];
 | 
				
			||||||
 | 
								if (key != state->pressed_keys[j]) {
 | 
				
			||||||
			bool key_found = false;
 | 
					 | 
				
			||||||
			for (int k = 0; k < SWAY_KEYBOARD_PRESSED_KEYS_CAP; ++k) {
 | 
					 | 
				
			||||||
				if (state->pressed_keys[k] == key) {
 | 
					 | 
				
			||||||
					key_found = true;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (!key_found) {
 | 
					 | 
				
			||||||
				match = false;
 | 
									match = false;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (!match) {
 | 
				
			||||||
		if (match) {
 | 
								continue;
 | 
				
			||||||
			return binding;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NULL;
 | 
							if (*current_binding && *current_binding != binding) {
 | 
				
			||||||
 | 
								wlr_log(L_DEBUG, "encountered duplicate bindings %d and %d",
 | 
				
			||||||
 | 
										(*current_binding)->order, binding->order);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								*current_binding = binding;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -204,69 +230,65 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	size_t raw_keysyms_len =
 | 
						size_t raw_keysyms_len =
 | 
				
			||||||
		keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &raw_modifiers);
 | 
							keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &raw_modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_input_device *device =
 | 
						uint32_t code_modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
 | 
				
			||||||
		keyboard->seat_device->input_device->wlr_device;
 | 
					 | 
				
			||||||
	uint32_t code_modifiers = wlr_keyboard_get_modifiers(device->keyboard);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool last_key_was_a_modifier = code_modifiers != keyboard->last_modifiers;
 | 
					 | 
				
			||||||
	keyboard->last_modifiers = code_modifiers;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update shortcut model state
 | 
						// Update shortcut model state
 | 
				
			||||||
	update_shortcut_state(&keyboard->state_keycodes, event,
 | 
						update_shortcut_state(&keyboard->state_keycodes, event,
 | 
				
			||||||
			(uint32_t)keycode, last_key_was_a_modifier);
 | 
								(uint32_t)keycode, code_modifiers);
 | 
				
			||||||
	for (size_t i = 0; i < translated_keysyms_len; ++i) {
 | 
						for (size_t i = 0; i < translated_keysyms_len; ++i) {
 | 
				
			||||||
		update_shortcut_state(&keyboard->state_keysyms_translated,
 | 
							update_shortcut_state(&keyboard->state_keysyms_translated,
 | 
				
			||||||
				event, (uint32_t)translated_keysyms[i],
 | 
									event, (uint32_t)translated_keysyms[i],
 | 
				
			||||||
				last_key_was_a_modifier && i == 0);
 | 
									code_modifiers);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (size_t i = 0; i < raw_keysyms_len; ++i) {
 | 
						for (size_t i = 0; i < raw_keysyms_len; ++i) {
 | 
				
			||||||
		update_shortcut_state(&keyboard->state_keysyms_raw,
 | 
							update_shortcut_state(&keyboard->state_keysyms_raw,
 | 
				
			||||||
				event, (uint32_t)raw_keysyms[i],
 | 
									event, (uint32_t)raw_keysyms[i],
 | 
				
			||||||
				last_key_was_a_modifier && i == 0);
 | 
									code_modifiers);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// identify which binding should be executed.
 | 
					 | 
				
			||||||
	struct sway_binding *binding = get_active_binding(
 | 
					 | 
				
			||||||
			&keyboard->state_keycodes,
 | 
					 | 
				
			||||||
			config->current_mode->keycode_bindings,
 | 
					 | 
				
			||||||
			code_modifiers, input_inhibited);
 | 
					 | 
				
			||||||
	struct sway_binding *translated_binding = get_active_binding(
 | 
					 | 
				
			||||||
			&keyboard->state_keysyms_translated,
 | 
					 | 
				
			||||||
			config->current_mode->keysym_bindings,
 | 
					 | 
				
			||||||
			translated_modifiers, input_inhibited);
 | 
					 | 
				
			||||||
	if (translated_binding && !binding) {
 | 
					 | 
				
			||||||
		binding = translated_binding;
 | 
					 | 
				
			||||||
	} else if (binding && translated_binding && binding != translated_binding) {
 | 
					 | 
				
			||||||
		wlr_log(L_DEBUG, "encountered duplicate bindings %d and %d",
 | 
					 | 
				
			||||||
			binding->order, translated_binding->order);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	struct sway_binding *raw_binding = get_active_binding(
 | 
					 | 
				
			||||||
			&keyboard->state_keysyms_raw,
 | 
					 | 
				
			||||||
			config->current_mode->keysym_bindings,
 | 
					 | 
				
			||||||
			raw_modifiers, input_inhibited);
 | 
					 | 
				
			||||||
	if (raw_binding && !binding) {
 | 
					 | 
				
			||||||
		binding = raw_binding;
 | 
					 | 
				
			||||||
	} else if (binding && raw_binding && binding != raw_binding) {
 | 
					 | 
				
			||||||
		wlr_log(L_DEBUG, "encountered duplicate bindings %d and %d",
 | 
					 | 
				
			||||||
			binding->order, raw_binding->order);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool handled = false;
 | 
						bool handled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Execute the identified binding if need be.
 | 
						// Identify active release binding
 | 
				
			||||||
	if (keyboard->held_binding && binding != keyboard->held_binding &&
 | 
						struct sway_binding *binding_released = NULL;
 | 
				
			||||||
 | 
						get_active_binding(&keyboard->state_keycodes,
 | 
				
			||||||
 | 
								config->current_mode->keycode_bindings, &binding_released,
 | 
				
			||||||
 | 
								code_modifiers, true, input_inhibited);
 | 
				
			||||||
 | 
						get_active_binding(&keyboard->state_keysyms_translated,
 | 
				
			||||||
 | 
								config->current_mode->keysym_bindings, &binding_released,
 | 
				
			||||||
 | 
								translated_modifiers, true, input_inhibited);
 | 
				
			||||||
 | 
						get_active_binding(&keyboard->state_keysyms_raw,
 | 
				
			||||||
 | 
								config->current_mode->keysym_bindings, &binding_released,
 | 
				
			||||||
 | 
								raw_modifiers, true, input_inhibited);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Execute stored release binding once no longer active
 | 
				
			||||||
 | 
						if (keyboard->held_binding && binding_released != keyboard->held_binding &&
 | 
				
			||||||
			event->state == WLR_KEY_RELEASED) {
 | 
								event->state == WLR_KEY_RELEASED) {
 | 
				
			||||||
		keyboard_execute_command(keyboard, keyboard->held_binding);
 | 
							keyboard_execute_command(keyboard, keyboard->held_binding);
 | 
				
			||||||
		handled = true;
 | 
							handled = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (binding != keyboard->held_binding) {
 | 
						if (binding_released != keyboard->held_binding) {
 | 
				
			||||||
		keyboard->held_binding = NULL;
 | 
							keyboard->held_binding = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (binding && event->state == WLR_KEY_PRESSED) {
 | 
						if (binding_released && event->state == WLR_KEY_PRESSED) {
 | 
				
			||||||
		if (binding->release) {
 | 
							keyboard->held_binding = binding_released;
 | 
				
			||||||
			keyboard->held_binding = binding;
 | 
						}
 | 
				
			||||||
		} else {
 | 
					
 | 
				
			||||||
			keyboard_execute_command(keyboard, binding);
 | 
						// Identify and execute active pressed binding
 | 
				
			||||||
 | 
						if (event->state == WLR_KEY_PRESSED) {
 | 
				
			||||||
 | 
							struct sway_binding *binding_pressed = NULL;
 | 
				
			||||||
 | 
							get_active_binding(&keyboard->state_keycodes,
 | 
				
			||||||
 | 
									config->current_mode->keycode_bindings, &binding_pressed,
 | 
				
			||||||
 | 
									code_modifiers, false, input_inhibited);
 | 
				
			||||||
 | 
							get_active_binding(&keyboard->state_keysyms_translated,
 | 
				
			||||||
 | 
									config->current_mode->keysym_bindings, &binding_pressed,
 | 
				
			||||||
 | 
									translated_modifiers, false, input_inhibited);
 | 
				
			||||||
 | 
							get_active_binding(&keyboard->state_keysyms_raw,
 | 
				
			||||||
 | 
									config->current_mode->keysym_bindings, &binding_pressed,
 | 
				
			||||||
 | 
									raw_modifiers, false, input_inhibited);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (binding_pressed) {
 | 
				
			||||||
 | 
								keyboard_execute_command(keyboard, binding_pressed);
 | 
				
			||||||
			handled = true;
 | 
								handled = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -315,10 +337,6 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
				
			||||||
	wl_list_init(&keyboard->keyboard_key.link);
 | 
						wl_list_init(&keyboard->keyboard_key.link);
 | 
				
			||||||
	wl_list_init(&keyboard->keyboard_modifiers.link);
 | 
						wl_list_init(&keyboard->keyboard_modifiers.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keyboard->state_keycodes.last_key_index = -1;
 | 
					 | 
				
			||||||
	keyboard->state_keysyms_raw.last_key_index = -1;
 | 
					 | 
				
			||||||
	keyboard->state_keysyms_translated.last_key_index = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return keyboard;
 | 
						return keyboard;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,7 +127,8 @@ void acquire_sleep_lock() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
 | 
					static int prepare_for_sleep(sd_bus_message *msg, void *userdata,
 | 
				
			||||||
		sd_bus_error *ret_error) {
 | 
							sd_bus_error *ret_error) {
 | 
				
			||||||
	bool going_down = true;
 | 
						/* "b" apparently reads into an int, not a bool */
 | 
				
			||||||
 | 
						int going_down = 1;
 | 
				
			||||||
	int ret = sd_bus_message_read(msg, "b", &going_down);
 | 
						int ret = sd_bus_message_read(msg, "b", &going_down);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s",
 | 
							wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue