diff options
| author | Federico Angelilli <code@fedang.net> | 2024-11-21 03:18:20 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-11-21 03:18:20 +0100 |
| commit | cd39dc62e94cbbb5025740552aa09731c8911bf7 (patch) | |
| tree | c368cf483b0c3e5e0fb0730f7d8c2db898e9222d /src/event.c | |
| parent | 3049e4b1e3e6b36812be84cf794b55b019380c63 (diff) | |
Start working on mouse hover
Diffstat (limited to 'src/event.c')
| -rw-r--r-- | src/event.c | 187 |
1 files changed, 113 insertions, 74 deletions
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); + } } |
