mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Compare commits
	
		
			5 commits
		
	
	
		
			6c27c2cdf2
			...
			170c9c9525
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 170c9c9525 | ||
|   | eb8acfd7b1 | ||
|   | 25ea1a0af2 | ||
|   | 4b15b3427f | ||
|   | 17f7c1b782 | 
					 12 changed files with 93 additions and 21 deletions
				
			
		|  | @ -141,3 +141,9 @@ bool sway_set_cloexec(int fd, bool cloexec) { | |||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| uint32_t get_current_time_in_msec(void) { | ||||
| 	struct timespec now; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||
| 	return now.tv_sec * 1000 + now.tv_nsec / 1000000; | ||||
| } | ||||
|  |  | |||
|  | @ -112,6 +112,9 @@ struct sway_server { | |||
| 	struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1; | ||||
| 	struct wlr_security_context_manager_v1 *security_context_manager_v1; | ||||
| 
 | ||||
| 	struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *ext_foreign_toplevel_image_capture_source_manager_v1; | ||||
| 	struct wl_listener new_foreign_toplevel_capture_request; | ||||
| 
 | ||||
| 	struct wlr_xdg_activation_v1 *xdg_activation_v1; | ||||
| 	struct wl_listener xdg_activation_v1_request_activate; | ||||
| 	struct wl_listener xdg_activation_v1_new_token; | ||||
|  |  | |||
|  | @ -69,6 +69,9 @@ struct sway_view { | |||
| 	struct wlr_scene_tree *content_tree; | ||||
| 	struct wlr_scene_tree *saved_surface_tree; | ||||
| 
 | ||||
| 	struct wlr_scene *image_capture_scene; | ||||
| 	struct wlr_ext_image_capture_source_v1 *image_capture_source; | ||||
| 
 | ||||
| 	struct sway_container *container; // NULL if unmapped and transactions finished
 | ||||
| 	struct wlr_surface *surface; // NULL for unmapped views
 | ||||
| 	struct sway_xdg_decoration *xdg_decoration; | ||||
|  | @ -124,6 +127,8 @@ struct sway_view { | |||
| struct sway_xdg_shell_view { | ||||
| 	struct sway_view view; | ||||
| 
 | ||||
| 	struct wlr_scene_tree *image_capture_tree; | ||||
| 
 | ||||
| 	struct wl_listener commit; | ||||
| 	struct wl_listener request_move; | ||||
| 	struct wl_listener request_resize; | ||||
|  | @ -142,6 +147,8 @@ struct sway_xwayland_view { | |||
| 
 | ||||
| 	struct wlr_scene_tree *surface_tree; | ||||
| 
 | ||||
| 	struct wlr_scene_surface *image_capture_scene_surface; | ||||
| 
 | ||||
| 	struct wl_listener commit; | ||||
| 	struct wl_listener request_move; | ||||
| 	struct wl_listener request_resize; | ||||
|  | @ -192,10 +199,12 @@ struct sway_popup_desc { | |||
| 
 | ||||
| struct sway_xdg_popup { | ||||
| 	struct sway_view *view; | ||||
| 	struct wlr_xdg_popup *wlr_xdg_popup; | ||||
| 
 | ||||
| 	struct wlr_scene_tree *scene_tree; | ||||
| 	struct wlr_scene_tree *xdg_surface_tree; | ||||
| 	struct wlr_xdg_popup *wlr_xdg_popup; | ||||
| 
 | ||||
| 	struct wlr_scene_tree *image_capture_tree; | ||||
| 
 | ||||
| 	struct sway_popup_desc desc; | ||||
| 
 | ||||
|  |  | |||
|  | @ -61,4 +61,6 @@ const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel); | |||
| 
 | ||||
| bool sway_set_cloexec(int fd, bool cloexec); | ||||
| 
 | ||||
| uint32_t get_current_time_in_msec(void); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ project( | |||
| 		'c_std=c11', | ||||
| 		'warning_level=2', | ||||
| 		'werror=true', | ||||
| 		'wrap_mode=nodownload', | ||||
| 	], | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -97,11 +97,11 @@ struct buffer_timer { | |||
| }; | ||||
| 
 | ||||
| static int handle_buffer_timer(void *data) { | ||||
| 	struct wlr_scene_buffer *buffer = data; | ||||
| 	struct wlr_scene_surface *scene_surface = data; | ||||
| 
 | ||||
| 	struct timespec now; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||
| 	wlr_scene_buffer_send_frame_done(buffer, &now); | ||||
| 	wlr_scene_surface_send_frame_done(scene_surface, &now); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -114,7 +114,9 @@ static void handle_buffer_timer_destroy(struct wl_listener *listener, | |||
| 	free(timer); | ||||
| } | ||||
| 
 | ||||
| static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_buffer *buffer) { | ||||
| static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_surface *scene_surface) { | ||||
| 	struct wlr_scene_buffer *buffer = scene_surface->buffer; | ||||
| 
 | ||||
| 	struct buffer_timer *timer = | ||||
| 		scene_descriptor_try_get(&buffer->node, SWAY_SCENE_DESC_BUFFER_TIMER); | ||||
| 	if (timer) { | ||||
|  | @ -127,7 +129,7 @@ static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_buffer * | |||
| 	} | ||||
| 
 | ||||
| 	timer->frame_done_timer = wl_event_loop_add_timer(server.wl_event_loop, | ||||
| 		handle_buffer_timer, buffer); | ||||
| 		handle_buffer_timer, scene_surface); | ||||
| 	if (!timer->frame_done_timer) { | ||||
| 		free(timer); | ||||
| 		return NULL; | ||||
|  | @ -151,6 +153,11 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(buffer); | ||||
| 	if (scene_surface == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_scene_node *current = &buffer->node; | ||||
| 	while (true) { | ||||
| 		struct sway_view *view = scene_descriptor_try_get(current, | ||||
|  | @ -173,13 +180,13 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, | |||
| 	struct buffer_timer *timer = NULL; | ||||
| 
 | ||||
| 	if (output->max_render_time != 0 && view_max_render_time != 0 && delay > 0) { | ||||
| 		timer = buffer_timer_get_or_create(buffer); | ||||
| 		timer = buffer_timer_get_or_create(scene_surface); | ||||
| 	} | ||||
| 
 | ||||
| 	if (timer) { | ||||
| 		wl_event_source_timer_update(timer->frame_done_timer, delay); | ||||
| 	} else { | ||||
| 		wlr_scene_buffer_send_frame_done(buffer, &data->when); | ||||
| 		wlr_scene_surface_send_frame_done(scene_surface, &data->when); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,13 +20,13 @@ | |||
| 
 | ||||
| static struct sway_xdg_popup *popup_create( | ||||
| 	struct wlr_xdg_popup *wlr_popup, struct sway_view *view, | ||||
| 	struct wlr_scene_tree *parent); | ||||
| 	struct wlr_scene_tree *parent, struct wlr_scene_tree *image_capture_parent); | ||||
| 
 | ||||
| static void popup_handle_new_popup(struct wl_listener *listener, void *data) { | ||||
| 	struct sway_xdg_popup *popup = | ||||
| 		wl_container_of(listener, popup, new_popup); | ||||
| 	struct wlr_xdg_popup *wlr_popup = data; | ||||
| 	popup_create(wlr_popup, popup->view, popup->xdg_surface_tree); | ||||
| 	popup_create(wlr_popup, popup->view, popup->xdg_surface_tree, popup->image_capture_tree); | ||||
| } | ||||
| 
 | ||||
| static void popup_handle_destroy(struct wl_listener *listener, void *data) { | ||||
|  | @ -77,7 +77,8 @@ static void popup_handle_reposition(struct wl_listener *listener, void *data) { | |||
| } | ||||
| 
 | ||||
| static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | ||||
| 		struct sway_view *view, struct wlr_scene_tree *parent) { | ||||
| 		struct sway_view *view, struct wlr_scene_tree *parent, | ||||
| 		struct wlr_scene_tree *image_capture_parent) { | ||||
| 	struct wlr_xdg_surface *xdg_surface = wlr_popup->base; | ||||
| 
 | ||||
| 	struct sway_xdg_popup *popup = calloc(1, sizeof(struct sway_xdg_popup)); | ||||
|  | @ -113,6 +114,11 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, | |||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	popup->image_capture_tree = wlr_scene_xdg_surface_create(image_capture_parent, xdg_surface); | ||||
| 	if (popup->image_capture_tree == NULL) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	popup->wlr_xdg_popup = xdg_surface->popup; | ||||
| 	struct sway_xdg_shell_view *shell_view = | ||||
| 		wl_container_of(view, shell_view, view); | ||||
|  | @ -359,7 +365,7 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { | |||
| 	struct wlr_xdg_popup *wlr_popup = data; | ||||
| 
 | ||||
| 	struct sway_xdg_popup *popup = popup_create(wlr_popup, | ||||
| 		&xdg_shell_view->view, root->layers.popup); | ||||
| 		&xdg_shell_view->view, root->layers.popup, xdg_shell_view->image_capture_tree); | ||||
| 	if (!popup) { | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -570,6 +576,8 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) { | |||
| 	wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy); | ||||
| 
 | ||||
| 	wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); | ||||
| 	xdg_shell_view->image_capture_tree = | ||||
| 		wlr_scene_xdg_surface_create(&xdg_shell_view->view.image_capture_scene->tree, xdg_toplevel->base); | ||||
| 
 | ||||
| 	xdg_toplevel->base->data = xdg_shell_view; | ||||
| } | ||||
|  |  | |||
|  | @ -497,6 +497,9 @@ static void handle_unmap(struct wl_listener *listener, void *data) { | |||
| 	wl_list_remove(&xwayland_view->commit.link); | ||||
| 	wl_list_remove(&xwayland_view->surface_tree_destroy.link); | ||||
| 
 | ||||
| 	wlr_scene_node_destroy(&xwayland_view->image_capture_scene_surface->buffer->node); | ||||
| 	xwayland_view->image_capture_scene_surface = NULL; | ||||
| 
 | ||||
| 	if (xwayland_view->surface_tree) { | ||||
| 		wlr_scene_node_destroy(&xwayland_view->surface_tree->node); | ||||
| 		xwayland_view->surface_tree = NULL; | ||||
|  | @ -537,6 +540,9 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
| 			&xwayland_view->surface_tree_destroy); | ||||
| 	} | ||||
| 
 | ||||
| 	xwayland_view->image_capture_scene_surface = | ||||
| 		wlr_scene_surface_create(&xwayland_view->view.image_capture_scene->tree, xsurface->surface); | ||||
| 
 | ||||
| 	transaction_commit_dirty(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,12 +32,6 @@ | |||
| #include "sway/tree/workspace.h" | ||||
| #include "wlr-layer-shell-unstable-v1-protocol.h" | ||||
| 
 | ||||
| static uint32_t get_current_time_msec(void) { | ||||
| 	struct timespec now; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||
| 	return now.tv_sec * 1000 + now.tv_nsec / 1000000; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the node at the cursor's position. If there is a surface at that | ||||
|  * location, it is stored in **surface (it may not be a view). | ||||
|  | @ -144,7 +138,7 @@ struct sway_node *node_at_coords( | |||
| } | ||||
| 
 | ||||
| void cursor_rebase(struct sway_cursor *cursor) { | ||||
| 	uint32_t time_msec = get_current_time_msec(); | ||||
| 	uint32_t time_msec = get_current_time_in_msec(); | ||||
| 	seatop_rebase(cursor->seat, time_msec); | ||||
| } | ||||
| 
 | ||||
|  | @ -359,7 +353,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
| 		struct wlr_input_device *device, uint32_t time_msec, uint32_t button, | ||||
| 		enum wl_pointer_button_state state) { | ||||
| 	if (time_msec == 0) { | ||||
| 		time_msec = get_current_time_msec(); | ||||
| 		time_msec = get_current_time_in_msec(); | ||||
| 	} | ||||
| 
 | ||||
| 	seatop_button(cursor->seat, time_msec, device, button, state); | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| #include "sway/tree/view.h" | ||||
| #include "sway/tree/workspace.h" | ||||
| #include "log.h" | ||||
| #include "util.h" | ||||
| #if WLR_HAS_XWAYLAND | ||||
| #include "sway/xwayland.h" | ||||
| #endif | ||||
|  | @ -1148,5 +1149,7 @@ void seatop_begin_default(struct sway_seat *seat) { | |||
| 
 | ||||
| 	seat->seatop_impl = &seatop_impl; | ||||
| 	seat->seatop_data = e; | ||||
| 	seatop_rebase(seat, 0); | ||||
| 
 | ||||
| 	uint32_t time_msec = get_current_time_in_msec(); | ||||
| 	seatop_rebase(seat, time_msec); | ||||
| } | ||||
|  |  | |||
|  | @ -232,6 +232,21 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) { | |||
| 	server->recreating_renderer = wl_event_loop_add_idle(server->wl_event_loop, do_renderer_recreate, server); | ||||
| } | ||||
| 
 | ||||
| static void handle_new_foreign_toplevel_capture_request(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data; | ||||
| 	struct sway_view *view = request->toplevel_handle->data; | ||||
| 
 | ||||
| 	if (view->image_capture_source == NULL) { | ||||
| 		view->image_capture_source = wlr_ext_image_capture_source_v1_create_with_scene_node( | ||||
| 			&view->image_capture_scene->tree.node, server.wl_event_loop, server.allocator, server.renderer); | ||||
| 		if (view->image_capture_source == NULL) { | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept(request, view->image_capture_source); | ||||
| } | ||||
| 
 | ||||
| bool server_init(struct sway_server *server) { | ||||
| 	sway_log(SWAY_DEBUG, "Initializing Wayland server"); | ||||
| 	server->wl_display = wl_display_create(); | ||||
|  | @ -395,6 +410,12 @@ bool server_init(struct sway_server *server) { | |||
| 		wlr_content_type_manager_v1_create(server->wl_display, 1); | ||||
| 	wlr_fractional_scale_manager_v1_create(server->wl_display, 1); | ||||
| 
 | ||||
| 	server->ext_foreign_toplevel_image_capture_source_manager_v1 = | ||||
| 		wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(server->wl_display, 1); | ||||
| 	server->new_foreign_toplevel_capture_request.notify = handle_new_foreign_toplevel_capture_request; | ||||
| 	wl_signal_add(&server->ext_foreign_toplevel_image_capture_source_manager_v1->events.new_request, | ||||
| 		&server->new_foreign_toplevel_capture_request); | ||||
| 
 | ||||
| 	server->tearing_control_v1 = | ||||
| 		wlr_tearing_control_manager_v1_create(server->wl_display, 1); | ||||
| 	server->tearing_control_new_object.notify = handle_new_tearing_hint; | ||||
|  | @ -488,6 +509,7 @@ void server_fini(struct sway_server *server) { | |||
| 	wl_list_remove(&server->xdg_activation_v1_request_activate.link); | ||||
| 	wl_list_remove(&server->xdg_activation_v1_new_token.link); | ||||
| 	wl_list_remove(&server->request_set_cursor_shape.link); | ||||
| 	wl_list_remove(&server->new_foreign_toplevel_capture_request.link); | ||||
| 	input_manager_finish(server->input); | ||||
| 
 | ||||
| 	// TODO: free sway-specific resources
 | ||||
|  |  | |||
|  | @ -49,6 +49,11 @@ bool view_init(struct sway_view *view, enum sway_view_type type, | |||
| 		failed = true; | ||||
| 	} | ||||
| 
 | ||||
| 	view->image_capture_scene = wlr_scene_create(); | ||||
| 	if (view->image_capture_scene == NULL) { | ||||
| 		failed = true; | ||||
| 	} | ||||
| 
 | ||||
| 	if (failed) { | ||||
| 		wlr_scene_node_destroy(&view->scene_tree->node); | ||||
| 		return false; | ||||
|  | @ -81,6 +86,7 @@ void view_destroy(struct sway_view *view) { | |||
| 	list_free(view->executed_criteria); | ||||
| 
 | ||||
| 	view_assign_ctx(view, NULL); | ||||
| 	wlr_scene_node_destroy(&view->image_capture_scene->tree.node); | ||||
| 	wlr_scene_node_destroy(&view->scene_tree->node); | ||||
| 	if (view->impl->destroy) { | ||||
| 		view->impl->destroy(view); | ||||
|  | @ -815,6 +821,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
| 	}; | ||||
| 	view->ext_foreign_toplevel = | ||||
| 		wlr_ext_foreign_toplevel_handle_v1_create(server.foreign_toplevel_list, &foreign_toplevel_state); | ||||
| 	view->ext_foreign_toplevel->data = view; | ||||
| 
 | ||||
| 	view->foreign_toplevel = | ||||
| 		wlr_foreign_toplevel_handle_v1_create(server.foreign_toplevel_manager); | ||||
|  | @ -1242,7 +1249,11 @@ bool view_can_tear(struct sway_view *view) { | |||
| static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer, | ||||
| 		int x, int y, void *data) { | ||||
| 	struct timespec *when = data; | ||||
| 	wl_signal_emit_mutable(&scene_buffer->events.frame_done, when); | ||||
| 	struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); | ||||
| 	if (scene_surface == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 	wlr_scene_surface_send_frame_done(scene_surface, when); | ||||
| } | ||||
| 
 | ||||
| void view_send_frame_done(struct sway_view *view) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue