After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 119888 - Calculator does respond to key press
Calculator does respond to key press
Status: RESOLVED FIXED
Product: gnome-calculator
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Rich Burridge
Rich Burridge
Depends on:
Blocks:
 
 
Reported: 2003-08-14 15:59 UTC by Dennis Cranston
Modified: 2004-12-22 21:47 UTC
See Also:
GNOME target: ---
GNOME version: 2.3/2.4


Attachments
Proposed fix. (7.43 KB, text/plain)
2003-08-14 19:35 UTC, Rich Burridge
Details
Second version of proposed patch to fix this. (7.71 KB, text/plain)
2003-08-18 14:51 UTC, Rich Burridge
Details

Description Dennis Cranston 2003-08-14 15:59:38 UTC
Hi Rich,

While using gcalctool, I discovered it's possible for it to ignore key
press events.  Here are the steps that cause the strange behaivor.

1.  Lanuch Calculator in Basic Mode.
2.  Type: Alt-V  (to select the view menu)
3.  Type: s  (to select the scientific mode)
4.  Type: 0,1,2,3,4,5,6,7,8, or 9   (gcaltool ignores them)

I am teaching a class this afternoon and won't have time to investigate
until tonight.

Thanks,
Dennis
Comment 1 Rich Burridge 2003-08-14 18:12:45 UTC
Hi Dennis. Here's what's happening. I added the following two 
lines of debug at the beginning of kframe_key_press_cb and
kframe_key_release_cb:

Index: gtk.c
===================================================================
RCS file: /cvs/gnome/gcalctool/gcalctool/gtk.c,v
retrieving revision 1.97
diff -u -r1.97 gtk.c
--- gtk.c	14 Aug 2003 14:39:53 -0000	1.97
+++ gtk.c	14 Aug 2003 18:05:38 -0000
@@ -1357,6 +1357,9 @@
     GtkWidget *focus;
     int retval = FALSE;
 
+/**/fprintf(stderr, "press cb: keyval: %d modetype: %d\n",
event->keyval, v->modetype);
+/**/fprintf(stderr, "press cb: alt_l: %d alt_r: %d ctrl_l: %d ctrl_r:
%d shft_l: %d shft_r: %d\n", X->alt_l, X->alt_r, X->ctrl_l, X->ctrl_r,
X->shft_l, X->shft_r);
+
     if (event->keyval == GDK_Alt_L) {
         X->alt_l = TRUE;
         return(TRUE);
@@ -1415,6 +1418,8 @@
 static gboolean
 kframe_key_release_cb(GtkWidget *widget, GdkEventKey *event, gpointer
data)
 {
+/**/fprintf(stderr, "release cb: keyval: %d modetype: %d\n",
event->keyval, v->modetype);
+/**/fprintf(stderr, "release cb: alt_l: %d alt_r: %d ctrl_l: %d
ctrl_r: %d shft_l: %d shft_r: %d\n", X->alt_l, X->alt_r, X->ctrl_l,
X->ctrl_r, X->shft_l, X->shft_r);
     if (event->keyval == GDK_Alt_L) {
         X->alt_l = FALSE;
         return(TRUE);

These two routines adjust various flags in the X struct
(alt_l, alt_r, ctrl_l, ctrl_r, shft_l, shft_r) on receipt
of Alt/Ctrl/Shift key press and release events.

When I run gcalctool and performs the steps you gave, I get:

% ./gcalctool
press cb: keyval: 65513 modetype: 0
press cb: alt_l: 0 alt_r: 0 ctrl_l: 0 ctrl_r: 0 shft_l: 0 shft_r: 0
press cb: keyval: 118 modetype: 0
press cb: alt_l: 1 alt_r: 0 ctrl_l: 0 ctrl_r: 0 shft_l: 0 shft_r: 0
release cb: keyval: 115 modetype: 2
release cb: alt_l: 1 alt_r: 0 ctrl_l: 0 ctrl_r: 0 shft_l: 0 shft_r: 0
press cb: keyval: 49 modetype: 2
press cb: alt_l: 1 alt_r: 0 ctrl_l: 0 ctrl_r: 0 shft_l: 0 shft_r: 0
release cb: keyval: 49 modetype: 2
release cb: alt_l: 1 alt_r: 0 ctrl_l: 0 ctrl_r: 0 shft_l: 0 shft_r: 0

So what I'm reading here is that I get a left Alt key press event
which sets X->alt_l but I don't get a corresponding left Alt
key release event that would allow me to clear the flag. So
when you then type 1, the testing logic still thinks the left
Alt key is down.

A workaround is to press/release the left Alt key, and the 
calculator starts functioning properly again.

I've cc:'ed Owen on this one for his take on this. Am I
misunderstanding how menu keyboard accelerators like Alt v
work here or should there be a corresponding Alt key release 
event generated?
Comment 2 Owen Taylor 2003-08-14 18:22:00 UTC
No, key events are not guaranteed to be paired. By the time
the menu pops up, the keyboard is grabbed, and the release
will be delivered to the menu.

You should be able to trigger the same bug, by pressing
the alt key, clicking on another window to focus it,
and then releasing the alt key.

Why are you trying to track modifier state by watching
key press/release events? Can't you just look at
event->state?
Comment 3 Rich Burridge 2003-08-14 18:26:22 UTC
Yes I probably can. I didn't realise it was there.
Thanks! Lemme see if I can cons up a patch...
Comment 4 Rich Burridge 2003-08-14 19:35:44 UTC
Created attachment 19225 [details]
Proposed fix.
Comment 5 Rich Burridge 2003-08-14 19:38:16 UTC
Well I do like a fix where you can take a load of
crappy code out and replace it with something that
is simpler and cleaner.

Dennis, could you give the attached patch a try
please? If it fixes the problem (and doesn't break
anything else), feel free to check it in. I'm away for
a long weekend later today, so I won't be able to do 
it until Monday morning at the earliest.

Thanks.
Comment 6 Dennis Cranston 2003-08-15 18:48:20 UTC
Rich,

The patch breaks keyboard input when the num lock key is set.  For
example, set the num lock key then type "1" from either the keyboard
or numeric keypad and the key press event is ignored.  

After a little research, the problem is in check_vals().  When the num
lock is set, the value of state is 16.  See below for the code change
that corrected this problem on my RH9 machine.  

I will not apply the patch to CVS.  I would rather wait until Monday
as I am unsure of the logic behind a state of 16, and I do not see it
documented in gtk+.

Thanks,
Dennis

@@ -1331,15 +1321,13 @@
         j = 0;
         while (buttons[i].value[j] != 0) {
             if (buttons[i].value[j] == keyval) {
-                if ((buttons[i].mods[j] == 0) &&
-                    ((X->alt_l  | X->alt_r  | X->ctrl_l | 
-                      X->ctrl_r | X->shft_l | X->shft_r) == 0)) {
+                if ((buttons[i].mods[j] == 0) && 
+                    (state == 0 || state == 16)) {
                     DO_KEY_PRESS(i);
Comment 7 Rich Burridge 2003-08-16 22:08:30 UTC
Hi Dennis. Well if I've got my shifting correct,
16 is GDK_MOD2_MASK in the GdkModifierType enum
in gdktypes.h, so I'll adjust to use that (and
add a comment accordingly to show that it means NumLock).
I'll also try it out on Solaris on Monday to make sure 
they don't do something funkily different there.

Thanks!
Comment 8 Owen Taylor 2003-08-17 18:36:44 UTC
The NumLock mapping is *not* standardized. 

You really want to mask in the mods you care about, not mask
out the ones you don't care about. E.g.:

 relevant_state = event_state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK |
GDK_MOD1_MASK);

 if (relevant_state == GDK_MOD1_MASK)
   {  
     /* Do stuff that applies only to Alt and not Alt+Control */
   }

Of course, you can generally just write:

 if ((event_state & GDK_MOD1_MASK) != 0)
   {
   }

gtk_accelerator_get_default_mod_mask() gives you the modifiers
that GTK+ cares about (the above three currently), but 
(without looking at the details of what you are doing), I
doubt there is an advantage to using it.
Comment 9 Rich Burridge 2003-08-18 01:08:28 UTC
Thanks Owen. I have enough now to rework this.
Dennis, I'll do it first thing tomorrow morning
and try it out on Solaris. I'll attach it to the
bug for you to try. When you give the okay on it,
I'll check it into CVS HEAD.
Comment 10 Rich Burridge 2003-08-18 14:51:38 UTC
Created attachment 19308 [details]
Second version of proposed patch to fix this.
Comment 11 Rich Burridge 2003-08-18 14:54:11 UTC
Using the approach Owen suggested, I think the fix
is even cleaner. I say "I think" because I've suddenly
got a return of the funky keysym vals for my numeric
keypad again on my Solaris S9U3 system.

Dennis, could you try the second rev. of the patch
(already attached), and let me know if this works for
you please?

Thanks.
Comment 12 Dennis Cranston 2003-08-18 15:58:47 UTC
Rich,

Good morning.  This patch works fine on my linux box, and the code
looks better too. ;-)  

Thanks,
Dennis
Comment 13 Rich Burridge 2003-08-18 16:22:55 UTC
Agreed. Changes checked in (fixed in gcalctool v4.3.2).
Thanks Dennis/Owen.