aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/action.c17
-rw-r--r--src/block.h1
-rw-r--r--src/comet.c1
-rw-r--r--src/config.c36
-rw-r--r--src/event.c16
-rw-r--r--src/event.h2
-rw-r--r--valgrind.supp13
7 files changed, 72 insertions, 14 deletions
diff --git a/src/action.c b/src/action.c
index c8ccee1..2ceae9b 100644
--- a/src/action.c
+++ b/src/action.c
@@ -3,6 +3,7 @@
#include "action.h"
#include "block.h"
+#include "any_log.h"
void action_perform(action_t *action, block_t *block, config_t *config)
{
@@ -13,9 +14,15 @@ void action_perform(action_t *action, block_t *block, config_t *config)
if (strncmp(key, "block.", 6))
abort();
+ int sep = 6;
+ while (key[sep] != '.' && key[sep] != '\0') sep++;
+
+ if (key[sep] == '\0') abort();
+
block_t *target = NULL;
for (size_t i = 0; i < config->n_blocks; i++) {
- if (!strcmp(key + 6, config->blocks[i]->label)) {
+ size_t length = strlen(config->blocks[i]->label);
+ if (length == (sep - 6) && !strncmp(key + 6, config->blocks[i]->label, length)) {
target = config->blocks[i];
break;
}
@@ -24,8 +31,15 @@ void action_perform(action_t *action, block_t *block, config_t *config)
if (target == NULL)
abort();
+ if (target->scheme->change_fn == NULL) {
+ log_warn("Block '%s' does not support changing values", target->label);
+ continue;
+ }
+
block_change(target, key, value);
}
+
+ log_debug("Performed action '%s'", action->label);
}
int action_validate(action_t *action, config_t *config)
@@ -42,4 +56,5 @@ void action_free(action_t *action)
}
free(action->parts);
+ free(action->label);
}
diff --git a/src/block.h b/src/block.h
index 896eb8a..73490ad 100644
--- a/src/block.h
+++ b/src/block.h
@@ -63,6 +63,7 @@ struct block {
unsigned int line_width;
unsigned int x_padding, y_padding;
unsigned int min_width, max_width;
+ action_t *actions; //[EVENT_LENGTH];
};
typedef struct {
diff --git a/src/comet.c b/src/comet.c
index be07826..21fae78 100644
--- a/src/comet.c
+++ b/src/comet.c
@@ -133,6 +133,7 @@ int main(int argc, char **argv)
rate.tv_nsec = (freq - rate.tv_sec) * 1000000000ul;
event_state_t state = { 0 };
+ state.config = &config;
while (running) {
timespec_get(&start, TIME_UTC);
diff --git a/src/config.c b/src/config.c
index d20aebe..619d95c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -41,6 +41,7 @@ static const config_entry_t block_entries[] = {
{ "min-width", CONFIG_UINT, NULL, offsetof(block_t, min_width) },
{ "max-width", CONFIG_UINT, NULL, offsetof(block_t, max_width) },
{ "interval", CONFIG_TIME, NULL, offsetof(block_t, update_interval) },
+ { "action", CONFIG_STRING, NULL, offsetof(block_t, actions) },
{ 0 },
};
@@ -574,7 +575,8 @@ int config_read(config_t *config, FILE *file)
"s:value", value,
"i:line", ini.line);
- if (!bar_section && block == NULL)
+ // Skip unknown sections
+ if (!bar_section && block == NULL && action == NULL)
goto skip_pair;
const char *type;
@@ -669,10 +671,32 @@ int config_validate(config_t *config)
return errors;
}
+bool config_resolve_action(config_t *config, block_t *block)
+{
+ char *label = (char *)block->actions;
+
+ if (label == NULL) return true;
+
+ for (size_t j = 0; j < config->n_actions; j++) {
+ if (!strcmp(label, config->actions[j].label)) {
+ log_debug("Block '%s' uses action '%s'", block->label, label);
+ free(label);
+ block->actions = &config->actions[j];
+ return true;
+ }
+ }
+
+ log_error("Action '%s' not found", label);
+ return false;
+}
+
bool config_resolve_children(config_t *config, block_t *block)
{
block->resolved = true;
+ if (!config_resolve_action(config, block))
+ return false;
+
if (block->type != BLOCK_GROUP)
return true;
@@ -698,11 +722,11 @@ bool config_resolve_children(config_t *config, block_t *block)
if (!strcmp(children[i], config->blocks[j]->label)) {
if (config->blocks[j]->resolved) {
- log_error("Block '%s' can only be referenced by one block", config->blocks[j]->label);
+ log_error("Block '%s' can only be referenced by one block", children[i]);
goto error;
}
- log_debug("Block '%s' is parent of '%s'", block->label, config->blocks[j]->label);
+ log_debug("Block '%s' is parent of '%s'", block->label, children[i]);
group->children[i] = config->blocks[j];
if (!config_resolve_children(config, config->blocks[j]))
@@ -747,12 +771,14 @@ void config_free(config_t *config)
for (size_t i = 0; i < config->n_blocks; i++)
block_free(config->blocks[i]);
+ free(config->blocks);
+
for (size_t i = 0; i < config->n_actions; i++)
action_free(&config->actions[i]);
- gradient_free(&config->background);
+ free(config->actions);
- free(config->blocks);
+ gradient_free(&config->background);
free(config->font);
free(config->monitor);
}
diff --git a/src/event.c b/src/event.c
index c2c98ab..c226bea 100644
--- a/src/event.c
+++ b/src/event.c
@@ -5,10 +5,11 @@
#include "layout.h"
#include "event.h"
#include "block.h"
+#include "action.h"
const char *event_type_to_string(event_type_t type)
{
- const char *types[] = {
+ const char *types[EVENT_LENGTH] = {
"trigger",
"left_click",
"middle_click",
@@ -20,7 +21,7 @@ const char *event_type_to_string(event_type_t type)
"hover_stop",
};
- assert(type >= EVENT_TRIGGER && type <= EVENT_HOVER_STOP);
+ assert(type >= EVENT_TRIGGER && type < EVENT_LENGTH);
return types[type];
}
@@ -62,7 +63,7 @@ static layout_t *event_dispatch_find(block_t *block, layout_t *layout)
return NULL;
}
-static void event_dispatch_callback(layout_t *layout, event_t event)
+static void event_dispatch_callback(event_state_t *state, layout_t *layout, event_t event)
{
block_event_t event_fn = layout->block->type == BLOCK_SPEC
? ((block_spec_t *)layout->block)->event_fn
@@ -77,8 +78,13 @@ static void event_dispatch_callback(layout_t *layout, event_t event)
"i:y", layout->y,
"i:width", layout->width,
"i:height", layout->height,
+ "b:action", layout->block->actions != NULL,
"b:callback", event_fn != NULL);
+ if (layout->block->actions != NULL) {
+ action_perform(layout->block->actions, layout->block, state->config);
+ }
+
if (event_fn != NULL) {
event_fn(layout, event);
log_trace("Completed event callback");
@@ -98,7 +104,7 @@ static void event_dispatch_callback_block(event_state_t *state, block_t *block,
? &tmp
: event_dispatch_find(block, state->layout);
- event_dispatch_callback(l, event);
+ event_dispatch_callback(state, l, event);
}
static bool event_dispatch_mouse(event_state_t *state, layout_t *layout, event_t event)
@@ -140,7 +146,7 @@ static bool event_dispatch_mouse(event_state_t *state, layout_t *layout, event_t
}
}
- event_dispatch_callback(layout, event);
+ event_dispatch_callback(state, layout, event);
return true;
}
diff --git a/src/event.h b/src/event.h
index 40424b7..3ebc718 100644
--- a/src/event.h
+++ b/src/event.h
@@ -16,6 +16,7 @@ typedef enum {
EVENT_HOVER_START,
EVENT_HOVER_MOVE,
EVENT_HOVER_STOP,
+ EVENT_LENGTH,
} event_type_t;
typedef struct {
@@ -27,6 +28,7 @@ typedef struct {
layout_t hovered;
int hover_x, hover_y;
layout_t *layout;
+ config_t *config;
} event_state_t;
const char *event_type_to_string(event_type_t type);
diff --git a/valgrind.supp b/valgrind.supp
index 5be2434..b256691 100644
--- a/valgrind.supp
+++ b/valgrind.supp
@@ -2,9 +2,7 @@
{
fontconfig_pango_leaks
Memcheck:Leak
- fun:*alloc
- ...
- obj:*fontconfig*
+ fun:*alloc*
...
obj:*pango*
...
@@ -28,3 +26,12 @@
fun:cairo_xcb_surface_create
...
}
+
+# Just why
+{
+ another_cairo_leak
+ Memcheck:Leak
+ ...
+ fun:pango_cairo_font_map_get_default
+ ...
+}