mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
src/rcxml.c: parse <keybind>
This commit is contained in:
parent
f6578248c0
commit
158f42d1e8
11 changed files with 108 additions and 50 deletions
20
data/rc.xml
20
data/rc.xml
|
|
@ -14,13 +14,21 @@
|
||||||
</keyboard>
|
</keyboard>
|
||||||
</lab>
|
</lab>
|
||||||
|
|
||||||
<!-- keybinds have not been implemented yet. For the time being, we use the
|
|
||||||
following:
|
|
||||||
- Alt+Escape Exit labwc
|
|
||||||
- Alt+F2 Cycle windows
|
|
||||||
- Alt+F3 Launch dmenu -->
|
|
||||||
<keyboard>
|
<keyboard>
|
||||||
|
<keybind key="A-Escape">
|
||||||
|
<action name="Exit"/>
|
||||||
|
</keybind>
|
||||||
|
<keybind key="A-Tab">
|
||||||
|
<action name="NextWindow"/>
|
||||||
|
</keybind>
|
||||||
|
<keybind key="A-F2">
|
||||||
|
<action name="NextWindow"/>
|
||||||
|
</keybind>
|
||||||
|
<keybind key="A-F3">
|
||||||
|
<action name="Execute">
|
||||||
|
<command>dmenu_run</command>
|
||||||
|
</action>
|
||||||
|
</keybind>
|
||||||
</keyboard>
|
</keyboard>
|
||||||
|
|
||||||
</openbox_config>
|
</openbox_config>
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,24 @@
|
||||||
|
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
|
||||||
|
#define BUG_ON(condition) \
|
||||||
|
do { \
|
||||||
|
if ((condition) != 0) { \
|
||||||
|
fprintf(stderr, "Badness in %s() at %s:%d\n", \
|
||||||
|
__func__, __FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
struct keybind {
|
struct keybind {
|
||||||
uint32_t modifiers;
|
uint32_t modifiers;
|
||||||
xkb_keysym_t *keysyms;
|
xkb_keysym_t *keysyms;
|
||||||
size_t keysyms_len;
|
size_t keysyms_len;
|
||||||
char *action;
|
char *action;
|
||||||
|
char *command;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
void keybind_add(struct wl_list *keybinds, const char *keybind, const char *action);
|
struct keybind *keybind_add(const char *keybind);
|
||||||
void keybind_init();
|
|
||||||
void keybind_print();
|
|
||||||
|
|
||||||
struct rcxml {
|
struct rcxml {
|
||||||
bool client_side_decorations;
|
bool client_side_decorations;
|
||||||
|
|
@ -28,7 +35,6 @@ struct rcxml {
|
||||||
|
|
||||||
extern struct rcxml rc;
|
extern struct rcxml rc;
|
||||||
|
|
||||||
void rcxml_init();
|
|
||||||
void rcxml_parse_xml(struct buf *b);
|
void rcxml_parse_xml(struct buf *b);
|
||||||
void rcxml_read(const char *filename);
|
void rcxml_read(const char *filename);
|
||||||
void rcxml_get_nodenames(struct buf *b);
|
void rcxml_get_nodenames(struct buf *b);
|
||||||
|
|
|
||||||
6
include/spawn.h
Normal file
6
include/spawn.h
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef SPAWN_H
|
||||||
|
#define SPAWN_H
|
||||||
|
|
||||||
|
void spawn_async_no_shell(char const *command);
|
||||||
|
|
||||||
|
#endif /* SPAWN_H */
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
#include "spawn.h"
|
||||||
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
|
|
@ -11,8 +12,7 @@ void action(struct server *server, struct keybind *keybind)
|
||||||
} else if (!strcasecmp(keybind->action, "NextWindow")) {
|
} else if (!strcasecmp(keybind->action, "NextWindow")) {
|
||||||
server->cycle_view = next_toplevel(view_front_toplevel(server));
|
server->cycle_view = next_toplevel(view_front_toplevel(server));
|
||||||
} else if (!strcasecmp(keybind->action, "Execute")) {
|
} else if (!strcasecmp(keybind->action, "Execute")) {
|
||||||
if (!fork())
|
spawn_async_no_shell(keybind->command);
|
||||||
execl("/bin/dmenu_run", "/bin/dmenu_run", (void *)NULL);
|
|
||||||
} else if (!strcasecmp(keybind->action, "debug-views")) {
|
} else if (!strcasecmp(keybind->action, "debug-views")) {
|
||||||
dbg_show_views(server);
|
dbg_show_views(server);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
labwc_sources += files(
|
labwc_sources += files(
|
||||||
'buf.c',
|
'buf.c',
|
||||||
|
'spawn.c',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
22
src/common/spawn.c
Normal file
22
src/common/spawn.c
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
void spawn_async_no_shell(char const *command)
|
||||||
|
{
|
||||||
|
GError *err = NULL;
|
||||||
|
gchar **argv = NULL;
|
||||||
|
|
||||||
|
g_shell_parse_argv((gchar *)command, NULL, &argv, &err);
|
||||||
|
if (err) {
|
||||||
|
g_message("%s", err->message);
|
||||||
|
g_error_free(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_spawn_async(NULL, argv, NULL,
|
||||||
|
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||||
|
NULL, NULL, NULL, &err);
|
||||||
|
if (err) {
|
||||||
|
g_message("%s", err->message);
|
||||||
|
g_error_free(err);
|
||||||
|
}
|
||||||
|
g_strfreev(argv);
|
||||||
|
}
|
||||||
|
|
@ -20,8 +20,7 @@ static uint32_t parse_modifier(const char *symname)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void keybind_add(struct wl_list *keybinds, const char *keybind,
|
struct keybind *keybind_add(const char *keybind)
|
||||||
const char *action)
|
|
||||||
{
|
{
|
||||||
struct keybind *k = calloc(1, sizeof(struct keybind));
|
struct keybind *k = calloc(1, sizeof(struct keybind));
|
||||||
xkb_keysym_t keysyms[32];
|
xkb_keysym_t keysyms[32];
|
||||||
|
|
@ -47,16 +46,10 @@ void keybind_add(struct wl_list *keybinds, const char *keybind,
|
||||||
}
|
}
|
||||||
g_strfreev(symnames);
|
g_strfreev(symnames);
|
||||||
if (!k)
|
if (!k)
|
||||||
return;
|
return NULL;
|
||||||
wl_list_insert(keybinds, &k->link);
|
wl_list_insert(&rc.keybinds, &k->link);
|
||||||
k->action = strdup(action);
|
|
||||||
k->keysyms = malloc(k->keysyms_len * sizeof(xkb_keysym_t));
|
k->keysyms = malloc(k->keysyms_len * sizeof(xkb_keysym_t));
|
||||||
memcpy(k->keysyms, keysyms, k->keysyms_len * sizeof(xkb_keysym_t));
|
memcpy(k->keysyms, keysyms, k->keysyms_len * sizeof(xkb_keysym_t));
|
||||||
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
void keybind_init()
|
|
||||||
{
|
|
||||||
keybind_add(&rc.keybinds, "A-Escape", "Exit");
|
|
||||||
keybind_add(&rc.keybinds, "A-Tab", "NextWindow");
|
|
||||||
keybind_add(&rc.keybinds, "A-F3", "Execute");
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ static bool in_keybind = false;
|
||||||
static bool is_attribute = false;
|
static bool is_attribute = false;
|
||||||
static bool write_to_nodename_buffer = false;
|
static bool write_to_nodename_buffer = false;
|
||||||
static struct buf *nodename_buffer;
|
static struct buf *nodename_buffer;
|
||||||
|
static struct keybind *current_keybind;
|
||||||
|
|
||||||
static void rstrip(char *buf, const char *pattern)
|
static void rstrip(char *buf, const char *pattern)
|
||||||
{
|
{
|
||||||
|
|
@ -27,9 +28,21 @@ static void rstrip(char *buf, const char *pattern)
|
||||||
|
|
||||||
static void fill_keybind(xmlNode *n, char *nodename, char *content)
|
static void fill_keybind(xmlNode *n, char *nodename, char *content)
|
||||||
{
|
{
|
||||||
|
if (!content)
|
||||||
|
return;
|
||||||
rstrip(nodename, ".keybind.keyboard");
|
rstrip(nodename, ".keybind.keyboard");
|
||||||
|
if (!strcmp(nodename, "key")) {
|
||||||
|
current_keybind = keybind_add(content);
|
||||||
|
fprintf(stderr, "[bind] %s: ", content);
|
||||||
|
}
|
||||||
|
/* We expect <keybind key=""> to come first */
|
||||||
|
BUG_ON(!current_keybind);
|
||||||
if (!strcmp(nodename, "name.action")) {
|
if (!strcmp(nodename, "name.action")) {
|
||||||
; /* TODO: populate keybind with stuff */
|
current_keybind->action = strdup(content);
|
||||||
|
fprintf(stderr, "%s", content);
|
||||||
|
} else if (!strcmp(nodename, "command.action")) {
|
||||||
|
current_keybind->command = strdup(content);
|
||||||
|
fprintf(stderr, " - %s", content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,18 +82,6 @@ static void entry(xmlNode *node, char *nodename, char *content)
|
||||||
setenv("XKB_DEFAULT_LAYOUT", content, 1);
|
setenv("XKB_DEFAULT_LAYOUT", content, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keybind_begin(void)
|
|
||||||
{
|
|
||||||
/* TODO: xcalloc struct keybind */
|
|
||||||
in_keybind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void keybind_end(void)
|
|
||||||
{
|
|
||||||
in_keybind = false;
|
|
||||||
/* TODO: wl_list_add keybind */
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *nodename(xmlNode *node, char *buf, int len)
|
static char *nodename(xmlNode *node, char *buf, int len)
|
||||||
{
|
{
|
||||||
if (!node || !node->name)
|
if (!node || !node->name)
|
||||||
|
|
@ -141,9 +142,10 @@ static void xml_tree_walk(xmlNode *node)
|
||||||
if (!strcasecmp((char *)n->name, "comment"))
|
if (!strcasecmp((char *)n->name, "comment"))
|
||||||
continue;
|
continue;
|
||||||
if (!strcasecmp((char *)n->name, "keybind")) {
|
if (!strcasecmp((char *)n->name, "keybind")) {
|
||||||
keybind_begin();
|
in_keybind = true;
|
||||||
traverse(n);
|
traverse(n);
|
||||||
keybind_end();
|
in_keybind = false;
|
||||||
|
fprintf(stderr, "\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
traverse(n);
|
traverse(n);
|
||||||
|
|
@ -163,11 +165,29 @@ void rcxml_parse_xml(struct buf *b)
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_init()
|
static void rcxml_init()
|
||||||
{
|
{
|
||||||
LIBXML_TEST_VERSION
|
LIBXML_TEST_VERSION
|
||||||
wl_list_init(&rc.keybinds);
|
}
|
||||||
keybind_init();
|
|
||||||
|
static void bind(const char *binding, const char *action)
|
||||||
|
{
|
||||||
|
if (!binding || !action)
|
||||||
|
return;
|
||||||
|
struct keybind *k = keybind_add(binding);
|
||||||
|
if (k)
|
||||||
|
k->action = strdup(action);
|
||||||
|
fprintf(stderr, "binding: %s: %s\n", binding, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void post_processing(void)
|
||||||
|
{
|
||||||
|
if (!wl_list_length(&rc.keybinds)) {
|
||||||
|
fprintf(stderr, "info: loading default key bindings\n");
|
||||||
|
bind("A-Escape", "Exit");
|
||||||
|
bind("A-Tab", "NextWindow");
|
||||||
|
bind("A-F3", "Execute");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_read(const char *filename)
|
void rcxml_read(const char *filename)
|
||||||
|
|
@ -177,11 +197,14 @@ void rcxml_read(const char *filename)
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
struct buf b;
|
struct buf b;
|
||||||
|
|
||||||
|
rcxml_init();
|
||||||
|
wl_list_init(&rc.keybinds);
|
||||||
|
|
||||||
/* Read <filename> into buffer and then call rcxml_parse_xml() */
|
/* Read <filename> into buffer and then call rcxml_parse_xml() */
|
||||||
stream = fopen(filename, "r");
|
stream = fopen(filename, "r");
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
fprintf(stderr, "warn: cannot read '%s'\n", filename);
|
fprintf(stderr, "warn: cannot read '%s'\n", filename);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
buf_init(&b);
|
buf_init(&b);
|
||||||
while (getline(&line, &len, stream) != -1) {
|
while (getline(&line, &len, stream) != -1) {
|
||||||
|
|
@ -194,6 +217,8 @@ void rcxml_read(const char *filename)
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
rcxml_parse_xml(&b);
|
rcxml_parse_xml(&b);
|
||||||
free(b.buf);
|
free(b.buf);
|
||||||
|
out:
|
||||||
|
post_processing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_get_nodenames(struct buf *b)
|
void rcxml_get_nodenames(struct buf *b)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcxml_init();
|
|
||||||
rcxml_read("data/rc.xml");
|
rcxml_read("data/rc.xml");
|
||||||
theme_read("data/themerc");
|
theme_read("data/themerc");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ int main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
write(fd, src, sizeof(src) - 1);
|
write(fd, src, sizeof(src) - 1);
|
||||||
|
|
||||||
rcxml_init();
|
|
||||||
rcxml_read(template);
|
rcxml_read(template);
|
||||||
unlink(template);
|
unlink(template);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ int main(int argc, char **argv)
|
||||||
plan(1);
|
plan(1);
|
||||||
diag("Parse simple rc.xml and read nodenames");
|
diag("Parse simple rc.xml and read nodenames");
|
||||||
|
|
||||||
rcxml_init();
|
|
||||||
rcxml_get_nodenames(&actual);
|
rcxml_get_nodenames(&actual);
|
||||||
rcxml_parse_xml(&source);
|
rcxml_parse_xml(&source);
|
||||||
printf("%s\n", actual.buf);
|
printf("%s\n", actual.buf);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue