From 7077d774a2aa4c66e258583acf72760a23652fd5 Mon Sep 17 00:00:00 2001 From: marc Date: Mon, 29 Jun 2009 22:53:31 +0000 Subject: [PATCH] * Implemented own way of tracking shiftstate, solves issues with reporting ssAlt or ssAltGr being pressed. Solves issue #009394 too git-svn-id: trunk@20767 - --- lcl/interfaces/gtk/gtkcallback.inc | 32 ++++++++++++++++++++++++++++++ lcl/interfaces/gtk/gtkdefines.inc | 6 ++++++ lcl/interfaces/gtk/gtkproc.inc | 20 +++++++++++++------ lcl/interfaces/gtk/gtkproc.pp | 12 ++++++++--- 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/lcl/interfaces/gtk/gtkcallback.inc b/lcl/interfaces/gtk/gtkcallback.inc index 506085c41c..e3818c268c 100644 --- a/lcl/interfaces/gtk/gtkcallback.inc +++ b/lcl/interfaces/gtk/gtkcallback.inc @@ -2478,6 +2478,14 @@ var KeyStateList.Remove(Pointer(PtrInt(AVKeyCode))); end; end; + {$ifdef UseOwnShiftState} + procedure UpdateShiftState(AShift: TShiftStateEnum; AInclude: Boolean); + begin + if AInclude + then Include(MShiftState, AShift) + else Exclude(MShiftState, AShift); + end; + {$endif} const STATE_MAP: array[0..3] of TShiftStateEnum = ( @@ -2501,6 +2509,7 @@ var n: Integer; ShiftState: TShiftState; + begin Result := 0; @@ -2513,6 +2522,29 @@ begin // not interested Exit; end; + + {$ifdef UseOwnShiftState} + case Event^.KeyVal of + GDK_Key_Shift_L, + GDK_Key_Shift_R: UpdateShiftState(ssShift, Pressed); + GDK_KEY_Control_L, + GDK_KEY_Control_R: UpdateShiftState(ssCtrl, Pressed); + GDK_KEY_Meta_L, + GDK_KEY_Meta_R: UpdateShiftState(ssMeta, Pressed); + GDK_KEY_Alt_L, + GDK_KEY_Alt_R: UpdateShiftState(ssAlt, Pressed); + GDK_KEY_Super_L, + GDK_KEY_Super_R: UpdateShiftState(ssSuper, Pressed); + GDK_KEY_Hyper_L, + GDK_KEY_Hyper_R: UpdateShiftState(ssHyper, Pressed); + GDK_KEY_ISO_Level3_Shift: UpdateShiftState(ssAltGr, Pressed); + // Num, scroll, caps lock can be toggled, use modmap in this case + // GDK_KEY_Num_Lock: UpdateShiftState(ssNum, Pressed); + // GDK_KEY_Scroll_Lock: UpdateShiftState(ssScroll, Pressed); + // GDK_KEY_Caps_Lock, + // GDK_KEY_Shift_Lock: UpdateShiftState(ssCaps, Pressed); + end; + {$endif} {$ifdef gtk1} KeyCode := XKeysymToKeycode(gdk_display, Event^.keyval); diff --git a/lcl/interfaces/gtk/gtkdefines.inc b/lcl/interfaces/gtk/gtkdefines.inc index 12e2dcd1e4..abb7f98df9 100644 --- a/lcl/interfaces/gtk/gtkdefines.inc +++ b/lcl/interfaces/gtk/gtkdefines.inc @@ -35,6 +35,12 @@ {$define RawimageConsistencyChecks} +(* + GTK or GNOME has problems reporting ssAlt and ssAltGr when different + keyboardlayouts are used. With UseOwnShiftState we keep track of the shiftate + ourself +*) +{$define UseOwnShiftState} (* keep track of keystates instead of using OS diff --git a/lcl/interfaces/gtk/gtkproc.inc b/lcl/interfaces/gtk/gtkproc.inc index 99ae30ae6e..a98a7d067c 100644 --- a/lcl/interfaces/gtk/gtkproc.inc +++ b/lcl/interfaces/gtk/gtkproc.inc @@ -2304,7 +2304,7 @@ begin end else begin // VKey is with ALT so SHIFT Alt is syskey - SysKey := ShiftState * [ssShift, ssAlt] = [ssShift, ssAlt] + SysKey := ShiftState * [ssShift, ssAltGr] = [ssShift, ssAltGr] end; if SysKey then Flags := Flags or KF_ALTDOWN; @@ -3091,12 +3091,16 @@ type if AModMap[AKeyCode] = 0 then Exit; case AKeySym of + GDK_KEY_Caps_Lock, + GDK_KEY_Shift_Lock: ShiftState := ssCaps; + GDK_KEY_Num_Lock: ShiftState := ssNum; + GDK_KEY_Scroll_Lock: ShiftState := ssScroll; + {$ifndef UseOwnShiftState} + // UseOwnShiftState will track these, so we don't have to put them in the modmap GDK_Key_Shift_L, GDK_Key_Shift_R: ShiftState := ssShift; GDK_KEY_Control_L, GDK_KEY_Control_R: ShiftState := ssCtrl; - GDK_KEY_Caps_Lock, - GDK_KEY_Shift_Lock: ShiftState := ssCaps; GDK_KEY_Meta_L, GDK_KEY_Meta_R: ShiftState := ssMeta; GDK_KEY_Alt_L, @@ -3105,9 +3109,9 @@ type GDK_KEY_Super_R: ShiftState := ssSuper; GDK_KEY_Hyper_L, GDK_KEY_Hyper_R: ShiftState := ssHyper; - GDK_KEY_Mode_switch: ShiftState := ssAltGr; - GDK_KEY_Num_Lock: ShiftState := ssNum; - GDK_KEY_Scroll_Lock: ShiftState := ssScroll; + GDK_KEY_ISO_Level3_Shift{, + GDK_KEY_Mode_switch}: ShiftState := ssAltGr; + {$endif} else Exit; end; @@ -3402,7 +3406,11 @@ function GTKEventStateToShiftState(KeyState: Word): TShiftState; var State: TShiftStateEnum; begin + {$ifdef UseOwnShiftState} + Result := MShiftState; + {$else} Result := []; + {$endif} for State := Low(State) to High(State) do begin if MModifiers[State].Mask = 0 then Continue; diff --git a/lcl/interfaces/gtk/gtkproc.pp b/lcl/interfaces/gtk/gtkproc.pp index 47f812374f..89687caf98 100644 --- a/lcl/interfaces/gtk/gtkproc.pp +++ b/lcl/interfaces/gtk/gtkproc.pp @@ -824,6 +824,10 @@ type var MModifiers: array[TShiftStateEnum] of TModifier; +{$ifdef UseOwnShiftState} +var + MShiftState: TShiftState = []; +{$endif} type // TLCLHandledKeyEvent is used to remember, if an gdk key event was already @@ -913,14 +917,16 @@ begin // fill initial modifier list FillByte(MModifiers, SizeOf(MModifiers), 0); // keyboard - MModifiers[ssShift].Mask := GDK_SHIFT_MASK; MModifiers[ssCaps].Mask := GDK_LOCK_MASK; + MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code + MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code + {$ifndef UseOwnShiftState} + MModifiers[ssShift].Mask := GDK_SHIFT_MASK; MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK; MModifiers[ssAlt].Mask := GDK_MOD1_MASK; - MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code MModifiers[ssSuper].Mask := GDK_MOD4_MASK; - MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code MModifiers[ssAltGr].Mask := GDK_RELEASE_MASK; + {$endif} // mouse MModifiers[ssLeft].Mask := GDK_BUTTON1_MASK; MModifiers[ssMiddle].Mask := GDK_BUTTON2_MASK;