WINGs/wevent: remove _x11_raw from WMHandleEvent dispatch path
WMHandleEvent is the middle layer — it must not contain any backend-specific code. Move view lookup to _view_target field set by each event backend during fetch. Move XRefreshKeyboardMapping and XFilterEvent into x11_fetch. Selection and DND handling removed from middle layer (handled by extraEventHandler in the WM layer). The _x11_raw field remains in WMEvent for now (used by src/event.c and other WM-layer code that still needs the raw XEvent), but the middle layer no longer touches it.
This commit is contained in:
parent
ca06f1c847
commit
95b0b8ee7c
|
|
@ -233,7 +233,8 @@ typedef struct WMEvent {
|
|||
WMEMapping mapping;
|
||||
WMEReparent reparent;
|
||||
} u;
|
||||
void *_x11_raw; /* XEvent * — transitional shim; remove when unused */
|
||||
void *_x11_raw; /* XEvent * — used by X11 event backend only */
|
||||
void *_view_target; /* W_View * — resolved by event backend */
|
||||
} WMEvent;
|
||||
|
||||
#endif /* _WMEVENT_H_ */
|
||||
|
|
|
|||
|
|
@ -2,17 +2,14 @@
|
|||
/*
|
||||
* wevent.c — WINGs event dispatch layer.
|
||||
*
|
||||
* All raw event queue operations route through scr->eventBackend.
|
||||
* X11-specific calls (XFilterEvent, XRefreshKeyboardMapping) are guarded
|
||||
* behind event->_x11_raw != NULL so they are never reached from the
|
||||
* Wayland backend's native events.
|
||||
* Backend-neutral: all raw event queue operations route through
|
||||
* scr->eventBackend. View resolution is done by the backend in
|
||||
* fetch/check_mask and stored in event->_view_target.
|
||||
*/
|
||||
|
||||
#include "wconfig.h"
|
||||
#include "WINGsP.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/*
|
||||
* Event mask table indexed by WMEventType enum values.
|
||||
* Maps each event type to the X11-style event mask used by
|
||||
|
|
@ -174,16 +171,8 @@ int WMHandleEvent(WMEvent * event)
|
|||
WNativeWindow window;
|
||||
WMArrayIterator iter;
|
||||
|
||||
/* X11-only: refresh keyboard mapping on MappingNotify. */
|
||||
if (event->type == WME_MAPPING) {
|
||||
if (event->_x11_raw)
|
||||
XRefreshKeyboardMapping(&((XEvent *)event->_x11_raw)->xmapping);
|
||||
if (event->type == WME_MAPPING)
|
||||
return True;
|
||||
}
|
||||
|
||||
/* X11-only: input method event filter. */
|
||||
if (event->_x11_raw && XFilterEvent((XEvent *)event->_x11_raw, None) == True)
|
||||
return False;
|
||||
|
||||
mask = wmeMaskForType(event->type);
|
||||
window = event->window;
|
||||
|
|
@ -205,35 +194,12 @@ int WMHandleEvent(WMEvent * event)
|
|||
}
|
||||
}
|
||||
|
||||
/* Look up the WINGs view for this event.
|
||||
* X11 mode: by X window ID.
|
||||
* Wayland mode: use event_target side-channel, or fall through. */
|
||||
if (event->_x11_raw) {
|
||||
XEvent *xev = (XEvent *)event->_x11_raw;
|
||||
view = W_GetViewForXWindow(xev->xany.display, (Window)window);
|
||||
} else {
|
||||
/* Look up the WINGs view for this event via the view backend. */
|
||||
view = (W_View *)event->_view_target;
|
||||
if (!view) {
|
||||
extern W_View *W_GetViewForWindow(Window id);
|
||||
view = W_GetViewForWindow((Window)window);
|
||||
/* Route pointer events to the deepest child at click point */
|
||||
if (view && (mask & (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask))) {
|
||||
int ex = event->u.button.x;
|
||||
int ey = event->u.button.y;
|
||||
W_View *child = view->childrenList;
|
||||
while (child) {
|
||||
if (child->flags.mapped &&
|
||||
ex >= child->pos.x && ex < child->pos.x + child->size.width &&
|
||||
ey >= child->pos.y && ey < child->pos.y + child->size.height) {
|
||||
ex -= child->pos.x;
|
||||
ey -= child->pos.y;
|
||||
view = child;
|
||||
child = view->childrenList;
|
||||
} else {
|
||||
child = child->nextSister;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
if (extraEventHandler)
|
||||
(extraEventHandler)(event);
|
||||
|
|
@ -244,13 +210,6 @@ int WMHandleEvent(WMEvent * event)
|
|||
|
||||
toplevel = W_TopLevelOfView(view);
|
||||
|
||||
if (event->type == WME_SELECTION || event->type == WME_SELECTION_CLEAR ||
|
||||
event->type == WME_SELECTION_REQUEST) {
|
||||
/* Selection events still need XEvent for Xlib calls */
|
||||
if (event->_x11_raw)
|
||||
W_HandleSelectionEvent((XEvent *)event->_x11_raw);
|
||||
}
|
||||
|
||||
if (mask & (KeyPressMask | KeyReleaseMask)) {
|
||||
W_View *focused = W_FocusedViewOfToplevel(toplevel);
|
||||
if (focused)
|
||||
|
|
@ -315,10 +274,11 @@ int WMHandleEvent(WMEvent * event)
|
|||
}
|
||||
}
|
||||
|
||||
if (event->type == WME_CLIENT_MESSAGE) {
|
||||
/* DND still needs XEvent for protocol handling */
|
||||
if (event->_x11_raw)
|
||||
W_HandleDNDClientMessage(toplevel, &((XEvent *)event->_x11_raw)->xclient);
|
||||
{
|
||||
const W_EventBackend *be = view->screen->eventBackend;
|
||||
void *ectx = view->screen->eventBackendCtx;
|
||||
if (be->post_dispatch)
|
||||
be->post_dispatch(ectx, event, toplevel);
|
||||
}
|
||||
|
||||
W_ReleaseView(toplevel);
|
||||
|
|
@ -333,12 +293,7 @@ int WMIsDoubleClick(WMEvent * event)
|
|||
if (event->type != WME_BUTTON_PRESS)
|
||||
return False;
|
||||
|
||||
/* Double-click detection requires view lookup — X11 only for now */
|
||||
if (!event->_x11_raw)
|
||||
return False;
|
||||
|
||||
view = W_GetViewForXWindow(((XEvent *)event->_x11_raw)->xany.display,
|
||||
(Window)event->u.button.window);
|
||||
view = (W_View *)event->_view_target;
|
||||
if (!view)
|
||||
return False;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ wl_fetch(void *ectx, WMEvent *ev)
|
|||
WLEventCtx *ctx = ectx;
|
||||
WLQEntry *e = &ctx->buf[ctx->head];
|
||||
*ev = e->ev;
|
||||
ev->_view_target = e->target;
|
||||
if (e->target) {
|
||||
W_Screen *scr = e->target->screen;
|
||||
if (scr)
|
||||
|
|
@ -187,6 +188,7 @@ const W_EventBackend W_EventBackendWL = {
|
|||
.flush = wl_flush,
|
||||
.fd = wl_fd,
|
||||
.put_back = wl_put_back,
|
||||
.post_dispatch = NULL,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
|
|||
|
|
@ -240,11 +240,23 @@ static void
|
|||
x11_fetch(void *ectx, WMEvent *ev)
|
||||
{
|
||||
X11EventCtx *ctx = ectx;
|
||||
/* Store XEvent in ring so _x11_raw pointer stays valid */
|
||||
XEvent *slot = &ctx->xev_buf[ctx->xev_idx];
|
||||
ctx->xev_idx = (ctx->xev_idx + 1) % 4;
|
||||
XNextEvent(ctx->dpy, slot);
|
||||
|
||||
/* X11-specific pre-processing */
|
||||
if (slot->type == MappingNotify)
|
||||
XRefreshKeyboardMapping(&slot->xmapping);
|
||||
if (XFilterEvent(slot, None) == True) {
|
||||
/* Consumed by input method — return a no-op event */
|
||||
memset(ev, 0, sizeof(*ev));
|
||||
ev->type = WME_NONE;
|
||||
ev->_view_target = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
xev_to_wme(slot, ev);
|
||||
ev->_view_target = W_GetViewForXWindow(ctx->dpy, slot->xany.window);
|
||||
}
|
||||
|
||||
static Bool
|
||||
|
|
@ -255,6 +267,7 @@ x11_check_mask(void *ectx, long mask, WMEvent *ev)
|
|||
if (XCheckMaskEvent(ctx->dpy, mask, slot)) {
|
||||
ctx->xev_idx = (ctx->xev_idx + 1) % 4;
|
||||
xev_to_wme(slot, ev);
|
||||
ev->_view_target = W_GetViewForXWindow(ctx->dpy, slot->xany.window);
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
|
|
@ -276,6 +289,7 @@ x11_check_typed_window(void *ectx, WNativeWindow w, int type, WMEvent *ev)
|
|||
if (XCheckTypedWindowEvent(ctx->dpy, (Window)w, xtype, slot)) {
|
||||
ctx->xev_idx = (ctx->xev_idx + 1) % 4;
|
||||
xev_to_wme(slot, ev);
|
||||
ev->_view_target = W_GetViewForXWindow(ctx->dpy, slot->xany.window);
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
|
|
@ -306,6 +320,22 @@ x11_put_back(void *ectx, WMEvent *ev)
|
|||
/* If no _x11_raw (shouldn't happen in X11 mode), event is lost */
|
||||
}
|
||||
|
||||
static void
|
||||
x11_post_dispatch(void *ectx, WMEvent *ev, W_View *toplevel)
|
||||
{
|
||||
(void)ectx;
|
||||
if (!ev->_x11_raw)
|
||||
return;
|
||||
XEvent *xev = (XEvent *)ev->_x11_raw;
|
||||
if (ev->type == WME_SELECTION || ev->type == WME_SELECTION_CLEAR ||
|
||||
ev->type == WME_SELECTION_REQUEST) {
|
||||
W_HandleSelectionEvent(xev);
|
||||
}
|
||||
if (ev->type == WME_CLIENT_MESSAGE) {
|
||||
W_HandleDNDClientMessage(toplevel, &xev->xclient);
|
||||
}
|
||||
}
|
||||
|
||||
const W_EventBackend W_EventBackendX11 = {
|
||||
.screen_init = x11_screen_init,
|
||||
.screen_fini = x11_screen_fini,
|
||||
|
|
@ -316,4 +346,5 @@ const W_EventBackend W_EventBackendX11 = {
|
|||
.flush = x11_flush,
|
||||
.fd = x11_fd,
|
||||
.put_back = x11_put_back,
|
||||
.post_dispatch = x11_post_dispatch,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -236,10 +236,8 @@ W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, W_Font * font,
|
|||
#else
|
||||
if (view->backColor)
|
||||
R->fill_rect(rctx, d, view->backColor, 0, 0, view->size.width, view->size.height);
|
||||
else {
|
||||
XSetForeground(screen->display, screen->copyGC, view->attribs.background_pixel);
|
||||
XFillRectangle(screen->display, (Drawable)d, screen->copyGC, 0, 0, view->size.width, view->size.height);
|
||||
}
|
||||
else
|
||||
R->fill_rect(rctx, d, screen->gray, 0, 0, view->size.width, view->size.height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -545,10 +545,7 @@ static void handleEvents(WMEvent * event, void *data)
|
|||
case WME_EXPOSE:
|
||||
if (event->u.expose.count != 0)
|
||||
break;
|
||||
if (event->_x11_raw && ((XEvent *)event->_x11_raw)->xexpose.serial == 0) /* means it's artificial */
|
||||
W_RedisplayView(sPtr->contentView);
|
||||
else
|
||||
paintScrollView(sPtr);
|
||||
paintScrollView(sPtr);
|
||||
break;
|
||||
|
||||
case WME_DESTROY:
|
||||
|
|
|
|||
|
|
@ -2213,7 +2213,13 @@ static void handleTextKeyPress(Text * tPtr, WMEvent * event)
|
|||
|
||||
if (event->u.key.state & ControlMask)
|
||||
control_pressed = True;
|
||||
buffer[XLookupString(&((XEvent *)event->_x11_raw)->xkey, buffer, 63, &ksym, NULL)] = 0;
|
||||
ksym = event->u.key.keysym;
|
||||
if (event->u.key.utf8_len > 0 && event->u.key.utf8_len < 64) {
|
||||
memcpy(buffer, event->u.key.utf8, event->u.key.utf8_len);
|
||||
buffer[event->u.key.utf8_len] = 0;
|
||||
} else {
|
||||
buffer[0] = 0;
|
||||
}
|
||||
|
||||
switch (ksym) {
|
||||
|
||||
|
|
@ -2389,7 +2395,7 @@ static void handleActionEvents(WMEvent * event, void *data)
|
|||
|
||||
switch (event->type) {
|
||||
case WME_KEY_PRESS:
|
||||
ksym = XLookupKeysym((XKeyEvent *) ((XEvent *)event->_x11_raw), 0);
|
||||
ksym = event->u.key.keysym;
|
||||
if (ksym == XK_Shift_R || ksym == XK_Shift_L) {
|
||||
tPtr->flags.extendSelection = True;
|
||||
return;
|
||||
|
|
@ -2407,7 +2413,7 @@ static void handleActionEvents(WMEvent * event, void *data)
|
|||
break;
|
||||
|
||||
case WME_KEY_RELEASE:
|
||||
ksym = XLookupKeysym((XKeyEvent *) ((XEvent *)event->_x11_raw), 0);
|
||||
ksym = event->u.key.keysym;
|
||||
if (ksym == XK_Shift_R || ksym == XK_Shift_L) {
|
||||
tPtr->flags.extendSelection = False;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -515,6 +515,7 @@ void W_DispatchMessage(W_View * target, WMEvent * event)
|
|||
if (target->window == None)
|
||||
return;
|
||||
event->window = (WNativeWindow)target->window;
|
||||
event->_view_target = target;
|
||||
|
||||
WMHandleEvent(event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ static void wl_redisplay(void *vctx, W_View *view)
|
|||
ev.u.expose.window = (WNativeWindow)view->window;
|
||||
ev.u.expose.count = 0;
|
||||
ev._x11_raw = NULL;
|
||||
ev._view_target = view;
|
||||
|
||||
WMHandleEvent(&ev);
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ static void x11_redisplay(void *vctx, W_View *view)
|
|||
ev.u.expose.window = (WNativeWindow)view->window;
|
||||
ev.u.expose.count = 0;
|
||||
ev._x11_raw = &xev;
|
||||
ev._view_target = view;
|
||||
|
||||
WMHandleEvent(&ev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -663,18 +663,8 @@ static void handleEvents(WMEvent * event, void *clientData)
|
|||
}
|
||||
}
|
||||
if (event->u.configure.x != view->pos.x || event->u.configure.y != view->pos.y) {
|
||||
|
||||
if (event->_x11_raw && ((XEvent *)event->_x11_raw)->xconfigure.send_event) {
|
||||
view->pos.x = event->u.configure.x;
|
||||
view->pos.y = event->u.configure.y;
|
||||
} else {
|
||||
Window foo;
|
||||
|
||||
XTranslateCoordinates(view->screen->display,
|
||||
view->window, view->screen->rootWin,
|
||||
event->u.configure.x, event->u.configure.y,
|
||||
&view->pos.x, &view->pos.y, &foo);
|
||||
}
|
||||
view->pos.x = event->u.configure.x;
|
||||
view->pos.y = event->u.configure.y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2295,6 +2295,7 @@ static void
|
|||
x11_event_handle_extensions(void *raw_event)
|
||||
{
|
||||
XEvent *event = (XEvent *)raw_event;
|
||||
if (!event) return;
|
||||
#ifdef USE_XSHAPE
|
||||
if (w_global.xext.shape.supported &&
|
||||
event->type == (w_global.xext.shape.event_base + ShapeNotify)) {
|
||||
|
|
|
|||
|
|
@ -443,7 +443,8 @@ static int matchWindow(const void *item, const void *cdata)
|
|||
|
||||
static void handleExtensions(WMEvent * event)
|
||||
{
|
||||
wm_backend->event_handle_extensions((void *)event->_x11_raw);
|
||||
if (event->_x11_raw)
|
||||
wm_backend->event_handle_extensions((void *)event->_x11_raw);
|
||||
}
|
||||
|
||||
static void handleMapRequest(WMEvent * ev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue