diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 15:41:39 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 15:41:39 +0300 |
| commit | 537b2d768b31deb0f95c5122e0d562e4406ae9a0 (patch) | |
| tree | cc3e85cb2990672c11b4e35c6dbcfaac733d09f5 /src/platform/x11/window.c | |
| parent | 98f0d51157fa2a2b8ccaae54ed4850a88d223d01 (diff) | |
Unify core and runner events into struct yasl_event
The core input queue and the yasl_run() runner each had their own event
type, and the runner translated one into the other. Both now share
struct yasl_event in <yasl/yasl.h>: yasl_surface_poll_event() returns the
same events the app event callback receives, so the runner forwards them
unchanged.
Pointer input becomes POINTER_DOWN/UP/MOTION/SCROLL/LEAVE with a named
yasl_pointer_button and a motion delta computed in the input queue. TEXT,
PASTE and DROP share one text payload, scale changes fold into
WINDOW_RESIZE, and every event carries a monotonic time_ns.
yasl_surface_set_mouse_mode() is replaced by
yasl_surface_set_pointer_mode(); no backend implements relative mode yet.
The export check now only counts YASL_API declarations, so function
pointer fields returning enum yasl_app_result are not mistaken for
exports.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/platform/x11/window.c')
| -rw-r--r-- | src/platform/x11/window.c | 132 |
1 files changed, 66 insertions, 66 deletions
diff --git a/src/platform/x11/window.c b/src/platform/x11/window.c index 3bab6e2..f60a878 100644 --- a/src/platform/x11/window.c +++ b/src/platform/x11/window.c @@ -159,21 +159,13 @@ static void leave(struct x11_display *d) } } -static void push(struct x11_surface *s, struct yasl_input_event event, +static void push(struct x11_surface *s, struct yasl_event event, const char *text, size_t len) { if (s->destroyed) return; if (text) { - if (event.kind == YASL_INPUT_TEXT) { - event.text.text = text; - event.text.len = len; - } else if (event.kind == YASL_INPUT_DROP_FILES) { - event.drop_files.files = text; - event.drop_files.len = len; - } else { - event.paste.text = text; - event.paste.len = len; - } + event.text.data = text; + event.text.len = len; } event.surface = &s->base; input_queue_push(&s->input, &event); @@ -354,42 +346,46 @@ static int8_t tilt_value(const struct tablet_axis *a) (int8_t)lround(fmax(-90, fmin(90, a->value))); } -static int pointer_button(unsigned button) +static enum yasl_pointer_button pointer_button(unsigned button) { - return button == 1 ? 0 : button == 2 ? 1 : button == 3 ? 2 : - button >= 8 && button <= INT16_MAX ? (int)button - 5 : 3; + return button == 1 ? YASL_BUTTON_PRIMARY : + button == 2 ? YASL_BUTTON_MIDDLE : + button == 3 ? YASL_BUTTON_SECONDARY : + button >= 8 && button <= INT16_MAX ? (enum yasl_pointer_button)(button - 5) : + YASL_BUTTON_BACK; } static void xi_pointer_event(struct x11_surface *s, const XIDeviceEvent *ev) { struct x11_display *d = (struct x11_display *)s->base.display; struct x11_pointer *p = pointer_for(d, ev->sourceid); - struct yasl_mouse_event mouse = { - .pos = {yasl_scale_to_device(ev->event_x, YASL_SCALE_UNIT), - yasl_scale_to_device(ev->event_y, YASL_SCALE_UNIT)}, - .device = p ? p->device : YASL_PTR_DEV_MOUSE, - .mods = modifiers(ev->mods.effective), - .button = 3, + struct yasl_event event = { + .pointer = { + .pos = {yasl_scale_to_device(ev->event_x, YASL_SCALE_UNIT), + yasl_scale_to_device(ev->event_y, YASL_SCALE_UNIT)}, + .device = p ? p->device : YASL_PTR_DEV_MOUSE, + .mods = modifiers(ev->mods.effective), + }, }; if (p && (p->device == YASL_PTR_DEV_PEN || p->device == YASL_PTR_DEV_ERASER)) { update_axes(p, &ev->valuators); if (ev->evtype == XI_ButtonRelease && ev->detail == 1) p->pressure.value = p->pressure.min; - mouse.pen = (struct yasl_pointer_pen){ + event.pointer.pen = (struct yasl_pointer_pen){ pressure_value(&p->pressure), tilt_value(&p->tilt_x), tilt_value(&p->tilt_y)}; } - if (ev->evtype == XI_Motion) mouse.kind = YASL_PTR_MOTION; + if (ev->evtype == XI_Motion) event.type = YASL_EVENT_POINTER_MOTION; else if (ev->detail >= 4 && ev->detail <= 7) { if (ev->evtype == XI_ButtonRelease) return; - mouse.kind = YASL_PTR_SCROLL; - if (ev->detail <= 5) mouse.scroll.y = ev->detail == 4 ? -1 : 1; - else mouse.scroll.x = ev->detail == 6 ? -1 : 1; + event.type = YASL_EVENT_POINTER_SCROLL; + if (ev->detail <= 5) event.pointer.scroll.y = ev->detail == 4 ? -1 : 1; + else event.pointer.scroll.x = ev->detail == 6 ? -1 : 1; } else { - mouse.kind = ev->evtype == XI_ButtonPress ? YASL_PTR_PRESS : YASL_PTR_RELEASE; - mouse.button = pointer_button(ev->detail); + event.type = ev->evtype == XI_ButtonPress ? YASL_EVENT_POINTER_DOWN : YASL_EVENT_POINTER_UP; + event.pointer.button = pointer_button(ev->detail); } - d->mods = mouse.mods; - push(s, (struct yasl_input_event){.kind = YASL_INPUT_MOUSE, .mouse = mouse}, NULL, 0); + d->mods = event.pointer.mods; + push(s, event, NULL, 0); } static void xi_event(struct x11_display *d, XGenericEventCookie *cookie) @@ -405,7 +401,7 @@ static void xi_event(struct x11_display *d, XGenericEventCookie *cookie) if (d->drag.active) drag_end(d, YASL_DRAG_CANCELLED); for (struct x11_surface *s = d->surfaces; s; s = s->next) - push(s, (struct yasl_input_event){.kind = YASL_INPUT_RESET}, NULL, 0); + push(s, (struct yasl_event){.type = YASL_EVENT_INPUT_RESET}, NULL, 0); } return; } @@ -413,7 +409,7 @@ static void xi_event(struct x11_display *d, XGenericEventCookie *cookie) if (!crossing && cookie->evtype != XI_Motion && cookie->evtype != XI_ButtonPress && cookie->evtype != XI_ButtonRelease) return; Window window = crossing ? ((XIEnterEvent *)cookie->data)->event : - ((XIDeviceEvent *)cookie->data)->event; + ((XIDeviceEvent *)cookie->data)->event; struct x11_surface *s = d->surfaces; while (s && s->window != window) s = s->next; if (cookie->evtype == XI_Motion && d->drag.active) { @@ -450,13 +446,15 @@ static void xi_event(struct x11_display *d, XGenericEventCookie *cookie) const XIEnterEvent *ev = cookie->data; struct x11_pointer *p = pointer_for(d, ev->sourceid); if (p) p->pressure.value = p->pressure.min; - push(s, (struct yasl_input_event){.kind = YASL_INPUT_MOUSE, .mouse = { - .pos = {yasl_scale_to_device(ev->event_x, YASL_SCALE_UNIT), - yasl_scale_to_device(ev->event_y, YASL_SCALE_UNIT)}, - .device = p ? p->device : YASL_PTR_DEV_MOUSE, - .button = 3, .mods = modifiers(ev->mods.effective), - .kind = cookie->evtype == XI_Leave ? YASL_PTR_LEAVE : YASL_PTR_MOTION, - }}, NULL, 0); + push(s, (struct yasl_event){ + .type = cookie->evtype == XI_Leave ? YASL_EVENT_POINTER_LEAVE : YASL_EVENT_POINTER_MOTION, + .pointer = { + .pos = {yasl_scale_to_device(ev->event_x, YASL_SCALE_UNIT), + yasl_scale_to_device(ev->event_y, YASL_SCALE_UNIT)}, + .device = p ? p->device : YASL_PTR_DEV_MOUSE, + .mods = modifiers(ev->mods.effective), + }, + }, NULL, 0); } } @@ -1002,7 +1000,7 @@ static void xdnd_selection_notify(struct x11_display *d, XSelectionEvent *event) size_t out_len = 0; char *parsed = parse_file_uris((const char *)data, count, &out_len); if (parsed && out_len > 0) { - push(s, (struct yasl_input_event){.kind = YASL_INPUT_DROP_FILES}, parsed, out_len); + push(s, (struct yasl_event){.type = YASL_EVENT_DROP}, parsed, out_len); free(parsed); success = true; } @@ -1090,7 +1088,7 @@ static void selection_notify(struct x11_display *d, XSelectionEvent *event) if (buf) total = utf8_len; } if (complete && buf && yasl_utf8_validate(buf, total)) - push(s, (struct yasl_input_event){.kind = YASL_INPUT_PASTE}, buf, total); + push(s, (struct yasl_event){.type = YASL_EVENT_PASTE}, buf, total); free(buf); XDestroyWindow(d->native, r->window); free(r); @@ -1151,8 +1149,8 @@ static void key_event(struct x11_surface *s, XKeyEvent *key, bool repeat) } } uint32_t cp = xkb_keysym_to_utf32((xkb_keysym_t)base); - push(s, (struct yasl_input_event){ - .kind = YASL_INPUT_KEY, + push(s, (struct yasl_event){ + .type = YASL_EVENT_KEY, .key = {.key = key->keycode < 256 ? d->keys[key->keycode] : YASL_KEY_UNKNOWN, .codepoint = yasl_key_label(cp), .native_code = key->keycode, .shifted = yasl_key_label(xkb_keysym_to_utf32((xkb_keysym_t)shifted)), @@ -1162,7 +1160,7 @@ static void key_event(struct x11_surface *s, XKeyEvent *key, bool repeat) }, NULL, 0); if (len > 0 && text && (unsigned char)text[0] >= 0x20 && text[0] != 0x7f && !(d->mods & (YASL_MOD_CTRL | YASL_MOD_SUPER | YASL_MOD_ALT))) - push(s, (struct yasl_input_event){.kind = YASL_INPUT_TEXT}, text, (size_t)len); + push(s, (struct yasl_event){.type = YASL_EVENT_TEXT}, text, (size_t)len); if (text != local) free(text); } @@ -1336,8 +1334,8 @@ static void dispatch(struct yasl_display *base) if (s->ic) { if (focused) XSetICFocus(s->ic); else XUnsetICFocus(s->ic); } if (focused) s->base.state |= YASL_STATE_ACTIVATED; else s->base.state &= ~YASL_STATE_ACTIVATED; - push(s, (struct yasl_input_event){ - .kind = YASL_INPUT_FOCUS, .focus.focused = focused}, NULL, 0); + push(s, (struct yasl_event){ + .type = YASL_EVENT_FOCUS, .focus.focused = focused}, NULL, 0); if (s->cbs && s->cbs->state) s->cbs->state(&s->base, s->base.state, s->ud); break; } @@ -1359,11 +1357,13 @@ static void dispatch(struct yasl_display *base) break; } case MotionNotify: case LeaveNotify: case EnterNotify: case ButtonPress: case ButtonRelease: { - struct yasl_mouse_event mouse = {.device = YASL_PTR_DEV_MOUSE}; + struct yasl_event ev = { + .pointer = {.device = YASL_PTR_DEV_MOUSE}, + }; unsigned state; if (event.type == MotionNotify) { - mouse.pos = (struct yasl_vector2i){event.xmotion.x, event.xmotion.y}; - mouse.kind = YASL_PTR_MOTION; + ev.pointer.pos = (struct yasl_vector2i){event.xmotion.x, event.xmotion.y}; + ev.type = YASL_EVENT_POINTER_MOTION; state = event.xmotion.state; if (d->drag.active) { if (d->drag.carried) @@ -1372,45 +1372,45 @@ static void dispatch(struct yasl_display *base) XMoveWindow(d->native, d->drag.icon_window, event.xmotion.x_root - d->drag.hotspot.x, event.xmotion.y_root - d->drag.hotspot.y); - struct yasl_vector2i hpos = mouse.pos; + struct yasl_vector2i hpos = ev.pointer.pos; struct x11_surface *hsurf = d->native ? surface_at_root_pos(d, event.xmotion.x_root, event.xmotion.y_root, &hpos) : s; drag_set_hover(d, hsurf, hpos); } } else if (event.type == EnterNotify) { - mouse.pos = (struct yasl_vector2i){event.xcrossing.x, event.xcrossing.y}; - mouse.kind = YASL_PTR_MOTION; + ev.pointer.pos = (struct yasl_vector2i){event.xcrossing.x, event.xcrossing.y}; + ev.type = YASL_EVENT_POINTER_MOTION; state = event.xcrossing.state; if (d->drag.active) { - struct yasl_vector2i hpos = mouse.pos; + struct yasl_vector2i hpos = ev.pointer.pos; struct x11_surface *hsurf = d->native ? surface_at_root_pos(d, event.xcrossing.x_root, event.xcrossing.y_root, &hpos) : s; drag_set_hover(d, hsurf, hpos); } } else if (event.type == LeaveNotify) { - mouse.pos = (struct yasl_vector2i){event.xcrossing.x, event.xcrossing.y}; - mouse.kind = YASL_PTR_LEAVE; + ev.pointer.pos = (struct yasl_vector2i){event.xcrossing.x, event.xcrossing.y}; + ev.type = YASL_EVENT_POINTER_LEAVE; state = event.xcrossing.state; if (d->drag.active) - drag_leave_hover(d, s, mouse.pos); + drag_leave_hover(d, s, ev.pointer.pos); } else { - mouse.pos = (struct yasl_vector2i){event.xbutton.x, event.xbutton.y}; + ev.pointer.pos = (struct yasl_vector2i){event.xbutton.x, event.xbutton.y}; state = event.xbutton.state; unsigned button = event.xbutton.button; if (button >= 4 && button <= 7) { if (event.type == ButtonRelease) break; - mouse.kind = YASL_PTR_SCROLL; - if (button <= 5) mouse.scroll.y = button == 4 ? -1 : 1; - else mouse.scroll.x = button == 6 ? -1 : 1; + ev.type = YASL_EVENT_POINTER_SCROLL; + if (button <= 5) ev.pointer.scroll.y = button == 4 ? -1 : 1; + else ev.pointer.scroll.x = button == 6 ? -1 : 1; } else { - mouse.kind = event.type == ButtonPress ? YASL_PTR_PRESS : YASL_PTR_RELEASE; - mouse.button = pointer_button(button); + ev.type = event.type == ButtonPress ? YASL_EVENT_POINTER_DOWN : YASL_EVENT_POINTER_UP; + ev.pointer.button = pointer_button(button); if (event.type == ButtonRelease && d->drag.active) drag_drop_hover(d); } } - d->mods = mouse.mods = modifiers(state); - push(s, (struct yasl_input_event){.kind = YASL_INPUT_MOUSE, .mouse = mouse}, NULL, 0); + d->mods = ev.pointer.mods = modifiers(state); + push(s, ev, NULL, 0); break; } } @@ -1708,7 +1708,7 @@ static void paste(struct yasl_display *base, enum yasl_selection sel, struct yas Atom selection = sel == YASL_PRIMARY ? XA_PRIMARY : d->clipboard; if (XGetSelectionOwner(d->native, selection) == d->selection_window) { const char *text = d->selection[sel]; - if (text) push(s, (struct yasl_input_event){.kind = YASL_INPUT_PASTE}, text, strlen(text)); + if (text) push(s, (struct yasl_event){.type = YASL_EVENT_PASTE}, text, strlen(text)); } else { struct paste_request *r = calloc(1, sizeof(*r)); if (!r) return; @@ -1723,7 +1723,7 @@ static void paste(struct yasl_display *base, enum yasl_selection sel, struct yas } } -static bool input_poll(struct yasl_surface *base, struct yasl_input_event *event) +static bool input_poll(struct yasl_surface *base, struct yasl_event *event) { struct x11_surface *s = (struct x11_surface *)base; return !s->destroyed && input_queue_pop(&s->input, event); @@ -2038,7 +2038,7 @@ const struct yasl_backend_ops yasl_x11_backend = { .surface_set_title = set_title, .surface_schedule_redraw = schedule_redraw, .surface_present = present, - .surface_input_poll = input_poll, + .surface_poll_event = input_poll, .surface_geometry = geometry, .surface_timing = timing, .surface_frame_time_ns = frame_time, |
