Merge lp:~larsu/ido/lp1229076 into lp:ido/13.10

Proposed by Lars Karlitski
Status: Merged
Approved by: Ted Gould
Approved revision: 149
Merged at revision: 149
Proposed branch: lp:~larsu/ido/lp1229076
Merge into: lp:ido/13.10
Diff against target: 141 lines (+59/-9)
1 file modified
src/idoscalemenuitem.c (+59/-9)
To merge this branch: bzr merge lp:~larsu/ido/lp1229076
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+187378@code.launchpad.net

Description of the change

idoscalemenuitem: don't update the action state when the action state changes

GtkRange has the same weird semantics for its "value-changed" signal that the check menu items have: it is emitted not only on user interaction, but also when gtk_range_set_value() is called.

The handler to "value-changed" updates the action. gtk_range_set_value() is called when the action notifies about a state change. Loop, meet loop.

This patch works around that by adding a "value-changed" to IdoScaleMenuItem that is only emitted when the user changes the slider's value.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Code looks fine. I'm not able to reproduce the issue with the previous version. But this version works for me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/idoscalemenuitem.c'
2--- src/idoscalemenuitem.c 2013-09-15 18:21:14 +0000
3+++ src/idoscalemenuitem.c 2013-09-24 22:29:17 +0000
4@@ -76,6 +76,7 @@
5 IdoScaleMenuItemStyle style;
6 IdoRangeStyle range_style;
7 gint toggle_size;
8+ gboolean ignore_value_changed;
9 };
10
11 enum {
12@@ -83,6 +84,7 @@
13 SLIDER_RELEASED,
14 PRIMARY_CLICKED,
15 SECONDARY_CLICKED,
16+ VALUE_CHANGED,
17 LAST_SIGNAL
18 };
19
20@@ -207,6 +209,20 @@
21 }
22
23 static void
24+ido_scale_menu_item_scale_value_changed (GtkRange *range,
25+ gpointer user_data)
26+{
27+ IdoScaleMenuItem *self = user_data;
28+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self);
29+
30+ /* The signal is not sent when it was set through
31+ * ido_scale_menu_item_set_value(). */
32+
33+ if (!priv->ignore_value_changed)
34+ g_signal_emit (self, signals[VALUE_CHANGED], 0, gtk_range_get_value (range));
35+}
36+
37+static void
38 ido_scale_menu_item_constructed (GObject *object)
39 {
40 IdoScaleMenuItem *self = IDO_SCALE_MENU_ITEM (object);
41@@ -222,6 +238,7 @@
42 NULL);
43
44 priv->scale = ido_range_new (adj, range_style);
45+ g_signal_connect (priv->scale, "value-changed", G_CALLBACK (ido_scale_menu_item_scale_value_changed), self);
46 g_object_ref (priv->scale);
47 gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
48
49@@ -368,6 +385,23 @@
50 G_TYPE_NONE, /* return type */
51 0 /* n_params */);
52
53+ /**
54+ * IdoScaleMenuItem::value-changed:
55+ * @menuitem: the #IdoScaleMenuItem for which the value changed
56+ * @value: the new value
57+ *
58+ * Emitted whenever the value of the contained scale changes because
59+ * of user input.
60+ */
61+ signals[VALUE_CHANGED] = g_signal_new ("value-changed",
62+ IDO_TYPE_SCALE_MENU_ITEM,
63+ G_SIGNAL_RUN_LAST,
64+ 0, NULL, NULL,
65+ g_cclosure_marshal_VOID__DOUBLE,
66+ G_TYPE_NONE,
67+ 1, G_TYPE_DOUBLE);
68+
69+
70 g_type_class_add_private (item_class, sizeof (IdoScaleMenuItemPrivate));
71 }
72
73@@ -977,6 +1011,26 @@
74 gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
75 }
76
77+/* ido_scale_menu_item_set_value:
78+ *
79+ * Sets the value of the scale inside @item to @value, without emitting
80+ * "value-changed".
81+ */
82+static void
83+ido_scale_menu_item_set_value (IdoScaleMenuItem *item,
84+ gdouble value)
85+{
86+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item);
87+
88+ /* set ignore_value_changed to signify to the scale menu item that it
89+ * should not emit its own value-changed signal, as that should only
90+ * be emitted when the value is changed by the user. */
91+
92+ priv->ignore_value_changed = TRUE;
93+ gtk_range_set_value (GTK_RANGE (priv->scale), value);
94+ priv->ignore_value_changed = FALSE;
95+}
96+
97 /**
98 * ido_scale_menu_item_state_changed:
99 *
100@@ -988,20 +1042,19 @@
101 GVariant *state,
102 gpointer user_data)
103 {
104- GtkWidget *scale;
105+ GtkWidget *menuitem;
106
107- scale = ido_scale_menu_item_get_scale (IDO_SCALE_MENU_ITEM (ido_action_helper_get_widget (helper)));
108- gtk_range_set_value (GTK_RANGE (scale), g_variant_get_double (state));
109+ menuitem = ido_action_helper_get_widget (helper);
110+ ido_scale_menu_item_set_value (IDO_SCALE_MENU_ITEM (menuitem), g_variant_get_double (state));
111 }
112
113 static void
114 ido_scale_menu_item_value_changed (GtkScale *scale,
115+ gdouble value,
116 gpointer user_data)
117 {
118 IdoActionHelper *helper = user_data;
119- gdouble value;
120
121- value = gtk_range_get_value (GTK_RANGE (scale));
122 ido_action_helper_change_action_state (helper, g_variant_new_double (value));
123 }
124
125@@ -1046,15 +1099,12 @@
126 if (g_menu_item_get_attribute (menuitem, "action", "s", &action))
127 {
128 IdoActionHelper *helper;
129- GtkWidget *scale;
130
131 helper = ido_action_helper_new (item, actions, action, NULL);
132 g_signal_connect (helper, "action-state-changed",
133 G_CALLBACK (ido_scale_menu_item_state_changed), NULL);
134
135- scale = ido_scale_menu_item_get_scale (IDO_SCALE_MENU_ITEM (item));
136- g_signal_connect (scale, "value-changed", G_CALLBACK (ido_scale_menu_item_value_changed), helper);
137-
138+ g_signal_connect (item, "value-changed", G_CALLBACK (ido_scale_menu_item_value_changed), helper);
139 g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper);
140
141 g_free (action);

Subscribers

People subscribed via source and target branches