CasildaCompositor: fix GdkTexture leaks

Unref texture after using g_set_object() since this adds a reference.
This commit is contained in:
Juan Pablo Ugarte 2026-03-17 15:34:32 -04:00
parent f2510637b5
commit a2d7043682
No known key found for this signature in database
2 changed files with 40 additions and 10 deletions

View file

@ -7,9 +7,14 @@ packaging changes like new dependencies or build system changes.
Casilda used even/odd minor numbers to differentiate between stable and
development releases.
## Unreleased
- Fix GdkTexture leak
## 1.2.0
2026-03-06 - 1.2 Release
- Migrated to wlroots 0.19
### Packaging

View file

@ -159,6 +159,7 @@
#define _POSIX_C_SOURCE 199309L /* clock_gettime */
#define WLR_USE_UNSTABLE 1
#define G_LOG_DOMAIN "Casilda"
#define ENABLE_TEXTURE_DEBUG 0
#define ENABLE_BORDERS 0
#include <sys/socket.h>
@ -616,6 +617,28 @@ debug_snapshot_border (GtkSnapshot *snapshot,
#define debug_snapshot_border(s,x,y,w,h,r,g,b)
#endif
#if ENABLE_TEXTURE_DEBUG
static gint texture_count = 0;
static void texture_weak_ref_callback (G_GNUC_UNUSED gpointer data, GObject* object)
{
texture_count--;
g_message("%s object=%p texture_count=%d", __func__, object, texture_count);
}
static void texture_debug_add_weak (gpointer object)
{
g_object_weak_ref(G_OBJECT(object), texture_weak_ref_callback, NULL);
texture_count++;
g_message("%s object=%p texture_count=%d", __func__, object, texture_count);
}
#else
#define texture_debug_add_weak(o)
#endif
typedef struct {
GtkSnapshot *snapshot;
GdkGLContext *gl_context;
@ -630,7 +653,8 @@ snapshot_surfaces (struct wlr_surface *surface, int sx, int sy, void *data)
struct wlr_texture *texture = wlr_surface_get_texture (surface);
gint w, h;
GdkTexture *tex = wlr_texture_as_gdk (texture, sdata->gl_context, &surface->buffer_damage, surface->data);
g_autoptr(GdkTexture) tex = wlr_texture_as_gdk (texture, sdata->gl_context, &surface->buffer_damage, surface->data);
texture_debug_add_weak (tex);
w = gdk_texture_get_width (tex);
h = gdk_texture_get_height (tex);
@ -1536,20 +1560,23 @@ cursor_handle_surface_commit (struct wl_listener *listener, void *data)
if (!texture)
return;
priv->cursor_gdk_texture = wlr_texture_as_gdk (texture, priv->gl_context, NULL, NULL);
g_autoptr(GdkTexture) tex = wlr_texture_as_gdk (texture, priv->gl_context, NULL, NULL);
texture_debug_add_weak (tex);
g_set_object (&priv->cursor_gdk_texture, tex);
priv->hotspot_x -= surface->current.dx;
priv->hotspot_y -= surface->current.dy;
if (!tex)
return;
/* Finally create cursor from texture */
if (priv->cursor_gdk_texture != NULL)
priv->cursor_gdk_cursor = gdk_cursor_new_from_texture (priv->cursor_gdk_texture,
priv->hotspot_x,
priv->hotspot_y,
NULL);
g_autoptr (GdkCursor) gdk_cursor = gdk_cursor_new_from_texture (tex, priv->hotspot_x, priv->hotspot_y, NULL);
g_set_object (&priv->cursor_gdk_cursor, gdk_cursor);
/* Set cursor */
if (priv->cursor_gdk_cursor)
if (gdk_cursor)
gtk_widget_set_cursor (priv->self, priv->cursor_gdk_cursor);
}
@ -1572,8 +1599,6 @@ on_seat_request_cursor (struct wl_listener *listener, void *data)
wlr_surface_send_enter (surface, &priv->output);
casilda_compositor_reset_cursor(priv);
/* We only keep track of the last cursor change */
casilda_compositor_cursor_handler_remove (priv);