mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	scaled-scene-buffer: use outputs_update signal
This fixes an issue with buffers not updating when an output is configured for a new scale. It also supports windows being on more than 2 outputs at once and in general simplifies the code.
This commit is contained in:
		
							parent
							
								
									1a6dd845a2
								
							
						
					
					
						commit
						6496773fd1
					
				
					 2 changed files with 13 additions and 56 deletions
				
			
		| 
						 | 
					@ -34,8 +34,7 @@ struct scaled_scene_buffer {
 | 
				
			||||||
	/* cached wlr_buffers for each scale */
 | 
						/* cached wlr_buffers for each scale */
 | 
				
			||||||
	struct wl_list cache;  /* struct scaled_buffer_cache_entry.link */
 | 
						struct wl_list cache;  /* struct scaled_buffer_cache_entry.link */
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
	struct wl_listener output_enter;
 | 
						struct wl_listener outputs_update;
 | 
				
			||||||
	struct wl_listener output_leave;
 | 
					 | 
				
			||||||
	const struct scaled_scene_buffer_impl *impl;
 | 
						const struct scaled_scene_buffer_impl *impl;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Pointer to the per-implementation list of scaled-scene-buffers.
 | 
						 * Pointer to the per-implementation list of scaled-scene-buffers.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,33 +8,11 @@
 | 
				
			||||||
#include <wlr/types/wlr_scene.h>
 | 
					#include <wlr/types/wlr_scene.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
#include "buffer.h"
 | 
					#include "buffer.h"
 | 
				
			||||||
 | 
					#include "common/macros.h"
 | 
				
			||||||
#include "common/mem.h"
 | 
					#include "common/mem.h"
 | 
				
			||||||
#include "common/scaled-scene-buffer.h"
 | 
					#include "common/scaled-scene-buffer.h"
 | 
				
			||||||
#include "node.h"
 | 
					#include "node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * TODO
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This implementation does not react to output scale changes itself but only
 | 
					 | 
				
			||||||
 * to movement of scene nodes to different outputs. To also handle output scale
 | 
					 | 
				
			||||||
 * changes we'd need to keep a list of struct wlr_outputs * in sync and listen
 | 
					 | 
				
			||||||
 * to their commit signals.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The detection of the max output scale is also not 100% robust for all use
 | 
					 | 
				
			||||||
 * cases as on output_enter we only compare the new output scale with the
 | 
					 | 
				
			||||||
 * primary_output scale. In specific conditions the primary output may be the
 | 
					 | 
				
			||||||
 * same as the new output even though a smaller part of the buffer node is
 | 
					 | 
				
			||||||
 * still visible on an output with a bigger scale. This could be solved the
 | 
					 | 
				
			||||||
 * same way as the previous point in keeping a list of outputs in sync.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Most of this would be easier when wlroots would instead provide a
 | 
					 | 
				
			||||||
 * max_scale_changed event because it already touches all the relevant parts
 | 
					 | 
				
			||||||
 * when calculating the primary_output and inform wlr_scene_buffers about
 | 
					 | 
				
			||||||
 * output changes.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * See wlroots/types/scene/wlr_scene.c scene_buffer_update_outputs()
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Internal API */
 | 
					/* Internal API */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
_cache_entry_destroy(struct scaled_scene_buffer_cache_entry *cache_entry, bool drop_buffer)
 | 
					_cache_entry_destroy(struct scaled_scene_buffer_cache_entry *cache_entry, bool drop_buffer)
 | 
				
			||||||
| 
						 | 
					@ -162,8 +140,7 @@ _handle_node_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
	struct scaled_scene_buffer *self = wl_container_of(listener, self, destroy);
 | 
						struct scaled_scene_buffer *self = wl_container_of(listener, self, destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&self->destroy.link);
 | 
						wl_list_remove(&self->destroy.link);
 | 
				
			||||||
	wl_list_remove(&self->output_enter.link);
 | 
						wl_list_remove(&self->outputs_update.link);
 | 
				
			||||||
	wl_list_remove(&self->output_leave.link);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_for_each_safe(cache_entry, cache_entry_tmp, &self->cache, link) {
 | 
						wl_list_for_each_safe(cache_entry, cache_entry_tmp, &self->cache, link) {
 | 
				
			||||||
		_cache_entry_destroy(cache_entry, self->drop_buffer);
 | 
							_cache_entry_destroy(cache_entry, self->drop_buffer);
 | 
				
			||||||
| 
						 | 
					@ -178,38 +155,21 @@ _handle_node_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
_handle_output_enter(struct wl_listener *listener, void *data)
 | 
					_handle_outputs_update(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct scaled_scene_buffer *self =
 | 
						struct scaled_scene_buffer *self =
 | 
				
			||||||
		wl_container_of(listener, self, output_enter);
 | 
							wl_container_of(listener, self, outputs_update);
 | 
				
			||||||
	/* primary_output is the output most of the node area is in */
 | 
					 | 
				
			||||||
	struct wlr_scene_output *primary = self->scene_buffer->primary_output;
 | 
					 | 
				
			||||||
	/* scene_output is the output we just entered */
 | 
					 | 
				
			||||||
	struct wlr_scene_output *scene_output = data;
 | 
					 | 
				
			||||||
	double max_scale = scene_output->output->scale;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (primary && primary->output->scale > max_scale) {
 | 
						double max_scale = 0;
 | 
				
			||||||
		max_scale = primary->output->scale;
 | 
						struct wlr_scene_outputs_update_event *event = data;
 | 
				
			||||||
 | 
						for (size_t i = 0; i < event->size; i++) {
 | 
				
			||||||
 | 
							max_scale = MAX(max_scale, event->active[i]->output->scale);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (max_scale && self->active_scale != max_scale) {
 | 
				
			||||||
	if (self->active_scale != max_scale) {
 | 
					 | 
				
			||||||
		_update_buffer(self, max_scale);
 | 
							_update_buffer(self, max_scale);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
_handle_output_leave(struct wl_listener *listener, void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct scaled_scene_buffer *self =
 | 
					 | 
				
			||||||
		wl_container_of(listener, self, output_leave);
 | 
					 | 
				
			||||||
	/* primary_output is the output most of the node area is in */
 | 
					 | 
				
			||||||
	struct wlr_scene_output *primary = self->scene_buffer->primary_output;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (primary && primary->output->scale != self->active_scale) {
 | 
					 | 
				
			||||||
		_update_buffer(self, primary->output->scale);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Public API */
 | 
					/* Public API */
 | 
				
			||||||
struct scaled_scene_buffer *
 | 
					struct scaled_scene_buffer *
 | 
				
			||||||
scaled_scene_buffer_create(struct wlr_scene_tree *parent,
 | 
					scaled_scene_buffer_create(struct wlr_scene_tree *parent,
 | 
				
			||||||
| 
						 | 
					@ -247,11 +207,9 @@ scaled_scene_buffer_create(struct wlr_scene_tree *parent,
 | 
				
			||||||
		wl_list_init(&self->link);
 | 
							wl_list_init(&self->link);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Listen to output enter/leave so we get notified about scale changes */
 | 
						/* Listen to outputs_update so we get notified about scale changes */
 | 
				
			||||||
	self->output_enter.notify = _handle_output_enter;
 | 
						self->outputs_update.notify = _handle_outputs_update;
 | 
				
			||||||
	wl_signal_add(&self->scene_buffer->events.output_enter, &self->output_enter);
 | 
						wl_signal_add(&self->scene_buffer->events.outputs_update, &self->outputs_update);
 | 
				
			||||||
	self->output_leave.notify = _handle_output_leave;
 | 
					 | 
				
			||||||
	wl_signal_add(&self->scene_buffer->events.output_leave, &self->output_leave);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Let it destroy automatically when the scene node destroys */
 | 
						/* Let it destroy automatically when the scene node destroys */
 | 
				
			||||||
	self->destroy.notify = _handle_node_destroy;
 | 
						self->destroy.notify = _handle_node_destroy;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue