diff options
| author | Federico Angelilli <code@fedang.net> | 2024-11-23 23:19:32 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-11-23 23:19:32 +0100 |
| commit | 828c4af8886b970fba9edcbaa5c6a97916ad4aa8 (patch) | |
| tree | a9d26db24d03ce0f5ffcf744e99e95d8620384b4 /src/event.c | |
| parent | 669fb0b98bc6802a34d7577f597f1a5aeb691e22 (diff) | |
Temporalily fix hidden block event
Diffstat (limited to 'src/event.c')
| -rw-r--r-- | src/event.c | 112 |
1 files changed, 79 insertions, 33 deletions
diff --git a/src/event.c b/src/event.c index 3c1ae81..c2c98ab 100644 --- a/src/event.c +++ b/src/event.c @@ -24,11 +24,9 @@ const char *event_type_to_string(event_type_t type) return types[type]; } -bool event_is_hover(event_t event) +bool event_is_trigger(event_t event) { - return event.type == EVENT_HOVER_START - || event.type == EVENT_HOVER_MOVE - || event.type == EVENT_HOVER_STOP; + return event.type == EVENT_TRIGGER; } bool event_is_click(event_t event) @@ -44,13 +42,33 @@ bool event_is_scroll(event_t event) || event.type == EVENT_SCROLL_DOWN; } +bool event_is_hover(event_t event) +{ + return event.type == EVENT_HOVER_START + || event.type == EVENT_HOVER_MOVE + || event.type == EVENT_HOVER_STOP; +} + +static layout_t *event_dispatch_find(block_t *block, layout_t *layout) +{ + if (layout->block == block) + return layout; + + for (size_t i = 0; i < layout->n_children; i++) { + layout_t *l = event_dispatch_find(block, &layout->children[i]); + if (l != NULL) return l; + } + + return NULL; +} + static void event_dispatch_callback(layout_t *layout, event_t event) { block_event_t event_fn = layout->block->type == BLOCK_SPEC ? ((block_spec_t *)layout->block)->event_fn : NULL; - log_value_debug("Block received a mouse event", + log_value_debug("Block received an event", "s:event", event_type_to_string(event.type), "i:event_x", event.x, "i:event_y", event.y, @@ -67,19 +85,20 @@ static void event_dispatch_callback(layout_t *layout, event_t event) } } -static bool event_dispatch_block(layout_t *layout, block_t *block, event_t event) +static void event_dispatch_callback_block(event_state_t *state, block_t *block, event_t event) { - if (layout->block == block) { - event_dispatch_callback(layout, event); - return true; - } + layout_t tmp = { + .block = block, + }; - for (int i = 0; i < layout->n_children; i++) { - if (event_dispatch_block(&layout->children[i], block, event)) - return true; - } + // XXX: As a workaround we are making a mock layout when we have to update an hidden block + // Fix this ugliness please + // + layout_t *l = block->hidden + ? &tmp + : event_dispatch_find(block, state->layout); - return false; + event_dispatch_callback(l, event); } static bool event_dispatch_mouse(event_state_t *state, layout_t *layout, event_t event) @@ -90,18 +109,34 @@ static bool event_dispatch_mouse(event_state_t *state, layout_t *layout, event_t if (!check_capsule(event.x, event.y, layout->x, layout->y, width, height)) return false; - for (int i = 0; i < layout->n_children; i++) { + for (size_t i = 0; i < layout->n_children; i++) { if (event_dispatch_mouse(state, &layout->children[i], event)) return true; } if (event_is_hover(event)) { - if (layout->block != state->hovered) { - event.type = EVENT_HOVER_STOP; - event_dispatch_block(state->layout, state->hovered, event); + // Compare only the part related to position and size + // + bool update = !memcmp(&state->hovered, layout, offsetof(layout_t, line_width)) + && event.x == state->hover_x + && event.y == state->hover_y; + + state->hover_x = event.x; + state->hover_y = event.y; + + if (layout->block != state->hovered.block) { + if (state->hovered.block != NULL) { + event.type = EVENT_HOVER_STOP; + event_dispatch_callback_block(state, state->hovered.block, event); + } event.type = EVENT_HOVER_START; - state->hovered = layout->block; + memcpy(&state->hovered, layout, sizeof(layout_t)); + + } else if (update) { + // Ignore a move with equal cursor position + // + return true; } } @@ -111,6 +146,18 @@ static bool event_dispatch_mouse(event_state_t *state, layout_t *layout, event_t void event_dispatch(event_state_t *state, window_t *window) { + // Check last cursor position again + // + if (state->hovered.block != NULL) { + event_t event = { + .type = EVENT_HOVER_MOVE, + .x = state->hover_x, + .y = state->hover_y, + }; + + event_dispatch_mouse(state, state->layout, event); + } + xcb_generic_event_t *xevent; xcb_motion_notify_event_t *motion = NULL; @@ -139,20 +186,17 @@ void event_dispatch(event_state_t *state, window_t *window) } case XCB_EXPOSE: { - xcb_expose_event_t *expose = (xcb_expose_event_t *)xevent; + //xcb_expose_event_t *expose = (xcb_expose_event_t *)xevent; log_trace("Processing 'Expose' event"); - // Redraw - (void)expose; + // XXX: Redraw when rendering ondemand break; } case XCB_CREATE_NOTIFY: { - xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xevent; + //xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xevent; log_trace("Processing 'CreateNotify' event"); - (void)create; - if (window->cw_params.override_redirect) break; xcb_circulate_window(window->display->connection, XCB_CIRCULATE_RAISE_LOWEST, window->window); break; @@ -163,16 +207,16 @@ void event_dispatch(event_state_t *state, window_t *window) log_trace("Processing 'LeaveNotify' event"); if (leave->event != window->window) break; - if (state->hovered == NULL) break; + if (state->hovered.block == NULL) break; event_t event = { + .type = EVENT_HOVER_STOP, .x = leave->event_x, .y = leave->event_y, - .type = EVENT_HOVER_STOP, }; - event_dispatch_block(state->layout, state->hovered, event); - state->hovered = NULL; + event_dispatch_callback_block(state, state->hovered.block, event); + memset(&state->hovered, 0, sizeof(layout_t)); if (motion != NULL && motion->time <= leave->time) { log_trace("Suppressed older 'MotionNotify' event"); @@ -193,10 +237,11 @@ void event_dispatch(event_state_t *state, window_t *window) break; } + // NOTE: The order of event_type_t is important! event_t event = { + .type = button->detail, .x = button->event_x, .y = button->event_y, - .type = button->detail, }; event_dispatch_mouse(state, state->layout, event); @@ -210,7 +255,8 @@ void event_dispatch(event_state_t *state, window_t *window) if (property->atom == XCB_ATOM_RESOURCE_MANAGER) { display_update_xrm(window->display); display_update_scale(window->display); - // Redraw + + // XXX: Redraw when rendering ondemand } break; } @@ -243,9 +289,9 @@ void event_dispatch(event_state_t *state, window_t *window) log_trace("Processing 'MotionNotify' event"); event_t event = { + .type = EVENT_HOVER_MOVE, .x = motion->event_x, .y = motion->event_y, - .type = EVENT_HOVER_MOVE, }; event_dispatch_mouse(state, state->layout, event); |
