GNOME Bugzilla – Bug 111269
Typing fast causes number transposing
Last modified: 2004-12-22 21:47:04 UTC
If you enter numbers in at a very fast rate, gcalctool will transpose the numbers. Simply typing 3, then 4 immediately after will display '43'. This can happen at any point. Typing 31415 yielded 31145 because I typed the 4 faster than the first 1.
I'm not seeing this problem at all. Which version of gcalctool are you using (Help->About will give you this)?
I just knew I was going to forget the version information. Doh! I'm using gcalctool 4.2.77 on Mandrake Linux Cooker.
Okay, I've managed to replicate this problem now. Investigating...
Adding Dennis to the cc: list for his thoughts. I added the following debug line: Index: gtk.c =================================================================== RCS file: /cvs/gnome/gcalctool/gcalctool/gtk.c,v retrieving revision 1.82 diff -u -r1.82 gtk.c --- gtk.c 15 Apr 2003 20:02:29 -0000 1.82 +++ gtk.c 23 Apr 2003 17:04:50 -0000 @@ -516,6 +516,7 @@ struct button *n; n = (struct button *) g_object_get_data(G_OBJECT(widget), "button"); +/**/fprintf(stderr, "bp: n: %c\n", n->func_char); if (v->pending) { if (v->current != NULL) { free(v->current); and when compiled and run, and with me alternately typing "1" and "2" continuously as fast as I can, I get: % ./gcalctool bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 2 bp: n: 1 bp: n: 2 bp: n: 1 ... It's frightenly consistent. Now this seems to be showing me that my callback is getting called in the wrong order (i.e. the problem is lower down in Gtk/gdk). This seems such a fundemental thing, that I suspect my conclusion is incorrect.
Created attachment 15946 [details] Simple Gtk program that seems to replicate the problem.
Steve, I've attached a small Gtk+ example application that seems to replicate the problem. Could you try it please and give me your feedback? Thanks.
Just chatted with Owen on IRC. His comments: "It's conceivable that the calculator should just connect to key_press_event on the toplevel and go from there. If I had to guess about what's causing the misordering, it's the code that: a) makes the button depress as long as the key is down (with a timeout if it doesnt' get the key release) b) fires ::clicked when the button pops up b) has to happen because otherwise, say, for a close button, you won't see the button press then release. So, just catching key_press wouldn't have that problem. It's conceivable that we could record timestamps for the key press, and queue up activate to occur in that order for multiple accelerators happening in a row, but it would be pretty funky and specialized."
I'm close to a fix for this. Just need to fixup the numeric keypad (to work on both Solaris and Linux). More hopefully tomorrow.
Well the numeric keypad is a mess because depending upon the keyboard and the O/S, it's possible to get back a variety of alternatives for the same key (GDK_KP_End, GDK_End and GDK_KP_1 all for the number 1 for example). Because of this, I think I'm going to end up adopting a similar coding approach to the gcalc application, where it stores potential alternates for each "button" as part of the button structure.
Created attachment 15993 [details] Proposed fix.
I've attached a set of diffs for latest CVS gcalctool that'll hopefully fix the original problem, and also provide a cleaner more extensible setup for adding extra key alternatives for the various buttons (if ever needed). Steve could you give it a try and let me know if it fixes the problem please? Dennis, could you give it a lookover too please, as this is a big change (i.e. it affects virtually every function that gcalctool does). Thanks.
Looks good so far! I haven't been able to trip it up yet. Sorry I didn't get to testing that earlier patch. Work has had me tied up this week. Thanks!
I found one more slight adjustment that needs to be made in the handle_menu_selection() function in graphics.c, about line 35: if (IS_KEY(v->pending, KEY_LPAR.value)) { /* Inside parentheses? */ should be: if (IS_KEY(v->pending, KEY_LPAR.value[0])) { /* Inside parentheses? */ I'll make sure that gets in the fix that's checked back. Apart from that, I think it's looking pretty good.
Created attachment 16007 [details] Proposed fix - take 2 - with Solaris numpad keysyms added.
Seems like the keysyms on Solaris are different then Linux (silly me), so I've added those in as alternates where needed. Adding the updated diffs here just in case we ever need 'em. I'm considering this bug fixed now, so I've checked in the changes. Fixed in v4.2.83.
Thanks much Rich.