Fix printer setting preventing from scrolling media size list

Upstream https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/1704
https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/1268

Related: rhbz#2063410
This commit is contained in:
Felipe Borges 2022-04-06 13:05:24 +02:00
parent d264937ac9
commit aa5d787cdc
2 changed files with 590 additions and 0 deletions

View File

@ -29,6 +29,9 @@ Patch1: prettify-info.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2064462
Patch2: 0001-online-accounts-Fix-goa-helper-on-X11.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2063410
Patch3: printers-use-gtkdropdown.patch
BuildRequires: chrpath
BuildRequires: cups-devel
BuildRequires: desktop-file-utils

View File

@ -0,0 +1,587 @@
From 7c5beecc97145962fa844f1d102b5a780ca55f7a Mon Sep 17 00:00:00 2001
From: Brandon Nielsen <nielsenb@jetfuse.net>
Date: Fri, 25 Mar 2022 20:54:47 -0500
Subject: [PATCH] printers: Use a GtkDropDown in PpOptionsDialog
PpPpdOptionWidget and PpIppOptionWidget both use combo boxes for
certain types of selections. With GTK4, combo boxes no longer
support scrolling[0], which in turn causes problems setting some
things in the PpOptionsDialog[1].
This replaces instances of GtkComboBox with GtkDropDown which do
support scrolling. This change was applied to both PpIppOptionWidget
and PpPpdOptionWidget as both are used in PpOptions dialog.
Since the configuration values passed to CUPS can no longer be stored
in a GtkTreeModel alongside the displayed values, some logic changes
to update_widget_real in PpPpdOptionWidget to maintain the reference
to the ppd_option_t so the selected index can be mapped to the
configuration value.
[0] - https://gitlab.gnome.org/GNOME/gtk/-/issues/3674
[1] - https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/1704
---
panels/printers/pp-ipp-option-widget.c | 165 ++++++++++--------------
panels/printers/pp-ppd-option-widget.c | 167 +++++++++----------------
2 files changed, 125 insertions(+), 207 deletions(-)
diff --git a/panels/printers/pp-ipp-option-widget.c b/panels/printers/pp-ipp-option-widget.c
index 8ab7ea06f..ea27ad737 100644
--- a/panels/printers/pp-ipp-option-widget.c
+++ b/panels/printers/pp-ipp-option-widget.c
@@ -40,7 +40,7 @@ struct _PpIPPOptionWidget
GtkWidget *switch_button;
GtkWidget *spin_button;
- GtkWidget *combo;
+ GtkWidget *dropdown;
IPPAttribute *option_supported;
IPPAttribute *option_default;
@@ -85,8 +85,10 @@ ipp_choice_translate (const gchar *option,
for (i = 0; i < G_N_ELEMENTS (ipp_choice_translations); i++)
{
if (g_strcmp0 (ipp_choice_translations[i].keyword, option) == 0 &&
- g_strcmp0 (ipp_choice_translations[i].choice, choice) == 0)
- return _(ipp_choice_translations[i].translation);
+ g_strcmp0 (ipp_choice_translations[i].choice, choice) == 0)
+ {
+ return _(ipp_choice_translations[i].translation);
+ }
}
return choice;
@@ -158,101 +160,68 @@ pp_ipp_option_widget_new (IPPAttribute *attr_supported,
return (GtkWidget *) self;
}
-enum {
- NAME_COLUMN,
- VALUE_COLUMN,
- N_COLUMNS
-};
-
static GtkWidget *
-combo_box_new (void)
+dropdown_new (void)
{
- GtkCellRenderer *cell;
- g_autoptr(GtkListStore) store = NULL;
- GtkWidget *combo_box;
-
- combo_box = gtk_combo_box_new ();
+ GtkStringList *store = NULL;
+ GtkWidget *dropdown;
- store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
- gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+ store = gtk_string_list_new (NULL);
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
- "text", NAME_COLUMN,
- NULL);
+ dropdown = gtk_drop_down_new (G_LIST_MODEL (store), NULL);
- return combo_box;
+ return dropdown;
}
static void
-combo_box_append (GtkWidget *combo,
- const gchar *display_text,
- const gchar *value)
+dropdown_append (GtkWidget *dropdown,
+ const gchar *display_text)
{
- GtkTreeModel *model;
- GtkListStore *store;
- GtkTreeIter iter;
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
- store = GTK_LIST_STORE (model);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- NAME_COLUMN, display_text,
- VALUE_COLUMN, value,
- -1);
-}
+ GtkStringList *store;
-struct ComboSet {
- GtkComboBox *combo;
- const gchar *value;
-};
+ store = GTK_STRING_LIST (gtk_drop_down_get_model (GTK_DROP_DOWN (dropdown)));
-static gboolean
-set_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- struct ComboSet *set_data = data;
- g_autofree gchar *value = NULL;
-
- gtk_tree_model_get (model, iter, VALUE_COLUMN, &value, -1);
- if (strcmp (value, set_data->value) == 0)
- {
- gtk_combo_box_set_active_iter (set_data->combo, iter);
- return TRUE;
- }
-
- return FALSE;
+ gtk_string_list_append (store, display_text);
}
static void
-combo_box_set (GtkWidget *combo,
- const gchar *value)
+dropdown_set (GtkWidget *dropdown,
+ IPPAttribute *option,
+ const gchar *value)
{
- struct ComboSet set_data;
- GtkTreeModel *model;
+ g_autofree gchar *attribute_value = NULL;
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+ for (guint i = 0; i < option->num_of_values; i++)
+ {
+ if (option->attribute_type == IPP_ATTRIBUTE_TYPE_INTEGER)
+ attribute_value = g_strdup_printf ("%d", option->attribute_values[i].integer_value);
+ else
+ attribute_value = g_strdup (option->attribute_values[i].string_value);
- set_data.combo = GTK_COMBO_BOX (combo);
- set_data.value = value;
- gtk_tree_model_foreach (model, set_cb, &set_data);
+ if (g_strcmp0 (attribute_value, value) == 0)
+ {
+ gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), i);
+ break;
+ }
+ }
}
static char *
-combo_box_get (GtkWidget *combo)
+dropdown_get (GtkWidget *dropdown,
+ IPPAttribute *option)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *value = NULL;
+ guint selected_item;
+ gchar *value = NULL;
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+ selected_item = gtk_drop_down_get_selected (GTK_DROP_DOWN (dropdown));
- if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
- gtk_tree_model_get (model, &iter, VALUE_COLUMN, &value, -1);
+ if (selected_item != GTK_INVALID_LIST_POSITION)
+ {
+ if (option->attribute_type == IPP_ATTRIBUTE_TYPE_INTEGER)
+ value = g_strdup_printf ("%d", option->attribute_values[selected_item].integer_value);
+ else
+ value = option->attribute_values[selected_item].string_value;
+ }
return value;
}
@@ -295,12 +264,12 @@ switch_changed_cb (PpIPPOptionWidget *self)
}
static void
-combo_changed_cb (PpIPPOptionWidget *self)
+dropdown_changed_cb (PpIPPOptionWidget *self)
{
gchar **values;
values = g_new0 (gchar *, 2);
- values[0] = combo_box_get (self->combo);
+ values[0] = g_strdup (dropdown_get (self->dropdown, self->option_supported));
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
@@ -380,34 +349,32 @@ construct_widget (PpIPPOptionWidget *self)
break;
case IPP_ATTRIBUTE_TYPE_INTEGER:
- self->combo = combo_box_new ();
+ self->dropdown = dropdown_new ();
for (i = 0; i < self->option_supported->num_of_values; i++)
{
g_autofree gchar *value = NULL;
value = g_strdup_printf ("%d", self->option_supported->attribute_values[i].integer_value);
- combo_box_append (self->combo,
- ipp_choice_translate (self->option_name,
- value),
- value);
+ dropdown_append (self->dropdown,
+ ipp_choice_translate (self->option_name,
+ value));
}
- gtk_box_append (GTK_BOX (self), self->combo);
- g_signal_connect_object (self->combo, "changed", G_CALLBACK (combo_changed_cb), self, G_CONNECT_SWAPPED);
+ gtk_box_append (GTK_BOX (self), self->dropdown);
+ g_signal_connect_object (self->dropdown, "notify::selected", G_CALLBACK (dropdown_changed_cb), self, G_CONNECT_SWAPPED);
break;
case IPP_ATTRIBUTE_TYPE_STRING:
- self->combo = combo_box_new ();
+ self->dropdown = dropdown_new ();
for (i = 0; i < self->option_supported->num_of_values; i++)
- combo_box_append (self->combo,
- ipp_choice_translate (self->option_name,
- self->option_supported->attribute_values[i].string_value),
- self->option_supported->attribute_values[i].string_value);
+ dropdown_append (self->dropdown,
+ ipp_choice_translate (self->option_name,
+ self->option_supported->attribute_values[i].string_value));
- gtk_box_append (GTK_BOX (self), self->combo);
- g_signal_connect_object (self->combo, "changed", G_CALLBACK (combo_changed_cb), self, G_CONNECT_SWAPPED);
+ gtk_box_append (GTK_BOX (self), self->dropdown);
+ g_signal_connect_object (self->dropdown, "notify::selected", G_CALLBACK (dropdown_changed_cb), self, G_CONNECT_SWAPPED);
break;
case IPP_ATTRIBUTE_TYPE_RANGE:
@@ -468,37 +435,37 @@ update_widget_real (PpIPPOptionWidget *self)
break;
case IPP_ATTRIBUTE_TYPE_INTEGER:
- g_signal_handlers_block_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_block_by_func (self->dropdown, dropdown_changed_cb, self);
if (attr && attr->num_of_values > 0 &&
attr->attribute_type == IPP_ATTRIBUTE_TYPE_INTEGER)
{
g_autofree gchar *value = g_strdup_printf ("%d", attr->attribute_values[0].integer_value);
- combo_box_set (self->combo, value);
+ dropdown_set (self->dropdown, self->option_supported, value);
}
else
{
g_autofree gchar *value = g_strdup_printf ("%d", self->option_supported->attribute_values[0].integer_value);
- combo_box_set (self->combo, value);
+ dropdown_set (self->dropdown, self->option_supported, value);
}
- g_signal_handlers_unblock_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_unblock_by_func (self->dropdown, dropdown_changed_cb, self);
break;
case IPP_ATTRIBUTE_TYPE_STRING:
- g_signal_handlers_block_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_block_by_func (self->dropdown, dropdown_changed_cb, self);
if (attr && attr->num_of_values > 0 &&
attr->attribute_type == IPP_ATTRIBUTE_TYPE_STRING)
{
- combo_box_set (self->combo, attr->attribute_values[0].string_value);
+ dropdown_set (self->dropdown, self->option_supported, attr->attribute_values[0].string_value);
}
else
{
- combo_box_set (self->combo, self->option_supported->attribute_values[0].string_value);
+ dropdown_set (self->dropdown, self->option_supported, self->option_supported->attribute_values[0].string_value);
}
- g_signal_handlers_unblock_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_unblock_by_func (self->dropdown, dropdown_changed_cb, self);
break;
case IPP_ATTRIBUTE_TYPE_RANGE:
diff --git a/panels/printers/pp-ppd-option-widget.c b/panels/printers/pp-ppd-option-widget.c
index 2f3962090..0375b16cb 100644
--- a/panels/printers/pp-ppd-option-widget.c
+++ b/panels/printers/pp-ppd-option-widget.c
@@ -40,7 +40,7 @@ struct _PpPPDOptionWidget
GtkBox parent_instance;
GtkWidget *switch_button;
- GtkWidget *combo;
+ GtkWidget *dropdown;
GtkWidget *image;
GtkWidget *box;
@@ -180,8 +180,10 @@ ppd_choice_translate (ppd_choice_t *choice)
for (i = 0; i < G_N_ELEMENTS (ppd_choice_translations); i++)
{
if (g_strcmp0 (ppd_choice_translations[i].keyword, keyword) == 0 &&
- g_strcmp0 (ppd_choice_translations[i].choice, choice->choice) == 0)
- return _(ppd_choice_translations[i].translation);
+ g_strcmp0 (ppd_choice_translations[i].choice, choice->choice) == 0)
+ {
+ return _(ppd_choice_translations[i].translation);
+ }
}
return choice->text;
@@ -216,102 +218,58 @@ pp_ppd_option_widget_new (ppd_option_t *option,
return (GtkWidget *) self;
}
-enum {
- NAME_COLUMN,
- VALUE_COLUMN,
- N_COLUMNS
-};
-
static GtkWidget *
-combo_box_new (void)
+dropdown_new (void)
{
- GtkCellRenderer *cell;
- g_autoptr(GtkListStore) store = NULL;
- GtkWidget *combo_box;
+ GtkStringList *store = NULL;
+ GtkWidget *dropdown;
- combo_box = gtk_combo_box_new ();
+ store = gtk_string_list_new (NULL);
- store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
- gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+ dropdown = gtk_drop_down_new (G_LIST_MODEL (store), NULL);
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
- "text", NAME_COLUMN,
- NULL);
-
- return combo_box;
+ return dropdown;
}
static void
-combo_box_append (GtkWidget *combo,
- const gchar *display_text,
- const gchar *value)
-{
- GtkTreeModel *model;
- GtkListStore *store;
- GtkTreeIter iter;
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
- store = GTK_LIST_STORE (model);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- NAME_COLUMN, display_text,
- VALUE_COLUMN, value,
- -1);
-}
-
-struct ComboSet {
- GtkComboBox *combo;
- const gchar *value;
-};
-
-static gboolean
-set_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
+dropdown_append (GtkWidget *dropdown,
+ const gchar *display_text)
{
- struct ComboSet *set_data = data;
- g_autofree gchar *value = NULL;
+ GtkStringList *store;
- gtk_tree_model_get (model, iter, VALUE_COLUMN, &value, -1);
+ store = GTK_STRING_LIST (gtk_drop_down_get_model (GTK_DROP_DOWN (dropdown)));
- if (strcmp (value, set_data->value) == 0)
- {
- gtk_combo_box_set_active_iter (set_data->combo, iter);
- return TRUE;
- }
-
- return FALSE;
+ gtk_string_list_append (store, display_text);
}
static void
-combo_box_set (GtkWidget *combo,
- const gchar *value)
+dropdown_set (GtkWidget *dropdown,
+ ppd_option_t *option,
+ const gchar *value)
{
- struct ComboSet set_data;
- GtkTreeModel *model;
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
-
- set_data.combo = GTK_COMBO_BOX (combo);
- set_data.value = value;
- gtk_tree_model_foreach (model, set_cb, &set_data);
+ for (guint i = 0; i < option->num_choices; i++)
+ {
+ if (g_strcmp0 (option->choices[i].choice, value) == 0)
+ {
+ gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), i);
+ break;
+ }
+ }
}
static char *
-combo_box_get (GtkWidget *combo)
+dropdown_get (GtkWidget *dropdown,
+ ppd_option_t *option)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *value = NULL;
+ guint selected_item;
+ gchar *value = NULL;
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+ selected_item = gtk_drop_down_get_selected (GTK_DROP_DOWN (dropdown));
- if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
- gtk_tree_model_get (model, &iter, VALUE_COLUMN, &value, -1);
+ if (selected_item != GTK_INVALID_LIST_POSITION)
+ {
+ value = option->choices[selected_item].choice;
+ }
return value;
}
@@ -354,12 +312,12 @@ switch_changed_cb (PpPPDOptionWidget *self)
}
static void
-combo_changed_cb (PpPPDOptionWidget *self)
+dropdown_changed_cb (PpPPDOptionWidget *self)
{
gchar **values;
values = g_new0 (gchar *, 2);
- values[0] = combo_box_get (self->combo);
+ values[0] = g_strdup (dropdown_get (self->dropdown, self->option));
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
@@ -394,31 +352,29 @@ construct_widget (PpPPDOptionWidget *self)
break;
case PPD_UI_PICKONE:
- self->combo = combo_box_new ();
+ self->dropdown = dropdown_new ();
for (i = 0; i < self->option->num_choices; i++)
{
- combo_box_append (self->combo,
- ppd_choice_translate (&self->option->choices[i]),
- self->option->choices[i].choice);
+ dropdown_append (self->dropdown,
+ ppd_choice_translate (&self->option->choices[i]));
}
- gtk_box_append (GTK_BOX (self), self->combo);
- g_signal_connect_object (self->combo, "changed", G_CALLBACK (combo_changed_cb), self, G_CONNECT_SWAPPED);
+ gtk_box_append (GTK_BOX (self), self->dropdown);
+ g_signal_connect_object (self->dropdown, "notify::selected", G_CALLBACK (dropdown_changed_cb), self, G_CONNECT_SWAPPED);
break;
case PPD_UI_PICKMANY:
- self->combo = combo_box_new ();
+ self->dropdown = dropdown_new ();
for (i = 0; i < self->option->num_choices; i++)
{
- combo_box_append (self->combo,
- ppd_choice_translate (&self->option->choices[i]),
- self->option->choices[i].choice);
+ dropdown_append (self->dropdown,
+ ppd_choice_translate (&self->option->choices[i]));
}
- gtk_box_append (GTK_BOX (self), self->combo);
- g_signal_connect_object (self->combo, "changed", G_CALLBACK (combo_changed_cb), self, G_CONNECT_SWAPPED);
+ gtk_box_append (GTK_BOX (self), self->dropdown);
+ g_signal_connect_object (self->dropdown, "notify::selected", G_CALLBACK (dropdown_changed_cb), self, G_CONNECT_SWAPPED);
break;
default:
@@ -445,13 +401,7 @@ update_widget_real (PpPPDOptionWidget *self)
ppd_file_t *ppd_file;
gint i;
- if (self->option)
- {
- option = cups_option_copy (self->option);
- cups_option_free (self->option);
- self->option = NULL;
- }
- else if (self->ppd_filename)
+ if (self->ppd_filename_set && self->ppd_filename)
{
ppd_file = ppdOpenFile (self->ppd_filename);
ppdLocalize (ppd_file);
@@ -464,7 +414,8 @@ update_widget_real (PpPPDOptionWidget *self)
{
if (g_str_equal (iter->keyword, self->option_name))
{
- option = cups_option_copy (iter);
+ g_clear_pointer (&self->option, cups_option_free);
+ self->option = cups_option_copy (iter);
break;
}
}
@@ -477,6 +428,8 @@ update_widget_real (PpPPDOptionWidget *self)
self->ppd_filename = NULL;
}
+ option = self->option;
+
if (option)
{
g_autofree gchar *value = NULL;
@@ -502,15 +455,15 @@ update_widget_real (PpPPDOptionWidget *self)
break;
case PPD_UI_PICKONE:
- g_signal_handlers_block_by_func (self->combo, combo_changed_cb, self);
- combo_box_set (self->combo, value);
- g_signal_handlers_unblock_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_block_by_func (self->dropdown, dropdown_changed_cb, self);
+ dropdown_set (self->dropdown, option, value);
+ g_signal_handlers_unblock_by_func (self->dropdown, dropdown_changed_cb, self);
break;
case PPD_UI_PICKMANY:
- g_signal_handlers_block_by_func (self->combo, combo_changed_cb, self);
- combo_box_set (self->combo, value);
- g_signal_handlers_unblock_by_func (self->combo, combo_changed_cb, self);
+ g_signal_handlers_block_by_func (self->dropdown, dropdown_changed_cb, self);
+ dropdown_set (self->dropdown, option, value);
+ g_signal_handlers_unblock_by_func (self->dropdown, dropdown_changed_cb, self);
break;
default:
@@ -523,8 +476,6 @@ update_widget_real (PpPPDOptionWidget *self)
else
gtk_widget_hide (self->image);
}
-
- cups_option_free (option);
}
static void
--
GitLab