GNOME Bugzilla – Bug 127480
Wrong callback order
Last modified: 2014-10-20 03:06:47 UTC
When an accelerator is connected to the activate-signal of a button (in fact it is done twice), then if you push the accelerator buttons fast enough after eachother then the callback functions are handled in the wrong order e.g. the callback of the button secondly activated is processed before the callback of the first button.
Sample application: (with glade) bug.py: #!/usr/bin/env python import pygtk pygtk.require("2.0") import gtk import gtk.glade import gobject widgets = gtk.glade.XML("bug.glade") entry = widgets.get_widget("entry") window = widgets.get_widget("window1") def on_button1_clicked(*args): entry.insert_text("a",-1) def on_button2_clicked(*args): entry.insert_text("b",-1) def quit(*args): gtk.main_quit() widgets.signal_autoconnect(locals()) gtk.main() bug.glade: <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> <glade-interface> <widget class="GtkWindow" id="window1"> <property name="visible">True</property> <property name="title" translatable="yes">window1</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> <signal name="destroy" handler="quit" last_modification_time="Thu, 20 Nov 2003 14:08:16 GMT"/> <child> <widget class="GtkTable" id="table1"> <property name="visible">True</property> <property name="n_rows">2</property> <property name="n_columns">2</property> <property name="homogeneous">False</property> <property name="row_spacing">0</property> <property name="column_spacing">0</property> <child> <widget class="GtkEntry" id="entry"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property> <property name="editable">True</property> <property name="visibility">True</property> <property name="max_length">0</property> <property name="text" translatable="yes"></property> <property name="has_frame">True</property> <property name="invisible_char" translatable="yes">*</property> <property name="activates_default">False</property> </widget> <packing> <property name="left_attach">0</property> <property name="right_attach">2</property> <property name="top_attach">0</property> <property name="bottom_attach">1</property> <property name="y_options"></property> </packing> </child> <child> <widget class="GtkButton" id="button1"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="label" translatable="yes">button1</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <signal name="clicked" handler="on_button1_clicked" last_modification_time="Thu, 20 Nov 2003 13:49:14 GMT"/> <accelerator key="1" modifiers="0" signal="activate"/> <accelerator key="KP_1" modifiers="0" signal="activate"/> </widget> <packing> <property name="left_attach">0</property> <property name="right_attach">1</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> <property name="x_options">fill</property> <property name="y_options"></property> </packing> </child> <child> <widget class="GtkButton" id="button2"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="label" translatable="yes">button2</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <signal name="clicked" handler="on_button2_clicked" last_modification_time="Thu, 20 Nov 2003 13:49:26 GMT"/> <accelerator key="KP_2" modifiers="0" signal="activate"/> <accelerator key="2" modifiers="0" signal="activate"/> </widget> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> <property name="x_options">fill</property> <property name="y_options"></property> </packing> </child> </widget> </child> </widget> </glade-interface>
Reporter, could you please try a post a shorter (minimal) test case?
Created attachment 22216 [details] Minimal Test Case
Created attachment 24900 [details] test program in pure C
This is a gtk+ bug, not pygtk, as the C test program demonstrates.
Moving to GTK+ for retriaging..
This is a consequence of the animation of buttons; I don't think it is particularly fixable in a reliable way.
Of the *animation* of the buttons? In what way does the animation of the buttons influence the order callbacks are processed?
Animation of the button, I look at the animation and yes. It looks like this: Button1 down Button2 down Button2 up Button1 up So the animation order is not right, e.g. the timeout-function doesn't handle the timeouts in te right order. But if a handler is connected to the activate-signal, the signals are handled in the right order. So why not chain the clicked signal right after the button goes down instead of after the button has gone up?
Because if that were done, you wouldn't be able to change your mind after clicking (press, move off the buttons target area, release is intentionally a nop). This is standard HIG fare.
Reopening in case anybody has bright ideas, and so I can mark another bug as a duplicate. It might actually be a simple bug, if someone wanted to track down the sequence of events that was going on.
*** Bug 108209 has been marked as a duplicate of this bug. ***
Can someone test this with threads disabled to check if the threads code triggers this bug?
closing ancient bugs