diff options
| -rw-r--r-- | src/comet.c | 7 | ||||
| -rw-r--r-- | src/config.c | 1 | ||||
| -rw-r--r-- | src/event.c | 187 | ||||
| -rw-r--r-- | src/event.h | 3 | ||||
| -rw-r--r-- | src/window.c | 4 |
5 files changed, 125 insertions, 77 deletions
diff --git a/src/comet.c b/src/comet.c index cf39f8d..ad42c7a 100644 --- a/src/comet.c +++ b/src/comet.c @@ -63,7 +63,12 @@ static cairo_surface_t *render_all(layout_t *layout, config_t *config, layout_in int main(int argc, char **argv) { setlocale(LC_CTYPE, ""); - any_log_init(stdout, ANY_LOG_DEBUG); + + any_log_level_t log_level = ANY_LOG_DEBUG; + if (argc != 1 && !strcmp(argv[1], "--trace")) + log_level = ANY_LOG_TRACE; + + any_log_init(stdout, log_level); config_t config; config_init(&config); diff --git a/src/config.c b/src/config.c index 3e83390..fc1acf8 100644 --- a/src/config.c +++ b/src/config.c @@ -298,6 +298,7 @@ static config_status_t config_read_entry(const config_entry_t *entries, void *re "double float", "boolean", "color", + "gradient", "enum", "time", "list", diff --git a/src/event.c b/src/event.c index fa40a82..9ff3e61 100644 --- a/src/event.c +++ b/src/event.c @@ -9,6 +9,7 @@ const char *event_type_to_string(event_type_t type) { const char *types[] = { + "hover", "left_click", "middle_click", "right_click", @@ -17,10 +18,15 @@ const char *event_type_to_string(event_type_t type) "trigger", }; - assert(type >= EVENT_LEFT_CLICK && type <= EVENT_TRIGGER); + assert(type >= EVENT_HOVER && type <= EVENT_TRIGGER); return types[type]; } +bool event_is_hover(event_t event) +{ + return event.type == EVENT_HOVER; +} + bool event_is_click(event_t event) { return event.type == EVENT_LEFT_CLICK @@ -34,7 +40,7 @@ bool event_is_scroll(event_t event) || event.type == EVENT_SCROLL_DOWN; } -static bool event_mouse(layout_t *layout, event_t event) +static bool event_dispatch_mouse(layout_t *layout, event_t event) { int width = layout->width - 2 * layout->x_padding; int height = layout->height - 2 * layout->y_padding; @@ -43,7 +49,7 @@ static bool event_mouse(layout_t *layout, event_t event) return false; for (int i = 0; i < layout->n_children; i++) { - if (event_mouse(&layout->children[i], event)) + if (event_dispatch_mouse(&layout->children[i], event)) return true; } @@ -70,95 +76,128 @@ static bool event_mouse(layout_t *layout, event_t event) return true; } -void event_dispatch(display_t *display, layout_t *layout) +static void event_dispatch_once(display_t *display, layout_t *layout, xcb_generic_event_t *xevent) { - xcb_generic_event_t *xevent; + int type = xevent->response_type & ~0x80; + switch (type) { + case 0: { + xcb_generic_error_t *error = (xcb_generic_error_t *)xevent; + + const char *extension; + const char *name = xcb_errors_get_name_for_error(display->errors, error->error_code, &extension); + const char *major = xcb_errors_get_name_for_major_code(display->errors, error->major_code); + const char *minor = xcb_errors_get_name_for_minor_code(display->errors, error->major_code, error->minor_code); + + log_value_error("Xcb error", + "s:name", name, + "s:extension", extension ? extension : "none", + "s:major", major, + "s:minor", minor ? minor : "none", + "u:resource", (unsigned int)error->resource_id, + "u:sequence", (unsigned int)error->sequence); + + // TODO: Handle errors instead of aborting + abort(); + break; + } - while ((xevent = xcb_poll_for_event(display->connection)) != NULL) { - int type = xevent->response_type & ~0x80; - switch (type) { - case 0: { - xcb_generic_error_t *error = (xcb_generic_error_t *)xevent; - - const char *extension; - const char *name = xcb_errors_get_name_for_error(display->errors, error->error_code, &extension); - const char *major = xcb_errors_get_name_for_major_code(display->errors, error->major_code); - const char *minor = xcb_errors_get_name_for_minor_code(display->errors, error->major_code, error->minor_code); - - log_value_error("Xcb error", - "s:name", name, - "s:extension", extension ? extension : "none", - "s:major", major, - "s:minor", minor ? minor : "none", - "u:resource", (unsigned int)error->resource_id, - "u:sequence", (unsigned int)error->sequence); - - // TODO: Handle errors instead of aborting - abort(); - break; - } + case XCB_EXPOSE: { + xcb_expose_event_t *expose = (xcb_expose_event_t *)xevent; + log_trace("Processing 'Expose' event"); - case XCB_EXPOSE: { - xcb_expose_event_t *expose = (xcb_expose_event_t *)xevent; - log_trace("Processing 'Expose' event"); + // Redraw + (void)expose; + break; + } - // Redraw - (void)expose; - break; - } + case XCB_CREATE_NOTIFY: { + xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xevent; + log_trace("Processing 'CreateNotify' event"); + + // TODO: Circulate top the window if override_redirect == 0 + (void)create; + break; + } - case XCB_CREATE_NOTIFY: { - xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xevent; - log_trace("Processing 'CreateNotify' event"); + case XCB_BUTTON_RELEASE: { + xcb_button_release_event_t *button = (xcb_button_release_event_t *)xevent; + log_trace("Processing 'ButtonRelease' event"); - // TODO: Circulate top the window if override_redirect == 0 - (void)create; + if (button->detail < XCB_BUTTON_INDEX_1 || button->detail > XCB_BUTTON_INDEX_5) { + log_value_trace("Ignoring button release", + "u:value", button->detail); break; } - case XCB_BUTTON_RELEASE: { - xcb_button_release_event_t *button = (xcb_button_release_event_t *)xevent; - log_trace("Processing 'ButtonRelease' event"); + event_t event = { + .x = button->event_x, + .y = button->event_y, + .type = button->detail, + }; - if (button->detail < XCB_BUTTON_INDEX_1 || button->detail > XCB_BUTTON_INDEX_5) { - log_value_trace("Ignoring button release", - "u:value", button->detail); - break; - } + event_dispatch_mouse(layout, event); + break; + } - event_t event = { - .x = button->event_x, - .y = button->event_y, - .type = button->detail - 1, - }; + case XCB_PROPERTY_NOTIFY: { + xcb_property_notify_event_t *property = (xcb_property_notify_event_t *)xevent; + log_trace("Processing 'PropertyNotify' event"); - event_mouse(layout, event); - break; + if (property->atom == XCB_ATOM_RESOURCE_MANAGER) { + display_update_xrm(display); + display_update_scale(display); + // Redraw } + break; + } - case XCB_PROPERTY_NOTIFY: { - xcb_property_notify_event_t *property = (xcb_property_notify_event_t *)xevent; - log_trace("Processing 'PropertyNotify' event"); + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xevent; + log_trace("Processing 'MotionNotify' event"); - if (property->atom == XCB_ATOM_RESOURCE_MANAGER) { - display_update_xrm(display); - display_update_scale(display); - // Redraw - } - break; - } + event_t event = { + .x = motion->event_x, + .y = motion->event_y, + .type = EVENT_HOVER, + }; - default: { - const char *extension; - const char *name = xcb_errors_get_name_for_xcb_event(display->errors, xevent, &extension); + event_dispatch_mouse(layout, event); + break; + } - log_value_trace("Ignoring Xcb event", - "s:name", name, - "u:type", xevent->response_type & 0x7f, - "s:extension", extension ? extension : "none"); - break; - } + default: { + const char *extension; + const char *name = xcb_errors_get_name_for_xcb_event(display->errors, xevent, &extension); + + log_value_trace("Ignoring Xcb event", + "s:name", name, + "u:type", xevent->response_type & 0x7f, + "s:extension", extension ? extension : "none"); + break; + } + } +} + +void event_dispatch(display_t *display, layout_t *layout) +{ + xcb_generic_event_t *xevent, *motion = NULL; + while ((xevent = xcb_poll_for_event(display->connection)) != NULL) { + + int type = xevent->response_type & ~0x80; + if (type == XCB_MOTION_NOTIFY) { + free(motion); + motion = xevent; + continue; } + + event_dispatch_once(display, layout, xevent); free(xevent); } + + // We only consider the last motion notify received + // + if (motion != NULL) { + event_dispatch_once(display, layout, motion); + free(motion); + } } diff --git a/src/event.h b/src/event.h index 5cc626d..1197afa 100644 --- a/src/event.h +++ b/src/event.h @@ -4,6 +4,7 @@ #include "display.h" typedef enum { + EVENT_HOVER, EVENT_LEFT_CLICK, EVENT_MIDDLE_CLICK, EVENT_RIGHT_CLICK, @@ -21,6 +22,8 @@ typedef struct layout layout_t; const char *event_type_to_string(event_type_t type); +bool event_is_hover(event_t event); + bool event_is_click(event_t event); bool event_is_scroll(event_t event); diff --git a/src/window.c b/src/window.c index 24ecd07..b4b68bd 100644 --- a/src/window.c +++ b/src/window.c @@ -99,8 +99,8 @@ void window_init(window_t *window, display_t *display, config_t *config) uint32_t event_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_FOCUS_CHANGE - | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS; - //| XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT; + | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS + | XCB_EVENT_MASK_POINTER_MOTION; xcb_colormap_t colormap = xcb_generate_id(display->connection); xcb_create_colormap(display->connection, XCB_COLORMAP_ALLOC_NONE, colormap, |
