]> git.mdlowis.com Git - proto/labwc.git/commitdiff
scaled-scene-buffer: use outputs_update signal
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 9 Jan 2025 17:39:59 +0000 (18:39 +0100)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Sat, 11 Jan 2025 06:29:46 +0000 (07:29 +0100)
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.

include/common/scaled-scene-buffer.h
src/common/scaled-scene-buffer.c

index 66d0df47b62e276250fb71b8ca70d3bc1f877dea..989600d9672e2ddaa89d11f942f2e86f8cd464f8 100644 (file)
@@ -34,8 +34,7 @@ struct scaled_scene_buffer {
        /* cached wlr_buffers for each scale */
        struct wl_list cache;  /* struct scaled_buffer_cache_entry.link */
        struct wl_listener destroy;
-       struct wl_listener output_enter;
-       struct wl_listener output_leave;
+       struct wl_listener outputs_update;
        const struct scaled_scene_buffer_impl *impl;
        /*
         * Pointer to the per-implementation list of scaled-scene-buffers.
index 19575f4b878db3f6311c7020924af6d5fa3ac04e..7ab0b8cefa29e385870498b7f449dba35d8e3624 100644 (file)
@@ -8,33 +8,11 @@
 #include <wlr/types/wlr_scene.h>
 #include <wlr/util/log.h>
 #include "buffer.h"
+#include "common/macros.h"
 #include "common/mem.h"
 #include "common/scaled-scene-buffer.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 */
 static void
 _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);
 
        wl_list_remove(&self->destroy.link);
-       wl_list_remove(&self->output_enter.link);
-       wl_list_remove(&self->output_leave.link);
+       wl_list_remove(&self->outputs_update.link);
 
        wl_list_for_each_safe(cache_entry, cache_entry_tmp, &self->cache, link) {
                _cache_entry_destroy(cache_entry, self->drop_buffer);
@@ -178,38 +155,21 @@ _handle_node_destroy(struct wl_listener *listener, void *data)
 }
 
 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 =
-               wl_container_of(listener, self, output_enter);
-       /* 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;
+               wl_container_of(listener, self, outputs_update);
 
-       if (primary && primary->output->scale > max_scale) {
-               max_scale = primary->output->scale;
+       double max_scale = 0;
+       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 (self->active_scale != max_scale) {
+       if (max_scale && self->active_scale != 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 */
 struct scaled_scene_buffer *
 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);
        }
 
-       /* Listen to output enter/leave so we get notified about scale changes */
-       self->output_enter.notify = _handle_output_enter;
-       wl_signal_add(&self->scene_buffer->events.output_enter, &self->output_enter);
-       self->output_leave.notify = _handle_output_leave;
-       wl_signal_add(&self->scene_buffer->events.output_leave, &self->output_leave);
+       /* Listen to outputs_update so we get notified about scale changes */
+       self->outputs_update.notify = _handle_outputs_update;
+       wl_signal_add(&self->scene_buffer->events.outputs_update, &self->outputs_update);
 
        /* Let it destroy automatically when the scene node destroys */
        self->destroy.notify = _handle_node_destroy;