From 448c61a2950fbe8d5f8153116eb03a6174d82955 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sun, 22 Jun 2025 23:26:59 +0200 Subject: [PATCH] scaled-icon-buffer: reduce the need for updates --- include/common/scaled-icon-buffer.h | 2 + src/common/scaled-icon-buffer.c | 67 ++++++++++++++++++++++++++--- src/view.c | 2 - 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/include/common/scaled-icon-buffer.h b/include/common/scaled-icon-buffer.h index 3039f158..46e71ebf 100644 --- a/include/common/scaled-icon-buffer.h +++ b/include/common/scaled-icon-buffer.h @@ -20,6 +20,8 @@ struct scaled_icon_buffer { bool view_icon_prefer_client; struct wl_array view_icon_buffers; struct { + struct wl_listener new_app_id; + struct wl_listener new_title; struct wl_listener set_icon; struct wl_listener destroy; } on_view; diff --git a/src/common/scaled-icon-buffer.c b/src/common/scaled-icon-buffer.c index 29620c08..bb9ca9eb 100644 --- a/src/common/scaled-icon-buffer.c +++ b/src/common/scaled-icon-buffer.c @@ -173,6 +173,8 @@ _destroy(struct scaled_scene_buffer *scaled_buffer) struct scaled_icon_buffer *self = scaled_buffer->data; if (self->view) { wl_list_remove(&self->on_view.set_icon.link); + wl_list_remove(&self->on_view.new_title.link); + wl_list_remove(&self->on_view.new_app_id.link); wl_list_remove(&self->on_view.destroy.link); } free(self->view_app_id); @@ -240,17 +242,54 @@ handle_view_set_icon(struct wl_listener *listener, void *data) struct scaled_icon_buffer *self = wl_container_of(listener, self, on_view.set_icon); - self->view_icon_prefer_client = window_rules_get_property( - self->view, "iconPreferClient") == LAB_PROP_TRUE; + bool icon_name_equal = str_equal(self->view_icon_name, self->view->icon.name); + if (icon_name_equal && icon_buffers_equal(&self->view_icon_buffers, + &self->view->icon.buffers)) { + return; + } - /* view_get_string_prop() never returns NULL */ - xstrdup_replace(self->view_app_id, view_get_string_prop(self->view, "app_id")); - zfree(self->view_icon_name); - if (self->view->icon.name) { - self->view_icon_name = xstrdup(self->view->icon.name); + if (!icon_name_equal) { + zfree(self->view_icon_name); + if (self->view->icon.name) { + xstrdup_replace(self->view_icon_name, self->view->icon.name); + } } + set_icon_buffers(self, &self->view->icon.buffers); + scaled_scene_buffer_request_update(self->scaled_buffer, + self->width, self->height); +} +static void +handle_view_new_title(struct wl_listener *listener, void *data) +{ + struct scaled_icon_buffer *self = + wl_container_of(listener, self, on_view.new_title); + + bool prefer_client = window_rules_get_property( + self->view, "iconPreferClient") == LAB_PROP_TRUE; + if (prefer_client == self->view_icon_prefer_client) { + return; + } + self->view_icon_prefer_client = prefer_client; + scaled_scene_buffer_request_update(self->scaled_buffer, + self->width, self->height); +} + +static void +handle_view_new_app_id(struct wl_listener *listener, void *data) +{ + struct scaled_icon_buffer *self = + wl_container_of(listener, self, on_view.new_app_id); + + const char *app_id = view_get_string_prop(self->view, "app_id"); + if (str_equal(app_id, self->view_app_id)) { + return; + } + + xstrdup_replace(self->view_app_id, app_id); + self->view_icon_prefer_client = window_rules_get_property( + self->view, "iconPreferClient") == LAB_PROP_TRUE; scaled_scene_buffer_request_update(self->scaled_buffer, self->width, self->height); } @@ -262,6 +301,8 @@ handle_view_destroy(struct wl_listener *listener, void *data) wl_container_of(listener, self, on_view.destroy); wl_list_remove(&self->on_view.destroy.link); wl_list_remove(&self->on_view.set_icon.link); + wl_list_remove(&self->on_view.new_title.link); + wl_list_remove(&self->on_view.new_app_id.link); self->view = NULL; } @@ -275,15 +316,27 @@ scaled_icon_buffer_set_view(struct scaled_icon_buffer *self, struct view *view) if (self->view) { wl_list_remove(&self->on_view.set_icon.link); + wl_list_remove(&self->on_view.new_title.link); + wl_list_remove(&self->on_view.new_app_id.link); wl_list_remove(&self->on_view.destroy.link); } self->view = view; + self->on_view.set_icon.notify = handle_view_set_icon; wl_signal_add(&view->events.set_icon, &self->on_view.set_icon); + + self->on_view.new_title.notify = handle_view_new_title; + wl_signal_add(&view->events.new_title, &self->on_view.new_title); + + self->on_view.new_app_id.notify = handle_view_new_app_id; + wl_signal_add(&view->events.new_app_id, &self->on_view.new_app_id); + self->on_view.destroy.notify = handle_view_destroy; wl_signal_add(&view->events.destroy, &self->on_view.destroy); handle_view_set_icon(&self->on_view.set_icon, NULL); + handle_view_new_app_id(&self->on_view.new_app_id, NULL); + handle_view_new_title(&self->on_view.new_title, NULL); } void diff --git a/src/view.c b/src/view.c index d8cb9b15..59c32e27 100644 --- a/src/view.c +++ b/src/view.c @@ -2400,7 +2400,6 @@ view_update_title(struct view *view) assert(view); ssd_update_title(view->ssd); wl_signal_emit_mutable(&view->events.new_title, NULL); - wl_signal_emit_mutable(&view->events.set_icon, NULL); } void @@ -2408,7 +2407,6 @@ view_update_app_id(struct view *view) { assert(view); wl_signal_emit_mutable(&view->events.new_app_id, NULL); - wl_signal_emit_mutable(&view->events.set_icon, NULL); } void -- 2.52.0