Version in base suite: 3.24.24-4 Base version: gtk+3.0_3.24.24-4 Target version: gtk+3.0_3.24.24-4+deb11u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/g/gtk+3.0/gtk+3.0_3.24.24-4.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/g/gtk+3.0/gtk+3.0_3.24.24-4+deb11u2.dsc changelog | 35 control | 2 control.in | 2 gbp.conf | 2 patches/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch | 82 + patches/debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch | 38 patches/printing-Create-temporary-queues-for-Avahi-printers.patch | 553 ++++++++++ patches/printing-Show-all-Avahi-advertised-printers.patch | 84 + patches/searchenginemodel-finalize-search-results.patch | 43 patches/series | 6 patches/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch | 132 ++ 11 files changed, 976 insertions(+), 3 deletions(-) diff -Nru gtk+3.0-3.24.24/debian/changelog gtk+3.0-3.24.24/debian/changelog --- gtk+3.0-3.24.24/debian/changelog 2021-05-02 11:34:12.000000000 +0000 +++ gtk+3.0-3.24.24/debian/changelog 2022-03-10 10:30:09.000000000 +0000 @@ -1,3 +1,38 @@ +gtk+3.0 (3.24.24-4+deb11u2) bullseye; urgency=medium + + [ Jian-Hong Pan ] + * d/p/printing-Create-temporary-queues-for-Avahi-printers.patch, + d/p/printing-Show-all-Avahi-advertised-printers.patch: + Backport patches from upstream 3.24.25 to enable temporary CUPS queues + for local printers advertised via mDNS. + This enables GTK to discover local printers and print to them, without + needing to install the cups-browsed package or configure CUPS queues + manually. + (Closes: #982925) + * d/p/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch: + Backport patch from upstream 3.24.29 to make the printing module + identical to the more widely-tested version in unstable. + + [ Simon McVittie ] + * debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch: + Avoid creating confusing duplicate printer entries if the printer's mDNS + name begins or ends with a non-alphanumeric character. This change is + specific to the Debian 11 version of cups-browsed, and is not necessary + with cups-browsed 1.28.11 or later. + * d/p/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch: + Backport patch from upstream 3.24.31 to prevent Wayland clipboard + handling from locking up in certain corner cases (Closes: #1006281) + + -- Simon McVittie Thu, 10 Mar 2022 10:30:09 +0000 + +gtk+3.0 (3.24.24-4+deb11u1) bullseye; urgency=medium + + * Add patch from upstream to fix missing search results when using NFS + (Closes: #976334) + * d/gbp.conf, d/control.in: Set packaging branch to debian/bullseye + + -- Simon McVittie Sun, 13 Feb 2022 13:27:26 +0000 + gtk+3.0 (3.24.24-4) unstable; urgency=medium * Add various patches from upstream 3.24.25 to 3.24.29, mostly diff -Nru gtk+3.0-3.24.24/debian/control gtk+3.0-3.24.24/debian/control --- gtk+3.0-3.24.24/debian/control 2021-05-02 11:34:12.000000000 +0000 +++ gtk+3.0-3.24.24/debian/control 2022-03-10 10:30:09.000000000 +0000 @@ -59,7 +59,7 @@ Rules-Requires-Root: no Standards-Version: 4.5.1 Vcs-Browser: https://salsa.debian.org/gnome-team/gtk3 -Vcs-Git: https://salsa.debian.org/gnome-team/gtk3.git +Vcs-Git: https://salsa.debian.org/gnome-team/gtk3.git -b debian/bullseye Homepage: https://www.gtk.org/ Package: libgtk-3-0 diff -Nru gtk+3.0-3.24.24/debian/control.in gtk+3.0-3.24.24/debian/control.in --- gtk+3.0-3.24.24/debian/control.in 2021-05-02 11:34:12.000000000 +0000 +++ gtk+3.0-3.24.24/debian/control.in 2022-03-10 10:30:09.000000000 +0000 @@ -59,7 +59,7 @@ Rules-Requires-Root: no Standards-Version: 4.5.1 Vcs-Browser: https://salsa.debian.org/gnome-team/gtk3 -Vcs-Git: https://salsa.debian.org/gnome-team/gtk3.git +Vcs-Git: https://salsa.debian.org/gnome-team/gtk3.git -b debian/bullseye Homepage: https://www.gtk.org/ Package: @SHARED_PKG@ diff -Nru gtk+3.0-3.24.24/debian/gbp.conf gtk+3.0-3.24.24/debian/gbp.conf --- gtk+3.0-3.24.24/debian/gbp.conf 2021-05-02 11:34:12.000000000 +0000 +++ gtk+3.0-3.24.24/debian/gbp.conf 2022-03-10 10:30:09.000000000 +0000 @@ -1,6 +1,6 @@ [DEFAULT] pristine-tar = True -debian-branch = debian/master +debian-branch = debian/bullseye upstream-branch = upstream/latest [buildpackage] diff -Nru gtk+3.0-3.24.24/debian/patches/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch gtk+3.0-3.24.24/debian/patches/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch --- gtk+3.0-3.24.24/debian/patches/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,82 @@ +From: John Ralls +Date: Fri, 16 Apr 2021 12:15:45 -0700 +Subject: Don't try to create local cups printers before CUPS 2.2 + +Not supported on earlier versions. + +Origin: upstream, 3.24.29, commit:3d53204c75c75ba195f9489f862c01f7ff956322 +--- + modules/printbackends/cups/gtkprintbackendcups.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c +index 6b8c9e0..d5c00f9 100644 +--- a/modules/printbackends/cups/gtkprintbackendcups.c ++++ b/modules/printbackends/cups/gtkprintbackendcups.c +@@ -61,6 +61,10 @@ + #include + #endif + ++#if ((CUPS_VERSION_MAJOR == 2 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 2) ++#define HAVE_CUPS_2_2 ++#endif ++ + typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass; + + #define GTK_PRINT_BACKEND_CUPS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_CUPS, GtkPrintBackendCupsClass)) +@@ -242,10 +246,12 @@ static void secrets_service_vanished_cb (GDBusConnec + const gchar *name, + gpointer user_data); + ++#ifdef HAVE_CUPS_2_2 + static void create_temporary_queue (GtkPrintBackendCups *backend, + const gchar *printer_name, + const gchar *printer_uri, + const gchar *device_uri); ++#endif + + static void + gtk_print_backend_cups_register_type (GTypeModule *module) +@@ -1896,10 +1902,12 @@ mark_printer_inactive (GtkPrinter *printer, + if (iter == NULL) + { + /* Recreate temporary queue since they are created for 60 seconds only. */ ++#ifdef HAVE_CUPS_2_2 + create_temporary_queue (GTK_PRINT_BACKEND_CUPS (backend), + gtk_printer_get_name (printer), + cups_printer->printer_uri, + cups_printer->temporary_queue_device_uri); ++#endif + } + } + else +@@ -3017,6 +3025,7 @@ cups_create_local_printer_cb (GtkPrintBackendCups *print_backend, + /* + * Create CUPS temporary queue. + */ ++#ifdef HAVE_CUPS_2_2 + static void + create_temporary_queue (GtkPrintBackendCups *backend, + const gchar *printer_name, +@@ -3057,7 +3066,7 @@ create_temporary_queue (GtkPrintBackendCups *backend, + NULL, + NULL); + } +- ++#endif + /* + * Create new GtkPrinter from informations included in TXT records. + */ +@@ -4552,10 +4561,12 @@ cups_printer_request_details (GtkPrinter *printer) + + if (cups_printer->avahi_browsed) + { ++#ifdef HAVE_CUPS_2_2 + create_temporary_queue (GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)), + gtk_printer_get_name (printer), + cups_printer->printer_uri, + cups_printer->temporary_queue_device_uri); ++#endif + } + else if (!cups_printer->reading_ppd && + gtk_printer_cups_get_ppd (cups_printer) == NULL) diff -Nru gtk+3.0-3.24.24/debian/patches/debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch gtk+3.0-3.24.24/debian/patches/debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch --- gtk+3.0-3.24.24/debian/patches/debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,38 @@ +From: Simon McVittie +Date: Sun, 20 Feb 2022 21:23:25 +0000 +Subject: cups: Use the same name-mangling as Debian 11's cups-browsed + +The name-mangling used in GTK 3.24.25 is appropriate for +cups-browsed >= 1.28.11, which eliminates leading and trailing +underscores in the normalized name, but the cups-browsed version in +Debian 11 is older and does not do that. We need to match the printer +names generated by the installed cups-browsed, to avoid a printer +showing up twice under confusingly similar names. + +Signed-off-by: Simon McVittie +Forwarded: not-needed, specific to Debian 11 software versions +--- + modules/printbackends/cups/gtkprintbackendcups.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c +index d5c00f9..eadcbad 100644 +--- a/modules/printbackends/cups/gtkprintbackendcups.c ++++ b/modules/printbackends/cups/gtkprintbackendcups.c +@@ -3368,7 +3368,15 @@ avahi_service_resolver_cb (GObject *source_object, + printer_name_compressed_strv = g_new0 (gchar *, g_strv_length (printer_name_strv) + 1); + for (i = 0, j = 0; printer_name_strv[i] != NULL; i++) + { +- if (printer_name_strv[i][0] != '\0') ++ /* ++ * Keep an empty segment at the beginning or end, if any. ++ * This emulates the way cups-browsed in Debian 11 created ++ * printer names (before 1.28.11), for example: ++ * "Some Printer (123456)" -> Some_Printer_123456_ ++ * and hypothetically ++ * "(Really) Working Printer" -> _Really_Working_Printer ++ */ ++ if (printer_name_strv[i][0] != '\0' || i == 0 || printer_name_strv[i + 1] == NULL) + { + printer_name_compressed_strv[j] = printer_name_strv[i]; + j++; diff -Nru gtk+3.0-3.24.24/debian/patches/printing-Create-temporary-queues-for-Avahi-printers.patch gtk+3.0-3.24.24/debian/patches/printing-Create-temporary-queues-for-Avahi-printers.patch --- gtk+3.0-3.24.24/debian/patches/printing-Create-temporary-queues-for-Avahi-printers.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/printing-Create-temporary-queues-for-Avahi-printers.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,553 @@ +From: Marek Kasik +Date: Fri, 5 Feb 2021 17:53:08 +0100 +Subject: printing: Create temporary queues for Avahi printers + +This change extends set of Avahi advertised printers which +works with Gtk's CUPS print backend. + +It creates a temporary queue (local printer) for each +Avahi printer in CUPS instead of accessing them directly +(via CUPS library). + +This makes some printers work which did not work before and +also gives users more options to change in the print dialog. + +This also changes naming of printers to be in accordance with CUPS. +It uses '_' instead of '-' and has hostname appended for CUPS remote +printers. + +Origin: upstream, 3.24.25, commit:d07bfbec1d2b9d196eb661e7b2a6dc24fba9ad47 +--- + modules/printbackends/cups/gtkprintbackendcups.c | 296 ++++++++++++++++++----- + modules/printbackends/cups/gtkprintercups.h | 4 +- + 2 files changed, 243 insertions(+), 57 deletions(-) + +diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c +index d95d632..b1ee058 100644 +--- a/modules/printbackends/cups/gtkprintbackendcups.c ++++ b/modules/printbackends/cups/gtkprintbackendcups.c +@@ -154,6 +154,9 @@ struct _GtkPrintBackendCups + gboolean secrets_service_available; + guint secrets_service_watch_id; + GCancellable *secrets_service_cancellable; ++ ++ GList *temporary_queues_in_construction; ++ GList *temporary_queues_removed; + }; + + static GObjectClass *backend_parent_class; +@@ -238,6 +241,11 @@ static void secrets_service_vanished_cb (GDBusConnec + const gchar *name, + gpointer user_data); + ++static void create_temporary_queue (GtkPrintBackendCups *backend, ++ const gchar *printer_name, ++ const gchar *printer_uri, ++ const gchar *device_uri); ++ + static void + gtk_print_backend_cups_register_type (GTypeModule *module) + { +@@ -897,6 +905,9 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups) + gtk_cups_secrets_service_watch (secrets_service_appeared_cb, + secrets_service_vanished_cb, + backend_cups); ++ ++ backend_cups->temporary_queues_in_construction = NULL; ++ backend_cups->temporary_queues_removed = NULL; + } + + static void +@@ -933,6 +944,12 @@ gtk_print_backend_cups_finalize (GObject *object) + g_bus_unwatch_name (backend_cups->secrets_service_watch_id); + } + ++ g_list_free_full (backend_cups->temporary_queues_in_construction, g_free); ++ backend_cups->temporary_queues_in_construction = NULL; ++ ++ g_list_free_full (backend_cups->temporary_queues_removed, g_free); ++ backend_cups->temporary_queues_removed = NULL; ++ + backend_parent_class->finalize (object); + } + +@@ -1861,8 +1878,28 @@ static void + mark_printer_inactive (GtkPrinter *printer, + GtkPrintBackend *backend) + { +- gtk_printer_set_is_active (printer, FALSE); +- g_signal_emit_by_name (backend, "printer-removed", printer); ++ GtkPrinterCups *cups_printer = GTK_PRINTER_CUPS (printer); ++ GList *iter; ++ ++ if (cups_printer->is_temporary) ++ { ++ /* Do not recreate printers which disappeared from Avahi. */ ++ iter = g_list_find_custom (GTK_PRINT_BACKEND_CUPS (backend)->temporary_queues_removed, ++ gtk_printer_get_name (printer), (GCompareFunc) g_strcmp0); ++ if (iter == NULL) ++ { ++ /* Recreate temporary queue since they are created for 60 seconds only. */ ++ create_temporary_queue (GTK_PRINT_BACKEND_CUPS (backend), ++ gtk_printer_get_name (printer), ++ cups_printer->printer_uri, ++ cups_printer->temporary_queue_device_uri); ++ } ++ } ++ else ++ { ++ gtk_printer_set_is_active (printer, FALSE); ++ g_signal_emit_by_name (backend, "printer-removed", printer); ++ } + } + + static gint +@@ -1913,7 +1950,8 @@ static const char * const printer_attrs[] = + "multiple-document-handling-supported", + "copies-supported", + "number-up-supported", +- "device-uri" ++ "device-uri", ++ "printer-is-temporary" + }; + + /* Attributes we're interested in for printers without PPD */ +@@ -2010,6 +2048,7 @@ typedef struct + gchar *output_bin_default; + GList *output_bin_supported; + gchar *original_device_uri; ++ gboolean is_temporary; + } PrinterSetupInfo; + + static void +@@ -2395,6 +2434,13 @@ cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend, + { + info->original_device_uri = g_strdup (ippGetString (attr, 0, NULL)); + } ++ else if (strcmp (ippGetName (attr), "printer-is-temporary") == 0) ++ { ++ if (ippGetBoolean (attr, 0) == 1) ++ info->is_temporary = TRUE; ++ else ++ info->is_temporary = FALSE; ++ } + else + { + GTK_NOTE (PRINTING, +@@ -2430,12 +2476,7 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, + cups_printer = gtk_printer_cups_new (info->printer_name, backend, NULL); + #endif + +- if (info->avahi_printer) +- { +- cups_printer->device_uri = g_strdup_printf ("/%s", +- info->avahi_resource_path); +- } +- else ++ if (!info->avahi_printer) + { + cups_printer->device_uri = g_strdup_printf ("/printers/%s", + info->printer_name); +@@ -2799,6 +2840,8 @@ cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend, + GTK_PRINTER_CUPS (printer)->output_bin_default = info->output_bin_default; + GTK_PRINTER_CUPS (printer)->output_bin_supported = info->output_bin_supported; + ++ GTK_PRINTER_CUPS (printer)->is_temporary = info->is_temporary; ++ + gtk_printer_set_has_details (printer, TRUE); + g_signal_emit_by_name (printer, "details-acquired", TRUE); + +@@ -2866,8 +2909,10 @@ cups_request_printer_info (GtkPrinterCups *printer) + typedef struct + { + gchar *printer_uri; ++ gchar *device_uri; + gchar *location; +- gchar *host; ++ gchar *address; ++ gchar *hostname; + gint port; + gchar *printer_name; + gchar *name; +@@ -2924,6 +2969,88 @@ find_printer_by_uuid (GtkPrintBackendCups *backend, + return result; + } + ++static void ++cups_create_local_printer_cb (GtkPrintBackendCups *print_backend, ++ GtkCupsResult *result, ++ gpointer user_data) ++{ ++ ipp_attribute_t *attr; ++ gchar *printer_name = NULL; ++ ipp_t *response; ++ GList *iter; ++ ++ response = gtk_cups_result_get_response (result); ++ ++ if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) ++ { ++ if ((attr = ippFindAttribute (response, "printer-uri-supported", IPP_TAG_URI)) != NULL) ++ { ++ printer_name = g_strdup (g_strrstr (ippGetString (attr, 0, NULL), "/") + 1); ++ } ++ ++ GTK_NOTE (PRINTING, ++ g_print ("CUPS Backend: Created local printer %s\n", printer_name)); ++ } ++ else ++ { ++ GTK_NOTE (PRINTING, ++ g_print ("CUPS Backend: Creating of local printer failed: %d\n", ippGetStatusCode (response))); ++ } ++ ++ iter = g_list_find_custom (print_backend->temporary_queues_in_construction, printer_name, (GCompareFunc) g_strcmp0); ++ if (iter != NULL) ++ { ++ g_free (iter->data); ++ print_backend->temporary_queues_in_construction = g_list_delete_link (print_backend->temporary_queues_in_construction, iter); ++ } ++ ++ g_free (printer_name); ++} ++ ++/* ++ * Create CUPS temporary queue. ++ */ ++static void ++create_temporary_queue (GtkPrintBackendCups *backend, ++ const gchar *printer_name, ++ const gchar *printer_uri, ++ const gchar *device_uri) ++{ ++ GtkCupsRequest *request; ++ GList *iter; ++ ++ /* There can be several queues with the same name (ipp and ipps versions of the same printer) */ ++ iter = g_list_find_custom (backend->temporary_queues_in_construction, printer_name, (GCompareFunc) g_strcmp0); ++ if (iter != NULL) ++ return; ++ ++ GTK_NOTE (PRINTING, ++ g_print ("CUPS Backend: Creating local printer %s\n", printer_name)); ++ ++ backend->temporary_queues_in_construction = g_list_prepend (backend->temporary_queues_in_construction, g_strdup (printer_name)); ++ ++ request = gtk_cups_request_new_with_username (NULL, ++ GTK_CUPS_POST, ++ IPP_OP_CUPS_CREATE_LOCAL_PRINTER, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++ ++ gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_URI, ++ "printer-uri", NULL, printer_uri); ++ gtk_cups_request_ipp_add_string (request, IPP_TAG_PRINTER, IPP_TAG_NAME, ++ "printer-name", NULL, printer_name); ++ gtk_cups_request_ipp_add_string (request, IPP_TAG_PRINTER, IPP_TAG_URI, ++ "device-uri", NULL, device_uri); ++ ++ cups_request_execute (backend, ++ request, ++ (GtkPrintCupsResponseCallbackFunc) cups_create_local_printer_cb, ++ NULL, ++ NULL); ++} ++ + /* + * Create new GtkPrinter from informations included in TXT records. + */ +@@ -2933,6 +3060,15 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) + PrinterSetupInfo *info = g_slice_new0 (PrinterSetupInfo); + GtkPrinter *printer; + ++ printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (data->backend), data->printer_name); ++ if (printer != NULL) ++ { ++ /* A printer with this name is already present in this backend. It is probably the same printer ++ * on another protocol (IPv4 vs IPv6). ++ */ ++ return; ++ } ++ + info->avahi_printer = TRUE; + info->printer_name = data->printer_name; + info->printer_uri = data->printer_uri; +@@ -2997,8 +3133,9 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) + GTK_PRINTER_CUPS (printer)->avahi_type = g_strdup (data->type); + GTK_PRINTER_CUPS (printer)->avahi_domain = g_strdup (data->domain); + GTK_PRINTER_CUPS (printer)->printer_uri = g_strdup (data->printer_uri); ++ GTK_PRINTER_CUPS (printer)->temporary_queue_device_uri = g_strdup (data->device_uri); + g_free (GTK_PRINTER_CUPS (printer)->hostname); +- GTK_PRINTER_CUPS (printer)->hostname = g_strdup (data->host); ++ GTK_PRINTER_CUPS (printer)->hostname = g_strdup (data->hostname); + GTK_PRINTER_CUPS (printer)->port = data->port; + gtk_printer_set_location (printer, data->location); + gtk_printer_set_state_message (printer, info->state_msg); +@@ -3031,10 +3168,11 @@ avahi_connection_test_cb (GObject *source_object, + { + AvahiConnectionTestData *data = (AvahiConnectionTestData *) user_data; + GSocketConnection *connection; ++ GError *error = NULL; + + connection = g_socket_client_connect_to_host_finish (G_SOCKET_CLIENT (source_object), + res, +- NULL); ++ &error); + g_object_unref (source_object); + + if (connection != NULL) +@@ -3044,15 +3182,25 @@ avahi_connection_test_cb (GObject *source_object, + + create_cups_printer_from_avahi_data (data); + } ++ else ++ { ++ GTK_NOTE (PRINTING, ++ g_warning ("CUPS Backend: Can not connect to %s: %s\n", ++ data->address, ++ error->message)); ++ g_error_free (error); ++ } + + g_free (data->printer_uri); + g_free (data->location); +- g_free (data->host); ++ g_free (data->address); ++ g_free (data->hostname); + g_free (data->printer_name); + g_free (data->name); + g_free (data->resource_path); + g_free (data->type); + g_free (data->domain); ++ g_free (data->device_uri); + g_free (data); + } + +@@ -3091,17 +3239,17 @@ avahi_service_resolver_cb (GObject *source_object, + AvahiConnectionTestData *data; + GtkPrintBackendCups *backend; + const gchar *name; +- const gchar *host; ++ const gchar *hostname; + const gchar *type; + const gchar *domain; + const gchar *address; +- const gchar *protocol_string; + GVariant *output; + GVariant *txt; + GVariant *child; + guint32 flags; + guint16 port; + GError *error = NULL; ++ GList *iter; + gchar *tmp; + gchar *printer_name; + gchar **printer_name_strv; +@@ -3128,7 +3276,7 @@ avahi_service_resolver_cb (GObject *source_object, + &name, + &type, + &domain, +- &host, ++ &hostname, + &aprotocol, + &address, + &port, +@@ -3193,51 +3341,50 @@ avahi_service_resolver_cb (GObject *source_object, + + if (data->resource_path != NULL) + { +- if (data->got_printer_type && +- (g_str_has_prefix (data->resource_path, "printers/") || +- g_str_has_prefix (data->resource_path, "classes/"))) ++ /* ++ * Create name of temporary queue from the name of the discovered service. ++ * This emulates the way how CUPS creates the name. ++ */ ++ printer_name = g_strdup_printf ("%s", name); ++ g_strcanon (printer_name, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", '_'); ++ ++ printer_name_strv = g_strsplit_set (printer_name, "_", -1); ++ printer_name_compressed_strv = g_new0 (gchar *, g_strv_length (printer_name_strv) + 1); ++ for (i = 0, j = 0; printer_name_strv[i] != NULL; i++) + { +- /* This is a CUPS printer advertised via Avahi */ +- printer_name = g_strrstr (data->resource_path, "/"); +- if (printer_name != NULL && printer_name[0] != '\0') +- data->printer_name = g_strdup (printer_name + 1); +- else +- data->printer_name = g_strdup (data->resource_path); +- } +- else +- { +- printer_name = g_strdup (name); +- g_strcanon (printer_name, PRINTER_NAME_ALLOWED_CHARACTERS, '-'); +- +- printer_name_strv = g_strsplit_set (printer_name, "-", -1); +- printer_name_compressed_strv = g_new0 (gchar *, g_strv_length (printer_name_strv) + 1); +- for (i = 0, j = 0; printer_name_strv[i] != NULL; i++) ++ if (printer_name_strv[i][0] != '\0') + { +- if (printer_name_strv[i][0] != '\0') +- { +- printer_name_compressed_strv[j] = printer_name_strv[i]; +- j++; +- } ++ printer_name_compressed_strv[j] = printer_name_strv[i]; ++ j++; + } ++ } ++ ++ data->printer_name = g_strjoinv ("_", printer_name_compressed_strv); + +- data->printer_name = g_strjoinv ("-", printer_name_compressed_strv); ++ g_strfreev (printer_name_strv); ++ g_free (printer_name_compressed_strv); ++ g_free (printer_name); + +- g_strfreev (printer_name_strv); +- g_free (printer_name_compressed_strv); +- g_free (printer_name); ++ iter = g_list_find_custom (backend->temporary_queues_removed, data->printer_name, (GCompareFunc) g_strcmp0); ++ if (iter != NULL) ++ { ++ g_free (iter->data); ++ backend->temporary_queues_removed = g_list_delete_link (backend->temporary_queues_removed, iter); + } + + if (g_strcmp0 (type, "_ipp._tcp") == 0) +- protocol_string = "ipp"; +- else +- protocol_string = "ipps"; +- +- if (aprotocol == AVAHI_PROTO_INET6) +- data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, address, port, data->resource_path); ++ { ++ data->printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", data->printer_name); ++ data->device_uri = g_strdup_printf ("ipp://%s:%d/%s", hostname, port, data->resource_path); ++ } + else +- data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, address, port, data->resource_path); ++ { ++ data->printer_uri = g_strdup_printf ("ipps://localhost/printers/%s", data->printer_name); ++ data->device_uri = g_strdup_printf ("ipps://%s:%d/%s", hostname, port, data->resource_path); ++ } + +- data->host = g_strdup (address); ++ data->address = g_strdup (address); ++ data->hostname = g_strdup (hostname); + data->port = port; + + data->name = g_strdup (name); +@@ -3351,6 +3498,9 @@ avahi_service_browser_signal_handler (GDBusConnection *connection, + backend->avahi_default_printer) == 0) + g_clear_pointer (&backend->avahi_default_printer, g_free); + ++ backend->temporary_queues_removed = g_list_prepend (backend->temporary_queues_removed, ++ g_strdup (gtk_printer_get_name (GTK_PRINTER (printer)))); ++ + g_signal_emit_by_name (backend, "printer-removed", printer); + gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend), + GTK_PRINTER (printer)); +@@ -3463,7 +3613,6 @@ avahi_create_browsers (GObject *source_object, + avahi_service_browser_signal_handler, + cups_backend, + NULL); +- + /* + * Create service browsers for _ipp._tcp and _ipps._tcp services. + */ +@@ -3591,6 +3740,12 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, + continue; + } + ++ /* Do not show printer for queue which was removed from Avahi. */ ++ iter = g_list_find_custom (GTK_PRINT_BACKEND_CUPS (backend)->temporary_queues_removed, ++ info->printer_name, (GCompareFunc) g_strcmp0); ++ if (iter != NULL) ++ continue; ++ + if (info->got_printer_type) + { + if (info->default_printer && !cups_backend->got_default_printer) +@@ -3626,7 +3781,24 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, + printer = cups_create_printer (cups_backend, info); + list_has_changed = TRUE; + } +- ++ else if (GTK_PRINTER_CUPS (printer)->avahi_browsed && info->is_temporary) ++ { ++ /* ++ * A temporary queue was created for a printer found via Avahi. ++ * We modify the placeholder GtkPrinter to point to the temporary queue ++ * instead of removing the placeholder GtkPrinter and creating new GtkPrinter. ++ */ ++ ++ g_object_ref (printer); ++ ++ GTK_PRINTER_CUPS (printer)->avahi_browsed = FALSE; ++ GTK_PRINTER_CUPS (printer)->is_temporary = TRUE; ++ g_free (GTK_PRINTER_CUPS (printer)->device_uri); ++ GTK_PRINTER_CUPS (printer)->device_uri = g_strdup_printf ("/printers/%s", ++ info->printer_name); ++ gtk_printer_set_has_details (printer, FALSE); ++ cups_printer_request_details (printer); ++ } + else + g_object_ref (printer); + +@@ -3657,6 +3829,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, + GTK_PRINTER_CUPS (printer)->supports_number_up = info->supports_number_up; + GTK_PRINTER_CUPS (printer)->number_of_covers = info->number_of_covers; + GTK_PRINTER_CUPS (printer)->covers = g_strdupv (info->covers); ++ GTK_PRINTER_CUPS (printer)->is_temporary = info->is_temporary; + status_changed = gtk_printer_set_job_count (printer, info->job_count); + status_changed |= gtk_printer_set_location (printer, info->location); + status_changed |= gtk_printer_set_description (printer, +@@ -3979,7 +4152,10 @@ cups_request_ppd (GtkPrinter *printer) + } + else + { +- hostname = cups_printer->hostname; ++ if (cups_printer->is_temporary) ++ hostname = cupsServer (); ++ else ++ hostname = cups_printer->hostname; + port = cups_printer->port; + resource = g_strdup_printf ("/printers/%s.ppd", + gtk_printer_cups_get_ppd_name (GTK_PRINTER_CUPS (printer))); +@@ -4352,8 +4528,16 @@ cups_printer_request_details (GtkPrinter *printer) + GtkPrinterCups *cups_printer; + + cups_printer = GTK_PRINTER_CUPS (printer); +- if (!cups_printer->reading_ppd && +- gtk_printer_cups_get_ppd (cups_printer) == NULL) ++ ++ if (cups_printer->avahi_browsed) ++ { ++ create_temporary_queue (GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)), ++ gtk_printer_get_name (printer), ++ cups_printer->printer_uri, ++ cups_printer->temporary_queue_device_uri); ++ } ++ else if (!cups_printer->reading_ppd && ++ gtk_printer_cups_get_ppd (cups_printer) == NULL) + { + if (cups_printer->remote && !cups_printer->avahi_browsed) + { +diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h +index bdc30ca..c8ad83f 100644 +--- a/modules/printbackends/cups/gtkprintercups.h ++++ b/modules/printbackends/cups/gtkprintercups.h +@@ -56,7 +56,9 @@ struct _GtkPrinterCups + gchar *original_hostname; + gchar *original_resource; + gint original_port; +- gboolean request_original_uri; /* Request PPD from original hostname */ ++ gboolean request_original_uri; /* Request PPD from original hostname */ ++ gboolean is_temporary; /* This printer is temporary queue */ ++ gchar *temporary_queue_device_uri; /* Device uri of temporary queue for this printer */ + + ipp_pstate_t state; + gboolean reading_ppd; diff -Nru gtk+3.0-3.24.24/debian/patches/printing-Show-all-Avahi-advertised-printers.patch gtk+3.0-3.24.24/debian/patches/printing-Show-all-Avahi-advertised-printers.patch --- gtk+3.0-3.24.24/debian/patches/printing-Show-all-Avahi-advertised-printers.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/printing-Show-all-Avahi-advertised-printers.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,84 @@ +From: Marek Kasik +Date: Fri, 5 Feb 2021 18:00:02 +0100 +Subject: printing: Show all Avahi advertised printers + +This commit unsubscribes CUPS backend from a DBus +signal in idle when listening for new items on Avahi. + +Since GDBus emits gathered signals in idle while +checking whether the signal has been unsubscribed +it could happen that a signal was not processed +because it was removed from hash table of +subscribed signals. +This caused the situation where printers advertised +on Avahi were not listed in CUPS backend sometimes. + +We need those signals since this happens when switching +from a general subscription which listens to signals +for all Avahi services to a specific one which listens +to just _ipp._tcp and _ipps._tcp (chicken and egg problem). + +Origin: upstream, 3.24.25, commit:de3e97309f91fc631a1a4b5ab48cd69dd1421ed5 +--- + modules/printbackends/cups/gtkprintbackendcups.c | 27 +++++++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c +index b1ee058..6b8c9e0 100644 +--- a/modules/printbackends/cups/gtkprintbackendcups.c ++++ b/modules/printbackends/cups/gtkprintbackendcups.c +@@ -150,6 +150,7 @@ struct _GtkPrintBackendCups + guint avahi_service_browser_subscription_ids[2]; + char *avahi_service_browser_paths[2]; + GCancellable *avahi_cancellable; ++ guint unsubscribe_general_subscription_id; + + gboolean secrets_service_available; + guint secrets_service_watch_id; +@@ -1009,6 +1010,12 @@ gtk_print_backend_cups_dispose (GObject *object) + backend_cups->avahi_service_browser_subscription_id = 0; + } + ++ if (backend_cups->unsubscribe_general_subscription_id > 0) ++ { ++ g_source_remove (backend_cups->unsubscribe_general_subscription_id); ++ backend_cups->unsubscribe_general_subscription_id = 0; ++ } ++ + backend_parent_class->dispose (object); + } + +@@ -3514,6 +3521,19 @@ avahi_service_browser_signal_handler (GDBusConnection *connection, + } + } + ++static gboolean ++unsubscribe_general_subscription_cb (gpointer user_data) ++{ ++ GtkPrintBackendCups *cups_backend = user_data; ++ ++ g_dbus_connection_signal_unsubscribe (cups_backend->dbus_connection, ++ cups_backend->avahi_service_browser_subscription_id); ++ cups_backend->avahi_service_browser_subscription_id = 0; ++ cups_backend->unsubscribe_general_subscription_id = 0; ++ ++ return G_SOURCE_REMOVE; ++} ++ + static void + avahi_service_browser_new_cb (GObject *source_object, + GAsyncResult *res, +@@ -3555,9 +3575,10 @@ avahi_service_browser_new_cb (GObject *source_object, + cups_backend->avahi_service_browser_paths[1] && + cups_backend->avahi_service_browser_subscription_id > 0) + { +- g_dbus_connection_signal_unsubscribe (cups_backend->dbus_connection, +- cups_backend->avahi_service_browser_subscription_id); +- cups_backend->avahi_service_browser_subscription_id = 0; ++ /* We need to unsubscribe in idle since signals in queue destined for emit ++ * are emitted in idle and check whether the subscriber is still subscribed. ++ */ ++ cups_backend->unsubscribe_general_subscription_id = g_idle_add (unsubscribe_general_subscription_cb, cups_backend); + } + + g_variant_unref (output); diff -Nru gtk+3.0-3.24.24/debian/patches/searchenginemodel-finalize-search-results.patch gtk+3.0-3.24.24/debian/patches/searchenginemodel-finalize-search-results.patch --- gtk+3.0-3.24.24/debian/patches/searchenginemodel-finalize-search-results.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/searchenginemodel-finalize-search-results.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,43 @@ +From: Pierre Ossman +Date: Mon, 4 Oct 2021 09:23:39 +0200 +Subject: searchenginemodel: finalize search results + +It is necessary to signal the search engine that we are finished and +that we found something for it to reliably show the results. It would +sometimes work anyway since it is sufficient if any backend signals +completion. However if GtkSearchEngineModel was the only backend +returning results then things would break. + +Origin: upstream, 3.24.31, commit:aca83684ed4c62210958b3dd2596a0f35404d215 +Bug-Debian: https://bugs.debian.org/976334 +--- + gtk/gtksearchenginemodel.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gtk/gtksearchenginemodel.c b/gtk/gtksearchenginemodel.c +index dae99f2..8f2ca0c 100644 +--- a/gtk/gtksearchenginemodel.c ++++ b/gtk/gtksearchenginemodel.c +@@ -84,6 +84,7 @@ do_search (gpointer data) + GtkSearchEngineModel *model = data; + GtkTreeIter iter; + GList *hits = NULL; ++ gboolean got_results = FALSE; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model->model), &iter)) + { +@@ -110,11 +111,14 @@ do_search (gpointer data) + { + _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (model), hits); + g_list_free_full (hits, (GDestroyNotify)_gtk_search_hit_free); ++ got_results = TRUE; + } + } + + model->idle = 0; + ++ _gtk_search_engine_finished (GTK_SEARCH_ENGINE (model), got_results); ++ + return G_SOURCE_REMOVE; + } + diff -Nru gtk+3.0-3.24.24/debian/patches/series gtk+3.0-3.24.24/debian/patches/series --- gtk+3.0-3.24.24/debian/patches/series 2021-05-02 11:34:12.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/series 2022-03-10 10:30:09.000000000 +0000 @@ -20,3 +20,9 @@ 060_ignore-random-icons.patch reftest-known-fail.patch Disable-accessibility-dump-aka-a11ytests-test.patch +searchenginemodel-finalize-search-results.patch +wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch +printing-Create-temporary-queues-for-Avahi-printers.patch +printing-Show-all-Avahi-advertised-printers.patch +Don-t-try-to-create-local-cups-printers-before-CUPS-2.2.patch +debian/cups-Use-the-same-name-mangling-as-Debian-11-s-cups-brows.patch diff -Nru gtk+3.0-3.24.24/debian/patches/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch gtk+3.0-3.24.24/debian/patches/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch --- gtk+3.0-3.24.24/debian/patches/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch 1970-01-01 00:00:00.000000000 +0000 +++ gtk+3.0-3.24.24/debian/patches/wayland-Ensure-clipboard-handling-doesn-t-lock-up-in-cert.patch 2022-03-10 10:30:09.000000000 +0000 @@ -0,0 +1,132 @@ +From: msizanoen1 +Date: Fri, 8 Oct 2021 07:08:24 +0700 +Subject: wayland: Ensure clipboard handling doesn't lock up in certain corner + cases + +When a selection request fails to be converted to the requested format in the +GTK layers, the wayland backend would miss bumping the machinery to handle +further pending selection requests. Fix this by reacting to +GdkDisplay::send_selection_notify with target=GDK_NONE (i.e. a failed +conversion as hinted from the upper layers) to do that. + +This ensures the clipboard handling doesn't lock up in the following +scenarios: + - GTK returned with a mismatching type to the one requested + - GTK fails to convert to the requested type + +Bug: https://gitlab.gnome.org/GNOME/gtk/-/issues/4340 +Bug-Debian: https://bugs.debian.org/1006281 +Origin: upstream, 3.24.31, commit:e23b4dd21b41329a804fadf6a89c79be17dffcdf +--- + gdk/wayland/gdkselection-wayland.c | 48 +++++++++++++++++++++++--------------- + 1 file changed, 29 insertions(+), 19 deletions(-) + +diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c +index f85f595..d7f3332 100644 +--- a/gdk/wayland/gdkselection-wayland.c ++++ b/gdk/wayland/gdkselection-wayland.c +@@ -100,7 +100,7 @@ struct _GdkWaylandSelection + + /* Source-side data */ + GPtrArray *stored_selections; /* Array of StoredSelection */ +- GdkAtom current_request_selection; ++ StoredSelection *current_request_selection; + GArray *source_targets; + GdkAtom requested_target; + +@@ -858,7 +858,12 @@ gdk_wayland_selection_reset_selection (GdkWaylandSelection *wayland_selection, + stored_selection = g_ptr_array_index (wayland_selection->stored_selections, i); + + if (stored_selection->selection_atom == selection) +- g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i); ++ { ++ if (wayland_selection->current_request_selection == stored_selection) ++ wayland_selection->current_request_selection = NULL; ++ ++ g_ptr_array_remove_index_fast (wayland_selection->stored_selections, i); ++ } + else + i++; + } +@@ -877,21 +882,10 @@ gdk_wayland_selection_store (GdkWindow *window, + + if (type == gdk_atom_intern_static_string ("NULL")) + return; +- if (selection->current_request_selection == GDK_NONE) ++ if (!selection->current_request_selection) + return; + +- stored_selection = +- gdk_wayland_selection_find_stored_selection (selection, window, +- selection->current_request_selection, +- type); +- +- if (!stored_selection) +- { +- stored_selection = stored_selection_new (selection, window, +- selection->current_request_selection, +- type); +- g_ptr_array_add (selection->stored_selections, stored_selection); +- } ++ stored_selection = selection->current_request_selection; + + if ((mode == GDK_PROP_MODE_PREPEND || + mode == GDK_PROP_MODE_REPLACE) && +@@ -915,7 +909,7 @@ gdk_wayland_selection_store (GdkWindow *window, + } + + /* Handle the next GDK_SELECTION_REQUEST / store, if any */ +- selection->current_request_selection = GDK_NONE; ++ selection->current_request_selection = NULL; + gdk_wayland_selection_handle_next_request (selection); + } + +@@ -979,7 +973,7 @@ gdk_wayland_selection_handle_next_request (GdkWaylandSelection *wayland_selectio + gdk_wayland_selection_emit_request (stored_selection->source, + stored_selection->selection_atom, + stored_selection->type); +- wayland_selection->current_request_selection = stored_selection->selection_atom; ++ wayland_selection->current_request_selection = stored_selection; + break; + } + } +@@ -1023,7 +1017,7 @@ gdk_wayland_selection_request_target (GdkWaylandSelection *wayland_selection, + + write_data = async_write_data_new (stored_selection, fd); + +- if (wayland_selection->current_request_selection == GDK_NONE) ++ if (!wayland_selection->current_request_selection) + gdk_wayland_selection_handle_next_request (wayland_selection); + + return TRUE; +@@ -1435,13 +1429,29 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display, + } + + void +-_gdk_wayland_display_send_selection_notify (GdkDisplay *dispay, ++_gdk_wayland_display_send_selection_notify (GdkDisplay *display, + GdkWindow *requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) + { ++ GdkWaylandSelection *wayland_selection; ++ ++ if (property != GDK_NONE) ++ return; ++ ++ wayland_selection = gdk_wayland_display_get_selection (display); ++ ++ if (!wayland_selection->current_request_selection) ++ return; ++ ++ g_ptr_array_remove_fast (wayland_selection->stored_selections, ++ wayland_selection->current_request_selection); ++ ++ /* Handle the next GDK_SELECTION_REQUEST / store, if any */ ++ wayland_selection->current_request_selection = NULL; ++ gdk_wayland_selection_handle_next_request (wayland_selection); + } + + gint