mirror of
https://github.com/swaywm/sway.git
synced 2024-11-25 17:31:28 +00:00
Implement key bindings
This commit is contained in:
parent
4181c36862
commit
a78b921803
|
@ -1,5 +1,6 @@
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbcommon-names.h>
|
#include <xkbcommon/xkbcommon-names.h>
|
||||||
|
#include <wlc/wlc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -22,6 +23,32 @@ int cmd_set(struct sway_config *config, int argc, char **argv) {
|
||||||
return 0;
|
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) {
|
int cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc);
|
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], "+");
|
list_t *split = split_string(argv[0], "+");
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < split->length; ++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);
|
xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE);
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sway_log(L_ERROR, "bindsym - unknown key %s", (char *)split->items[i]);
|
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));
|
xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
|
||||||
*key = sym;
|
*key = sym;
|
||||||
|
@ -60,7 +97,8 @@ int cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
||||||
/* Keep alphabetized */
|
/* Keep alphabetized */
|
||||||
struct cmd_handler handlers[] = {
|
struct cmd_handler handlers[] = {
|
||||||
{ "bindsym", cmd_bindsym },
|
{ "bindsym", cmd_bindsym },
|
||||||
{ "set", cmd_set }
|
{ "exit", cmd_exit },
|
||||||
|
{ "set", cmd_set },
|
||||||
};
|
};
|
||||||
|
|
||||||
char **split_directive(char *line, int *argc) {
|
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) {
|
int handle_command(struct sway_config *config, char *exec) {
|
||||||
|
sway_log(L_INFO, "Handling command '%s'", exec);
|
||||||
char *ptr, *cmd;
|
char *ptr, *cmd;
|
||||||
if ((ptr = strchr(exec, ' ')) == NULL) {
|
if ((ptr = strchr(exec, ' ')) == NULL) {
|
||||||
cmd = malloc(strlen(exec) + 1);
|
cmd = malloc(strlen(exec) + 1);
|
||||||
strcpy(exec, cmd);
|
strcpy(cmd, exec);
|
||||||
} else {
|
} else {
|
||||||
int index = ptr - exec;
|
int index = ptr - exec;
|
||||||
cmd = malloc(index + 1);
|
cmd = malloc(index + 1);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "readline.h"
|
#include "readline.h"
|
||||||
#include "stringop.h"
|
#include "stringop.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ struct sway_config *read_config(FILE *file) {
|
||||||
goto _continue;
|
goto _continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle_command(config, line) != 0) {
|
if (!temp_depth && handle_command(config, line) != 0) {
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,4 +30,6 @@ struct sway_config {
|
||||||
struct sway_config *read_config(FILE *file);
|
struct sway_config *read_config(FILE *file);
|
||||||
char *do_var_replacement(struct sway_config *config, char *str);
|
char *do_var_replacement(struct sway_config *config, char *str);
|
||||||
|
|
||||||
|
extern struct sway_config *config;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wlc/wlc.h>
|
#include <wlc/wlc.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
|
|
||||||
bool handle_output_created(wlc_handle output) {
|
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) {
|
void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) {
|
||||||
// deny that shit
|
// 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_focus(wlc_handle view, bool focus);
|
||||||
void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry);
|
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
|
#endif
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct sway_config *config;
|
||||||
|
|
||||||
void load_config() {
|
void load_config() {
|
||||||
// TODO: Allow use of more config file locations
|
// TODO: Allow use of more config file locations
|
||||||
const char *name = "/.i3/config";
|
const char *name = "/.sway/config";
|
||||||
const char *home = getenv("HOME");
|
const char *home = getenv("HOME");
|
||||||
char *temp = malloc(strlen(home) + strlen(name) + 1);
|
char *temp = malloc(strlen(home) + strlen(name) + 1);
|
||||||
strcpy(temp, home);
|
strcpy(temp, home);
|
||||||
|
@ -45,6 +45,9 @@ int main(int argc, char **argv) {
|
||||||
.request = {
|
.request = {
|
||||||
.geometry = handle_view_geometry_request
|
.geometry = handle_view_geometry_request
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
.keyboard = {
|
||||||
|
.key = handle_key
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue