|  |  | @ -47,7 +47,21 @@ static int xwm_selection_flush_source_data(struct wlr_xwm_selection *selection) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return length; |  |  |  | 	return length; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int xwm_read_data_source(int fd, uint32_t mask, void *data) { |  |  |  | static void xwm_data_source_remove_property_source( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct wlr_xwm_selection *selection) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (selection->property_source) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wl_event_source_remove(selection->property_source); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	selection->property_source = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static void xwm_data_source_close_source_fd( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct wlr_xwm_selection *selection) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	close(selection->source_fd); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	selection->source_fd = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static int xwm_data_source_read(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwm_selection *selection = data; |  |  |  | 	struct wlr_xwm_selection *selection = data; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwm *xwm = selection->xwm; |  |  |  | 	struct wlr_xwm *xwm = selection->xwm; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -89,20 +103,17 @@ static int xwm_read_data_source(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 					1, &incr_chunk_size); |  |  |  | 					1, &incr_chunk_size); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->property_set = true; |  |  |  | 			selection->property_set = true; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->flush_property_on_delete = 1; |  |  |  | 			selection->flush_property_on_delete = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_event_source_remove(selection->property_source); |  |  |  | 			xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->property_source = NULL; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			xwm_selection_send_notify(selection, selection->request.property); |  |  |  | 			xwm_selection_send_notify(selection, selection->request.property); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else if (selection->property_set) { |  |  |  | 		} else if (selection->property_set) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, waiting for " |  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, waiting for property delete", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				"property delete", selection->source_data.size); |  |  |  | 				selection->source_data.size); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->flush_property_on_delete = 1; |  |  |  | 			selection->flush_property_on_delete = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_event_source_remove(selection->property_source); |  |  |  | 			xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->property_source = NULL; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  | 		} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, " |  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, property deleted, setting new " | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				"property deleted, setting new property", |  |  |  | 				"property", selection->source_data.size); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				selection->source_data.size); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			xwm_selection_flush_source_data(selection); |  |  |  | 			xwm_selection_flush_source_data(selection); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (len == 0 && !selection->incr) { |  |  |  | 	} else if (len == 0 && !selection->incr) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -111,9 +122,8 @@ static int xwm_read_data_source(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xwm_selection_flush_source_data(selection); |  |  |  | 		xwm_selection_flush_source_data(selection); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xwm_selection_send_notify(selection, selection->request.property); |  |  |  | 		xwm_selection_send_notify(selection, selection->request.property); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_flush(xwm->xcb_conn); |  |  |  | 		xcb_flush(xwm->xcb_conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_event_source_remove(selection->property_source); |  |  |  | 		xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_source = NULL; |  |  |  | 		xwm_data_source_close_source_fd(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		close(fd); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		wl_array_release(&selection->source_data); |  |  |  | 		wl_array_release(&selection->source_data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->request.requestor = XCB_NONE; |  |  |  | 		selection->request.requestor = XCB_NONE; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (len == 0 && selection->incr) { |  |  |  | 	} else if (len == 0 && selection->incr) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -121,20 +131,16 @@ static int xwm_read_data_source(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->flush_property_on_delete = 1; |  |  |  | 		selection->flush_property_on_delete = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (selection->property_set) { |  |  |  | 		if (selection->property_set) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, waiting for " |  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, waiting for property delete", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 					"property delete", selection->source_data.size); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, " |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					"property deleted, setting new property", |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 				selection->source_data.size); |  |  |  | 				selection->source_data.size); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			wlr_log(L_DEBUG, "got %zu bytes, property deleted, setting new " | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				"property", selection->source_data.size); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			xwm_selection_flush_source_data(selection); |  |  |  | 			xwm_selection_flush_source_data(selection); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_flush(xwm->xcb_conn); |  |  |  | 		xcb_flush(xwm->xcb_conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_event_source_remove(selection->property_source); |  |  |  | 		xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_source = NULL; |  |  |  | 		xwm_data_source_close_source_fd(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		close(selection->source_fd); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->source_fd = -1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		close(fd); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  | 	} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(L_DEBUG, "nothing happened, buffered the bytes"); |  |  |  | 		wlr_log(L_DEBUG, "nothing happened, buffered the bytes"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
	
		
		
			
				
					|  |  | @ -143,9 +149,8 @@ static int xwm_read_data_source(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | error_out: |  |  |  | error_out: | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xwm_selection_send_notify(selection, XCB_ATOM_NONE); |  |  |  | 	xwm_selection_send_notify(selection, XCB_ATOM_NONE); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_event_source_remove(selection->property_source); |  |  |  | 	xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	selection->property_source = NULL; |  |  |  | 	xwm_data_source_close_source_fd(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	close(fd); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	wl_array_release(&selection->source_data); |  |  |  | 	wl_array_release(&selection->source_data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return 0; |  |  |  | 	return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | @ -191,9 +196,7 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wl_event_loop *loop = |  |  |  | 	struct wl_event_loop *loop = | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_display_get_event_loop(selection->xwm->xwayland->wl_display); |  |  |  | 		wl_display_get_event_loop(selection->xwm->xwayland->wl_display); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	selection->property_source = wl_event_loop_add_fd(loop, |  |  |  | 	selection->property_source = wl_event_loop_add_fd(loop, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->source_fd, |  |  |  | 		selection->source_fd, WL_EVENT_READABLE, xwm_data_source_read, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		WL_EVENT_READABLE, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xwm_read_data_source, |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		selection); |  |  |  | 		selection); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xwm_selection_source_send(selection, mime_type, p[1]); |  |  |  | 	xwm_selection_source_send(selection, mime_type, p[1]); | 
			
		
	
	
		
		
			
				
					|  |  | @ -371,7 +374,13 @@ static void xwm_handle_selection_request(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int writable_callback(int fd, uint32_t mask, void *data) { |  |  |  | static void xwm_data_source_destroy_property_reply( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct wlr_xwm_selection *selection) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	free(selection->property_reply); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	selection->property_reply = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static int xwm_data_source_write(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwm_selection *selection = data; |  |  |  | 	struct wlr_xwm_selection *selection = data; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwm *xwm = selection->xwm; |  |  |  | 	struct wlr_xwm *xwm = selection->xwm; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -381,13 +390,9 @@ static int writable_callback(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int len = write(fd, property + selection->property_start, remainder); |  |  |  | 	int len = write(fd, property + selection->property_start, remainder); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (len == -1) { |  |  |  | 	if (len == -1) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		free(selection->property_reply); |  |  |  | 		xwm_data_source_destroy_property_reply(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_reply = NULL; |  |  |  | 		xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if (selection->property_source) { |  |  |  | 		xwm_data_source_close_source_fd(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_event_source_remove(selection->property_source); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_source = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		close(fd); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(L_ERROR, "write error to target fd: %m"); |  |  |  | 		wlr_log(L_ERROR, "write error to target fd: %m"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return 1; |  |  |  | 		return 1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
	
		
		
			
				
					|  |  | @ -398,12 +403,8 @@ static int writable_callback(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	selection->property_start += len; |  |  |  | 	selection->property_start += len; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (len == remainder) { |  |  |  | 	if (len == remainder) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		free(selection->property_reply); |  |  |  | 		xwm_data_source_destroy_property_reply(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_reply = NULL; |  |  |  | 		xwm_data_source_remove_property_source(selection); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if (selection->property_source) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_event_source_remove(selection->property_source); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_source = NULL; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (selection->incr) { |  |  |  | 		if (selection->incr) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			xcb_delete_property(xwm->xcb_conn, |  |  |  | 			xcb_delete_property(xwm->xcb_conn, | 
			
		
	
	
		
		
			
				
					|  |  | @ -411,7 +412,7 @@ static int writable_callback(int fd, uint32_t mask, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				xwm->atoms[WL_SELECTION]); |  |  |  | 				xwm->atoms[WL_SELECTION]); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  | 		} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_log(L_DEBUG, "transfer complete"); |  |  |  | 			wlr_log(L_DEBUG, "transfer complete"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			close(fd); |  |  |  | 			xwm_data_source_close_source_fd(selection); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -422,13 +423,13 @@ static void xwm_write_property(struct wlr_xwm_selection *selection, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_get_property_reply_t *reply) { |  |  |  | 		xcb_get_property_reply_t *reply) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	selection->property_start = 0; |  |  |  | 	selection->property_start = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	selection->property_reply = reply; |  |  |  | 	selection->property_reply = reply; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	writable_callback(selection->source_fd, WL_EVENT_WRITABLE, selection); |  |  |  | 	xwm_data_source_write(selection->source_fd, WL_EVENT_WRITABLE, selection); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (selection->property_reply) { |  |  |  | 	if (selection->property_reply) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wl_event_loop *loop = |  |  |  | 		struct wl_event_loop *loop = | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_display_get_event_loop(selection->xwm->xwayland->wl_display); |  |  |  | 			wl_display_get_event_loop(selection->xwm->xwayland->wl_display); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		selection->property_source = wl_event_loop_add_fd(loop, |  |  |  | 		selection->property_source = wl_event_loop_add_fd(loop, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			selection->source_fd, WL_EVENT_WRITABLE, writable_callback, |  |  |  | 			selection->source_fd, WL_EVENT_WRITABLE, xwm_data_source_write, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			selection); |  |  |  | 			selection); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |