mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-03 09:01:42 -05:00
Set pointer image only in response to 'target' event
This commit is contained in:
parent
8a40871645
commit
1d7ffd32f8
7 changed files with 43 additions and 54 deletions
20
TODO
20
TODO
|
|
@ -16,26 +16,6 @@ Core wayland protocol
|
||||||
|
|
||||||
- DnD issues:
|
- 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)
|
How to handle drop decline (accept with type=NULL)
|
||||||
|
|
||||||
- Targets must send a NULL type in accept if they don't accept a
|
- Targets must send a NULL type in accept if they don't accept a
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ struct dnd {
|
||||||
struct display *display;
|
struct display *display;
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
struct item *items[16];
|
struct item *items[16];
|
||||||
|
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
int hotspot_x, hotspot_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct item {
|
struct item {
|
||||||
|
|
@ -249,7 +252,16 @@ static void
|
||||||
drag_target(void *data,
|
drag_target(void *data,
|
||||||
struct wl_drag *drag, const char *mime_type)
|
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);
|
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
|
static void
|
||||||
|
|
@ -269,7 +281,7 @@ static void
|
||||||
drag_data(void *data,
|
drag_data(void *data,
|
||||||
struct wl_drag *drag, struct wl_array *contents)
|
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 = {
|
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;
|
int32_t x, y, hotspot_x, hotspot_y, pointer_width, pointer_height;
|
||||||
struct rectangle rectangle;
|
struct rectangle rectangle;
|
||||||
struct item *item;
|
struct item *item;
|
||||||
struct wl_buffer *buffer;
|
|
||||||
cairo_surface_t *surface, *pointer;
|
cairo_surface_t *surface, *pointer;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
|
||||||
|
|
@ -334,12 +345,12 @@ dnd_button_handler(struct window *window,
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
|
|
||||||
buffer = display_get_buffer_for_surface(dnd->display,
|
dnd->buffer = display_get_buffer_for_surface(dnd->display,
|
||||||
surface);
|
surface);
|
||||||
window_start_drag(window, input, time,
|
dnd->hotspot_x = pointer_width + x - item->x;
|
||||||
buffer,
|
dnd->hotspot_y = pointer_height + y - item->y;
|
||||||
pointer_width + x - item->x,
|
|
||||||
pointer_height + y - item->y);
|
window_start_drag(window, input, time);
|
||||||
|
|
||||||
/* FIXME: We leak the surface because we can't free it
|
/* FIXME: We leak the surface because we can't free it
|
||||||
* until the server has referenced 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;
|
rectangle.height = 4 * (item_height + item_padding) + item_padding;
|
||||||
window_set_child_size(dnd->window, &rectangle);
|
window_set_child_size(dnd->window, &rectangle);
|
||||||
|
|
||||||
|
display_add_drag_listener(display, &drag_listener, dnd);
|
||||||
|
|
||||||
dnd_draw(dnd);
|
dnd_draw(dnd);
|
||||||
|
|
||||||
return dnd;
|
return dnd;
|
||||||
|
|
@ -428,8 +441,6 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
d = display_create(&argc, &argv, option_entries);
|
d = display_create(&argc, &argv, option_entries);
|
||||||
|
|
||||||
display_add_drag_listener(d, &drag_listener, d);
|
|
||||||
|
|
||||||
dnd = dnd_create (d);
|
dnd = dnd_create (d);
|
||||||
|
|
||||||
display_run(d);
|
display_run(d);
|
||||||
|
|
|
||||||
|
|
@ -561,9 +561,10 @@ window_handle_motion(void *data, struct wl_input_device *input_device,
|
||||||
set_pointer_image(input, pointer);
|
set_pointer_image(input, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_handle_button(void *data,
|
static void
|
||||||
struct wl_input_device *input_device,
|
window_handle_button(void *data,
|
||||||
uint32_t time, uint32_t button, uint32_t state)
|
struct wl_input_device *input_device,
|
||||||
|
uint32_t time, uint32_t button, uint32_t state)
|
||||||
{
|
{
|
||||||
struct input *input = data;
|
struct input *input = data;
|
||||||
struct window *window = input->pointer_focus;
|
struct window *window = input->pointer_focus;
|
||||||
|
|
@ -717,6 +718,12 @@ input_get_position(struct input *input, int32_t *x, int32_t *y)
|
||||||
*y = input->sy;
|
*y = input->sy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wl_input_device *
|
||||||
|
input_get_input_device(struct input *input)
|
||||||
|
{
|
||||||
|
return input->input_device;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
display_add_drag_listener(struct display *display,
|
display_add_drag_listener(struct display *display,
|
||||||
const struct wl_drag_listener *drag_listener,
|
const struct wl_drag_listener *drag_listener,
|
||||||
|
|
@ -729,12 +736,11 @@ display_add_drag_listener(struct display *display,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_start_drag(struct window *window, struct input *input, uint32_t time,
|
window_start_drag(struct window *window, struct input *input, uint32_t time)
|
||||||
struct wl_buffer *buffer, int32_t x, int32_t y)
|
|
||||||
{
|
{
|
||||||
cairo_device_flush (window->display->device);
|
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_offer(input->drag, "text/plain");
|
||||||
wl_drag_activate(input->drag);
|
wl_drag_activate(input->drag);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,10 +188,12 @@ window_set_frame_handler(struct window *window,
|
||||||
window_frame_handler_t handler);
|
window_frame_handler_t handler);
|
||||||
|
|
||||||
void
|
void
|
||||||
window_start_drag(struct window *window, struct input *input, uint32_t time,
|
window_start_drag(struct window *window, struct input *input, uint32_t time);
|
||||||
struct wl_buffer *buffer, int32_t x, int32_t y);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
input_get_position(struct input *input, int32_t *x, int32_t *y);
|
input_get_position(struct input *input, int32_t *x, int32_t *y);
|
||||||
|
|
||||||
|
struct wl_input_device *
|
||||||
|
input_get_input_device(struct input *input);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
15
compositor.c
15
compositor.c
|
|
@ -952,8 +952,11 @@ input_device_attach(struct wl_client *client,
|
||||||
(struct wlsc_input_device *) device_base;
|
(struct wlsc_input_device *) device_base;
|
||||||
struct wlsc_buffer *buffer = (struct wlsc_buffer *) buffer_base;
|
struct wlsc_buffer *buffer = (struct wlsc_buffer *) buffer_base;
|
||||||
|
|
||||||
if (device->pointer_focus == NULL ||
|
if (device->pointer_focus == NULL)
|
||||||
device->pointer_focus->base.client != client)
|
return;
|
||||||
|
if (device->pointer_focus->base.client != client &&
|
||||||
|
!(&device->pointer_focus->base == &wl_grab_surface &&
|
||||||
|
device->grab_surface->base.client == client))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
|
|
@ -1052,8 +1055,7 @@ wl_drag_reset(struct wl_drag *drag)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drag_prepare(struct wl_client *client,
|
drag_prepare(struct wl_client *client,
|
||||||
struct wl_drag *drag, struct wl_surface *surface, uint32_t time,
|
struct wl_drag *drag, struct wl_surface *surface, uint32_t time)
|
||||||
struct wl_buffer *buffer, int32_t hotspot_x, int32_t hotspot_y)
|
|
||||||
{
|
{
|
||||||
struct wlsc_input_device *device =
|
struct wlsc_input_device *device =
|
||||||
(struct wlsc_input_device *) drag->input_device;
|
(struct wlsc_input_device *) drag->input_device;
|
||||||
|
|
@ -1065,9 +1067,6 @@ drag_prepare(struct wl_client *client,
|
||||||
wl_drag_reset(drag);
|
wl_drag_reset(drag);
|
||||||
drag->source = surface;
|
drag->source = surface;
|
||||||
drag->time = time;
|
drag->time = time;
|
||||||
drag->buffer = buffer;
|
|
||||||
drag->hotspot_x = hotspot_x;
|
|
||||||
drag->hotspot_y = hotspot_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1112,8 +1111,6 @@ drag_activate(struct wl_client *client,
|
||||||
|
|
||||||
wlsc_input_device_start_grab(device, drag->time,
|
wlsc_input_device_start_grab(device, drag->time,
|
||||||
WLSC_DEVICE_GRAB_DRAG);
|
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);
|
surface = pick_surface(device, &sx, &sy);
|
||||||
wl_drag_set_pointer_focus(&device->drag, surface, drag->time,
|
wl_drag_set_pointer_focus(&device->drag, surface, drag->time,
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,6 @@
|
||||||
grab started by the button click at time -->
|
grab started by the button click at time -->
|
||||||
<arg name="surface" type="object" interface="surface"/>
|
<arg name="surface" type="object" interface="surface"/>
|
||||||
<arg name="time" type="uint"/>
|
<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>
|
</request>
|
||||||
|
|
||||||
<!-- Add an offered mime type. Can be called several times to
|
<!-- Add an offered mime type. Can be called several times to
|
||||||
|
|
|
||||||
|
|
@ -134,10 +134,6 @@ struct wl_drag {
|
||||||
struct wl_array types;
|
struct wl_array types;
|
||||||
const char *type;
|
const char *type;
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
|
|
||||||
struct wl_buffer *buffer;
|
|
||||||
int32_t hotspot_x;
|
|
||||||
int32_t hotspot_y;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue