summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-05-16 16:54:49 -0400
committerKristian Høgsberg <krh@bitplanet.net>2013-05-16 16:54:49 -0400
commit660127c22a03bbe960cf6274b3c8bf244f96a4ae (patch)
tree64b088389087c9d65d6d567be97d738c153594cc
parenta90d8fcc23877f8e5e698f6bd59921a132213618 (diff)
Enter/leave for subwindows
-rw-r--r--src/input.c66
-rw-r--r--src/private.h2
-rw-r--r--src/test.c17
-rw-r--r--src/window.c19
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;
diff --git a/src/test.c b/src/test.c
index ca92d29..a8928a0 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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)
{