diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2013-05-16 16:54:49 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-05-16 16:54:49 -0400 |
commit | 660127c22a03bbe960cf6274b3c8bf244f96a4ae (patch) | |
tree | 64b088389087c9d65d6d567be97d738c153594cc | |
parent | a90d8fcc23877f8e5e698f6bd59921a132213618 (diff) |
Enter/leave for subwindows
-rw-r--r-- | src/input.c | 66 | ||||
-rw-r--r-- | src/private.h | 2 | ||||
-rw-r--r-- | src/test.c | 17 | ||||
-rw-r--r-- | src/window.c | 19 |
4 files changed, 72 insertions, 32 deletions
diff --git a/src/input.c b/src/input.c index 3274fee..10f9d7d 100644 --- a/src/input.c +++ b/src/input.c @@ -11,9 +11,10 @@ struct csx_seat { struct wl_seat *seat; struct wl_pointer *pointer; struct csx_display *display; - struct csx_window *pointer_focus; + struct csx_window *pointer_focus, *child; uint32_t button_mask; - wl_fixed_t pointer_x, pointer_y; + int pointer_x, pointer_y; + int window_x, window_y; }; void @@ -28,14 +29,14 @@ csx_seat_send_crossing_event(struct csx_seat *seat, int type) event->xevent.xcrossing.serial = display->serial; event->xevent.xcrossing.send_event = False; event->xevent.xcrossing.display = display->xdisplay; - event->xevent.xcrossing.window = seat->pointer_focus->id; + event->xevent.xcrossing.window = seat->child->id; event->xevent.xcrossing.root = display->root->id; event->xevent.xcrossing.subwindow = None; event->xevent.xcrossing.time = 0; - event->xevent.xcrossing.x = wl_fixed_to_int(seat->pointer_x); - event->xevent.xcrossing.y = wl_fixed_to_int(seat->pointer_y); - event->xevent.xcrossing.x_root = wl_fixed_to_int(seat->pointer_x); - event->xevent.xcrossing.y_root = wl_fixed_to_int(seat->pointer_y); + event->xevent.xcrossing.x = seat->window_x; + event->xevent.xcrossing.y = seat->window_y; + event->xevent.xcrossing.x_root = seat->pointer_x; + event->xevent.xcrossing.y_root = seat->pointer_y; event->xevent.xcrossing.mode = NotifyGrab; event->xevent.xcrossing.detail = NotifyAncestor; event->xevent.xcrossing.same_screen = True; @@ -58,14 +59,14 @@ csx_seat_send_button_event(struct csx_seat *seat, event->xevent.xbutton.serial = display->serial; event->xevent.xbutton.send_event = False; event->xevent.xbutton.display = display->xdisplay; - event->xevent.xbutton.window = seat->pointer_focus->id; + event->xevent.xbutton.window = seat->child->id; event->xevent.xbutton.root = display->root->id; event->xevent.xbutton.subwindow = None; event->xevent.xbutton.time = time; - event->xevent.xbutton.x = wl_fixed_to_int(seat->pointer_x); - event->xevent.xbutton.y = wl_fixed_to_int(seat->pointer_y); - event->xevent.xbutton.x_root = wl_fixed_to_int(seat->pointer_x); - event->xevent.xbutton.y_root = wl_fixed_to_int(seat->pointer_y); + event->xevent.xbutton.x = seat->window_x; + event->xevent.xbutton.y = seat->window_y; + event->xevent.xbutton.x_root = seat->pointer_x; + event->xevent.xbutton.y_root = seat->pointer_y; event->xevent.xbutton.state = 0; event->xevent.xbutton.button = button; event->xevent.xbutton.same_screen = True; @@ -85,14 +86,14 @@ csx_seat_send_motion(struct csx_seat *seat, uint32_t time) event->xevent.xmotion.serial = display->serial; event->xevent.xmotion.send_event = False; event->xevent.xmotion.display = display->xdisplay; - event->xevent.xmotion.window = seat->pointer_focus->id; + event->xevent.xmotion.window = seat->child->id; event->xevent.xmotion.root = display->root->id; event->xevent.xmotion.subwindow = None; event->xevent.xmotion.time = time; - event->xevent.xmotion.x = wl_fixed_to_int(seat->pointer_x); - event->xevent.xmotion.y = wl_fixed_to_int(seat->pointer_y); - event->xevent.xmotion.x_root = wl_fixed_to_int(seat->pointer_x); - event->xevent.xmotion.y_root = wl_fixed_to_int(seat->pointer_y); + event->xevent.xmotion.x = seat->window_x; + event->xevent.xmotion.y = seat->window_y; + event->xevent.xmotion.x_root = seat->pointer_x; + event->xevent.xmotion.y_root = seat->pointer_y; event->xevent.xmotion.state = 0; /* key or button mask */ event->xevent.xmotion.is_hint = 0; /* detail */ event->xevent.xmotion.same_screen = True; @@ -106,12 +107,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, wl_fixed_t x, wl_fixed_t y) { struct csx_seat *seat = data; - struct csx_window *window; + struct csx_window *window, *child; + int child_x, child_y; seat->pointer_focus = wl_surface_get_user_data(surface); - seat->pointer_x = x; - seat->pointer_y = y; + seat->pointer_x = wl_fixed_to_int(x); + seat->pointer_y = wl_fixed_to_int(y); window = seat->pointer_focus; + seat->child = csx_window_pick(window, seat->pointer_x, seat->pointer_y, + &seat->window_x, &seat->window_y); if (window->event_mask & EnterWindowMask) csx_seat_send_crossing_event(seat, EnterNotify); } @@ -136,9 +140,20 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, struct csx_seat *seat = data; struct csx_window *window; - window = seat->pointer_focus; - seat->pointer_x = x; - seat->pointer_y = y; + seat->pointer_x = wl_fixed_to_int(x); + seat->pointer_y = wl_fixed_to_int(y); + window = csx_window_pick(seat->pointer_focus, + seat->pointer_x, seat->pointer_y, + &seat->window_x, &seat->window_y); + + if (seat->child != window) { + if (seat->child->event_mask & LeaveWindowMask) + csx_seat_send_crossing_event(seat, LeaveNotify); + seat->child = window; + if (window->event_mask & EnterWindowMask) + csx_seat_send_crossing_event(seat, EnterNotify); + } + if ((window->event_mask & PointerMotionMask) && seat->button_mask == 0) csx_seat_send_motion(seat, time); @@ -162,7 +177,10 @@ pointer_handle_button(void *data, struct wl_pointer *wl_pointer, else seat->button_mask &= ~mask; - window = seat->pointer_focus; + seat->child = csx_window_pick(seat->pointer_focus, + seat->pointer_x, seat->pointer_y, + &seat->window_x, &seat->window_y); + window = seat->child; if (state && (window->event_mask & ButtonPressMask)) csx_seat_send_button_event(seat, time, button, ButtonPress); else if (!state && (window->event_mask & ButtonPressMask)) diff --git a/src/private.h b/src/private.h index f0bad24..2dffdcc 100644 --- a/src/private.h +++ b/src/private.h @@ -77,6 +77,8 @@ struct csx_window * csx_window_create(struct csx_display *display, struct csx_window *parent); void csx_window_destroy(struct csx_window *window); +struct csx_window *csx_window_pick(struct csx_window *window, + int x, int y, int *local_x, int *local_y); struct csx_pixmap { unsigned int width; @@ -16,20 +16,20 @@ print_event(XEvent *e) e->xreparent.window); break; case MotionNotify: - printf("got MotionNotify event: window %d\n", - e->xmotion.window); + printf("got MotionNotify event: window %d (%d,%d)\n", + e->xmotion.window, e->xmotion.x, e->xmotion.y); break; case ButtonPress: - printf("got ButtonPress event: window %d\n", - e->xbutton.window); + printf("got ButtonPress event: window %d (%d,%d)\n", + e->xbutton.window, e->xbutton.x, e->xbutton.y); break; case ButtonRelease: - printf("got ButtonRelease event: window %d\n", - e->xbutton.window); + printf("got ButtonRelease event: window %d (%d,%d)\n", + e->xbutton.window, e->xbutton.x, e->xbutton.y); break; case EnterNotify: - printf("got EnterNotify event: window %d\n", - e->xcrossing.window); + printf("got EnterNotify event: window %d (%d,%d)\n", + e->xcrossing.window, e->xcrossing.x, e->xcrossing.y); break; case LeaveNotify: printf("got LeaveaNotify event: window %d\n", @@ -89,6 +89,7 @@ int main(int argc, char *argv[]) printf("created window %d and subwindow %d\n", win, sub); XMapWindow(display, win); + XMapWindow(display, sub); XFlush(display); run(display); diff --git a/src/window.c b/src/window.c index afd5f2f..71203d8 100644 --- a/src/window.c +++ b/src/window.c @@ -29,6 +29,25 @@ csx_window_create(struct csx_display *display, struct csx_window *parent) return window; } +struct csx_window * +csx_window_pick(struct csx_window *window, + int x, int y, int *local_x, int *local_y) +{ + struct csx_window *w; + + wl_list_for_each(w, &window->child_list, link) { + if (w->mapped && w->x <= x & w->y <= y && + x < w->x + w->width && y < w->y + w->height) + return csx_window_pick(w, x - w->x, y - w->y, + local_x, local_y); + } + + *local_x = x; + *local_y = y; + + return window; +} + void csx_window_send_create_notify(struct csx_window *window) { |