diff --git a/SOURCES/printers-Update-entries.patch b/SOURCES/printers-Update-entries.patch new file mode 100644 index 0000000..042f5b9 --- /dev/null +++ b/SOURCES/printers-Update-entries.patch @@ -0,0 +1,531 @@ +--- gnome-control-center-3.28.2/panels/printers/cc-printers-panel.c ++++ gnome-control-center-3.28.2/panels/printers/cc-printers-panel.c +@@ -105,6 +105,8 @@ struct _CcPrintersPanelPrivate + gchar *renamed_printer_name; + gchar *old_printer_name; + gchar *deleted_printer_name; ++ GList *deleted_printers; ++ GObject *reference; + + GHashTable *printer_entries; + gboolean entries_filled; +@@ -267,18 +269,40 @@ printer_removed_cb (GObject *source + GAsyncResult *result, + gpointer user_data) + { +- GError *error = NULL; ++ PpPrinter *printer = PP_PRINTER (source_object); ++ g_autoptr(GError) error = NULL; ++ g_autofree gchar *printer_name = NULL; + +- pp_printer_delete_finish (PP_PRINTER (source_object), result, &error); +- g_object_unref (source_object); ++ g_object_get (printer, "printer-name", &printer_name, NULL); ++ pp_printer_delete_finish (printer, result, &error); + +- if (error != NULL) ++ if (user_data != NULL) + { +- g_warning ("Printer could not be deleted: %s", error->message); +- g_error_free (error); ++ g_autoptr(GObject) reference = G_OBJECT (user_data); ++ ++ if (g_object_get_data (reference, "self") != NULL) ++ { ++ CcPrintersPanel *self = CC_PRINTERS_PANEL (g_object_get_data (reference, "self")); ++ CcPrintersPanelPrivate *priv = self->priv; ++ GList *iter; ++ ++ for (iter = priv->deleted_printers; iter != NULL; iter = iter->next) ++ { ++ if (g_strcmp0 (iter->data, printer_name) == 0) ++ { ++ g_free (iter->data); ++ priv->deleted_printers = g_list_delete_link (priv->deleted_printers, iter); ++ break; ++ } ++ } ++ } + } ++ ++ if (error != NULL) ++ g_warning ("Printer could not be deleted: %s", error->message); + } + ++ + static void + cc_printers_panel_dispose (GObject *object) + { +@@ -368,6 +392,12 @@ cc_printers_panel_dispose (GObject *obje + + g_clear_pointer (&priv->printer_entries, g_hash_table_destroy); + ++ g_list_free_full (priv->deleted_printers, g_free); ++ priv->deleted_printers = NULL; ++ if (priv->reference != NULL) ++ g_object_set_data (priv->reference, "self", NULL); ++ g_clear_object (&priv->reference); ++ + G_OBJECT_CLASS (cc_printers_panel_parent_class)->dispose (object); + } + +@@ -793,8 +823,7 @@ on_printer_deleted (PpPrinterEntry *prin + GtkLabel *label; + gchar *notification_message; + gchar *printer_name; +- +- gtk_widget_hide (GTK_WIDGET (printer_entry)); ++ GtkWidget *widget; + + priv = PRINTERS_PANEL_PRIVATE (self); + +@@ -816,6 +845,9 @@ on_printer_deleted (PpPrinterEntry *prin + priv->deleted_printer_name = g_strdup (printer_name); + g_free (printer_name); + ++ widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content"); ++ gtk_list_box_invalidate_filter (GTK_LIST_BOX (widget)); ++ + gtk_revealer_set_reveal_child (priv->notification, TRUE); + + priv->remove_printer_timeout_id = g_timeout_add_seconds (10, on_remove_printer_timeout, self); +@@ -910,6 +942,36 @@ set_current_page (GObject *source_o + } + + static void ++destroy_nonexisting_entries (PpPrinterEntry *entry, ++ gpointer user_data) ++{ ++ CcPrintersPanelPrivate *priv; ++ CcPrintersPanel *self = (CcPrintersPanel *) user_data; ++ g_autofree gchar *printer_name = NULL; ++ gboolean exists = FALSE; ++ gint i; ++ ++ priv = PRINTERS_PANEL_PRIVATE (self); ++ ++ g_object_get (G_OBJECT (entry), "printer-name", &printer_name, NULL); ++ ++ for (i = 0; i < priv->num_dests; i++) ++ { ++ if (g_strcmp0 (priv->dests[i].name, printer_name) == 0) ++ { ++ exists = TRUE; ++ break; ++ } ++ } ++ ++ if (!exists) ++ { ++ gtk_widget_destroy (GTK_WIDGET (entry)); ++ g_hash_table_remove (priv->printer_entries, printer_name); ++ } ++} ++ ++static void + actualize_printers_list_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +@@ -920,6 +982,7 @@ actualize_printers_list_cb (GObject + PpCups *cups = PP_CUPS (source_object); + PpCupsDests *cups_dests; + gboolean new_printer_available = FALSE; ++ gpointer item; + GError *error = NULL; + int i; + +@@ -950,7 +1013,7 @@ actualize_printers_list_cb (GObject + gtk_stack_set_visible_child_name (GTK_STACK (widget), "printers-list"); + + widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content"); +- gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_destroy, NULL); ++ gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) destroy_nonexisting_entries, self); + + for (i = 0; i < priv->num_dests; i++) + { +@@ -961,13 +1024,14 @@ actualize_printers_list_cb (GObject + + for (i = 0; i < priv->num_dests; i++) + { +- if (g_strcmp0 (priv->dests[i].name, priv->deleted_printer_name) == 0) +- continue; +- + if (new_printer_available && g_strcmp0 (priv->dests[i].name, priv->old_printer_name) == 0) + continue; + +- add_printer_entry (self, priv->dests[i]); ++ item = g_hash_table_lookup (priv->printer_entries, priv->dests[i].name); ++ if (item != NULL) ++ pp_printer_entry_update (PP_PRINTER_ENTRY (item), priv->dests[i], priv->is_authorized); ++ else ++ add_printer_entry (self, priv->dests[i]); + } + + if (!priv->entries_filled) +@@ -983,6 +1047,30 @@ actualize_printers_list_cb (GObject + } + + update_sensitivity (user_data); ++ ++ if (priv->new_printer_name != NULL) ++ { ++ GtkScrolledWindow *scrolled_window; ++ GtkAllocation allocation; ++ GtkAdjustment *adjustment; ++ GtkWidget *printer_entry; ++ ++ /* Scroll the view to show the newly added printer-entry. */ ++ scrolled_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (priv->builder, ++ "scrolled-window")); ++ adjustment = gtk_scrolled_window_get_vadjustment (scrolled_window); ++ ++ printer_entry = GTK_WIDGET (g_hash_table_lookup (priv->printer_entries, ++ priv->new_printer_name)); ++ if (printer_entry != NULL) ++ { ++ gtk_widget_get_allocation (printer_entry, &allocation); ++ g_clear_pointer (&priv->new_printer_name, g_free); ++ ++ gtk_adjustment_set_value (adjustment, ++ allocation.y - gtk_widget_get_margin_top (printer_entry)); ++ } ++ } + } + + static void +@@ -1028,10 +1116,6 @@ new_printer_dialog_response_cb (PpNewPri + { + CcPrintersPanelPrivate *priv; + CcPrintersPanel *self = (CcPrintersPanel*) user_data; +- GtkScrolledWindow *scrolled_window; +- GtkAllocation allocation; +- GtkAdjustment *adjustment; +- GtkWidget *printer_entry; + + priv = PRINTERS_PANEL_PRIVATE (self); + +@@ -1059,22 +1143,6 @@ new_printer_dialog_response_cb (PpNewPri + } + + actualize_printers_list (self); +- +- if (priv->new_printer_name == NULL) +- return; +- +- /* Scroll the view to show the newly added printer-entry. */ +- scrolled_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (priv->builder, +- "scrolled-window")); +- adjustment = gtk_scrolled_window_get_vadjustment (scrolled_window); +- +- printer_entry = GTK_WIDGET (g_hash_table_lookup (priv->printer_entries, +- priv->new_printer_name)); +- gtk_widget_get_allocation (printer_entry, &allocation); +- g_clear_pointer (&priv->new_printer_name, g_free); +- +- gtk_adjustment_set_value (adjustment, +- allocation.y - gtk_widget_get_margin_top (printer_entry)); + } + + static void +@@ -1288,11 +1356,17 @@ filter_function (GtkListBoxRow *row, + CcPrintersPanel *self = (CcPrintersPanel*) user_data; + GtkWidget *search_entry; + gboolean retval; +- gchar *search; +- gchar *name; +- gchar *location; +- gchar *printer_name; +- gchar *printer_location; ++ g_autofree gchar *search = NULL; ++ g_autofree gchar *name = NULL; ++ g_autofree gchar *location = NULL; ++ g_autofree gchar *printer_name = NULL; ++ g_autofree gchar *printer_location = NULL; ++ GList *iter; ++ ++ g_object_get (G_OBJECT (row), ++ "printer-name", &printer_name, ++ "printer-location", &printer_location, ++ NULL); + + priv = PRINTERS_PANEL_PRIVATE (self); + +@@ -1300,31 +1374,72 @@ filter_function (GtkListBoxRow *row, + gtk_builder_get_object (priv->builder, "search-entry"); + + if (gtk_entry_get_text_length (GTK_ENTRY (search_entry)) == 0) +- return TRUE; ++ { ++ retval = TRUE; ++ } ++ else ++ { ++ name = cc_util_normalize_casefold_and_unaccent (printer_name); ++ location = cc_util_normalize_casefold_and_unaccent (printer_location); + +- g_object_get (G_OBJECT (row), +- "printer-name", &printer_name, +- "printer-location", &printer_location, +- NULL); ++ search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (search_entry))); + +- name = cc_util_normalize_casefold_and_unaccent (printer_name); +- location = cc_util_normalize_casefold_and_unaccent (printer_location); ++ retval = strstr (name, search) != NULL; ++ if (location != NULL) ++ retval = retval || (strstr (location, search) != NULL); ++ } + +- g_free (printer_name); +- g_free (printer_location); ++ if (priv->deleted_printer_name != NULL && ++ g_strcmp0 (priv->deleted_printer_name, printer_name) == 0) ++ { ++ retval = FALSE; ++ } + +- search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (search_entry))); ++ if (priv->deleted_printers != NULL) ++ { ++ for (iter = priv->deleted_printers; iter != NULL; iter = iter->next) ++ { ++ if (g_strcmp0 (iter->data, printer_name) == 0) ++ { ++ retval = FALSE; ++ break; ++ } ++ } ++ } + ++ return retval; ++} + +- retval = strstr (name, search) != NULL; +- if (location != NULL) +- retval = retval || (strstr (location, search) != NULL); ++static gint ++sort_function (GtkListBoxRow *row1, ++ GtkListBoxRow *row2, ++ gpointer user_data) ++{ ++ g_autofree gchar *printer_name1 = NULL; ++ g_autofree gchar *printer_name2 = NULL; + +- g_free (search); +- g_free (name); +- g_free (location); ++ g_object_get (G_OBJECT (row1), ++ "printer-name", &printer_name1, ++ NULL); + +- return retval; ++ g_object_get (G_OBJECT (row2), ++ "printer-name", &printer_name2, ++ NULL); ++ ++ if (printer_name1 != NULL) ++ { ++ if (printer_name2 != NULL) ++ return g_ascii_strcasecmp (printer_name1, printer_name2); ++ else ++ return 1; ++ } ++ else ++ { ++ if (printer_name2 != NULL) ++ return -1; ++ else ++ return 0; ++ } + } + + static void +@@ -1364,6 +1479,8 @@ cc_printers_panel_init (CcPrintersPanel + priv->renamed_printer_name = NULL; + priv->old_printer_name = NULL; + priv->deleted_printer_name = NULL; ++ priv->deleted_printers = NULL; ++ priv->reference = g_object_new (G_TYPE_OBJECT, NULL); + + priv->permission = NULL; + priv->lockdown_settings = NULL; +@@ -1380,6 +1497,8 @@ cc_printers_panel_init (CcPrintersPanel + priv->actualize_printers_list_cancellable = g_cancellable_new (); + priv->cups_status_check_cancellable = g_cancellable_new (); + ++ g_object_set_data_full (priv->reference, "self", self, g_free); ++ + builder_result = gtk_builder_add_objects_from_resource (priv->builder, + "/org/gnome/control-center/printers/printers.ui", + objects, &error); +@@ -1430,6 +1549,10 @@ cc_printers_panel_init (CcPrintersPanel + "search-changed", + G_CALLBACK (gtk_list_box_invalidate_filter), + widget); ++ gtk_list_box_set_sort_func (GTK_LIST_BOX (widget), ++ sort_function, ++ NULL, ++ NULL); + + priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); + if (priv->lockdown_settings) +--- gnome-control-center-3.28.2/panels/printers/pp-printer-entry.c ++++ gnome-control-center-3.28.2/panels/printers/pp-printer-entry.c +@@ -45,7 +45,6 @@ struct _PpPrinterEntry + { + GtkListBoxRow parent; + +- gchar *printer_uri; + gchar *printer_name; + gchar *ppd_file_name; + int num_jobs; +@@ -727,11 +726,34 @@ pp_printer_entry_new (cups_dest_t print + gboolean is_authorized) + { + PpPrinterEntry *self; ++ ++ self = g_object_new (PP_PRINTER_ENTRY_TYPE, "printer-name", printer.name, NULL); ++ ++ self->clean_command = pp_maintenance_command_new (self->printer_name, ++ "Clean", ++ "all", ++ /* Translators: Name of job which makes printer to clean its heads */ ++ _("Clean print heads")); ++ check_clean_heads_maintenance_command (self); ++ ++ g_signal_connect_object (self->supply_drawing_area, "draw", G_CALLBACK (supply_levels_draw_cb), self, G_CONNECT_SWAPPED); ++ ++ pp_printer_entry_update (self, printer, is_authorized); ++ ++ return self; ++} ++ ++void ++pp_printer_entry_update (PpPrinterEntry *self, ++ cups_dest_t printer, ++ gboolean is_authorized) ++{ + cups_ptype_t printer_type = 0; +- gboolean is_accepting_jobs; ++ gboolean is_accepting_jobs = TRUE; + gboolean ink_supply_is_empty; + gchar *instance; + gchar *printer_uri = NULL; ++ const gchar *device_uri = NULL; + gchar *location = NULL; + gchar *printer_icon_name = NULL; + gchar *default_icon_name = NULL; +@@ -798,8 +820,6 @@ pp_printer_entry_new (cups_dest_t print + N_("The optical photo conductor is no longer functioning") + }; + +- self = g_object_new (PP_PRINTER_ENTRY_TYPE, "printer-name", printer.name, NULL); +- + self->inklevel = g_slice_new0 (InkLevelData); + + if (printer.instance) +@@ -816,7 +836,7 @@ pp_printer_entry_new (cups_dest_t print + for (i = 0; i < printer.num_options; i++) + { + if (g_strcmp0 (printer.options[i].name, "device-uri") == 0) +- self->printer_uri = printer.options[i].value; ++ device_uri = printer.options[i].value; + else if (g_strcmp0 (printer.options[i].name, "printer-uri-supported") == 0) + printer_uri = printer.options[i].value; + else if (g_strcmp0 (printer.options[i].name, "printer-type") == 0) +@@ -826,13 +846,25 @@ pp_printer_entry_new (cups_dest_t print + else if (g_strcmp0 (printer.options[i].name, "printer-state-reasons") == 0) + reason = printer.options[i].value; + else if (g_strcmp0 (printer.options[i].name, "marker-names") == 0) +- self->inklevel->marker_names = g_strcompress (printer.options[i].value); ++ { ++ g_free (self->inklevel->marker_names); ++ self->inklevel->marker_names = g_strcompress (g_strdup (printer.options[i].value)); ++ } + else if (g_strcmp0 (printer.options[i].name, "marker-levels") == 0) +- self->inklevel->marker_levels = g_strdup (printer.options[i].value); ++ { ++ g_free (self->inklevel->marker_levels); ++ self->inklevel->marker_levels = g_strdup (printer.options[i].value); ++ } + else if (g_strcmp0 (printer.options[i].name, "marker-colors") == 0) +- self->inklevel->marker_colors = g_strdup (printer.options[i].value); ++ { ++ g_free (self->inklevel->marker_colors); ++ self->inklevel->marker_colors = g_strdup (printer.options[i].value); ++ } + else if (g_strcmp0 (printer.options[i].name, "marker-types") == 0) +- self->inklevel->marker_types = g_strdup (printer.options[i].value); ++ { ++ g_free (self->inklevel->marker_types); ++ self->inklevel->marker_types = g_strdup (printer.options[i].value); ++ } + else if (g_strcmp0 (printer.options[i].name, "printer-make-and-model") == 0) + printer_make_and_model = printer.options[i].value; + else if (g_strcmp0 (printer.options[i].name, "printer-state") == 0) +@@ -896,6 +928,11 @@ pp_printer_entry_new (cups_dest_t print + gtk_label_set_label (self->error_status, status); + gtk_widget_set_visible (GTK_WIDGET (self->printer_error), TRUE); + } ++ else ++ { ++ gtk_label_set_label (self->error_status, ""); ++ gtk_widget_set_visible (GTK_WIDGET (self->printer_error), FALSE); ++ } + + switch (self->printer_state) + { +@@ -921,7 +958,7 @@ pp_printer_entry_new (cups_dest_t print + break; + } + +- if (printer_is_local (printer_type, self->printer_uri)) ++ if (printer_is_local (printer_type, device_uri)) + printer_icon_name = g_strdup ("printer"); + else + printer_icon_name = g_strdup ("printer-network"); +@@ -931,14 +968,8 @@ pp_printer_entry_new (cups_dest_t print + self->is_accepting_jobs = is_accepting_jobs; + self->is_authorized = is_authorized; + +- self->printer_hostname = printer_get_hostname (printer_type, self->printer_uri, printer_uri); +- +- self->clean_command = pp_maintenance_command_new (self->printer_name, +- "Clean", +- "all", +- /* Translators: Name of job which makes printer to clean its heads */ +- _("Clean print heads")); +- check_clean_heads_maintenance_command (self); ++ g_free (self->printer_hostname); ++ self->printer_hostname = printer_get_hostname (printer_type, device_uri, printer_uri); + + gtk_image_set_from_icon_name (self->printer_icon, printer_icon_name, GTK_ICON_SIZE_DIALOG); + gtk_label_set_text (self->printer_status, printer_status); +@@ -970,7 +1001,6 @@ pp_printer_entry_new (cups_dest_t print + gtk_label_set_text (self->printer_location_address_label, location); + } + +- g_signal_connect (self->supply_drawing_area, "draw", G_CALLBACK (supply_levels_draw_cb), self); + ink_supply_is_empty = supply_level_is_empty (self); + gtk_widget_set_visible (GTK_WIDGET (self->printer_inklevel_label), !ink_supply_is_empty); + gtk_widget_set_visible (GTK_WIDGET (self->supply_frame), !ink_supply_is_empty); +@@ -983,8 +1013,6 @@ pp_printer_entry_new (cups_dest_t print + g_free (instance); + g_free (printer_icon_name); + g_free (default_icon_name); +- +- return self; + } + + static void +--- gnome-control-center-3.28.2/panels/printers/pp-printer-entry.h ++++ gnome-control-center-3.28.2/panels/printers/pp-printer-entry.h +@@ -42,4 +42,8 @@ void pp_printer_entry_show_jo + + void pp_printer_entry_authenticate_jobs (PpPrinterEntry *self); + ++void pp_printer_entry_update (PpPrinterEntry *self, ++ cups_dest_t printer, ++ gboolean is_authorized); ++ + #endif /* PP_PRINTER_ENTRY_H */ diff --git a/SPECS/gnome-control-center.spec b/SPECS/gnome-control-center.spec index e74253d..a50e6db 100644 --- a/SPECS/gnome-control-center.spec +++ b/SPECS/gnome-control-center.spec @@ -10,7 +10,7 @@ Name: gnome-control-center Version: 3.28.2 -Release: 22%{?dist} +Release: 23%{?dist} Summary: Utilities to configure the GNOME desktop License: GPLv2+ and CC-BY-SA @@ -54,6 +54,8 @@ Patch23: 0001-sound-Ensure-to-preserve-sound-theme-when-changing-f.patch Patch24: categorize-infiniband.patch +Patch25: printers-Update-entries.patch + BuildRequires: chrpath BuildRequires: cups-devel BuildRequires: desktop-file-utils @@ -226,6 +228,10 @@ chrpath --delete $RPM_BUILD_ROOT%{_bindir}/gnome-control-center %dir %{_datadir}/gnome/wm-properties %changelog +* Tue Nov 24 2020 Marek Kasik - 3.28.2-23 +- Update list of printers instead of regenerating it +- Resolves: #1700002 + * Wed Sep 02 2020 Carlos Garnacho - 3.28.2-22 - Categorize Infiniband devices correctly Resolves: #1826379