GtkButtons and RUN_FIRST/RUN_LAST



The change:

2001-10-18  Havoc Pennington  <hp redhat com>

        * gtk/gtkbutton.c (gtk_button_class_init): Change button signals
        to GTK_RUN_LAST, #50239

broke GtkRadioButton clicked signal behavior.

Attached is a test app. With the old RUN_FIRST behavior, the clicked signal
trace when you click on the Bar button is:

class_clicked_handler (bar)
class_clicked_handler (foo)
user_clicked_handler (foo)
user_clicked_handler (bar)

The output is:

"clicked" event on bar: active
"clicked" event on foo: inactive

so in the end, "bar" is chosen, an dthe user callback sees it as active.
With the new RUN_LAST behavior, the trace looks like:

user_clicked_handler (bar)
class_clicked_handler (bar)
user_clicked_handler (foo)
class_clicked_handler (foo)

The output is:

"clicked" event on bar: inactive
"clicked" event on foo: active

so in the end, the user callback sees "foo" as chosen, even though "bar"
is was clicked, and "bar" ends up active.

So while the RUN_LAST change now allows you to stop_emission on toggle
buttons, it totally breaks the expected behavior for radio button clicked
emissions. Requiring the use to use signal_after is lame and inconsistent
with expected gtk behavior.

-Yosh
#include <gtk/gtk.h>


static void
print_value (GtkWidget *widget, const gchar *value)
{
  g_print ("\"clicked\" event on %s: %s\n", value,
           GTK_TOGGLE_BUTTON(widget)->active ?
           "active" : "inactive");
}

int
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *button;
  GSList    *group;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect_swapped (G_OBJECT (window), "delete_event",
			    G_CALLBACK (gtk_main_quit), NULL);

  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  button = gtk_radio_button_new_with_label (NULL, "Foo");
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, 0, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
		    G_CALLBACK (print_value), "foo");

  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
  button = gtk_radio_button_new_with_label (group, "Bar");
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, 0, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
		    G_CALLBACK (print_value), "bar");

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]