Set pointer image only in response to 'target' event

dev
Kristian Høgsberg 14 years ago
parent 8a40871645
commit 1d7ffd32f8
  1. 20
      TODO
  2. 29
      clients/dnd.c
  3. 14
      clients/window.c
  4. 6
      clients/window.h
  5. 15
      compositor.c
  6. 3
      protocol.xml
  7. 4
      wayland-server.h

20
TODO

@ -16,26 +16,6 @@ Core wayland protocol
- DnD issues:
How to roboustly handle failing drag, ie the case where an
application gets a button event, tries to activate a drag, but when
the server gets the drag request, the button has already been
released and the grab is no longer active. What's the concern:
- Application may set a drag cursor that doesn't revert back,
since a failed drag doesn't result in a pointer_focus event to
give focus back to the surface. We could just do that: if the
pointer_focus is the same surface as we tried to start a grab
for, just remove and give back pointer_focus.
Alternatively, set drag cursors only in response to drag events,
like drag focus. But drag_focus and drag_motion are sent to the
drag target, so the source surface won't always get those. We
may also end up setting the cursor after the drag ends, but in
this case the drag started and ended and we'll get a
pointer_focus event, which will make the application reset the
pointer image. Could introduce a drag start event that
indicates that the drag active.
How to handle drop decline (accept with type=NULL)
- Targets must send a NULL type in accept if they don't accept a

@ -44,6 +44,9 @@ struct dnd {
struct display *display;
uint32_t key;
struct item *items[16];
struct wl_buffer *buffer;
int hotspot_x, hotspot_y;
};
struct item {
@ -249,7 +252,16 @@ static void
drag_target(void *data,
struct wl_drag *drag, const char *mime_type)
{
struct dnd *dnd = data;
struct input *input;
struct wl_input_device *device;
fprintf(stderr, "target %s\n", mime_type);
input = wl_drag_get_user_data(drag);
device = input_get_input_device(input);
wl_input_device_attach(device, dnd->buffer,
dnd->hotspot_x, dnd->hotspot_y);
}
static void
@ -269,7 +281,7 @@ static void
drag_data(void *data,
struct wl_drag *drag, struct wl_array *contents)
{
fprintf(stderr, "drag drop, data %s\n", contents->data);
fprintf(stderr, "drag drop, data %s\n", (char *) contents->data);
}
static const struct wl_drag_listener drag_listener = {
@ -291,7 +303,6 @@ dnd_button_handler(struct window *window,
int32_t x, y, hotspot_x, hotspot_y, pointer_width, pointer_height;
struct rectangle rectangle;
struct item *item;
struct wl_buffer *buffer;
cairo_surface_t *surface, *pointer;
cairo_t *cr;
@ -334,12 +345,12 @@ dnd_button_handler(struct window *window,
cairo_paint(cr);
cairo_destroy(cr);
buffer = display_get_buffer_for_surface(dnd->display,
dnd->buffer = display_get_buffer_for_surface(dnd->display,
surface);
window_start_drag(window, input, time,
buffer,
pointer_width + x - item->x,
pointer_height + y - item->y);
dnd->hotspot_x = pointer_width + x - item->x;
dnd->hotspot_y = pointer_height + y - item->y;
window_start_drag(window, input, time);
/* FIXME: We leak the surface because we can't free it
* until the server has referenced it. */
@ -407,6 +418,8 @@ dnd_create(struct display *display)
rectangle.height = 4 * (item_height + item_padding) + item_padding;
window_set_child_size(dnd->window, &rectangle);
display_add_drag_listener(display, &drag_listener, dnd);
dnd_draw(dnd);
return dnd;
@ -428,8 +441,6 @@ main(int argc, char *argv[])
d = display_create(&argc, &argv, option_entries);
display_add_drag_listener(d, &drag_listener, d);
dnd = dnd_create (d);
display_run(d);

@ -561,7 +561,8 @@ window_handle_motion(void *data, struct wl_input_device *input_device,
set_pointer_image(input, pointer);
}
static void window_handle_button(void *data,
static void
window_handle_button(void *data,
struct wl_input_device *input_device,
uint32_t time, uint32_t button, uint32_t state)
{
@ -717,6 +718,12 @@ input_get_position(struct input *input, int32_t *x, int32_t *y)
*y = input->sy;
}
struct wl_input_device *
input_get_input_device(struct input *input)
{
return input->input_device;
}
void
display_add_drag_listener(struct display *display,
const struct wl_drag_listener *drag_listener,
@ -729,12 +736,11 @@ display_add_drag_listener(struct display *display,
}
void
window_start_drag(struct window *window, struct input *input, uint32_t time,
struct wl_buffer *buffer, int32_t x, int32_t y)
window_start_drag(struct window *window, struct input *input, uint32_t time)
{
cairo_device_flush (window->display->device);
wl_drag_prepare(input->drag, window->surface, time, buffer, x, y);
wl_drag_prepare(input->drag, window->surface, time);
wl_drag_offer(input->drag, "text/plain");
wl_drag_activate(input->drag);
}

@ -188,10 +188,12 @@ window_set_frame_handler(struct window *window,
window_frame_handler_t handler);
void
window_start_drag(struct window *window, struct input *input, uint32_t time,
struct wl_buffer *buffer, int32_t x, int32_t y);
window_start_drag(struct window *window, struct input *input, uint32_t time);
void
input_get_position(struct input *input, int32_t *x, int32_t *y);
struct wl_input_device *
input_get_input_device(struct input *input);
#endif

@ -952,8 +952,11 @@ input_device_attach(struct wl_client *client,
(struct wlsc_input_device *) device_base;
struct wlsc_buffer *buffer = (struct wlsc_buffer *) buffer_base;
if (device->pointer_focus == NULL ||
device->pointer_focus->base.client != client)
if (device->pointer_focus == NULL)
return;
if (device->pointer_focus->base.client != client &&
!(&device->pointer_focus->base == &wl_grab_surface &&
device->grab_surface->base.client == client))
return;
if (buffer == NULL) {
@ -1052,8 +1055,7 @@ wl_drag_reset(struct wl_drag *drag)
static void
drag_prepare(struct wl_client *client,
struct wl_drag *drag, struct wl_surface *surface, uint32_t time,
struct wl_buffer *buffer, int32_t hotspot_x, int32_t hotspot_y)
struct wl_drag *drag, struct wl_surface *surface, uint32_t time)
{
struct wlsc_input_device *device =
(struct wlsc_input_device *) drag->input_device;
@ -1065,9 +1067,6 @@ drag_prepare(struct wl_client *client,
wl_drag_reset(drag);
drag->source = surface;
drag->time = time;
drag->buffer = buffer;
drag->hotspot_x = hotspot_x;
drag->hotspot_y = hotspot_y;
}
static void
@ -1112,8 +1111,6 @@ drag_activate(struct wl_client *client,
wlsc_input_device_start_grab(device, drag->time,
WLSC_DEVICE_GRAB_DRAG);
wlsc_input_device_attach(device, (struct wlsc_buffer *) drag->buffer,
drag->hotspot_x, drag->hotspot_y);
surface = pick_surface(device, &sx, &sy);
wl_drag_set_pointer_focus(&device->drag, surface, drag->time,

@ -102,9 +102,6 @@
grab started by the button click at time -->
<arg name="surface" type="object" interface="surface"/>
<arg name="time" type="uint"/>
<arg name="buffer" type="object" interface="buffer"/>
<arg name="hotspot_x" type="int"/>
<arg name="hotspot_y" type="int"/>
</request>
<!-- Add an offered mime type. Can be called several times to

@ -134,10 +134,6 @@ struct wl_drag {
struct wl_array types;
const char *type;
uint32_t time;
struct wl_buffer *buffer;
int32_t hotspot_x;
int32_t hotspot_y;
};
void

Loading…
Cancel
Save