Implement input dispatch: hit-test pointer events to WM windows
- frame_buf_at(): hit-test finds which WM frame_buf is under pointer - Button/motion events set window field to frame_buf ID or root_win - Root window gets synthetic ID (0x0FFFFFFF) in Wayland mode - Right-click on background → handleButtonPress → OpenRootMenu path - wSelectWindows: remove XEvent dependency, take (x, y) coordinates - Zero X11 symbols in event.o and moveres.o (verified with nm)
This commit is contained in:
parent
fe8f7a923f
commit
ac739a1a5c
|
|
@ -53,7 +53,7 @@ void wUnshadeWindow(WWindow *wwin);
|
|||
void wIconifyWindow(WWindow *wwin);
|
||||
void wDeiconifyWindow(WWindow *wwin);
|
||||
|
||||
void wSelectWindows(WScreen *scr, XEvent *ev);
|
||||
void wSelectWindows(WScreen *scr, int x_root, int y_root);
|
||||
|
||||
void wSelectWindow(WWindow *wwin, Bool flag);
|
||||
void wUnselectWindows(WScreen *scr);
|
||||
|
|
|
|||
|
|
@ -3442,7 +3442,7 @@ wl_screen_open(WScreen *scr)
|
|||
scr->scr_height = wl_state.output ?
|
||||
(int)wl_state.output->height : 1080;
|
||||
scr->depth = 24;
|
||||
scr->root_win = WNATIVE_NONE;
|
||||
scr->root_win = (WNativeWindow)0x0FFFFFFF; /* synthetic root window ID */
|
||||
scr->colormap = 0;
|
||||
|
||||
/* XWayland bridge: fill in real X11 screen values so RCreateContext
|
||||
|
|
@ -3501,6 +3501,22 @@ frame_buf_find(WNativeWindow id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Hit-test: find the topmost frame_buf containing (px, py). */
|
||||
static struct wl_frame_buf *
|
||||
frame_buf_at(int px, int py)
|
||||
{
|
||||
struct wl_frame_buf *hit = NULL;
|
||||
struct wl_frame_buf *fb;
|
||||
wl_list_for_each(fb, &wl_state.frame_list, link) {
|
||||
if (!fb->scene_buf || !fb->scene_buf->node.enabled)
|
||||
continue;
|
||||
if (px >= fb->x && px < fb->x + fb->width &&
|
||||
py >= fb->y && py < fb->y + fb->height)
|
||||
hit = fb; /* last match = topmost in scene order */
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Frame / window lifecycle */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -3879,10 +3895,22 @@ handle_pointer_motion(struct wl_listener *listener, void *data)
|
|||
WMEvent wev;
|
||||
memset(&wev, 0, sizeof(wev));
|
||||
wev.type = WME_MOTION;
|
||||
wev.window = WNATIVE_NONE;
|
||||
struct wl_frame_buf *fb = frame_buf_at(wl_state.pointer_x,
|
||||
wl_state.pointer_y);
|
||||
if (fb) {
|
||||
wev.window = fb->id;
|
||||
wev.u.motion.window = fb->id;
|
||||
wev.u.motion.x = wl_state.pointer_x - fb->x;
|
||||
wev.u.motion.y = wl_state.pointer_y - fb->y;
|
||||
} else {
|
||||
WScreen *scr0 = wScreenWithNumber(0);
|
||||
WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;
|
||||
wev.window = root;
|
||||
wev.u.motion.window = root;
|
||||
wev.u.motion.x = wl_state.pointer_x;
|
||||
wev.u.motion.y = wl_state.pointer_y;
|
||||
}
|
||||
wev.u.motion.time = ev->time_msec;
|
||||
wev.u.motion.x = wl_state.pointer_x;
|
||||
wev.u.motion.y = wl_state.pointer_y;
|
||||
wev.u.motion.x_root = wl_state.pointer_x;
|
||||
wev.u.motion.y_root = wl_state.pointer_y;
|
||||
W_WL_EnqueueEvent(wmscr, &wev, NULL);
|
||||
|
|
@ -3920,10 +3948,22 @@ handle_pointer_motion_absolute(struct wl_listener *listener, void *data)
|
|||
WMEvent wev;
|
||||
memset(&wev, 0, sizeof(wev));
|
||||
wev.type = WME_MOTION;
|
||||
wev.window = WNATIVE_NONE;
|
||||
struct wl_frame_buf *fb = frame_buf_at(wl_state.pointer_x,
|
||||
wl_state.pointer_y);
|
||||
if (fb) {
|
||||
wev.window = fb->id;
|
||||
wev.u.motion.window = fb->id;
|
||||
wev.u.motion.x = wl_state.pointer_x - fb->x;
|
||||
wev.u.motion.y = wl_state.pointer_y - fb->y;
|
||||
} else {
|
||||
WScreen *scr0 = wScreenWithNumber(0);
|
||||
WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;
|
||||
wev.window = root;
|
||||
wev.u.motion.window = root;
|
||||
wev.u.motion.x = wl_state.pointer_x;
|
||||
wev.u.motion.y = wl_state.pointer_y;
|
||||
}
|
||||
wev.u.motion.time = ev->time_msec;
|
||||
wev.u.motion.x = wl_state.pointer_x;
|
||||
wev.u.motion.y = wl_state.pointer_y;
|
||||
wev.u.motion.x_root = wl_state.pointer_x;
|
||||
wev.u.motion.y_root = wl_state.pointer_y;
|
||||
W_WL_EnqueueEvent(wmscr2, &wev, NULL);
|
||||
|
|
@ -4448,10 +4488,24 @@ handle_pointer_button(struct wl_listener *listener, void *data)
|
|||
memset(&wev, 0, sizeof(wev));
|
||||
wev.type = (ev->state == WLR_BUTTON_PRESSED)
|
||||
? WME_BUTTON_PRESS : WME_BUTTON_RELEASE;
|
||||
wev.window = WNATIVE_NONE;
|
||||
|
||||
/* Hit-test: determine which WM window was clicked */
|
||||
struct wl_frame_buf *fb = frame_buf_at(wl_state.pointer_x,
|
||||
wl_state.pointer_y);
|
||||
if (fb) {
|
||||
wev.window = fb->id;
|
||||
wev.u.button.window = fb->id;
|
||||
wev.u.button.x = wl_state.pointer_x - fb->x;
|
||||
wev.u.button.y = wl_state.pointer_y - fb->y;
|
||||
} else {
|
||||
WScreen *scr0 = wScreenWithNumber(0);
|
||||
WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;
|
||||
wev.window = root;
|
||||
wev.u.button.window = root;
|
||||
wev.u.button.x = wl_state.pointer_x;
|
||||
wev.u.button.y = wl_state.pointer_y;
|
||||
}
|
||||
wev.u.button.time = ev->time_msec;
|
||||
wev.u.button.x = wl_state.pointer_x;
|
||||
wev.u.button.y = wl_state.pointer_y;
|
||||
wev.u.button.x_root = wl_state.pointer_x;
|
||||
wev.u.button.y_root = wl_state.pointer_y;
|
||||
/* Linux evdev BTN_LEFT=0x110, BTN_RIGHT=0x111, BTN_MIDDLE=0x112
|
||||
|
|
|
|||
|
|
@ -744,7 +744,7 @@ static void executeButtonAction(WScreen *scr, WMEvent *event, int action)
|
|||
switch (action) {
|
||||
case WA_SELECT_WINDOWS:
|
||||
wUnselectWindows(scr);
|
||||
wSelectWindows(scr, (XEvent *)event->_x11_raw);
|
||||
wSelectWindows(scr, event->u.button.x_root, event->u.button.y_root);
|
||||
if (wPreferences.close_rootmenu_left_right_click){
|
||||
WMenu *menu = NULL;
|
||||
WMPropList *definition;
|
||||
|
|
|
|||
|
|
@ -2311,12 +2311,10 @@ static void selectWindowsInside(WScreen * scr, int x1, int y1, int x2, int y2)
|
|||
}
|
||||
}
|
||||
|
||||
void wSelectWindows(WScreen * scr, XEvent * ev)
|
||||
void wSelectWindows(WScreen * scr, int xp, int yp)
|
||||
{
|
||||
WMEvent event;
|
||||
WNativeWindow root = scr->root_win;
|
||||
int xp = ev->xbutton.x_root;
|
||||
int yp = ev->xbutton.y_root;
|
||||
int w = 0, h = 0;
|
||||
int x = xp, y = yp;
|
||||
|
||||
|
|
@ -2357,8 +2355,6 @@ void wSelectWindows(WScreen * scr, XEvent * ev)
|
|||
break;
|
||||
|
||||
case WME_BUTTON_RELEASE:
|
||||
if (event.u.button.button != ev->xbutton.button)
|
||||
break;
|
||||
|
||||
wm_backend->overlay_draw_rect(scr, x, y, w, h);
|
||||
wm_backend->server_ungrab();
|
||||
|
|
|
|||
Loading…
Reference in New Issue