mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	xwayland: allow drag data source transfer after drag ends
This commit is contained in:
		
							parent
							
								
									743466d475
								
							
						
					
					
						commit
						ca2a73b90d
					
				
					 2 changed files with 33 additions and 19 deletions
				
			
		| 
						 | 
					@ -139,6 +139,7 @@ struct wlr_xwm {
 | 
				
			||||||
	struct wl_listener seat_drag_motion;
 | 
						struct wl_listener seat_drag_motion;
 | 
				
			||||||
	struct wl_listener seat_drag_drop;
 | 
						struct wl_listener seat_drag_drop;
 | 
				
			||||||
	struct wl_listener seat_drag_destroy;
 | 
						struct wl_listener seat_drag_destroy;
 | 
				
			||||||
 | 
						struct wl_listener seat_drag_source_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland);
 | 
					struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +186,7 @@ static void xwm_selection_source_send(struct wlr_xwm_selection *selection,
 | 
				
			||||||
		const char *mime_type, int32_t fd) {
 | 
							const char *mime_type, int32_t fd) {
 | 
				
			||||||
	if (selection == &selection->xwm->clipboard_selection) {
 | 
						if (selection == &selection->xwm->clipboard_selection) {
 | 
				
			||||||
		struct wlr_data_source *source =
 | 
							struct wlr_data_source *source =
 | 
				
			||||||
			selection->xwm->seat->selection_data_source;
 | 
								selection->xwm->seat->selection_source;
 | 
				
			||||||
		if (source != NULL) {
 | 
							if (source != NULL) {
 | 
				
			||||||
			source->send(source, mime_type, fd);
 | 
								source->send(source, mime_type, fd);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
| 
						 | 
					@ -199,15 +199,13 @@ static void xwm_selection_source_send(struct wlr_xwm_selection *selection,
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (selection == &selection->xwm->dnd_selection) {
 | 
						} else if (selection == &selection->xwm->dnd_selection) {
 | 
				
			||||||
		if (selection->xwm->seat->drag != NULL) {
 | 
					 | 
				
			||||||
		struct wlr_data_source *source =
 | 
							struct wlr_data_source *source =
 | 
				
			||||||
				selection->xwm->seat->drag->source;
 | 
								selection->xwm->seat->drag_source;
 | 
				
			||||||
		if (source != NULL) {
 | 
							if (source != NULL) {
 | 
				
			||||||
			source->send(source, mime_type, fd);
 | 
								source->send(source, mime_type, fd);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(L_DEBUG, "not sending selection: no selection source available");
 | 
						wlr_log(L_DEBUG, "not sending selection: no selection source available");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -216,7 +214,7 @@ static struct wl_array *xwm_selection_source_get_mime_types(
 | 
				
			||||||
		struct wlr_xwm_selection *selection) {
 | 
							struct wlr_xwm_selection *selection) {
 | 
				
			||||||
	if (selection == &selection->xwm->clipboard_selection) {
 | 
						if (selection == &selection->xwm->clipboard_selection) {
 | 
				
			||||||
		struct wlr_data_source *source =
 | 
							struct wlr_data_source *source =
 | 
				
			||||||
			selection->xwm->seat->selection_data_source;
 | 
								selection->xwm->seat->selection_source;
 | 
				
			||||||
		if (source != NULL) {
 | 
							if (source != NULL) {
 | 
				
			||||||
			return &source->mime_types;
 | 
								return &source->mime_types;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -227,9 +225,10 @@ static struct wl_array *xwm_selection_source_get_mime_types(
 | 
				
			||||||
			return &source->mime_types;
 | 
								return &source->mime_types;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (selection == &selection->xwm->dnd_selection) {
 | 
						} else if (selection == &selection->xwm->dnd_selection) {
 | 
				
			||||||
		if (selection->xwm->seat->drag != NULL &&
 | 
							struct wlr_data_source *source =
 | 
				
			||||||
				selection->xwm->seat->drag->source != NULL) {
 | 
								selection->xwm->seat->drag_source;
 | 
				
			||||||
			return &selection->xwm->seat->drag->source->mime_types;
 | 
							if (source != NULL) {
 | 
				
			||||||
 | 
								return &source->mime_types;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
| 
						 | 
					@ -815,8 +814,7 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) {
 | 
				
			||||||
	// set the wayland selection to the X11 selection
 | 
						// set the wayland selection to the X11 selection
 | 
				
			||||||
	struct wlr_xwm *xwm = selection->xwm;
 | 
						struct wlr_xwm *xwm = selection->xwm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (selection == &xwm->clipboard_selection ||
 | 
						if (selection == &xwm->clipboard_selection) {
 | 
				
			||||||
			selection == &xwm->dnd_selection) {
 | 
					 | 
				
			||||||
		struct x11_data_source *source =
 | 
							struct x11_data_source *source =
 | 
				
			||||||
			calloc(1, sizeof(struct x11_data_source));
 | 
								calloc(1, sizeof(struct x11_data_source));
 | 
				
			||||||
		if (source == NULL) {
 | 
							if (source == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -827,8 +825,6 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) {
 | 
				
			||||||
		source->base.send = data_source_send;
 | 
							source->base.send = data_source_send;
 | 
				
			||||||
		source->base.cancel = data_source_cancel;
 | 
							source->base.cancel = data_source_cancel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// TODO: DND
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		source->selection = selection;
 | 
							source->selection = selection;
 | 
				
			||||||
		wl_array_init(&source->mime_types_atoms);
 | 
							wl_array_init(&source->mime_types_atoms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -861,6 +857,8 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) {
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			source->base.cancel(&source->base);
 | 
								source->base.cancel(&source->base);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else if (selection == &xwm->dnd_selection) {
 | 
				
			||||||
 | 
							// TODO
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1082,8 +1080,8 @@ void xwm_selection_finish(struct wlr_xwm *xwm) {
 | 
				
			||||||
		xcb_destroy_window(xwm->xcb_conn, xwm->selection_window);
 | 
							xcb_destroy_window(xwm->xcb_conn, xwm->selection_window);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (xwm->seat) {
 | 
						if (xwm->seat) {
 | 
				
			||||||
		if (xwm->seat->selection_data_source &&
 | 
							if (xwm->seat->selection_source &&
 | 
				
			||||||
				xwm->seat->selection_data_source->cancel == data_source_cancel) {
 | 
									xwm->seat->selection_source->cancel == data_source_cancel) {
 | 
				
			||||||
			wlr_seat_set_selection(xwm->seat, NULL,
 | 
								wlr_seat_set_selection(xwm->seat, NULL,
 | 
				
			||||||
					wl_display_next_serial(xwm->xwayland->wl_display));
 | 
										wl_display_next_serial(xwm->xwayland->wl_display));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1118,7 +1116,7 @@ static void seat_handle_selection(struct wl_listener *listener,
 | 
				
			||||||
	struct wlr_seat *seat = data;
 | 
						struct wlr_seat *seat = data;
 | 
				
			||||||
	struct wlr_xwm *xwm =
 | 
						struct wlr_xwm *xwm =
 | 
				
			||||||
		wl_container_of(listener, xwm, seat_selection);
 | 
							wl_container_of(listener, xwm, seat_selection);
 | 
				
			||||||
	struct wlr_data_source *source = seat->selection_data_source;
 | 
						struct wlr_data_source *source = seat->selection_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source != NULL && source->send == data_source_send) {
 | 
						if (source != NULL && source->send == data_source_send) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -1211,10 +1209,21 @@ static void seat_handle_drag_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&xwm->seat_drag_focus.link);
 | 
						wl_list_remove(&xwm->seat_drag_focus.link);
 | 
				
			||||||
 | 
						wl_list_remove(&xwm->seat_drag_motion.link);
 | 
				
			||||||
 | 
						wl_list_remove(&xwm->seat_drag_drop.link);
 | 
				
			||||||
	wl_list_remove(&xwm->seat_drag_destroy.link);
 | 
						wl_list_remove(&xwm->seat_drag_destroy.link);
 | 
				
			||||||
	xwm->drag = NULL;
 | 
						xwm->drag = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void seat_handle_drag_source_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_xwm *xwm =
 | 
				
			||||||
 | 
							wl_container_of(listener, xwm, seat_drag_source_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_remove(&xwm->seat_drag_source_destroy.link);
 | 
				
			||||||
 | 
						xwm->drag_focus = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_handle_start_drag(struct wl_listener *listener, void *data) {
 | 
					static void seat_handle_start_drag(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_start_drag);
 | 
						struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_start_drag);
 | 
				
			||||||
| 
						 | 
					@ -1232,6 +1241,10 @@ static void seat_handle_start_drag(struct wl_listener *listener, void *data) {
 | 
				
			||||||
		xwm->seat_drag_drop.notify = seat_handle_drag_drop;
 | 
							xwm->seat_drag_drop.notify = seat_handle_drag_drop;
 | 
				
			||||||
		wl_signal_add(&drag->events.destroy, &xwm->seat_drag_destroy);
 | 
							wl_signal_add(&drag->events.destroy, &xwm->seat_drag_destroy);
 | 
				
			||||||
		xwm->seat_drag_destroy.notify = seat_handle_drag_destroy;
 | 
							xwm->seat_drag_destroy.notify = seat_handle_drag_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wl_signal_add(&drag->source->events.destroy,
 | 
				
			||||||
 | 
								&xwm->seat_drag_source_destroy);
 | 
				
			||||||
 | 
							xwm->seat_drag_source_destroy.notify = seat_handle_drag_source_destroy;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue