Compare commits
3 Commits
f7534a551e
...
f8fe84f839
Author | SHA1 | Date | |
---|---|---|---|
f8fe84f839 | |||
58bc1089f2 | |||
01e8c16e8b |
213
src/config.c
213
src/config.c
@ -2,8 +2,6 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -17,11 +15,50 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
|
|
||||||
|
static const KeybindFunctionCommand __wm_keybind_commands[] = {
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "spawn",
|
||||||
|
.function = &wm_kb_spawn
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "focus",
|
||||||
|
.function = &wm_kb_focus_dir
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "move",
|
||||||
|
.function = &wm_kb_move_dir
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "switch_ws",
|
||||||
|
.function = &wm_kb_switch_ws
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "move_to_ws",
|
||||||
|
.function = &wm_kb_move_client_ws
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "quit",
|
||||||
|
.function = &wm_kb_exit
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "quit_client",
|
||||||
|
.function = &wm_kb_kill
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "split_vertical",
|
||||||
|
.function = &wm_kb_switch_split_mode
|
||||||
|
},
|
||||||
|
(KeybindFunctionCommand) {
|
||||||
|
.command = "split_horizontal",
|
||||||
|
.function = &wm_kb_switch_split_mode
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
void wm_cfg_init_def(Config *config)
|
void wm_cfg_init_def(Config *config)
|
||||||
{
|
{
|
||||||
config->ms_p = 0.5;
|
config->ms_p = 0.5;
|
||||||
config->border_col = "#222222";
|
strncpy(config->border_col, "#222222", CONFIG_COLOR_MAX);
|
||||||
config->focused_border_col = "#444444";
|
strncpy(config->focused_border_col, "#444444", CONFIG_COLOR_MAX);
|
||||||
config->border_width = 2;
|
config->border_width = 2;
|
||||||
config->focus_on_motion = true;
|
config->focus_on_motion = true;
|
||||||
|
|
||||||
@ -165,6 +202,14 @@ void wm_keybinds_init_def(Config *config)
|
|||||||
memcpy(config->keybinds, k, size);
|
memcpy(config->keybinds, k, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wm_keybinds_free(Config *config)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < config->kb_count; i++) {
|
||||||
|
if (config->keybinds[i].function == &wm_kb_spawn)
|
||||||
|
free(config->keybinds[i].args.sl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wm_configfile_init(ConfigFile *config, const char *filename)
|
void wm_configfile_init(ConfigFile *config, const char *filename)
|
||||||
{
|
{
|
||||||
assert(config);
|
assert(config);
|
||||||
@ -175,23 +220,23 @@ void wm_configfile_init(ConfigFile *config, const char *filename)
|
|||||||
ConfigCommand commands[] = {
|
ConfigCommand commands[] = {
|
||||||
(ConfigCommand) {.string = "border_color", .arg_count = 1,
|
(ConfigCommand) {.string = "border_color", .arg_count = 1,
|
||||||
.cfg_var_offset[0] = offsetof(Config, border_col),
|
.cfg_var_offset[0] = offsetof(Config, border_col),
|
||||||
.argc = 0},
|
.argc = 0, .arg_type = TYPE_STRING},
|
||||||
|
|
||||||
(ConfigCommand) {.string = "focused_border_color", .arg_count = 1,
|
(ConfigCommand) {.string = "focused_border_color", .arg_count = 1,
|
||||||
.cfg_var_offset[0] = offsetof(Config, focused_border_col),
|
.cfg_var_offset[0] = offsetof(Config, focused_border_col),
|
||||||
.argc = 0},
|
.argc = 0, .arg_type = TYPE_STRING},
|
||||||
|
|
||||||
(ConfigCommand) {.string = "border_width", .arg_count = 1,
|
(ConfigCommand) {.string = "border_width", .arg_count = 1,
|
||||||
.cfg_var_offset[0] = offsetof(Config, border_width),
|
.cfg_var_offset[0] = offsetof(Config, border_width),
|
||||||
.argc = 0},
|
.argc = 0, .arg_type = TYPE_UNSIGNED_INTEGER},
|
||||||
|
|
||||||
(ConfigCommand) {.string = "keybind", .arg_count = 0,
|
(ConfigCommand) {.string = "keybind", .arg_count = 0,
|
||||||
.cfg_var_offset[0] = -1,
|
.cfg_var_offset[0] = -1,
|
||||||
.argc = 0},
|
.argc = 0, .arg_type = TYPE_KEYBIND},
|
||||||
|
|
||||||
(ConfigCommand) {.string = "focus_on_motion", .arg_count = 1,
|
(ConfigCommand) {.string = "focus_on_motion", .arg_count = 1,
|
||||||
.cfg_var_offset[0] = offsetof(Config, focus_on_motion),
|
.cfg_var_offset[0] = offsetof(Config, focus_on_motion),
|
||||||
.argc = 0},
|
.argc = 0, .arg_type = TYPE_BOOL},
|
||||||
};
|
};
|
||||||
|
|
||||||
config->command_count = sizeof(commands) / sizeof (commands[0]);
|
config->command_count = sizeof(commands) / sizeof (commands[0]);
|
||||||
@ -210,6 +255,8 @@ void wm_configfile_free(ConfigFile *config)
|
|||||||
for (size_t i = 0; i < config->command_count; i++) {
|
for (size_t i = 0; i < config->command_count; i++) {
|
||||||
wm_configcommand_free(&config->available_commands[i]);
|
wm_configcommand_free(&config->available_commands[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(config->available_commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wm_configfile_read(ConfigFile *cfile, Config *config)
|
void wm_configfile_read(ConfigFile *cfile, Config *config)
|
||||||
@ -253,31 +300,31 @@ void wm_config_apply_command(Config *config, ConfigCommand *command)
|
|||||||
switch (command->arg_type) {
|
switch (command->arg_type) {
|
||||||
case TYPE_INTEGER:
|
case TYPE_INTEGER:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
*(int*)((char*)config + (command->cfg_var_offset[i])) = command->args[i].i;
|
*(int*)(((char*)config) + (command->cfg_var_offset[i])) = command->args[i].i;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_UNSIGNED_INTEGER:
|
case TYPE_UNSIGNED_INTEGER:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
*(unsigned int*)((char*)config + (command->cfg_var_offset[i])) = command->args[i].ui;
|
*(unsigned int*)(((char*)config) + (command->cfg_var_offset[i])) = command->args[i].ui;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
*(bool*)((char*)config + (command->cfg_var_offset[i])) = command->args[i].i;
|
*(bool*)(((char*)config) + (command->cfg_var_offset[i])) = command->args[i].i;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_KEYBIND:
|
case TYPE_KEYBIND:
|
||||||
// TODO
|
wm_config_replace_keybind(config, &command->keybind);
|
||||||
wm_config_parse_bind_command(command);
|
return;
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
size_t len = strnlen(command->argv[i], CONFIG_ARGLEN_MAX);
|
size_t len = strnlen(command->argv[i], CONFIG_ARGLEN_MAX);
|
||||||
memcpy((char*)(config + (command->cfg_var_offset)[i]), command->argv[i], len);
|
memcpy(((char*)(config) + (command->cfg_var_offset)[i]), command->argv[i], len);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
*(float*)((char*)config + (command->cfg_var_offset[i])) = atof(command->argv[i]);
|
*(float*)(((char*)config) + (command->cfg_var_offset[i])) = atof(command->argv[i]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -298,6 +345,9 @@ ParserResult wm_configfile_parse_line(const ConfigFile *cfile, Config *config,
|
|||||||
if (line[0] == '\n')
|
if (line[0] == '\n')
|
||||||
return (ParserResult) {.success = true, .message = ""};
|
return (ParserResult) {.success = true, .message = ""};
|
||||||
|
|
||||||
|
if (!token)
|
||||||
|
return (ParserResult) {.success = true, .message = ""};
|
||||||
|
|
||||||
// try to match command
|
// try to match command
|
||||||
for (size_t i = 0; i < cfile->command_count; i++) {
|
for (size_t i = 0; i < cfile->command_count; i++) {
|
||||||
if (strncmp(cfile->available_commands[i].string, token,
|
if (strncmp(cfile->available_commands[i].string, token,
|
||||||
@ -333,12 +383,15 @@ ParserResult wm_configfile_parse_line(const ConfigFile *cfile, Config *config,
|
|||||||
CONFIG_ARGC_MAX);
|
CONFIG_ARGC_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command->argc > command->arg_count) {
|
if (command->argc > command->arg_count && command->arg_type != TYPE_KEYBIND) {
|
||||||
PARSER_RETURN(result, false, "Too many arguments to command %s\n",
|
PARSER_RETURN(result, false, "Too many arguments to command %s\n",
|
||||||
command->string);
|
command->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(command->argv[command->argc-1], token, CONFIG_ARGLEN_MAX);
|
strncpy(command->argv[command->argc-1], token, CONFIG_ARGLEN_MAX);
|
||||||
|
char *arg = command->argv[command->argc-1];
|
||||||
|
for (size_t i = 0; i < strnlen(arg, CONFIG_ARGLEN_MAX); i++)
|
||||||
|
if (arg[i] == '\n') arg[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of args
|
// end of args
|
||||||
@ -419,8 +472,8 @@ void wm_configcommand_argv_parse(ConfigCommand *command)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_KEYBIND:
|
case TYPE_KEYBIND:
|
||||||
// todo
|
command->keybind = wm_config_parse_bind_command(command);
|
||||||
wm_config_parse_bind_command(command);
|
return;
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
for (size_t i = 0; i < command->argc; i++) {
|
for (size_t i = 0; i < command->argc; i++) {
|
||||||
size_t len = strnlen(command->argv[i], CONFIG_ARGLEN_MAX);
|
size_t len = strnlen(command->argv[i], CONFIG_ARGLEN_MAX);
|
||||||
@ -474,6 +527,99 @@ bool atobool(char *arr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Arg wm_keybind_argv_to_args(Keybind kb, ConfigCommand command)
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("%s\n", __func__);
|
||||||
|
Arg ret;
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_spawn) {
|
||||||
|
ret.sl = calloc(command.argc - 2, sizeof(char*));
|
||||||
|
for (size_t i = 2; i < command.argc; i++) {
|
||||||
|
ret.sl[i] = calloc(CONFIG_ARGLEN_MAX, 1);
|
||||||
|
strncpy(ret.sl[i], command.argv[i], CONFIG_ARGLEN_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_focus_dir) {
|
||||||
|
assert(command.argc == 3);
|
||||||
|
ret.i = wm_string_to_direction(command.argv[command.argc - 1]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_move_dir) {
|
||||||
|
assert(command.argc == 3);
|
||||||
|
ret.i = wm_string_to_direction(command.argv[command.argc - 1]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_switch_ws) {
|
||||||
|
assert(command.argc == 3);
|
||||||
|
ret.i = atoi(command.argv[command.argc - 1]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_move_client_ws) {
|
||||||
|
assert(command.argc == 3);
|
||||||
|
ret.i = atoi(command.argv[command.argc - 1]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kb.function == &wm_kb_switch_split_mode) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wm_string_to_direction(const char *str)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char lower[CONFIG_ARGLEN_MAX];
|
||||||
|
strncpy(lower, str, CONFIG_ARGLEN_MAX);
|
||||||
|
|
||||||
|
for (char *c = lower; *c; c++) *c = tolower(*c);
|
||||||
|
|
||||||
|
ret = strncmp(lower, "right", CONFIG_ARGLEN_MAX);
|
||||||
|
if (ret == 0) return RIGHT;
|
||||||
|
|
||||||
|
ret = strncmp(lower, "left", CONFIG_ARGLEN_MAX);
|
||||||
|
if (ret == 0) return LEFT;
|
||||||
|
|
||||||
|
ret = strncmp(lower, "up", CONFIG_ARGLEN_MAX);
|
||||||
|
if (ret == 0) return UP;
|
||||||
|
|
||||||
|
ret = strncmp(lower, "down", CONFIG_ARGLEN_MAX);
|
||||||
|
if (ret == 0) return DOWN;
|
||||||
|
|
||||||
|
fprintf(stderr, "wm: encountered invalid direction \"%s\"\n. exiting.",
|
||||||
|
str);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeybindFunction wm_str_to_keybindfunction(const char* str)
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("%s %s\n", __func__, str);
|
||||||
|
char lower[CONFIG_ARGLEN_MAX];
|
||||||
|
strncpy(lower, str, CONFIG_ARGLEN_MAX);
|
||||||
|
|
||||||
|
for (char *c = lower; *c; c++) *c = tolower(*c);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(__wm_keybind_commands) / sizeof(__wm_keybind_commands[0]); i++) {
|
||||||
|
if (strncmp(lower, __wm_keybind_commands[i].command, CONFIG_ARGLEN_MAX) == 0)
|
||||||
|
return __wm_keybind_commands[i].function;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "wm: encountered invalid keybind command \"%s\"\n. exiting.",
|
||||||
|
str);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int wm_string_to_mask(const char* str)
|
unsigned int wm_string_to_mask(const char* str)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -504,12 +650,12 @@ unsigned int wm_string_to_mask(const char* str)
|
|||||||
ret = strncmp(str, "Super", CONFIG_ARGLEN_MAX);
|
ret = strncmp(str, "Super", CONFIG_ARGLEN_MAX);
|
||||||
if (ret == 0) return Mod4Mask;
|
if (ret == 0) return Mod4Mask;
|
||||||
|
|
||||||
fprintf(stderr, "wm: encountered invalid modifier token %s\n. exiting.",
|
fprintf(stderr, "wm: encountered invalid modifier token \"%s\"\n. exiting.",
|
||||||
str);
|
str);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
KeySym* wm_keybind_str_to_mask_keysym(const char* kb_argv)
|
KeySym* wm_keybind_string_to_mask_keysym(const char* kb_argv)
|
||||||
{
|
{
|
||||||
KeySym *ret = calloc(2, sizeof(KeySym));
|
KeySym *ret = calloc(2, sizeof(KeySym));
|
||||||
char* str = strdup(kb_argv);
|
char* str = strdup(kb_argv);
|
||||||
@ -531,7 +677,7 @@ KeySym* wm_keybind_str_to_mask_keysym(const char* kb_argv)
|
|||||||
token = strtok(NULL, "+");
|
token = strtok(NULL, "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINT("str: %s token count: %d\n", kb_argv, token_count);
|
DEBUG_PRINT("str: %s, str[0]: %d, token count: %d\n", kb_argv, kb_argv[0], token_count);
|
||||||
|
|
||||||
ret[0] = wm_string_to_mask(tokens[0]);
|
ret[0] = wm_string_to_mask(tokens[0]);
|
||||||
|
|
||||||
@ -541,7 +687,7 @@ KeySym* wm_keybind_str_to_mask_keysym(const char* kb_argv)
|
|||||||
|
|
||||||
KeySym keysym = XStringToKeysym(tokens[token_count - 1]);
|
KeySym keysym = XStringToKeysym(tokens[token_count - 1]);
|
||||||
if (keysym == NoSymbol) {
|
if (keysym == NoSymbol) {
|
||||||
fprintf(stderr, "wm: encountered invalid keybind token %s\n. exiting.",
|
fprintf(stderr, "wm: encountered invalid keybind token \"%s\"\n. exiting.",
|
||||||
tokens[token_count-1]);
|
tokens[token_count-1]);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -553,8 +699,27 @@ KeySym* wm_keybind_str_to_mask_keysym(const char* kb_argv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
Keybind wm_config_parse_bind_command(ConfigCommand *command)
|
Keybind wm_config_parse_bind_command(ConfigCommand *command)
|
||||||
{
|
{
|
||||||
|
DEBUG_PRINT("%s\n", __func__);
|
||||||
|
Keybind ret;
|
||||||
|
KeySym *keysyms = wm_keybind_string_to_mask_keysym(command->argv[0]);
|
||||||
|
|
||||||
|
ret.mask = keysyms[0];
|
||||||
|
ret.keysym = keysyms[1];
|
||||||
|
free(keysyms);
|
||||||
|
|
||||||
|
ret.function = wm_str_to_keybindfunction(command->argv[1]);
|
||||||
|
ret.args = wm_keybind_argv_to_args(ret, *command);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wm_config_replace_keybind(Config *config, const Keybind *keybind)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < config->kb_count; i++)
|
||||||
|
if (config->keybinds[i].function == keybind->function) {
|
||||||
|
config->keybinds[i] = *keybind;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
28
src/config.h
28
src/config.h
@ -11,6 +11,7 @@
|
|||||||
#define CONFIG_PARSERRESULT_MAX 1024
|
#define CONFIG_PARSERRESULT_MAX 1024
|
||||||
#define CONFIG_ARGC_MAX 16
|
#define CONFIG_ARGC_MAX 16
|
||||||
#define CONFIG_ARGLEN_MAX 256
|
#define CONFIG_ARGLEN_MAX 256
|
||||||
|
#define CONFIG_COLOR_MAX 16
|
||||||
|
|
||||||
#define PARSER_RETURN(result, _success, fmt, ...) \
|
#define PARSER_RETURN(result, _success, fmt, ...) \
|
||||||
do { (result).success = (_success); \
|
do { (result).success = (_success); \
|
||||||
@ -33,13 +34,20 @@ struct Arg {
|
|||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*KeybindFunction)(Wm*, Arg*) ;
|
||||||
|
|
||||||
struct Keybind {
|
struct Keybind {
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
void (*func)(Wm*, Arg*);
|
KeybindFunction function;
|
||||||
Arg args;
|
Arg args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char command[CONFIG_ARGLEN_MAX];
|
||||||
|
const KeybindFunction function;
|
||||||
|
} KeybindFunctionCommand;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TYPE_INTEGER,
|
TYPE_INTEGER,
|
||||||
TYPE_UNSIGNED_INTEGER,
|
TYPE_UNSIGNED_INTEGER,
|
||||||
@ -62,6 +70,7 @@ typedef struct {
|
|||||||
size_t argc;
|
size_t argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
Arg *args;
|
Arg *args;
|
||||||
|
Keybind keybind;
|
||||||
} ConfigCommand;
|
} ConfigCommand;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -72,8 +81,8 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float ms_p;
|
float ms_p;
|
||||||
char *border_col;
|
char border_col[CONFIG_COLOR_MAX];
|
||||||
char *focused_border_col;
|
char focused_border_col[CONFIG_COLOR_MAX];
|
||||||
unsigned int border_width;
|
unsigned int border_width;
|
||||||
Keybind *keybinds;
|
Keybind *keybinds;
|
||||||
int kb_count;
|
int kb_count;
|
||||||
@ -83,6 +92,7 @@ typedef struct {
|
|||||||
|
|
||||||
void wm_cfg_init_def(Config *config);
|
void wm_cfg_init_def(Config *config);
|
||||||
void wm_keybinds_init_def(Config *config);
|
void wm_keybinds_init_def(Config *config);
|
||||||
|
void wm_keybinds_free(Config *config);
|
||||||
void wm_configfile_init(ConfigFile *config, const char *path);
|
void wm_configfile_init(ConfigFile *config, const char *path);
|
||||||
void wm_configfile_free(ConfigFile *config);
|
void wm_configfile_free(ConfigFile *config);
|
||||||
void wm_configfile_read(ConfigFile *cfile, Config *config);
|
void wm_configfile_read(ConfigFile *cfile, Config *config);
|
||||||
@ -95,13 +105,23 @@ void wm_configcommand_argv_parse(ConfigCommand *command);
|
|||||||
void wm_configcommand_free(ConfigCommand *command);
|
void wm_configcommand_free(ConfigCommand *command);
|
||||||
bool atobool(char *arr);
|
bool atobool(char *arr);
|
||||||
|
|
||||||
|
Arg wm_keybind_argv_to_args(Keybind kb, ConfigCommand command);
|
||||||
|
|
||||||
|
int wm_string_to_direction(const char *str);
|
||||||
|
|
||||||
|
KeybindFunction wm_string_to_keybindfunction(const char* str);
|
||||||
|
|
||||||
/* Converts string to Key mask (see X.h:218-228). */
|
/* Converts string to Key mask (see X.h:218-228). */
|
||||||
unsigned int wm_string_to_mask(const char* str);
|
unsigned int wm_string_to_mask(const char* str);
|
||||||
|
|
||||||
/* The first element is the mask, the second element is the
|
/* The first element is the mask, the second element is the
|
||||||
* key. The returned array needs to be freed. */
|
* key. The returned array needs to be freed. */
|
||||||
KeySym* wm_keybind_str_to_mask_keysym(const char* kb_argv);
|
KeySym* wm_keybind_string_to_mask_keysym(const char* kb_argv);
|
||||||
|
|
||||||
Keybind wm_config_parse_bind_command(ConfigCommand *command);
|
Keybind wm_config_parse_bind_command(ConfigCommand *command);
|
||||||
|
|
||||||
|
/* Finds a keybind matching the function of the keybind parameter, and
|
||||||
|
* replaces it. */
|
||||||
|
void wm_config_replace_keybind(Config *config, const Keybind *keybind);
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
@ -59,7 +59,7 @@ void wm_keypress_handler(Wm *wm, XKeyPressedEvent e)
|
|||||||
k = wm->config.keybinds[i];
|
k = wm->config.keybinds[i];
|
||||||
if (k.mask == e.state && k.keysym == XLookupKeysym(&e, 0))
|
if (k.mask == e.state && k.keysym == XLookupKeysym(&e, 0))
|
||||||
{
|
{
|
||||||
(*k.func)(wm, &k.args);
|
(*k.function)(wm, &k.args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
139
src/tests.c
139
src/tests.c
@ -6,6 +6,7 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <cmocka.h>
|
#include <cmocka.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -528,31 +529,159 @@ static void test_wm_keybind_str_to_mask_keysym(void **state)
|
|||||||
|
|
||||||
KeySym *ret;
|
KeySym *ret;
|
||||||
|
|
||||||
ret = wm_keybind_str_to_mask_keysym(keybind1);
|
ret = wm_keybind_string_to_mask_keysym(keybind1);
|
||||||
assert_int_equal(ret[0], Mod4Mask | ShiftMask);
|
assert_int_equal(ret[0], Mod4Mask | ShiftMask);
|
||||||
assert_int_equal(ret[1], XK_h);
|
assert_int_equal(ret[1], XK_h);
|
||||||
|
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = wm_keybind_str_to_mask_keysym(keybind2);
|
ret = wm_keybind_string_to_mask_keysym(keybind2);
|
||||||
assert_int_equal(ret[0], Mod1Mask);
|
assert_int_equal(ret[0], Mod1Mask);
|
||||||
assert_int_equal(ret[1], XK_1);
|
assert_int_equal(ret[1], XK_1);
|
||||||
|
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = wm_keybind_str_to_mask_keysym(keybind3);
|
ret = wm_keybind_string_to_mask_keysym(keybind3);
|
||||||
assert_int_equal(ret[0], Mod4Mask | Mod1Mask | ShiftMask);
|
assert_int_equal(ret[0], Mod4Mask | Mod1Mask | ShiftMask);
|
||||||
assert_int_equal(ret[1], XK_j);
|
assert_int_equal(ret[1], XK_j);
|
||||||
|
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = wm_keybind_str_to_mask_keysym(keybind4);
|
ret = wm_keybind_string_to_mask_keysym(keybind4);
|
||||||
assert_int_equal(ret[0], LockMask);
|
assert_int_equal(ret[0], LockMask);
|
||||||
assert_int_equal(ret[1], XK_k);
|
assert_int_equal(ret[1], XK_k);
|
||||||
|
|
||||||
free(ret);
|
free(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_wm_config_parse_bind_command(void **state)
|
||||||
|
{
|
||||||
|
char line1[] = "keybind Windows+h focus left";
|
||||||
|
|
||||||
|
ConfigFile file;
|
||||||
|
Config config;
|
||||||
|
ConfigCommand command;
|
||||||
|
|
||||||
|
char tmp[] = "/tmp/XXXXXX";
|
||||||
|
mkstemp(tmp);
|
||||||
|
|
||||||
|
wm_configfile_init(&file, tmp);
|
||||||
|
wm_configcommand_init(&command);
|
||||||
|
|
||||||
|
ParserResult res = wm_configfile_parse_line(&file, &config, line1, &command);
|
||||||
|
|
||||||
|
assert_true(res.success);
|
||||||
|
|
||||||
|
Keybind keybind = wm_config_parse_bind_command(&command);
|
||||||
|
|
||||||
|
assert_ptr_equal(keybind.function, &wm_kb_focus_dir);
|
||||||
|
assert_ptr_equal(keybind.args.i, LEFT);
|
||||||
|
|
||||||
|
wm_configfile_free(&file);
|
||||||
|
wm_configcommand_free(&command);
|
||||||
|
|
||||||
|
char line2[] = "keybind Alt+j move down";
|
||||||
|
|
||||||
|
file = (ConfigFile) {0};
|
||||||
|
config = (Config) {0};
|
||||||
|
command = (ConfigCommand) {0};
|
||||||
|
|
||||||
|
wm_configfile_init(&file, tmp);
|
||||||
|
wm_configcommand_init(&command);
|
||||||
|
|
||||||
|
res = wm_configfile_parse_line(&file, &config, line2, &command);
|
||||||
|
|
||||||
|
assert_true(res.success);
|
||||||
|
|
||||||
|
keybind = wm_config_parse_bind_command(&command);
|
||||||
|
|
||||||
|
assert_ptr_equal(keybind.function, &wm_kb_move_dir);
|
||||||
|
assert_ptr_equal(keybind.args.i, DOWN);
|
||||||
|
|
||||||
|
wm_configfile_free(&file);
|
||||||
|
wm_configcommand_free(&command);
|
||||||
|
|
||||||
|
char line3[] = "keybind Alt+1 switch_ws 1";
|
||||||
|
|
||||||
|
file = (ConfigFile) {0};
|
||||||
|
config = (Config) {0};
|
||||||
|
command = (ConfigCommand) {0};
|
||||||
|
|
||||||
|
wm_configfile_init(&file, tmp);
|
||||||
|
wm_configcommand_init(&command);
|
||||||
|
|
||||||
|
res = wm_configfile_parse_line(&file, &config, line3, &command);
|
||||||
|
|
||||||
|
assert_true(res.success);
|
||||||
|
|
||||||
|
keybind = wm_config_parse_bind_command(&command);
|
||||||
|
|
||||||
|
assert_ptr_equal(keybind.function, &wm_kb_switch_ws);
|
||||||
|
assert_ptr_equal(keybind.args.i, 1);
|
||||||
|
|
||||||
|
wm_configfile_free(&file);
|
||||||
|
wm_configcommand_free(&command);
|
||||||
|
unlink(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_wm_config(void **state)
|
||||||
|
{
|
||||||
|
char configstr[] =
|
||||||
|
"border_color #112233\n"
|
||||||
|
"focused_border_color #445566\n"
|
||||||
|
"border_width 1\n"
|
||||||
|
"keybind Windows+Alt+Shift+h focus left\n"
|
||||||
|
"focus_on_motion true\n";
|
||||||
|
|
||||||
|
char tmp[] = "/tmp/XXXXXX";
|
||||||
|
mkstemp(tmp);
|
||||||
|
|
||||||
|
int fd = open(tmp, O_CREAT | O_TRUNC | O_RDWR, 0664);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("open");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = write(fd, configstr, sizeof(configstr));
|
||||||
|
|
||||||
|
assert_int_equal(ret, sizeof(configstr));
|
||||||
|
|
||||||
|
ret = close(fd);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("close");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigFile file = (ConfigFile) {0};
|
||||||
|
Config config = (Config) {0};
|
||||||
|
|
||||||
|
wm_cfg_init_def(&config);
|
||||||
|
|
||||||
|
wm_configfile_init(&file, tmp);
|
||||||
|
wm_configfile_read(&file, &config);
|
||||||
|
|
||||||
|
assert_string_equal(config.border_col, "#112233");
|
||||||
|
assert_string_equal(config.focused_border_col, "#445566");
|
||||||
|
assert_int_equal(config.border_width, 1);
|
||||||
|
|
||||||
|
bool found_keybind = false;
|
||||||
|
for (size_t i = 0; i < config.kb_count; i++) {
|
||||||
|
if (config.keybinds[i].mask == (Mod4Mask | Mod1Mask | ShiftMask) &&
|
||||||
|
config.keybinds[i].keysym == XK_h &&
|
||||||
|
config.keybinds[i].function == &wm_kb_focus_dir &&
|
||||||
|
config.keybinds[i].args.i == LEFT)
|
||||||
|
found_keybind = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_true(found_keybind);
|
||||||
|
assert_true(config.focus_on_motion);
|
||||||
|
|
||||||
|
wm_configfile_free(&file);
|
||||||
|
wm_keybinds_free(&config);
|
||||||
|
free(config.keybinds);
|
||||||
|
unlink(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_wm_postorder_traversal(void **state)
|
static void test_wm_postorder_traversal(void **state)
|
||||||
{
|
{
|
||||||
TreeNode *node1 = (TreeNode*)*state;
|
TreeNode *node1 = (TreeNode*)*state;
|
||||||
@ -1059,6 +1188,8 @@ int main(void)
|
|||||||
cmocka_unit_test(test_wm_read_log),
|
cmocka_unit_test(test_wm_read_log),
|
||||||
cmocka_unit_test(test_wm_logentries_calculate_distances),
|
cmocka_unit_test(test_wm_logentries_calculate_distances),
|
||||||
cmocka_unit_test(test_wm_keybind_str_to_mask_keysym),
|
cmocka_unit_test(test_wm_keybind_str_to_mask_keysym),
|
||||||
|
cmocka_unit_test(test_wm_config_parse_bind_command),
|
||||||
|
cmocka_unit_test(test_wm_config),
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct CMUnitTest test_group2[] = {
|
const struct CMUnitTest test_group2[] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user