mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Restore nested resize
Chases: 756ecf8ee9f1e75bc7b8297dc84f97c7d699174b backend/wayland: use request_state when toplevel is resized Chases: 3ef68a484243555b020200c6f95246d994932c3f backend/x11: use request_state when window is resized Ref: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/2693 We now delay requested resolution changes by the backend until the next frame event which causes us to render the new content on the already enlarged buffer. Before this change, an empty (black) buffer would have been shown instead before the next frame event caused a new render of the actual contents. Keep commiting the new state and then scheduling a frame event would not help as due to the commit call it would still show an empty buffer in the meantime. Just modifying wlr_output->pending wouldn't work either because wlr_scene_output_commit() *completely* ignores it (and it will be removed in future wlroots commits). For this reason we move to wlr_scene_output_build_state() directly because it allows us to supply the current wlr_output->pending state and thus apply any resolution change in lockstep with new rendering. Result: No more flickering in the wayland backend and resizing is again smooth as butter. This prevents constant flicker while resizing when running nested via the wayland backend. For the X11 backend (can be tested via `WLR_BACKENDS=x11 labwc`), it is still rather janky but at least doesn't cause endless self- resizing anymore.
This commit is contained in:
		
							parent
							
								
									1626092639
								
							
						
					
					
						commit
						ddc9047a67
					
				
					 5 changed files with 94 additions and 6 deletions
				
			
		
							
								
								
									
										54
									
								
								src/output.c
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								src/output.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include <wlr/util/log.h>
 | 
			
		||||
#include "common/macros.h"
 | 
			
		||||
#include "common/mem.h"
 | 
			
		||||
#include "common/scene-helpers.h"
 | 
			
		||||
#include "labwc.h"
 | 
			
		||||
#include "layers.h"
 | 
			
		||||
#include "node.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -31,12 +32,11 @@ output_frame_notify(struct wl_listener *listener, void *data)
 | 
			
		|||
	if (!output_is_usable(output)) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_scene_output_commit(output->scene_output, NULL);
 | 
			
		||||
 | 
			
		||||
	struct timespec now = { 0 };
 | 
			
		||||
	clock_gettime(CLOCK_MONOTONIC, &now);
 | 
			
		||||
	wlr_scene_output_send_frame_done(output->scene_output, &now);
 | 
			
		||||
	if (lab_wlr_scene_output_commit(output->scene_output)) {
 | 
			
		||||
		struct timespec now = { 0 };
 | 
			
		||||
		clock_gettime(CLOCK_MONOTONIC, &now);
 | 
			
		||||
		wlr_scene_output_send_frame_done(output->scene_output, &now);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +48,7 @@ output_destroy_notify(struct wl_listener *listener, void *data)
 | 
			
		|||
	wl_list_remove(&output->link);
 | 
			
		||||
	wl_list_remove(&output->frame.link);
 | 
			
		||||
	wl_list_remove(&output->destroy.link);
 | 
			
		||||
	wl_list_remove(&output->request_state.link);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) {
 | 
			
		||||
		wlr_scene_node_destroy(&output->layer_tree[i]->node);
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +71,44 @@ output_destroy_notify(struct wl_listener *listener, void *data)
 | 
			
		|||
	free(output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_request_state_notify(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	/* This ensures nested backends can be resized */
 | 
			
		||||
	struct output *output = wl_container_of(listener, output, request_state);
 | 
			
		||||
	const struct wlr_output_event_request_state *event = data;
 | 
			
		||||
	struct wlr_output_state *pending = &output->wlr_output->pending;
 | 
			
		||||
 | 
			
		||||
	if (!pending->committed) {
 | 
			
		||||
		/* No pending changes, just use the supplied state as new pending */
 | 
			
		||||
		wlr_output_state_copy(pending, event->state);
 | 
			
		||||
		wlr_output_schedule_frame(output->wlr_output);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (event->state->committed == WLR_OUTPUT_STATE_MODE) {
 | 
			
		||||
		/* Only the resolution has changed, apply to pending */
 | 
			
		||||
		switch (event->state->mode_type) {
 | 
			
		||||
		case WLR_OUTPUT_STATE_MODE_FIXED:
 | 
			
		||||
			wlr_output_set_mode(output->wlr_output, event->state->mode);
 | 
			
		||||
			break;
 | 
			
		||||
		case WLR_OUTPUT_STATE_MODE_CUSTOM:
 | 
			
		||||
			wlr_output_set_custom_mode(output->wlr_output,
 | 
			
		||||
				event->state->custom_mode.width,
 | 
			
		||||
				event->state->custom_mode.height,
 | 
			
		||||
				event->state->custom_mode.refresh);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		wlr_output_schedule_frame(output->wlr_output);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fallback path for everything that we didn't handle above */
 | 
			
		||||
	if (!wlr_output_commit_state(output->wlr_output, event->state)) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "Backend requested a new state that could not be applied");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_output_layout_change(struct server *server);
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
| 
						 | 
				
			
			@ -180,6 +219,9 @@ new_output_notify(struct wl_listener *listener, void *data)
 | 
			
		|||
	output->frame.notify = output_frame_notify;
 | 
			
		||||
	wl_signal_add(&wlr_output->events.frame, &output->frame);
 | 
			
		||||
 | 
			
		||||
	output->request_state.notify = output_request_state_notify;
 | 
			
		||||
	wl_signal_add(&wlr_output->events.request_state, &output->request_state);
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&output->regions);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue