Add timestamp to pointer image attach request
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 14 Sep 2010 19:39:45 +0000 (15:39 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 14 Sep 2010 19:39:45 +0000 (15:39 -0400)
This lets the server discard requests received after the pointer has
exited and the re-entered a surface.

TODO
clients/dnd.c
clients/window.c
compositor/compositor.c
compositor/compositor.h
wayland/Makefile
wayland/protocol.xml

diff --git a/TODO b/TODO
index c864b69..9be90be 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,12 +6,6 @@ Core wayland protocol
    another menu item), but we need events for the popup menu surface
    as well.
 
- - input_device.attach() should use a timestamp so the server can
-   discard late requests (sending a request to set the pointer image
-   in response to a motion event, the pointer leaves and then reenters
-   the surface, before the server receives the reqest -> the server
-   must discard it).
-
  - The message format has to include information about number of fds
    in the message so we can skip a message correctly.  Or we should
    just give up on trying to recover from unknown messages.
index 9095672..af8dc1c 100644 (file)
@@ -52,6 +52,7 @@ struct dnd_drag {
        int hotspot_x, hotspot_y;
        struct dnd *dnd;
        struct input *input;
+       uint32_t time;
 };
 
 struct dnd_offer {
@@ -245,7 +246,7 @@ drag_target(void *data,
                surface = dnd_drag->translucent;
 
        buffer = display_get_buffer_for_surface(dnd->display, surface);
-       wl_input_device_attach(device, buffer,
+       wl_input_device_attach(device, dnd_drag->time, buffer,
                               dnd_drag->hotspot_x, dnd_drag->hotspot_y);
 }
 
@@ -488,6 +489,7 @@ dnd_button_handler(struct window *window,
                dnd_drag = malloc(sizeof *dnd_drag);
                dnd_drag->dnd = dnd;
                dnd_drag->input = input;
+               dnd_drag->time = time;
 
                dnd_drag->opaque =
                        create_drag_cursor(dnd_drag, item, x, y, 1);
index f1b435b..31c294f 100644 (file)
@@ -525,7 +525,7 @@ get_pointer_location(struct window *window, int32_t x, int32_t y)
 }
 
 static void
-set_pointer_image(struct input *input, int pointer)
+set_pointer_image(struct input *input, uint32_t time, int pointer)
 {
        struct display *display = input->display;
        struct wl_buffer *buffer;
@@ -564,7 +564,7 @@ set_pointer_image(struct input *input, int pointer)
                if (input->current_pointer_image == POINTER_DEFAULT)
                        return;
 
-               wl_input_device_attach(input->input_device, NULL, 0, 0);
+               wl_input_device_attach(input->input_device, time, NULL, 0, 0);
                input->current_pointer_image = POINTER_DEFAULT;
                return;
        default:
@@ -577,7 +577,7 @@ set_pointer_image(struct input *input, int pointer)
        input->current_pointer_image = pointer;
        surface = display->pointer_surfaces[pointer];
        buffer = display_get_buffer_for_surface(display, surface);
-       wl_input_device_attach(input->input_device, buffer,
+       wl_input_device_attach(input->input_device, time, buffer,
                               pointer_images[pointer].hotspot_x,
                               pointer_images[pointer].hotspot_y);
 }
@@ -603,7 +603,7 @@ window_handle_motion(void *data, struct wl_input_device *input_device,
                                                    x, y, sx, sy,
                                                    window->user_data);
 
-       set_pointer_image(input, pointer);
+       set_pointer_image(input, time, pointer);
 }
 
 static void
@@ -703,7 +703,7 @@ window_handle_pointer_focus(void *data,
                                                            x, y, sx, sy,
                                                            window->user_data);
 
-               set_pointer_image(input, pointer);
+               set_pointer_image(input, time, pointer);
        } else {
                input->pointer_focus = NULL;
                input->current_pointer_image = POINTER_UNSET;
index f71b7e6..df75b61 100644 (file)
@@ -706,6 +706,7 @@ wlsc_input_device_set_pointer_focus(struct wlsc_input_device *device,
                                                    WLSC_POINTER_LEFT_PTR);
 
        device->pointer_focus = surface;
+       device->pointer_focus_time = time;
 }
 
 static struct wlsc_surface *
@@ -980,12 +981,15 @@ notify_key(struct wlsc_input_device *device,
 static void
 input_device_attach(struct wl_client *client,
                    struct wl_input_device *device_base,
+                   uint32_t time,
                    struct wl_buffer *buffer_base, int32_t x, int32_t y)
 {
        struct wlsc_input_device *device =
                (struct wlsc_input_device *) device_base;
        struct wlsc_buffer *buffer = (struct wlsc_buffer *) buffer_base;
 
+       if (time < device->pointer_focus_time)
+               return;
        if (device->pointer_focus == NULL)
                return;
        if (device->pointer_focus->base.client != client &&
index 2cbdf8e..3122c0a 100644 (file)
@@ -99,6 +99,7 @@ struct wlsc_input_device {
        struct wlsc_surface *keyboard_focus;
        struct wl_array keys;
        uint32_t modifier_state;
+       uint32_t pointer_focus_time;
 
        enum wlsc_grab_type grab;
        struct wlsc_surface *grab_surface;
index 827c73e..e922bf6 100644 (file)
@@ -49,7 +49,7 @@ scanner :                                     \
 
 scanner : LDLIBS += $(EXPAT_LIBS)
 
-install : $(libs) compositor
+install : $(libs)
        install -d $(libdir) $(includedir) $(libdir)/pkgconfig
        install wayland-server.pc wayland-client.pc $(libdir)/pkgconfig
        install $(libs) $(libdir)
index 9da4b49..9fa5db4 100644 (file)
 
   <interface name="input_device" version="1">
     <request name="attach">
+      <arg name="time" type="uint"/>
       <arg name="buffer" type="object" interface="buffer"/>
       <arg name="hotspot_x" type="int"/>
       <arg name="hotspot_y" type="int"/>