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>
|
||||
</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>
|
||||
|
||||
<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>
|
||||
|
||||
</openbox_config>
|
||||
|
|
|
|||
|
|
@ -9,17 +9,24 @@
|
|||
|
||||
#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 {
|
||||
uint32_t modifiers;
|
||||
xkb_keysym_t *keysyms;
|
||||
size_t keysyms_len;
|
||||
char *action;
|
||||
struct wl_list link;
|
||||
uint32_t modifiers;
|
||||
xkb_keysym_t *keysyms;
|
||||
size_t keysyms_len;
|
||||
char *action;
|
||||
char *command;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
void keybind_add(struct wl_list *keybinds, const char *keybind, const char *action);
|
||||
void keybind_init();
|
||||
void keybind_print();
|
||||
struct keybind *keybind_add(const char *keybind);
|
||||
|
||||
struct rcxml {
|
||||
bool client_side_decorations;
|
||||
|
|
@ -28,7 +35,6 @@ struct rcxml {
|
|||
|
||||
extern struct rcxml rc;
|
||||
|
||||
void rcxml_init();
|
||||
void rcxml_parse_xml(struct buf *b);
|
||||
void rcxml_read(const char *filename);
|
||||
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 "spawn.h"
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
|
|
@ -11,8 +12,7 @@ void action(struct server *server, struct keybind *keybind)
|
|||
} else if (!strcasecmp(keybind->action, "NextWindow")) {
|
||||
server->cycle_view = next_toplevel(view_front_toplevel(server));
|
||||
} else if (!strcasecmp(keybind->action, "Execute")) {
|
||||
if (!fork())
|
||||
execl("/bin/dmenu_run", "/bin/dmenu_run", (void *)NULL);
|
||||
spawn_async_no_shell(keybind->command);
|
||||
} else if (!strcasecmp(keybind->action, "debug-views")) {
|
||||
dbg_show_views(server);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
labwc_sources += files(
|
||||
'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;
|
||||
}
|
||||
|
||||
void keybind_add(struct wl_list *keybinds, const char *keybind,
|
||||
const char *action)
|
||||
struct keybind *keybind_add(const char *keybind)
|
||||
{
|
||||
struct keybind *k = calloc(1, sizeof(struct keybind));
|
||||
xkb_keysym_t keysyms[32];
|
||||
|
|
@ -47,16 +46,10 @@ void keybind_add(struct wl_list *keybinds, const char *keybind,
|
|||
}
|
||||
g_strfreev(symnames);
|
||||
if (!k)
|
||||
return;
|
||||
wl_list_insert(keybinds, &k->link);
|
||||
k->action = strdup(action);
|
||||
return NULL;
|
||||
wl_list_insert(&rc.keybinds, &k->link);
|
||||
k->keysyms = malloc(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 write_to_nodename_buffer = false;
|
||||
static struct buf *nodename_buffer;
|
||||
static struct keybind *current_keybind;
|
||||
|
||||
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)
|
||||
{
|
||||
if (!content)
|
||||
return;
|
||||
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")) {
|
||||
; /* 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!node || !node->name)
|
||||
|
|
@ -141,9 +142,10 @@ static void xml_tree_walk(xmlNode *node)
|
|||
if (!strcasecmp((char *)n->name, "comment"))
|
||||
continue;
|
||||
if (!strcasecmp((char *)n->name, "keybind")) {
|
||||
keybind_begin();
|
||||
in_keybind = true;
|
||||
traverse(n);
|
||||
keybind_end();
|
||||
in_keybind = false;
|
||||
fprintf(stderr, "\n");
|
||||
continue;
|
||||
}
|
||||
traverse(n);
|
||||
|
|
@ -163,11 +165,29 @@ void rcxml_parse_xml(struct buf *b)
|
|||
xmlCleanupParser();
|
||||
}
|
||||
|
||||
void rcxml_init()
|
||||
static void rcxml_init()
|
||||
{
|
||||
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)
|
||||
|
|
@ -177,11 +197,14 @@ void rcxml_read(const char *filename)
|
|||
size_t len = 0;
|
||||
struct buf b;
|
||||
|
||||
rcxml_init();
|
||||
wl_list_init(&rc.keybinds);
|
||||
|
||||
/* Read <filename> into buffer and then call rcxml_parse_xml() */
|
||||
stream = fopen(filename, "r");
|
||||
if (!stream) {
|
||||
fprintf(stderr, "warn: cannot read '%s'\n", filename);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
buf_init(&b);
|
||||
while (getline(&line, &len, stream) != -1) {
|
||||
|
|
@ -194,6 +217,8 @@ void rcxml_read(const char *filename)
|
|||
fclose(stream);
|
||||
rcxml_parse_xml(&b);
|
||||
free(b.buf);
|
||||
out:
|
||||
post_processing();
|
||||
}
|
||||
|
||||
void rcxml_get_nodenames(struct buf *b)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
rcxml_init();
|
||||
rcxml_read("data/rc.xml");
|
||||
theme_read("data/themerc");
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
write(fd, src, sizeof(src) - 1);
|
||||
|
||||
rcxml_init();
|
||||
rcxml_read(template);
|
||||
unlink(template);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ int main(int argc, char **argv)
|
|||
plan(1);
|
||||
diag("Parse simple rc.xml and read nodenames");
|
||||
|
||||
rcxml_init();
|
||||
rcxml_get_nodenames(&actual);
|
||||
rcxml_parse_xml(&source);
|
||||
printf("%s\n", actual.buf);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue