xwayland: send DND_LEAVE
This commit is contained in:
		
							parent
							
								
									e208f8dd8c
								
							
						
					
					
						commit
						30babb3865
					
				|  | @ -269,11 +269,31 @@ static xcb_atom_t xwm_get_mime_type_atom(struct wlr_xwm *xwm, char *mime_type) { | ||||||
| 	return atom; | 	return atom; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void xwm_dnd_send_event(struct wlr_xwm *xwm, xcb_atom_t type, | ||||||
|  | 		xcb_client_message_data_t *data) { | ||||||
|  | 	struct wlr_xwayland_surface *dest = xwm->drag_focus; | ||||||
|  | 	assert(dest != NULL); | ||||||
|  | 
 | ||||||
|  | 	xcb_client_message_event_t event = { | ||||||
|  | 		.response_type = XCB_CLIENT_MESSAGE, | ||||||
|  | 		.format = 32, | ||||||
|  | 		.sequence = 0, | ||||||
|  | 		.window = dest->window_id, | ||||||
|  | 		.type = type, | ||||||
|  | 		.data = *data, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	xcb_send_event(xwm->xcb_conn, | ||||||
|  | 		0, // propagate
 | ||||||
|  | 		dest->window_id, | ||||||
|  | 		XCB_EVENT_MASK_NO_EVENT, | ||||||
|  | 		(const char *)&event); | ||||||
|  | 	xcb_flush(xwm->xcb_conn); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void xwm_dnd_send_enter(struct wlr_xwm *xwm) { | static void xwm_dnd_send_enter(struct wlr_xwm *xwm) { | ||||||
| 	struct wlr_drag *drag = xwm->drag; | 	struct wlr_drag *drag = xwm->drag; | ||||||
| 	assert(drag != NULL); | 	assert(drag != NULL); | ||||||
| 	struct wlr_xwayland_surface *dest = xwm->drag_focus; |  | ||||||
| 	assert(dest != NULL); |  | ||||||
| 	struct wl_array *mime_types = &drag->source->mime_types; | 	struct wl_array *mime_types = &drag->source->mime_types; | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_data_t data = { 0 }; | 	xcb_client_message_data_t data = { 0 }; | ||||||
|  | @ -312,29 +332,13 @@ static void xwm_dnd_send_enter(struct wlr_xwm *xwm) { | ||||||
| 			n, targets); | 			n, targets); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_event_t event = { | 	xwm_dnd_send_event(xwm, xwm->atoms[DND_ENTER], &data); | ||||||
| 		.response_type = XCB_CLIENT_MESSAGE, |  | ||||||
| 		.format = 32, |  | ||||||
| 		.sequence = 0, |  | ||||||
| 		.window = dest->window_id, |  | ||||||
| 		.type = xwm->atoms[DND_ENTER], |  | ||||||
| 		.data = data, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	xcb_send_event(xwm->xcb_conn, |  | ||||||
| 		0, // propagate
 |  | ||||||
| 		dest->window_id, |  | ||||||
| 		XCB_EVENT_MASK_NO_EVENT, |  | ||||||
| 		(const char *)&event); |  | ||||||
| 	xcb_flush(xwm->xcb_conn); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void xwm_dnd_send_position(struct wlr_xwm *xwm, uint32_t time, int16_t x, | static void xwm_dnd_send_position(struct wlr_xwm *xwm, uint32_t time, int16_t x, | ||||||
| 		int16_t y) { | 		int16_t y) { | ||||||
| 	struct wlr_drag *drag = xwm->drag; | 	struct wlr_drag *drag = xwm->drag; | ||||||
| 	assert(drag != NULL); | 	assert(drag != NULL); | ||||||
| 	struct wlr_xwayland_surface *dest = xwm->drag_focus; |  | ||||||
| 	assert(dest != NULL); |  | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_data_t data = { 0 }; | 	xcb_client_message_data_t data = { 0 }; | ||||||
| 	data.data32[0] = xwm->dnd_selection.window; | 	data.data32[0] = xwm->dnd_selection.window; | ||||||
|  | @ -343,21 +347,7 @@ static void xwm_dnd_send_position(struct wlr_xwm *xwm, uint32_t time, int16_t x, | ||||||
| 	data.data32[4] = | 	data.data32[4] = | ||||||
| 		data_device_manager_dnd_action_to_atom(xwm, drag->source->actions); | 		data_device_manager_dnd_action_to_atom(xwm, drag->source->actions); | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_event_t event = { | 	xwm_dnd_send_event(xwm, xwm->atoms[DND_POSITION], &data); | ||||||
| 		.response_type = XCB_CLIENT_MESSAGE, |  | ||||||
| 		.format = 32, |  | ||||||
| 		.sequence = 0, |  | ||||||
| 		.window = dest->window_id, |  | ||||||
| 		.type = xwm->atoms[DND_POSITION], |  | ||||||
| 		.data = data, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	xcb_send_event(xwm->xcb_conn, |  | ||||||
| 		0, // propagate
 |  | ||||||
| 		dest->window_id, |  | ||||||
| 		XCB_EVENT_MASK_NO_EVENT, |  | ||||||
| 		(const char *)&event); |  | ||||||
| 	xcb_flush(xwm->xcb_conn); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void xwm_dnd_send_drop(struct wlr_xwm *xwm, uint32_t time) { | static void xwm_dnd_send_drop(struct wlr_xwm *xwm, uint32_t time) { | ||||||
|  | @ -370,21 +360,19 @@ static void xwm_dnd_send_drop(struct wlr_xwm *xwm, uint32_t time) { | ||||||
| 	data.data32[0] = xwm->dnd_selection.window; | 	data.data32[0] = xwm->dnd_selection.window; | ||||||
| 	data.data32[2] = time; | 	data.data32[2] = time; | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_event_t event = { | 	xwm_dnd_send_event(xwm, xwm->atoms[DND_DROP], &data); | ||||||
| 		.response_type = XCB_CLIENT_MESSAGE, | } | ||||||
| 		.format = 32, |  | ||||||
| 		.sequence = 0, |  | ||||||
| 		.window = dest->window_id, |  | ||||||
| 		.type = xwm->atoms[DND_DROP], |  | ||||||
| 		.data = data, |  | ||||||
| 	}; |  | ||||||
| 
 | 
 | ||||||
| 	xcb_send_event(xwm->xcb_conn, | static void xwm_dnd_send_leave(struct wlr_xwm *xwm) { | ||||||
| 		0, // propagate
 | 	struct wlr_drag *drag = xwm->drag; | ||||||
| 		dest->window_id, | 	assert(drag != NULL); | ||||||
| 		XCB_EVENT_MASK_NO_EVENT, | 	struct wlr_xwayland_surface *dest = xwm->drag_focus; | ||||||
| 		(const char *)&event); | 	assert(dest != NULL); | ||||||
| 	xcb_flush(xwm->xcb_conn); | 
 | ||||||
|  | 	xcb_client_message_data_t data = { 0 }; | ||||||
|  | 	data.data32[0] = xwm->dnd_selection.window; | ||||||
|  | 
 | ||||||
|  | 	xwm_dnd_send_event(xwm, xwm->atoms[DND_LEAVE], &data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*static void xwm_dnd_send_finished(struct wlr_xwm *xwm) {
 | /*static void xwm_dnd_send_finished(struct wlr_xwm *xwm) {
 | ||||||
|  | @ -402,21 +390,7 @@ static void xwm_dnd_send_drop(struct wlr_xwm *xwm, uint32_t time) { | ||||||
| 			drag->source->current_dnd_action); | 			drag->source->current_dnd_action); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	xcb_client_message_event_t event = { | 	xwm_dnd_send_event(xwm, xwm->atoms[DND_FINISHED], &data); | ||||||
| 		.response_type = XCB_CLIENT_MESSAGE, |  | ||||||
| 		.format = 32, |  | ||||||
| 		.sequence = 0, |  | ||||||
| 		.window = dest->window_id, |  | ||||||
| 		.type = xwm->atoms[DND_FINISHED], |  | ||||||
| 		.data = data, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	xcb_send_event(xwm->xcb_conn, |  | ||||||
| 		0, // propagate
 |  | ||||||
| 		dest->window_id, |  | ||||||
| 		XCB_EVENT_MASK_NO_EVENT, |  | ||||||
| 		(const char *)&event); |  | ||||||
| 	xcb_flush(xwm->xcb_conn); |  | ||||||
| }*/ | }*/ | ||||||
| 
 | 
 | ||||||
| static struct wl_array *xwm_selection_source_get_mime_types( | static struct wl_array *xwm_selection_source_get_mime_types( | ||||||
|  | @ -1128,21 +1102,31 @@ static void seat_handle_drag_focus(struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_drag *drag = data; | 	struct wlr_drag *drag = data; | ||||||
| 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_focus); | 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_focus); | ||||||
| 
 | 
 | ||||||
| 	// TODO: check for subsurfaces?
 | 	struct wlr_xwayland_surface *focus = NULL; | ||||||
| 	bool found = false; | 	if (drag->focus != NULL) { | ||||||
| 	struct wlr_xwayland_surface *surface; | 		// TODO: check for subsurfaces?
 | ||||||
| 	wl_list_for_each(surface, &xwm->surfaces, link) { | 		struct wlr_xwayland_surface *surface; | ||||||
| 		if (surface->surface == drag->focus) { | 		wl_list_for_each(surface, &xwm->surfaces, link) { | ||||||
| 			found = true; | 			if (surface->surface == drag->focus) { | ||||||
| 			break; | 				focus = surface; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (!found) { | 
 | ||||||
|  | 	if (focus == xwm->drag_focus) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	xwm->drag_focus = surface; | 	if (xwm->drag_focus != NULL) { | ||||||
| 	xwm_dnd_send_enter(xwm); | 		xwm_dnd_send_leave(xwm); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	xwm->drag_focus = focus; | ||||||
|  | 
 | ||||||
|  | 	if (xwm->drag_focus != NULL) { | ||||||
|  | 		xwm_dnd_send_enter(xwm); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void seat_handle_drag_motion(struct wl_listener *listener, void *data) { | static void seat_handle_drag_motion(struct wl_listener *listener, void *data) { | ||||||
|  | @ -1161,9 +1145,8 @@ static void seat_handle_drag_motion(struct wl_listener *listener, void *data) { | ||||||
| static void seat_handle_drag_drop(struct wl_listener *listener, void *data) { | static void seat_handle_drag_drop(struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_drop); | 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_drop); | ||||||
| 	struct wlr_drag_drop_event *event = data; | 	struct wlr_drag_drop_event *event = data; | ||||||
| 	struct wlr_xwayland_surface *surface = xwm->drag_focus; |  | ||||||
| 
 | 
 | ||||||
| 	if (surface == NULL) { | 	if (xwm->drag_focus == NULL) { | ||||||
| 		return; // No xwayland surface focused
 | 		return; // No xwayland surface focused
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1173,6 +1156,10 @@ static void seat_handle_drag_drop(struct wl_listener *listener, void *data) { | ||||||
| static void seat_handle_drag_destroy(struct wl_listener *listener, void *data) { | static void seat_handle_drag_destroy(struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_destroy); | 	struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_drag_destroy); | ||||||
| 
 | 
 | ||||||
|  | 	if (xwm->drag_focus != NULL) { | ||||||
|  | 		xwm_dnd_send_leave(xwm); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	wl_list_remove(&xwm->seat_drag_focus.link); | 	wl_list_remove(&xwm->seat_drag_focus.link); | ||||||
| 	wl_list_remove(&xwm->seat_drag_destroy.link); | 	wl_list_remove(&xwm->seat_drag_destroy.link); | ||||||
| 	xwm->drag = NULL; | 	xwm->drag = NULL; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue