Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gnome-network-displays for 
openSUSE:Factory checked in at 2026-01-26 11:05:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gnome-network-displays (Old)
 and      /work/SRC/openSUSE:Factory/.gnome-network-displays.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gnome-network-displays"

Mon Jan 26 11:05:36 2026 rev:11 rq:1329056 version:0.99.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/gnome-network-displays/gnome-network-displays.changes
    2025-12-18 18:37:31.636925615 +0100
+++ 
/work/SRC/openSUSE:Factory/.gnome-network-displays.new.1928/gnome-network-displays.changes
  2026-01-26 11:05:42.662501444 +0100
@@ -1,0 +2,9 @@
+Fri Jan 23 08:23:57 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 0.99.0:
+  + wfd: Fix keep-alive and RTCP port handling for Roku/Hisense
+    sinks
+  + sink-row: Add adw_preferences_row_set_use_markup
+  + Fix a couple of memory leaks and a use-after-free crash
+
+-------------------------------------------------------------------

Old:
----
  gnome-network-displays-0.98.0.obscpio

New:
----
  gnome-network-displays-0.99.0.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gnome-network-displays.spec ++++++
--- /var/tmp/diff_new_pack.okPuJ0/_old  2026-01-26 11:05:43.382531569 +0100
+++ /var/tmp/diff_new_pack.okPuJ0/_new  2026-01-26 11:05:43.386531736 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package gnome-network-displays
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           gnome-network-displays
-Version:        0.98.0
+Version:        0.99.0
 Release:        0
 Summary:        Miracast implementation for GNOME
 License:        GPL-3.0-or-later
@@ -35,7 +35,7 @@
 BuildRequires:  pkgconfig(gstreamer-plugins-base-1.0)
 BuildRequires:  pkgconfig(gstreamer-rtsp-server-1.0)
 BuildRequires:  pkgconfig(gstreamer-video-1.0)
-BuildRequires:  pkgconfig(gtk4)
+BuildRequires:  pkgconfig(gtk4) >= 4.13.0
 BuildRequires:  pkgconfig(json-glib-1.0) >= 1.0
 BuildRequires:  pkgconfig(libadwaita-1)
 BuildRequires:  pkgconfig(libnm) >= 1.15

++++++ _service ++++++
--- /var/tmp/diff_new_pack.okPuJ0/_old  2026-01-26 11:05:43.422533243 +0100
+++ /var/tmp/diff_new_pack.okPuJ0/_new  2026-01-26 11:05:43.426533410 +0100
@@ -3,7 +3,7 @@
   <service name="obs_scm" mode="manual">
     <param name="scm">git</param>
     <param 
name="url">https://gitlab.gnome.org/GNOME/gnome-network-displays.git</param>
-    <param name="revision">0.98.0</param>
+    <param name="revision">0.99.0</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">v?(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ gnome-network-displays-0.98.0.obscpio -> 
gnome-network-displays-0.99.0.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/NEWS 
new/gnome-network-displays-0.99.0/NEWS
--- old/gnome-network-displays-0.98.0/NEWS      2025-12-15 00:58:20.000000000 
+0100
+++ new/gnome-network-displays-0.99.0/NEWS      2026-01-23 06:57:54.000000000 
+0100
@@ -1,3 +1,9 @@
+GNOME Network Displays 0.99.0
+=============================
+* wfd: Fix keep-alive and RTCP port handling for Roku/Hisense sinks 
(@christophermarek)
+* sink-row: Add adw_preferences_row_set_use_markup (@lorbus)
+* fix a couple of memory leaks and a use-after-free crash
+
 GNOME Network Displays 0.98.0
 =============================
 * Add a dbus daemon program (@pesader)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gnome-network-displays-0.98.0/data/org.gnome.NetworkDisplays.metainfo.xml.in
 
new/gnome-network-displays-0.99.0/data/org.gnome.NetworkDisplays.metainfo.xml.in
--- 
old/gnome-network-displays-0.98.0/data/org.gnome.NetworkDisplays.metainfo.xml.in
    2025-12-15 00:58:20.000000000 +0100
+++ 
new/gnome-network-displays-0.99.0/data/org.gnome.NetworkDisplays.metainfo.xml.in
    2026-01-23 06:57:54.000000000 +0100
@@ -29,6 +29,7 @@
        <update_contact>[email protected]</update_contact>
        <content_rating type="oars-1.1"/>
        <releases>
+               <release version="0.99.0" date="2026-01-23"/>
                <release version="0.98.0" date="2025-12-15"/>
                <release version="0.97.0" date="2025-05-22"/>
                <release version="0.96.0" date="2025-04-07"/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/meson.build 
new/gnome-network-displays-0.99.0/meson.build
--- old/gnome-network-displays-0.98.0/meson.build       2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/meson.build       2026-01-23 
06:57:54.000000000 +0100
@@ -1,5 +1,5 @@
 project('gnome-network-displays', 'c',
-  version: '0.98.0',
+  version: '0.99.0',
   meson_version: '>= 0.59.0',
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/app/nd-sink-row.c 
new/gnome-network-displays-0.99.0/src/app/nd-sink-row.c
--- old/gnome-network-displays-0.98.0/src/app/nd-sink-row.c     2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/app/nd-sink-row.c     2026-01-23 
06:57:54.000000000 +0100
@@ -126,6 +126,7 @@
 nd_sink_row_init (NdSinkRow *self)
 {
   gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), TRUE);
+  adw_preferences_row_set_use_markup (ADW_PREFERENCES_ROW (self), FALSE);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/app/nd-window.c 
new/gnome-network-displays-0.99.0/src/app/nd-window.c
--- old/gnome-network-displays-0.98.0/src/app/nd-window.c       2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/app/nd-window.c       2026-01-23 
06:57:54.000000000 +0100
@@ -131,9 +131,10 @@
   if (src == NULL)
     g_error ("GStreamer element \"pipewiresrc\" could not be created!");
 
+  g_autofree gchar *path_str = g_strdup_printf ("%u", node_id);
   g_object_set (src,
                 "fd", xdp_session_open_pipewire_remote (self->session),
-                "path", g_strdup_printf ("%u", node_id),
+                "path", path_str,
                 "do-timestamp", TRUE,
                 NULL);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/cc/cc-ctrl.c 
new/gnome-network-displays-0.99.0/src/cc/cc-ctrl.c
--- old/gnome-network-displays-0.98.0/src/cc/cc-ctrl.c  2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/cc/cc-ctrl.c  2026-01-23 
06:57:54.000000000 +0100
@@ -54,9 +54,10 @@
 #else
   gchar *platform = "Wayland; Linux x86_64";
 #endif
+  g_autofree gchar *user_agent = g_strdup_printf ("GND/%s (%s)", 
PACKAGE_VERSION, platform);
   gchar *json = cc_json_helper_build_string (
     "type", CC_JSON_TYPE_STRING, "CONNECT",
-    "userAgent", CC_JSON_TYPE_STRING, g_strdup_printf ("GND/%s (%s)", 
PACKAGE_VERSION, platform),
+    "userAgent", CC_JSON_TYPE_STRING, user_agent,
     "connType", CC_JSON_TYPE_INT, 0,
     "origin", CC_JSON_TYPE_OBJECT, cc_json_helper_build_node (NULL),
     "senderInfo", CC_JSON_TYPE_OBJECT, cc_json_helper_build_node (
@@ -229,12 +230,13 @@
 
   g_array_append_val (tracks, track_node);
 
+  g_autofree gchar *content_url = g_strdup_printf ("http://%s:%d/";,
+                                                    ctrl->comm.local_address,
+                                                    port);
   gchar *json = cc_json_helper_build_string (
     "type", CC_JSON_TYPE_STRING, "LOAD",
     "media", CC_JSON_TYPE_OBJECT, cc_json_helper_build_node (
-      "contentUrl", CC_JSON_TYPE_STRING, g_strdup_printf ("http://%s:%d/";,
-                                                          
ctrl->comm.local_address,
-                                                          port),
+      "contentUrl", CC_JSON_TYPE_STRING, content_url,
       "streamType", CC_JSON_TYPE_STRING, "LIVE",
       "contentType", CC_JSON_TYPE_STRING, 
content_types[cc_media_factory_profiles[factory->factory_profile].muxer],
       NULL),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-cc-sink.c 
new/gnome-network-displays-0.99.0/src/nd-cc-sink.c
--- old/gnome-network-displays-0.98.0/src/nd-cc-sink.c  2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-cc-sink.c  2026-01-23 
06:57:54.000000000 +0100
@@ -259,6 +259,9 @@
 {
   NdCCSink *self = ND_CC_SINK (sink);
 
+  if (self->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
   nd_cc_sink_sink_stop_stream_int (self);
 
   self->state = ND_SINK_STATE_DISCONNECTED;
@@ -338,16 +341,16 @@
 nd_cc_sink_sink_to_uri (NdSink *sink)
 {
   NdCCSink *self = ND_CC_SINK (sink);
-  GHashTable *params = g_hash_table_new (g_str_hash, g_str_equal);
+  g_autoptr(GHashTable) params = g_hash_table_new_full (g_str_hash, 
g_str_equal, NULL, g_free);
 
   /* protocol */
-  g_hash_table_insert (params, "protocol", (gpointer *) g_strdup_printf ("%d", 
protocol));
+  g_hash_table_insert (params, "protocol", g_strdup_printf ("%d", protocol));
 
   /* remote name */
-  g_hash_table_insert (params, "name", (gpointer *) g_strdup (self->name));
+  g_hash_table_insert (params, "name", g_strdup (self->name));
 
   /* remote address */
-  g_hash_table_insert (params, "ip", (gpointer *) g_strdup (self->ip));
+  g_hash_table_insert (params, "ip", g_strdup (self->ip));
 
   return nd_uri_helpers_generate_uri (params);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-dummy-cc-sink.c 
new/gnome-network-displays-0.99.0/src/nd-dummy-cc-sink.c
--- old/gnome-network-displays-0.98.0/src/nd-dummy-cc-sink.c    2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-dummy-cc-sink.c    2026-01-23 
06:57:54.000000000 +0100
@@ -171,10 +171,10 @@
 static gchar *
 nd_dummy_cc_sink_sink_to_uri (NdSink *sink)
 {
-  GHashTable *params = g_hash_table_new (g_str_hash, g_str_equal);
+  g_autoptr(GHashTable) params = g_hash_table_new_full (g_str_hash, 
g_str_equal, NULL, g_free);
 
   /* protocol */
-  g_hash_table_insert (params, "protocol", (gpointer *) g_strdup_printf ("%d", 
protocol));
+  g_hash_table_insert (params, "protocol", g_strdup_printf ("%d", protocol));
 
   return nd_uri_helpers_generate_uri (params);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gnome-network-displays-0.98.0/src/nd-dummy-wfd-sink.c 
new/gnome-network-displays-0.99.0/src/nd-dummy-wfd-sink.c
--- old/gnome-network-displays-0.98.0/src/nd-dummy-wfd-sink.c   2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-dummy-wfd-sink.c   2026-01-23 
06:57:54.000000000 +0100
@@ -36,6 +36,7 @@
   GtkStringList *missing_audio_codec;
 
   WfdServer     *server;
+  WfdClient     *wfd_client;
   guint          server_source_id;
 };
 
@@ -171,10 +172,10 @@
 static gchar *
 nd_dummy_wfd_sink_sink_to_uri (NdSink *sink)
 {
-  GHashTable *params = g_hash_table_new (g_str_hash, g_str_equal);
+  g_autoptr(GHashTable) params = g_hash_table_new_full (g_str_hash, 
g_str_equal, NULL, g_free);
 
   /* protocol */
-  g_hash_table_insert (params, "protocol", (gpointer *) g_strdup_printf ("%d", 
protocol));
+  g_hash_table_insert (params, "protocol", g_strdup_printf ("%d", protocol));
 
   return nd_uri_helpers_generate_uri (params);
 }
@@ -203,7 +204,12 @@
 static void
 closed_cb (NdDummyWFDSink *sink, WfdClient *client)
 {
-  /* Connection was closed, do a clean shutdown*/
+  if (sink->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
+  if (sink->wfd_client == NULL)
+    return;
+
   nd_dummy_wfd_sink_sink_stop_stream (ND_SINK (sink));
 }
 
@@ -216,7 +222,8 @@
   sink->state = ND_SINK_STATE_WAIT_STREAMING;
   g_object_notify (G_OBJECT (sink), "state");
 
-  /* XXX: connect to further events. */
+  sink->wfd_client = g_object_ref (client);
+
   g_signal_connect_object (client,
                            "play-request",
                            (GCallback) play_request_cb,
@@ -322,18 +329,26 @@
   return g_object_ref (sink);
 }
 
-void
+static void
 nd_dummy_wfd_sink_sink_stop_stream (NdSink *sink)
 {
   NdDummyWFDSink *self = ND_DUMMY_WFD_SINK (sink);
 
+  if (self->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
   if (self->server_source_id)
     {
       g_source_remove (self->server_source_id);
       self->server_source_id = 0;
     }
 
-  /* Needs to protect against recursion. */
+  if (self->wfd_client)
+    {
+      g_signal_handlers_disconnect_by_data (self->wfd_client, self);
+      g_clear_object (&self->wfd_client);
+    }
+
   if (self->server)
     {
       g_autoptr(WfdServer) server = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-manager.c 
new/gnome-network-displays-0.99.0/src/nd-manager.c
--- old/gnome-network-displays-0.98.0/src/nd-manager.c  2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-manager.c  2026-01-23 
06:57:54.000000000 +0100
@@ -126,7 +126,7 @@
                                  const gchar *uuid,
                                  const gchar *display_name)
 {
-  const gchar *unit_name = g_strdup_printf 
("gnome-network-displays-stream-%s.service", uuid);
+  g_autofree gchar *unit_name = g_strdup_printf 
("gnome-network-displays-stream-%s.service", uuid);
 
   g_autoptr(GError) error = NULL;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-pulseaudio.c 
new/gnome-network-displays-0.99.0/src/nd-pulseaudio.c
--- old/gnome-network-displays-0.98.0/src/nd-pulseaudio.c       2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-pulseaudio.c       2026-01-23 
06:57:54.000000000 +0100
@@ -202,16 +202,17 @@
   g_debug ("NdPulseaudio: Creating sink for: %s", self->name);
   /* We have reached the list end without being cancelled first.
    * This means no screencast sink exist, and we need to create it. */
+  g_autofree gchar *module_args = g_strdup_printf ("sink_name=" ND_PA_SINK 
"_%.8s"
+                                                   " "
+                                                   "rate=48000 "
+                                                   
"sink_properties=device.class=\"sound\" "
+                                                   
"device.icon_name=\"network-wireless\" "
+                                                   "device.description=\"%s\"",
+                                                   self->uuid,
+                                                   self->name);
   self->operation = pa_context_load_module (self->context,
                                             "module-null-sink",
-                                            g_strdup_printf ("sink_name=" 
ND_PA_SINK "_%.8s"
-                                                             " "
-                                                             "rate=48000 "
-                                                             
"sink_properties=device.class=\"sound\" "
-                                                             
"device.icon_name=\"network-wireless\" "
-                                                             
"device.description=\"%s\"",
-                                                             self->uuid,
-                                                             self->name),
+                                            module_args,
                                             on_pa_null_module_loaded,
                                             self);
 }
@@ -267,8 +268,9 @@
         return;
 
       g_debug ("NdPulseaudio: Querying sink info by name");
+      g_autofree gchar *sink_name = g_strdup_printf (ND_PA_SINK "_%.8s", 
self->uuid);
       self->operation = pa_context_get_sink_info_by_name (self->context,
-                                                          g_strdup_printf 
(ND_PA_SINK "_%.8s", self->uuid),
+                                                          sink_name,
                                                           
on_pa_nd_sink_got_info,
                                                           self);
       break;
@@ -309,8 +311,10 @@
   self->mainloop_api = pa_threaded_mainloop_get_api (self->mainloop);
 
   proplist = pa_proplist_new ();
-  pa_proplist_sets (proplist, PA_PROP_APPLICATION_NAME, g_strdup_printf 
("GNOME Network Displays PulseAudio Client for %s", self->name));
-  pa_proplist_sets (proplist, PA_PROP_APPLICATION_ID, g_strdup_printf 
("org.gnome.NetworkDisplays.PulseAudio_%.8s", self->uuid));
+  g_autofree gchar *app_name = g_strdup_printf ("GNOME Network Displays 
PulseAudio Client for %s", self->name);
+  g_autofree gchar *app_id = g_strdup_printf 
("org.gnome.NetworkDisplays.PulseAudio_%.8s", self->uuid);
+  pa_proplist_sets (proplist, PA_PROP_APPLICATION_NAME, app_name);
+  pa_proplist_sets (proplist, PA_PROP_APPLICATION_ID, app_id);
   /* pa_proplist_sets (proplist, PA_PROP_APPLICATION_ICON_NAME, ); */
 
   self->context = pa_context_new_with_proplist (self->mainloop_api, NULL, 
proplist);
@@ -382,6 +386,8 @@
   self->mainloop_api = NULL;
   pa_threaded_mainloop_stop (self->mainloop);
   g_clear_pointer (&self->mainloop, pa_threaded_mainloop_free);
+  g_clear_pointer (&self->name, g_free);
+  g_clear_pointer (&self->uuid, g_free);
 
   G_OBJECT_CLASS (nd_pulseaudio_parent_class)->finalize (object);
 }
@@ -426,11 +432,14 @@
   g_assert (self->init_task == NULL);
   g_assert (self->context != NULL);
 
-  src = gst_element_factory_make ("pulsesrc", g_strdup_printf 
("pulseaudio-source-%s", self->uuid));
+  g_autofree gchar *element_name = g_strdup_printf ("pulseaudio-source-%s", 
self->uuid);
+  src = gst_element_factory_make ("pulsesrc", element_name);
 
+  g_autofree gchar *device_name = g_strdup_printf (ND_PA_SINK "_%.8s.monitor", 
self->uuid);
+  g_autofree gchar *client_name = g_strdup_printf ("GNOME Network Displays 
Audio Grabber for %s", self->name);
   g_object_set (src,
-                "device", g_strdup_printf (ND_PA_SINK "_%.8s.monitor", 
self->uuid),
-                "client-name", g_strdup_printf ("GNOME Network Displays Audio 
Grabber for %s", self->name),
+                "device", device_name,
+                "client-name", client_name,
                 "do-timestamp", TRUE,
                 "server", pa_context_get_server (self->context),
                 NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gnome-network-displays-0.98.0/src/nd-systemd-helpers.c 
new/gnome-network-displays-0.99.0/src/nd-systemd-helpers.c
--- old/gnome-network-displays-0.98.0/src/nd-systemd-helpers.c  2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-systemd-helpers.c  2026-01-23 
06:57:54.000000000 +0100
@@ -31,7 +31,7 @@
 static GVariant *
 build_description (const gchar *name)
 {
-  const gchar *desc = g_strdup_printf ("GNOME Network Displays stream for %s", 
name);
+  g_autofree gchar *desc = g_strdup_printf ("GNOME Network Displays stream for 
%s", name);
 
   GVariant *description;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-uri-helpers.c 
new/gnome-network-displays-0.99.0/src/nd-uri-helpers.c
--- old/gnome-network-displays-0.98.0/src/nd-uri-helpers.c      2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-uri-helpers.c      2026-01-23 
06:57:54.000000000 +0100
@@ -42,15 +42,14 @@
   g_autoptr(GStrvBuilder) strv_builder = g_strv_builder_new ();
   GHashTableIter iter;
   gpointer key, value;
-  gpointer key_parsed, value_parsed;
   g_hash_table_iter_init (&iter, params);
   while (g_hash_table_iter_next (&iter, &key, &value))
     {
-      key_parsed = g_uri_escape_string (key, 
G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, FALSE);
-      value_parsed = g_uri_escape_string (value, 
G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, FALSE);
+      g_autofree gchar *key_escaped = g_uri_escape_string (key, 
G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, FALSE);
+      g_autofree gchar *value_escaped = g_uri_escape_string (value, 
G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, FALSE);
+      g_autofree gchar *param_str = g_strdup_printf ("%s=%s", key_escaped, 
value_escaped);
 
-      g_strv_builder_add (strv_builder,
-                          g_strdup_printf ("%s=%s", (gchar *) key_parsed, 
(gchar *) value_parsed));
+      g_strv_builder_add (strv_builder, param_str);
     }
 
   g_auto(GStrv) params_array = g_strv_builder_end (strv_builder);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-wfd-mice-sink.c 
new/gnome-network-displays-0.99.0/src/nd-wfd-mice-sink.c
--- old/gnome-network-displays-0.98.0/src/nd-wfd-mice-sink.c    2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-wfd-mice-sink.c    2026-01-23 
06:57:54.000000000 +0100
@@ -45,6 +45,7 @@
   GSocketConnection *signalling_client_conn;
 
   WfdServer         *server;
+  WfdClient         *wfd_client;
   guint              server_source_id;
 };
 
@@ -319,16 +320,16 @@
 nd_wfd_mice_sink_sink_to_uri (NdSink *sink)
 {
   NdWFDMiceSink *self = ND_WFD_MICE_SINK (sink);
-  GHashTable *params = g_hash_table_new (g_str_hash, g_str_equal);
+  g_autoptr(GHashTable) params = g_hash_table_new_full (g_str_hash, 
g_str_equal, NULL, g_free);
 
   /* protocol */
-  g_hash_table_insert (params, "protocol", (gpointer *) g_strdup_printf ("%d", 
protocol));
+  g_hash_table_insert (params, "protocol", g_strdup_printf ("%d", protocol));
 
   /* remote name */
-  g_hash_table_insert (params, "name", (gpointer *) g_strdup (self->name));
+  g_hash_table_insert (params, "name", g_strdup (self->name));
 
   /* remote ip */
-  g_hash_table_insert (params, "ip", (gpointer *) g_strdup (self->ip));
+  g_hash_table_insert (params, "ip", g_strdup (self->ip));
 
   return nd_uri_helpers_generate_uri (params);
 }
@@ -420,10 +421,16 @@
 static void
 closed_cb (NdWFDMiceSink *sink, WfdClient *client)
 {
-  g_autoptr(GError) error = NULL;
+  if (sink->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
+  if (sink->wfd_client == NULL)
+    return;
+
+  nd_wfd_mice_sink_sink_stop_stream_int (sink);
 
-  /* Connection was closed, do a clean shutdown*/
-  nd_wfd_mice_sink_sink_stop_stream (ND_SINK (sink));
+  sink->state = ND_SINK_STATE_DISCONNECTED;
+  g_object_notify (G_OBJECT (sink), "state");
 }
 
 static void
@@ -435,7 +442,8 @@
   sink->state = ND_SINK_STATE_WAIT_STREAMING;
   g_object_notify (G_OBJECT (sink), "state");
 
-  /* XXX: connect to further events. */
+  sink->wfd_client = g_object_ref (client);
+
   g_signal_connect_object (client,
                            "play-request",
                            (GCallback) play_request_cb,
@@ -644,6 +652,12 @@
       self->server_source_id = 0;
     }
 
+  if (self->wfd_client)
+    {
+      g_signal_handlers_disconnect_by_data (self->wfd_client, self);
+      g_clear_object (&self->wfd_client);
+    }
+
   /* Needs to protect against recursion. */
   if (self->server)
     {
@@ -660,6 +674,9 @@
 {
   NdWFDMiceSink *self = ND_WFD_MICE_SINK (sink);
 
+  if (self->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
   nd_wfd_mice_sink_sink_stop_stream_int (self);
 
   self->state = ND_SINK_STATE_DISCONNECTED;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/nd-wfd-p2p-sink.c 
new/gnome-network-displays-0.99.0/src/nd-wfd-p2p-sink.c
--- old/gnome-network-displays-0.98.0/src/nd-wfd-p2p-sink.c     2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/nd-wfd-p2p-sink.c     2026-01-23 
06:57:54.000000000 +0100
@@ -44,6 +44,7 @@
   char               *missing_firewall_zone;
 
   WfdServer          *server;
+  WfdClient          *wfd_client;
   guint               server_source_id;
 };
 
@@ -307,18 +308,18 @@
 nd_wfd_p2p_sink_sink_to_uri (NdSink *sink)
 {
   NdWFDP2PSink *self = ND_WFD_P2P_SINK (sink);
-  GHashTable *params = g_hash_table_new (g_str_hash, g_str_equal);
+  g_autoptr(GHashTable) params = g_hash_table_new_full (g_str_hash, 
g_str_equal, NULL, g_free);
 
   /* protocol */
-  g_hash_table_insert (params, "protocol", (gpointer *) g_strdup_printf ("%d", 
protocol));
+  g_hash_table_insert (params, "protocol", g_strdup_printf ("%d", protocol));
 
   /* device */
   const gchar *device_path = nm_object_get_path ((NMObject *) self->nm_device);
-  g_hash_table_insert (params, "device", (gpointer *) g_strdup (device_path));
+  g_hash_table_insert (params, "device", g_strdup (device_path));
 
   /* peer */
   const gchar *peer_path = nm_object_get_path ((NMObject *) self->nm_peer);
-  g_hash_table_insert (params, "peer", (gpointer *) g_strdup (peer_path));
+  g_hash_table_insert (params, "peer", g_strdup (peer_path));
 
   return nd_uri_helpers_generate_uri (params);
 }
@@ -347,8 +348,16 @@
 static void
 closed_cb (NdWFDP2PSink *sink, WfdClient *client)
 {
-  /* Connection was closed, do a clean shutdown*/
-  nd_wfd_p2p_sink_sink_stop_stream (ND_SINK (sink));
+  if (sink->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
+  if (sink->wfd_client == NULL)
+    return;
+
+  nd_wfd_p2p_sink_sink_stop_stream_int (sink);
+
+  sink->state = ND_SINK_STATE_DISCONNECTED;
+  g_object_notify (G_OBJECT (sink), "state");
 }
 
 static void
@@ -360,7 +369,8 @@
   sink->state = ND_SINK_STATE_WAIT_STREAMING;
   g_object_notify (G_OBJECT (sink), "state");
 
-  /* XXX: connect to further events. */
+  sink->wfd_client = g_object_ref (client);
+
   g_signal_connect_object (client,
                            "play-request",
                            (GCallback) play_request_cb,
@@ -609,6 +619,12 @@
       self->server_source_id = 0;
     }
 
+  if (self->wfd_client)
+    {
+      g_signal_handlers_disconnect_by_data (self->wfd_client, self);
+      g_clear_object (&self->wfd_client);
+    }
+
   /* Needs to protect against recursion. */
   if (self->server)
     {
@@ -633,6 +649,9 @@
 {
   NdWFDP2PSink *self = ND_WFD_P2P_SINK (sink);
 
+  if (self->state == ND_SINK_STATE_DISCONNECTED)
+    return;
+
   nd_wfd_p2p_sink_sink_stop_stream_int (self);
 
   self->state = ND_SINK_STATE_DISCONNECTED;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/stream/nd-stream.c 
new/gnome-network-displays-0.99.0/src/stream/nd-stream.c
--- old/gnome-network-displays-0.98.0/src/stream/nd-stream.c    2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/stream/nd-stream.c    2026-01-23 
06:57:54.000000000 +0100
@@ -144,15 +144,18 @@
 
   g_object_get (self->sink, "uuid", &uuid, NULL);
 
-  src = gst_element_factory_make ("pipewiresrc", g_strdup_printf 
("portal-pipewire-source-%.8s", uuid));
+  g_autofree gchar *element_name = g_strdup_printf 
("portal-pipewire-source-%.8s", uuid);
+  src = gst_element_factory_make ("pipewiresrc", element_name);
   if (src == NULL)
     g_error ("GStreamer element \"pipewiresrc\" could not be created!");
 
+  g_autofree gchar *path_str = g_strdup_printf ("%u", node_id);
   g_object_set (src,
                 "fd", xdp_session_open_pipewire_remote (self->session),
-                "path", g_strdup_printf ("%u", node_id),
+                "path", path_str,
                 "do-timestamp", TRUE,
                 NULL);
+  g_free (uuid);
 
   gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
 
@@ -502,7 +505,7 @@
   g_object_get (sink, "display-name", &name, NULL);
   g_object_get (sink, "uuid", &uuid, NULL);
 
-  self->pulse = nd_pulseaudio_new (g_strdup (name), g_strdup (uuid));
+  self->pulse = nd_pulseaudio_new (name, uuid);
   g_async_initable_init_async (G_ASYNC_INITABLE (self->pulse),
                                G_PRIORITY_LOW,
                                self->cancellable,
@@ -587,12 +590,12 @@
 nd_stream_new ()
 {
   NdStream *stream;
-  gchar * uuid = g_uuid_string_random ();
-  gchar * id = g_strdup_printf ("org.gnome.NetworkDisplays.Stream_%.8s", uuid);
+  g_autofree gchar *uuid = g_uuid_string_random ();
+  g_autofree gchar *id = g_strdup_printf 
("org.gnome.NetworkDisplays.Stream_%.8s", uuid);
 
   g_debug ("NdStream: Starting with app-id: %s", id);
   stream = g_object_new (ND_TYPE_STREAM,
-                         "application-id", g_strdup (id),
+                         "application-id", id,
                          "flags", G_APPLICATION_HANDLES_OPEN,
                          NULL);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/wfd/wfd-client.c 
new/gnome-network-displays-0.99.0/src/wfd/wfd-client.c
--- old/gnome-network-displays-0.98.0/src/wfd/wfd-client.c      2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/wfd/wfd-client.c      2026-01-23 
06:57:54.000000000 +0100
@@ -369,12 +369,25 @@
                                         gpointer        user_data)
 {
   GstRTSPMessage msg = { 0 };
+  GstRTSPConnection *connection;
+  GstRTSPResult res;
+
+  connection = gst_rtsp_client_get_connection (client);
+  if (!connection)
+    {
+      g_debug ("WfdClient: No connection, skipping keep-alive");
+      return GST_RTSP_FILTER_REMOVE;
+    }
 
   g_debug ("WfdClient: Doing keep-alive");
 
   gst_rtsp_message_init_request (&msg, GST_RTSP_GET_PARAMETER, 
"rtsp://localhost/wfd1.0");
 
-  gst_rtsp_client_send_message (client, sess, &msg);
+  res = gst_rtsp_client_send_message (client, sess, &msg);
+  if (res != GST_RTSP_OK)
+    {
+      g_debug ("WfdClient: Keep-alive send failed: %d (continuing anyway)", 
res);
+    }
 
   gst_rtsp_message_unset (&msg);
 
@@ -385,6 +398,20 @@
 wfd_client_keep_alive_timeout (gpointer user_data)
 {
   GstRTSPClient *client = GST_RTSP_CLIENT (user_data);
+  WfdClient *self = WFD_CLIENT (client);
+  GstRTSPConnection *connection;
+
+  connection = gst_rtsp_client_get_connection (client);
+  if (!connection)
+    {
+      g_debug ("WfdClient: No connection, disabling keep-alive");
+      if (self->keep_alive_source_id)
+        {
+          g_source_remove (self->keep_alive_source_id);
+          self->keep_alive_source_id = 0;
+        }
+      return G_SOURCE_REMOVE;
+    }
 
   gst_rtsp_client_session_filter (client, 
wfd_client_timeout_session_filter_func, NULL);
 
@@ -396,12 +423,15 @@
 {
   WfdClient *self = WFD_CLIENT (client);
 
-  /* The WFD standard suggests a timeout of 30 seconds */
   gst_rtsp_session_set_timeout (session, 30);
   g_object_set (session, "timeout-always-visible", FALSE, NULL);
 
-  if (self->connection_type == CONNECTION_TYPE_WFD && 
self->keep_alive_source_id == 0)
-    self->keep_alive_source_id = g_timeout_add_seconds (25, 
wfd_client_keep_alive_timeout, client);
+  if (self->connection_type == CONNECTION_TYPE_WFD && 
+      self->keep_alive_source_id == 0)
+    {
+      g_debug ("WfdClient: Enabling keep-alive timer");
+      self->keep_alive_source_id = g_timeout_add_seconds (25, 
wfd_client_keep_alive_timeout, client);
+    }
 }
 
 static GstRTSPResult
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gnome-network-displays-0.98.0/src/wfd/wfd-media-factory.c 
new/gnome-network-displays-0.99.0/src/wfd/wfd-media-factory.c
--- old/gnome-network-displays-0.98.0/src/wfd/wfd-media-factory.c       
2025-12-15 00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/wfd/wfd-media-factory.c       
2026-01-23 06:57:54.000000000 +0100
@@ -541,6 +541,12 @@
   if (encoder_impl == ELEMENT_VAAPIH264)
     quirks = WFD_QUIRK_NO_IDR;
 
+  if (params->rtcp_port_invalid)
+    {
+      g_debug ("WfdMediaFactory: Detected potential RTCP port issue, disabling 
keep-alive");
+      quirks |= WFD_QUIRK_NO_KEEPALIVE;
+    }
+
   /* Decrease the number of keyframes if the device is able to request
    * IDRs by itself.
    * Note that VAAPI H264 appears to run into an assertion error in version 
1.14.4 */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gnome-network-displays-0.98.0/src/wfd/wfd-media-factory.h 
new/gnome-network-displays-0.99.0/src/wfd/wfd-media-factory.h
--- old/gnome-network-displays-0.98.0/src/wfd/wfd-media-factory.h       
2025-12-15 00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/wfd/wfd-media-factory.h       
2026-01-23 06:57:54.000000000 +0100
@@ -75,6 +75,7 @@
 
 typedef enum {
   WFD_QUIRK_NO_IDR = 0x01,
+  WFD_QUIRK_NO_KEEPALIVE = 0x02,
 } WfdMediaQuirks;
 
 WfdMediaFactory * wfd_media_factory_new (void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/wfd/wfd-params.c 
new/gnome-network-displays-0.99.0/src/wfd/wfd-params.c
--- old/gnome-network-displays-0.98.0/src/wfd/wfd-params.c      2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/wfd/wfd-params.c      2026-01-23 
06:57:54.000000000 +0100
@@ -86,6 +86,7 @@
 
   copy->primary_rtp_port = self->primary_rtp_port;
   copy->secondary_rtp_port = self->secondary_rtp_port;
+  copy->rtcp_port_invalid = self->rtcp_port_invalid;
   if (self->edid)
     {
       copy->edid = g_byte_array_new ();
@@ -225,6 +226,26 @@
 
           self->primary_rtp_port = g_ascii_strtoll (split_value[1], NULL, 10);
           self->secondary_rtp_port = g_ascii_strtoll (split_value[2], NULL, 
10);
+          
+          if (self->secondary_rtp_port == 0)
+            {
+              g_warning ("WfdParams: Missing RTCP port (secondary_rtp_port=0, 
primary_rtp_port=%u). "
+                        "Auto-correcting to primary_rtp_port + 1.",
+                        self->primary_rtp_port);
+              self->rtcp_port_invalid = TRUE;
+              self->secondary_rtp_port = self->primary_rtp_port + 1;
+            }
+          else if (self->secondary_rtp_port == self->primary_rtp_port)
+            {
+              g_warning ("WfdParams: Invalid RTCP port (secondary_rtp_port=%u 
equals primary_rtp_port=%u). "
+                        "Auto-correcting to primary_rtp_port + 1.",
+                        self->secondary_rtp_port, self->primary_rtp_port);
+              self->rtcp_port_invalid = TRUE;
+              self->secondary_rtp_port = self->primary_rtp_port + 1;
+            }
+          
+          g_debug ("WfdParams: RTP ports - primary=%u, secondary (RTCP)=%u", 
+                   self->primary_rtp_port, self->secondary_rtp_port);
         }
       else if (g_str_equal (option, "wfd_video_formats"))
         {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gnome-network-displays-0.98.0/src/wfd/wfd-params.h 
new/gnome-network-displays-0.99.0/src/wfd/wfd-params.h
--- old/gnome-network-displays-0.98.0/src/wfd/wfd-params.h      2025-12-15 
00:58:20.000000000 +0100
+++ new/gnome-network-displays-0.99.0/src/wfd/wfd-params.h      2026-01-23 
06:57:54.000000000 +0100
@@ -14,6 +14,7 @@
   gchar         *profile;
   guint16        primary_rtp_port;
   guint16        secondary_rtp_port;
+  gboolean       rtcp_port_invalid;
   GByteArray    *edid;
 
   gboolean       idr_request_capability;

++++++ gnome-network-displays.obsinfo ++++++
--- /var/tmp/diff_new_pack.okPuJ0/_old  2026-01-26 11:05:43.742546632 +0100
+++ /var/tmp/diff_new_pack.okPuJ0/_new  2026-01-26 11:05:43.746546799 +0100
@@ -1,5 +1,5 @@
 name: gnome-network-displays
-version: 0.98.0
-mtime: 1765756700
-commit: 38f830add96c5fa83aef56d9c603d042aab65853
+version: 0.99.0
+mtime: 1769147874
+commit: eba3ce5dada5f6065e77041c973e73e3c2886bfd
 

Reply via email to