[gtk+/wip/dboles/combobox-cleanup: 3/4] combobox: Avoid constantly NULL-checking the menu
- From: Daniel Boles <dboles src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/dboles/combobox-cleanup: 3/4] combobox: Avoid constantly NULL-checking the menu
- Date: Fri, 20 Jan 2017 04:06:49 +0000 (UTC)
commit 342aa6e14181fe4d7565445ecc04066715604f86
Author: Daniel Boles <dboles src gnome org>
Date: Fri Jan 20 02:24:16 2017 +0000
combobox: Avoid constantly NULL-checking the menu
By reordering a few pieces of code, we can ensure that the TreeMenu
popup_widget is always valid, so we don’t have to constantly check it.
ComboBoxText must be changed to set its model in constructed(), not
init() – because CB::set_model() uses cell_area, which can be set by a
ctor property and so is only definitely valid after CB::constructed().
Benjamin wants to bin those constructors, but until then, this works!
gtk/gtkcombobox.c | 97 ++++++++++++++-----------------------------------
gtk/gtkcomboboxtext.c | 24 +++++++-----
2 files changed, 41 insertions(+), 80 deletions(-)
---
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index d6bc2c9..f483925 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -1030,7 +1030,6 @@ gtk_combo_box_init (GtkComboBox *combo_box)
combo_box->priv = gtk_combo_box_get_instance_private (combo_box);
priv = combo_box->priv;
- priv->popup_widget = NULL;
priv->wrap_width = 0;
priv->active = -1;
@@ -1375,12 +1374,9 @@ gtk_combo_box_remove (GtkContainer *container,
gtk_widget_queue_resize (GTK_WIDGET (container));
- if (priv->popup_widget)
- {
- gtk_combo_box_menu_destroy (combo_box);
- gtk_menu_detach (GTK_MENU (priv->popup_widget));
- priv->popup_widget = NULL;
- }
+ gtk_combo_box_menu_destroy (combo_box);
+ gtk_menu_detach (GTK_MENU (priv->popup_widget));
+ priv->popup_widget = NULL;
gtk_combo_box_create_child (combo_box);
@@ -1725,8 +1721,7 @@ gtk_combo_box_popup_for_device (GtkComboBox *combo_box,
if (gtk_widget_get_mapped (priv->popup_widget))
return;
- if (priv->popup_widget)
- gtk_combo_box_menu_popup (combo_box, priv->trigger_event);
+ gtk_combo_box_menu_popup (combo_box, priv->trigger_event);
}
static void
@@ -1734,8 +1729,7 @@ gtk_combo_box_real_popup (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv = combo_box->priv;
- if (priv->popup_widget)
- gtk_combo_box_menu_popup (combo_box, priv->trigger_event);
+ gtk_combo_box_menu_popup (combo_box, priv->trigger_event);
}
static gboolean
@@ -1768,8 +1762,7 @@ gtk_combo_box_popdown (GtkComboBox *combo_box)
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
- if (priv->popup_widget)
- gtk_menu_popdown (GTK_MENU (priv->popup_widget));
+ gtk_menu_popdown (GTK_MENU (priv->popup_widget));
}
static void
@@ -2088,10 +2081,6 @@ gtk_combo_box_menu_setup (GtkComboBox *combo_box)
g_signal_connect (menu, "key-press-event",
G_CALLBACK (gtk_combo_box_menu_key_press), combo_box);
- /* Set up the popup menu */
- if (priv->popup_widget)
- gtk_menu_detach (GTK_MENU (priv->popup_widget));
-
priv->popup_widget = menu;
g_signal_connect (menu, "show", G_CALLBACK (gtk_combo_box_menu_show), combo_box);
@@ -2107,10 +2096,14 @@ gtk_combo_box_menu_destroy (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv = combo_box->priv;
+ if (!priv->popup_widget)
+ return;
+
g_signal_handlers_disconnect_matched (priv->button,
G_SIGNAL_MATCH_DATA,
0, 0, NULL,
gtk_combo_box_menu_button_press, NULL);
+
g_signal_handlers_disconnect_matched (priv->popup_widget,
G_SIGNAL_MATCH_DATA,
0, 0, NULL,
@@ -2128,8 +2121,7 @@ gtk_combo_box_menu_button_press (GtkWidget *widget,
GtkComboBox *combo_box = GTK_COMBO_BOX (user_data);
GtkComboBoxPrivate *priv = combo_box->priv;
- if (priv->popup_widget &&
- event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY)
+ if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY)
{
if (gtk_widget_get_focus_on_click (GTK_WIDGET (combo_box)) &&
!gtk_widget_has_focus (priv->button))
@@ -2440,10 +2432,7 @@ gtk_combo_box_set_wrap_width (GtkComboBox *combo_box,
if (width != priv->wrap_width)
{
priv->wrap_width = width;
-
- if (priv->popup_widget)
- _gtk_tree_menu_set_wrap_width (GTK_TREE_MENU (priv->popup_widget), priv->wrap_width);
-
+ _gtk_tree_menu_set_wrap_width (GTK_TREE_MENU (priv->popup_widget), priv->wrap_width);
g_object_notify (G_OBJECT (combo_box), "wrap-width");
}
}
@@ -2494,10 +2483,7 @@ gtk_combo_box_set_row_span_column (GtkComboBox *combo_box,
if (row_span != priv->row_column)
{
priv->row_column = row_span;
-
- if (priv->popup_widget)
- _gtk_tree_menu_set_row_span_column (GTK_TREE_MENU (priv->popup_widget), priv->row_column);
-
+ _gtk_tree_menu_set_row_span_column (GTK_TREE_MENU (priv->popup_widget), priv->row_column);
g_object_notify (G_OBJECT (combo_box), "row-span-column");
}
}
@@ -2548,10 +2534,7 @@ gtk_combo_box_set_column_span_column (GtkComboBox *combo_box,
if (column_span != priv->col_column)
{
priv->col_column = column_span;
-
- if (priv->popup_widget)
- _gtk_tree_menu_set_column_span_column (GTK_TREE_MENU (priv->popup_widget), priv->col_column);
-
+ _gtk_tree_menu_set_column_span_column (GTK_TREE_MENU (priv->popup_widget), priv->col_column);
g_object_notify (G_OBJECT (combo_box), "column-span-column");
}
}
@@ -2662,8 +2645,7 @@ gtk_combo_box_set_active_internal (GtkComboBox *combo_box,
if (!path)
{
- if (priv->popup_widget)
- gtk_menu_set_active (GTK_MENU (priv->popup_widget), -1);
+ gtk_menu_set_active (GTK_MENU (priv->popup_widget), -1);
if (priv->cell_view)
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (priv->cell_view), NULL);
@@ -2681,9 +2663,8 @@ gtk_combo_box_set_active_internal (GtkComboBox *combo_box,
gtk_tree_row_reference_new (priv->model, path);
/* FIXME handle nested menus better */
- if (priv->popup_widget)
- gtk_menu_set_active (GTK_MENU (priv->popup_widget),
- gtk_tree_path_get_indices (path)[0]);
+ gtk_menu_set_active (GTK_MENU (priv->popup_widget),
+ gtk_tree_path_get_indices (path)[0]);
if (priv->cell_view)
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (priv->cell_view),
@@ -2808,9 +2789,8 @@ gtk_combo_box_set_model (GtkComboBox *combo_box,
G_CALLBACK (gtk_combo_box_model_row_changed),
combo_box);
- if (priv->popup_widget)
- _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget),
- priv->model);
+ _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget),
+ priv->model);
if (priv->cell_view)
gtk_cell_view_set_model (GTK_CELL_VIEW (priv->cell_view),
@@ -3006,8 +2986,6 @@ gtk_combo_box_destroy (GtkWidget *widget)
_gtk_bin_set_child (GTK_BIN (combo_box), NULL);
}
- gtk_combo_box_popdown (combo_box);
-
if (priv->row_separator_destroy)
priv->row_separator_destroy (priv->row_separator_data);
@@ -3116,9 +3094,7 @@ gtk_combo_box_constructed (GObject *object)
gtk_combo_box_create_child (combo_box);
- /* Create the popup menu, if it doesn’t already exist. */
- if (!priv->popup_widget)
- gtk_combo_box_menu_setup (combo_box);
+ gtk_combo_box_menu_setup (combo_box);
if (priv->has_entry)
{
@@ -3137,12 +3113,9 @@ gtk_combo_box_dispose(GObject* object)
GtkComboBox *combo_box = GTK_COMBO_BOX (object);
GtkComboBoxPrivate *priv = combo_box->priv;
- if (priv->popup_widget)
- {
- gtk_combo_box_menu_destroy (combo_box);
- gtk_menu_detach (GTK_MENU (priv->popup_widget));
- priv->popup_widget = NULL;
- }
+ gtk_combo_box_menu_destroy (combo_box);
+ gtk_menu_detach (GTK_MENU (priv->popup_widget));
+ priv->popup_widget = NULL;
if (priv->area)
{
@@ -3249,7 +3222,6 @@ gtk_combo_box_set_popup_fixed_width (GtkComboBox *combo_box,
if (priv->popup_fixed_width != fixed)
{
priv->popup_fixed_width = fixed;
-
g_object_notify (G_OBJECT (combo_box), "popup-fixed-width");
}
}
@@ -3291,20 +3263,9 @@ gtk_combo_box_get_popup_fixed_width (GtkComboBox *combo_box)
AtkObject*
gtk_combo_box_get_popup_accessible (GtkComboBox *combo_box)
{
- GtkComboBoxPrivate *priv;
- AtkObject *atk_obj;
-
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), NULL);
- priv = combo_box->priv;
-
- if (priv->popup_widget)
- {
- atk_obj = gtk_widget_get_accessible (priv->popup_widget);
- return atk_obj;
- }
-
- return NULL;
+ return gtk_widget_get_accessible (combo_box->priv->popup_widget);
}
/**
@@ -3357,12 +3318,9 @@ gtk_combo_box_set_row_separator_func (GtkComboBox *combo_box,
priv->row_separator_data = data;
priv->row_separator_destroy = destroy;
- /* Provoke the underlying menu to rebuild themselves with the new separator func */
- if (priv->popup_widget)
- {
- _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), NULL);
- _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), priv->model);
- }
+ /* Rebuild the menu with the new separator function */
+ _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), NULL);
+ _gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), priv->model);
gtk_widget_queue_draw (GTK_WIDGET (combo_box));
}
@@ -3392,7 +3350,6 @@ gtk_combo_box_set_button_sensitivity (GtkComboBox *combo_box,
{
priv->button_sensitivity = sensitivity;
gtk_combo_box_update_sensitivity (combo_box);
-
g_object_notify (G_OBJECT (combo_box), "button-sensitivity");
}
}
diff --git a/gtk/gtkcomboboxtext.c b/gtk/gtkcomboboxtext.c
index 4b15c04..491d739 100644
--- a/gtk/gtkcomboboxtext.c
+++ b/gtk/gtkcomboboxtext.c
@@ -109,20 +109,29 @@ G_DEFINE_TYPE_WITH_CODE (GtkComboBoxText, gtk_combo_box_text, GTK_TYPE_COMBO_BOX
static void
gtk_combo_box_text_constructed (GObject *object)
{
+ GtkComboBox *combo_box = (GtkComboBox *)object;
const gint text_column = 0;
+ GtkListStore *store;
G_OBJECT_CLASS (gtk_combo_box_text_parent_class)->constructed (object);
- gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (object), text_column);
- gtk_combo_box_set_id_column (GTK_COMBO_BOX (object), 1);
+ /* Do this here, not in init(), because combo_box_set_model() calls
+ * combo_box_menu_setup(), which relies on ::cell area being valid, and the
+ * area is not guaranteed to be set until after ComboBox::constructed(). */
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ gtk_combo_box_set_entry_text_column (combo_box, text_column);
+ gtk_combo_box_set_id_column (combo_box, 1);
- if (!gtk_combo_box_get_has_entry (GTK_COMBO_BOX (object)))
+ if (!gtk_combo_box_get_has_entry (combo_box))
{
GtkCellRenderer *cell;
cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (object), cell, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (object), cell,
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
"text", text_column,
NULL);
}
@@ -131,11 +140,6 @@ gtk_combo_box_text_constructed (GObject *object)
static void
gtk_combo_box_text_init (GtkComboBoxText *combo_box)
{
- GtkListStore *store;
-
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
- g_object_unref (store);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]