mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	Use a grab object for drag and drop
This commit is contained in:
		
							parent
							
								
									6d65d5f4d4
								
							
						
					
					
						commit
						287343a0d3
					
				
					 3 changed files with 63 additions and 50 deletions
				
			
		| 
						 | 
					@ -571,7 +571,7 @@ move_grab_motion(struct wl_grab *grab,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
move_grab_end(struct wl_grab *grab)
 | 
					move_grab_end(struct wl_grab *grab, uint32_t time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	free(grab);
 | 
						free(grab);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -655,7 +655,7 @@ resize_grab_motion(struct wl_grab *grab,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
resize_grab_end(struct wl_grab *grab)
 | 
					resize_grab_end(struct wl_grab *grab, uint32_t time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	free(grab);
 | 
						free(grab);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -894,17 +894,6 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
 | 
				
			||||||
				     time, x, y, sx, sy);
 | 
									     time, x, y, sx, sy);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case WLSC_DEVICE_GRAB_DRAG:
 | 
					 | 
				
			||||||
		es = pick_surface(device, &sx, &sy);
 | 
					 | 
				
			||||||
		wl_drag_set_pointer_focus(device->drag,
 | 
					 | 
				
			||||||
					  &es->surface, time, x, y, sx, sy);
 | 
					 | 
				
			||||||
		if (es)
 | 
					 | 
				
			||||||
			wl_client_post_event(es->surface.client,
 | 
					 | 
				
			||||||
					     &device->drag->drag_offer.object,
 | 
					 | 
				
			||||||
					     WL_DRAG_OFFER_MOTION,
 | 
					 | 
				
			||||||
					     time, x, y, sx, sy);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		/* Other grabs are handled as grab objects. */
 | 
							/* Other grabs are handled as grab objects. */
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -920,26 +909,16 @@ notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time)
 | 
					wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_drag *drag = device->drag;
 | 
					 | 
				
			||||||
	struct wlsc_surface *es;
 | 
						struct wlsc_surface *es;
 | 
				
			||||||
	const struct wl_grab_interface *interface;
 | 
						const struct wl_grab_interface *interface;
 | 
				
			||||||
	int32_t sx, sy;
 | 
						int32_t sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (device->grab_object) {
 | 
						if (device->grab_object) {
 | 
				
			||||||
		interface = device->grab_object->interface;
 | 
							interface = device->grab_object->interface;
 | 
				
			||||||
		interface->end(device->grab_object);
 | 
							interface->end(device->grab_object, time);
 | 
				
			||||||
		device->grab_object = NULL;
 | 
							device->grab_object = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (device->grab) {
 | 
					 | 
				
			||||||
	case WLSC_DEVICE_GRAB_DRAG:
 | 
					 | 
				
			||||||
		wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
 | 
					 | 
				
			||||||
		device->drag = NULL;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_remove(&device->grab_listener.link);
 | 
						wl_list_remove(&device->grab_listener.link);
 | 
				
			||||||
	device->grab = WLSC_DEVICE_GRAB_NONE;
 | 
						device->grab = WLSC_DEVICE_GRAB_NONE;
 | 
				
			||||||
	es = pick_surface(device, &sx, &sy);
 | 
						es = pick_surface(device, &sx, &sy);
 | 
				
			||||||
| 
						 | 
					@ -954,7 +933,6 @@ notify_button(struct wlsc_input_device *device,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_surface *surface;
 | 
						struct wlsc_surface *surface;
 | 
				
			||||||
	struct wlsc_compositor *compositor = device->ec;
 | 
						struct wlsc_compositor *compositor = device->ec;
 | 
				
			||||||
	struct wl_drag *drag = device->drag;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	surface = (struct wlsc_surface *) device->input_device.pointer_focus;
 | 
						surface = (struct wlsc_surface *) device->input_device.pointer_focus;
 | 
				
			||||||
	if (!surface)
 | 
						if (!surface)
 | 
				
			||||||
| 
						 | 
					@ -1000,11 +978,6 @@ notify_button(struct wlsc_input_device *device,
 | 
				
			||||||
	} else if (!state &&
 | 
						} else if (!state &&
 | 
				
			||||||
		   device->grab != WLSC_DEVICE_GRAB_NONE &&
 | 
							   device->grab != WLSC_DEVICE_GRAB_NONE &&
 | 
				
			||||||
		   device->grab_button == button) {
 | 
							   device->grab_button == button) {
 | 
				
			||||||
		drag = device->drag;
 | 
					 | 
				
			||||||
		if (drag && drag->target)
 | 
					 | 
				
			||||||
			wl_client_post_event(drag->target,
 | 
					 | 
				
			||||||
					     &drag->drag_offer.object,
 | 
					 | 
				
			||||||
					     WL_DRAG_OFFER_DROP);
 | 
					 | 
				
			||||||
		wlsc_input_device_end_grab(device, time);
 | 
							wlsc_input_device_end_grab(device, time);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1209,6 +1182,43 @@ drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
 | 
				
			||||||
		wl_client_post_no_memory(client);
 | 
							wl_client_post_no_memory(client);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					drag_grab_motion(struct wl_grab *grab,
 | 
				
			||||||
 | 
							   uint32_t time, int32_t x, int32_t y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
 | 
				
			||||||
 | 
						struct wlsc_input_device *device =
 | 
				
			||||||
 | 
							(struct wlsc_input_device *) grab->input_device;
 | 
				
			||||||
 | 
						struct wlsc_surface *es;
 | 
				
			||||||
 | 
						int32_t sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						es = pick_surface(device, &sx, &sy);
 | 
				
			||||||
 | 
						wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy);
 | 
				
			||||||
 | 
						if (es)
 | 
				
			||||||
 | 
							wl_client_post_event(es->surface.client,
 | 
				
			||||||
 | 
									     &drag->drag_offer.object,
 | 
				
			||||||
 | 
									     WL_DRAG_OFFER_MOTION,
 | 
				
			||||||
 | 
									     time, x, y, sx, sy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					drag_grab_end(struct wl_grab *grab, uint32_t time)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (drag->target)
 | 
				
			||||||
 | 
							wl_client_post_event(drag->target,
 | 
				
			||||||
 | 
									     &drag->drag_offer.object,
 | 
				
			||||||
 | 
									     WL_DRAG_OFFER_DROP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wl_grab_interface drag_grab_interface = {
 | 
				
			||||||
 | 
						drag_grab_motion,
 | 
				
			||||||
 | 
						drag_grab_end
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
drag_activate(struct wl_client *client,
 | 
					drag_activate(struct wl_client *client,
 | 
				
			||||||
	      struct wl_drag *drag,
 | 
						      struct wl_drag *drag,
 | 
				
			||||||
| 
						 | 
					@ -1225,8 +1235,11 @@ drag_activate(struct wl_client *client,
 | 
				
			||||||
					  surface, time) < 0)
 | 
										  surface, time) < 0)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						device->grab_object = &drag->grab;
 | 
				
			||||||
 | 
						drag->grab.interface = &drag_grab_interface;
 | 
				
			||||||
 | 
						drag->grab.input_device = input_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drag->source = surface;
 | 
						drag->source = surface;
 | 
				
			||||||
	drag->input_device = input_device;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drag->drag_offer.object.interface = &wl_drag_offer_interface;
 | 
						drag->drag_offer.object.interface = &wl_drag_offer_interface;
 | 
				
			||||||
	drag->drag_offer.object.implementation =
 | 
						drag->drag_offer.object.implementation =
 | 
				
			||||||
| 
						 | 
					@ -1234,17 +1247,16 @@ drag_activate(struct wl_client *client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_display_add_object(display, &drag->drag_offer.object);
 | 
						wl_display_add_object(display, &drag->drag_offer.object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	device->drag = drag;
 | 
					 | 
				
			||||||
	target = pick_surface(device, &sx, &sy);
 | 
						target = pick_surface(device, &sx, &sy);
 | 
				
			||||||
	wl_drag_set_pointer_focus(device->drag, &target->surface, time,
 | 
						wl_drag_set_pointer_focus(drag, &target->surface, time,
 | 
				
			||||||
				  device->x, device->y, sx, sy);
 | 
									  device->x, device->y, sx, sy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
drag_cancel(struct wl_client *client, struct wl_drag *drag)
 | 
					drag_destroy(struct wl_client *client, struct wl_drag *drag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_input_device *device =
 | 
						struct wlsc_input_device *device =
 | 
				
			||||||
		(struct wlsc_input_device *) drag->input_device;
 | 
							(struct wlsc_input_device *) drag->grab.input_device;
 | 
				
			||||||
	uint32_t time;
 | 
						uint32_t time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (drag->source == NULL || drag->source->client != client)
 | 
						if (drag->source == NULL || drag->source->client != client)
 | 
				
			||||||
| 
						 | 
					@ -1252,12 +1264,13 @@ drag_cancel(struct wl_client *client, struct wl_drag *drag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	time = get_time();
 | 
						time = get_time();
 | 
				
			||||||
	wlsc_input_device_end_grab(device, time);
 | 
						wlsc_input_device_end_grab(device, time);
 | 
				
			||||||
 | 
						wl_resource_destroy(&drag->resource, client);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct wl_drag_interface drag_interface = {
 | 
					static const struct wl_drag_interface drag_interface = {
 | 
				
			||||||
	drag_offer,
 | 
						drag_offer,
 | 
				
			||||||
	drag_activate,
 | 
						drag_activate,
 | 
				
			||||||
	drag_cancel,
 | 
						drag_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,18 +81,6 @@ enum wlsc_pointer_type {
 | 
				
			||||||
	WLSC_POINTER_IBEAM,
 | 
						WLSC_POINTER_IBEAM,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_grab;
 | 
					 | 
				
			||||||
struct wl_grab_interface {
 | 
					 | 
				
			||||||
	void (*motion)(struct wl_grab *grab,
 | 
					 | 
				
			||||||
		       uint32_t time, int32_t x, int32_t y);
 | 
					 | 
				
			||||||
	void (*end)(struct wl_grab *grab);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct wl_grab {
 | 
					 | 
				
			||||||
	const struct wl_grab_interface *interface;
 | 
					 | 
				
			||||||
	struct wl_input_device *input_device;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct wlsc_input_device {
 | 
					struct wlsc_input_device {
 | 
				
			||||||
	struct wl_input_device input_device;
 | 
						struct wl_input_device input_device;
 | 
				
			||||||
	int32_t x, y;
 | 
						int32_t x, y;
 | 
				
			||||||
| 
						 | 
					@ -110,7 +98,6 @@ struct wlsc_input_device {
 | 
				
			||||||
	int32_t grab_width, grab_height;
 | 
						int32_t grab_width, grab_height;
 | 
				
			||||||
	int32_t grab_dx, grab_dy;
 | 
						int32_t grab_dx, grab_dy;
 | 
				
			||||||
	uint32_t grab_button;
 | 
						uint32_t grab_button;
 | 
				
			||||||
	struct wl_drag *drag;
 | 
					 | 
				
			||||||
	struct wl_listener grab_listener;
 | 
						struct wl_listener grab_listener;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,18 +144,31 @@ struct wl_visual {
 | 
				
			||||||
	struct wl_object object;
 | 
						struct wl_object object;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wl_grab;
 | 
				
			||||||
 | 
					struct wl_grab_interface {
 | 
				
			||||||
 | 
						void (*motion)(struct wl_grab *grab,
 | 
				
			||||||
 | 
							       uint32_t time, int32_t x, int32_t y);
 | 
				
			||||||
 | 
						void (*end)(struct wl_grab *grab, uint32_t time);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wl_grab {
 | 
				
			||||||
 | 
						const struct wl_grab_interface *interface;
 | 
				
			||||||
 | 
						struct wl_input_device *input_device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_drag_offer {
 | 
					struct wl_drag_offer {
 | 
				
			||||||
	struct wl_object object;
 | 
						struct wl_object object;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wl_drag {
 | 
					struct wl_drag {
 | 
				
			||||||
	struct wl_resource resource;
 | 
						struct wl_resource resource;
 | 
				
			||||||
 | 
						struct wl_grab grab;
 | 
				
			||||||
	struct wl_drag_offer drag_offer;
 | 
						struct wl_drag_offer drag_offer;
 | 
				
			||||||
	struct wl_surface *source;
 | 
						struct wl_surface *source;
 | 
				
			||||||
	struct wl_surface *drag_focus;
 | 
						struct wl_surface *drag_focus;
 | 
				
			||||||
	struct wl_client *target;
 | 
						struct wl_client *target;
 | 
				
			||||||
	int32_t x, y, sx, sy;
 | 
						int32_t x, y, sx, sy;
 | 
				
			||||||
	struct wl_input_device *input_device;
 | 
					 | 
				
			||||||
	struct wl_array types;
 | 
						struct wl_array types;
 | 
				
			||||||
	const char *type;
 | 
						const char *type;
 | 
				
			||||||
	uint32_t pointer_focus_time;
 | 
						uint32_t pointer_focus_time;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue