mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Implement key bindings
This commit is contained in:
		
							parent
							
								
									4181c36862
								
							
						
					
					
						commit
						a78b921803
					
				
					 6 changed files with 97 additions and 7 deletions
				
			
		|  | @ -1,5 +1,6 @@ | |||
| #include <xkbcommon/xkbcommon.h> | ||||
| #include <xkbcommon/xkbcommon-names.h> | ||||
| #include <wlc/wlc.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | @ -22,6 +23,32 @@ int cmd_set(struct sway_config *config, int argc, char **argv) { | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int cmd_exit(struct sway_config *config, int argc, char **argv) { | ||||
| 	if (argc != 0) { | ||||
| 		sway_log(L_ERROR, "Invalid exit command (expected 1 arguments, got %d)", argc); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	// TODO: Some kind of clean up is probably in order
 | ||||
| 	exit(0); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| struct modifier_key { | ||||
| 	char *name; | ||||
| 	uint32_t mod; | ||||
| }; | ||||
| 
 | ||||
| struct modifier_key modifiers[] = { | ||||
| 	{ XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT }, | ||||
| 	{ XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS }, | ||||
| 	{ XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL }, | ||||
| 	{ XKB_MOD_NAME_ALT, WLC_BIT_MOD_ALT }, | ||||
| 	{ XKB_MOD_NAME_NUM, WLC_BIT_MOD_MOD2 }, | ||||
| 	{ "Mod3", WLC_BIT_MOD_MOD3 }, | ||||
| 	{ XKB_MOD_NAME_LOGO, WLC_BIT_MOD_LOGO }, | ||||
| 	{ "Mod5", WLC_BIT_MOD_MOD5 }, | ||||
| }; | ||||
| 
 | ||||
| int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | ||||
| 	if (argc < 2) { | ||||
| 		sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc); | ||||
|  | @ -37,12 +64,22 @@ int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
| 	list_t *split = split_string(argv[0], "+"); | ||||
| 	int i; | ||||
| 	for (i = 0; i < split->length; ++i) { | ||||
| 		// TODO: Parse modifier keys
 | ||||
| 		// Check for a modifier key
 | ||||
| 		int j; | ||||
| 		bool is_mod = false; | ||||
| 		for (j = 0; j < sizeof(modifiers) / sizeof(struct modifier_key); ++j) { | ||||
| 			if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { | ||||
| 				binding->modifiers |= modifiers[j].mod; | ||||
| 				is_mod = true; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if (is_mod) continue; | ||||
| 		// Check for xkb key
 | ||||
| 		xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); | ||||
| 		if (!sym) { | ||||
| 			sway_log(L_ERROR, "bindsym - unknown key %s", (char *)split->items[i]); | ||||
| 			// Ignore for now, we need to deal with modifier keys
 | ||||
| 			// return 1;
 | ||||
| 			return 1; | ||||
| 		} | ||||
| 		xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); | ||||
| 		*key = sym; | ||||
|  | @ -60,7 +97,8 @@ int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
| /* Keep alphabetized */ | ||||
| struct cmd_handler handlers[] = { | ||||
| 	{ "bindsym", cmd_bindsym }, | ||||
| 	{ "set", cmd_set } | ||||
| 	{ "exit", cmd_exit }, | ||||
| 	{ "set", cmd_set }, | ||||
| }; | ||||
| 
 | ||||
| char **split_directive(char *line, int *argc) { | ||||
|  | @ -128,10 +166,11 @@ struct cmd_handler *find_handler(struct cmd_handler handlers[], int l, char *lin | |||
| } | ||||
| 
 | ||||
| int handle_command(struct sway_config *config, char *exec) { | ||||
| 	sway_log(L_INFO, "Handling command '%s'", exec); | ||||
| 	char *ptr, *cmd; | ||||
| 	if ((ptr = strchr(exec, ' ')) == NULL) { | ||||
| 		cmd = malloc(strlen(exec) + 1); | ||||
| 		strcpy(exec, cmd); | ||||
| 		strcpy(cmd, exec); | ||||
| 	} else { | ||||
| 		int index = ptr - exec; | ||||
| 		cmd = malloc(index + 1); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "readline.h" | ||||
| #include "stringop.h" | ||||
| #include "list.h" | ||||
| #include "log.h" | ||||
| #include "commands.h" | ||||
| #include "config.h" | ||||
| 
 | ||||
|  | @ -33,7 +34,7 @@ struct sway_config *read_config(FILE *file) { | |||
| 			goto _continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (handle_command(config, line) != 0) { | ||||
| 		if (!temp_depth && handle_command(config, line) != 0) { | ||||
| 			success = false; | ||||
| 		} | ||||
| 		 | ||||
|  |  | |||
|  | @ -30,4 +30,6 @@ struct sway_config { | |||
| struct sway_config *read_config(FILE *file); | ||||
| char *do_var_replacement(struct sway_config *config, char *str); | ||||
| 
 | ||||
| extern struct sway_config *config; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,8 +1,12 @@ | |||
| #include <xkbcommon/xkbcommon.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdbool.h> | ||||
| #include <wlc/wlc.h> | ||||
| #include <ctype.h> | ||||
| #include "layout.h" | ||||
| #include "log.h" | ||||
| #include "config.h" | ||||
| #include "commands.h" | ||||
| #include "handlers.h" | ||||
| 
 | ||||
| bool handle_output_created(wlc_handle output) { | ||||
|  | @ -41,3 +45,41 @@ void handle_view_focus(wlc_handle view, bool focus) { | |||
| void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) { | ||||
| 	// deny that shit
 | ||||
| } | ||||
| 
 | ||||
| bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers | ||||
| 		*modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state) { | ||||
| 	// TODO: handle keybindings with more than 1 non-modifier key involved
 | ||||
| 	// Note: reminder to check conflicts with mod+q+a versus mod+q
 | ||||
| 	 | ||||
| 	bool ret = true; | ||||
| 	struct sway_mode *mode = config->current_mode; | ||||
| 	sway_log(L_DEBUG, "key pressed: %d %d", sym, modifiers->mods); | ||||
| 
 | ||||
| 	// Lowercase if necessary
 | ||||
| 	sym = tolower(sym); | ||||
| 
 | ||||
| 	if (state == WLC_KEY_STATE_PRESSED) { | ||||
| 		int i; | ||||
| 		for (i = 0; i < mode->bindings->length; ++i) { | ||||
| 			struct sway_binding *binding = mode->bindings->items[i]; | ||||
| 
 | ||||
| 			if ((modifiers->mods & binding->modifiers) == binding->modifiers) { | ||||
| 				bool match = true; | ||||
| 				int j; | ||||
| 				for (j = 0; j < binding->keys->length; ++j) { | ||||
| 					xkb_keysym_t *k = binding->keys->items[j]; | ||||
| 					if (sym != *k) { | ||||
| 						match = false; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if (match) { | ||||
| 					ret = false; | ||||
| 					handle_command(config, binding->command); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -13,4 +13,7 @@ void handle_view_destroyed(wlc_handle view); | |||
| void handle_view_focus(wlc_handle view, bool focus); | ||||
| void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry); | ||||
| 
 | ||||
| bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers | ||||
| 		*modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ struct sway_config *config; | |||
| 
 | ||||
| void load_config() { | ||||
| 	// TODO: Allow use of more config file locations
 | ||||
| 	const char *name = "/.i3/config"; | ||||
| 	const char *name = "/.sway/config"; | ||||
| 	const char *home = getenv("HOME"); | ||||
| 	char *temp = malloc(strlen(home) + strlen(name) + 1); | ||||
| 	strcpy(temp, home); | ||||
|  | @ -45,6 +45,9 @@ int main(int argc, char **argv) { | |||
| 			.request = { | ||||
| 				.geometry = handle_view_geometry_request | ||||
| 			} | ||||
| 		}, | ||||
| 		.keyboard = { | ||||
| 			.key = handle_key | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drew DeVault
						Drew DeVault