The Trunk: Kernel-mt.1289.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Kernel-mt.1289.mcz

commits-2
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1289.mcz

==================== Summary ====================

Name: Kernel-mt.1289
Author: mt
Time: 19 December 2019, 11:45:58.637761 am
UUID: e9f9d6a0-0ce8-114e-b3d2-26b481f590a1
Ancestors: Kernel-mt.1288

- fixes ctrl <-> alt key swapping bug in #processEvent:
- fixes ctrl <-> alt key swapping by extending the range to the same range as for "duplicate *all*"
- LINUX ONLY: fixes swapping and duplication of ctrl/alt keys
- LINUX ONLY: maps controls keys that arrive as ASCII 64 to 127 down to ASCII 0 to 31
- document that other (older) "duplicate keys" preference to be deprecated after the 5.3 release

So, the current VM 201911282316 should be fine for all platforms for Squeak 5.3 at the moment.

=============== Diff against Kernel-mt.1288 ===============

Item was added:
+ ----- Method: EventSensor class>>installControlKeyEntryFor: (in category 'key decode table') -----
+ installControlKeyEntryFor: aPrintableCharacter
+
+ | upper lower |
+ self assert: (aPrintableCharacter asInteger between: 64 and: 95).
+
+ upper := aPrintableCharacter asInteger.
+ lower := aPrintableCharacter asInteger bitOr: 16r20.
+
+ "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+ self flag: #unixOnly.
+ KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
+ KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!

Item was changed:
  ----- Method: EventSensor class>>installDuplicateKeyEntryFor: (in category 'key decode table') -----
  installDuplicateKeyEntryFor: aPrintableCharacter
  "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
  Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."
 
  | upper lower |
  upper := aPrintableCharacter asUppercase asInteger.
  lower := aPrintableCharacter asLowercase asInteger.
 
  KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
  KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+
+ "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+ self flag: #unixOnly.
+ KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+ KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
- !

Item was changed:
  ----- Method: EventSensor class>>installKeyDecodeTable (in category 'class initialization') -----
  installKeyDecodeTable
+ "Create a decode table that swaps or duplicates some keys if the respective preference is set."
+
- "Create a decode table that swaps some keys if
- Preferences swapControlAndAltKeys is set"
  KeyDecodeTable := Dictionary new.
+
+ "In any case, ensure that control keys are mapped correctly."
+ self flag: #toRemove. "mt: If all VMs send the correct control keys on all platforms, we will remove this mapping."
+ 64 "$@" to: 95 "$_"do: [:keyCode | self installControlKeyEntryFor: keyCode asCharacter].
+
- Preferences duplicateControlAndAltKeys
- ifTrue: [ self defaultCrossPlatformKeys do:
- [ :c | self installDuplicateKeyEntryFor: c ] ].
  Preferences swapControlAndAltKeys
+ ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
- ifTrue: [ self defaultCrossPlatformKeys do:
  [ :c | self installSwappedKeyEntryFor: c ] ].
  Preferences duplicateAllControlAndAltKeys
  ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
  [ :c | self installDuplicateKeyEntryFor: c ] ].
+
+ self flag: #toDeprecate. "mt: This mapping should be deprecated in the future."
+ Preferences duplicateControlAndAltKeys
+ ifTrue: [ self defaultCrossPlatformKeys do:
+ [ :c | self installDuplicateKeyEntryFor: c ] ].
  !

Item was changed:
  ----- Method: EventSensor class>>installSwappedKeyEntryFor: (in category 'key decode table') -----
  installSwappedKeyEntryFor: aPrintableCharacter
  "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
  Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."
 
  | upper lower |
  upper := aPrintableCharacter asUppercase asInteger.
  lower := aPrintableCharacter asLowercase asInteger.
 
  KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
  KeyDecodeTable at: { lower . 8 "cmd/alt" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
  KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+ KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.
+
+ "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+ self flag: #unixOnly.
+ KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+ KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
- KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!

Item was changed:
  ----- Method: EventSensor>>processEvent: (in category 'private-I/O') -----
  processEvent: evt
  "Process a single event. This method is run at high priority."
  | type buttons window |
  type := evt at: 1.
 
  "Only process main window events, forward others to host window proxies"
  window := evt at: 8.
  (window isNil or: [window isZero]) ifTrue:
  [window := 1.
  evt at: 8 put: window].
  window = 1 ifFalse: [
  ^Smalltalk at: #HostWindowProxy ifPresent: [:w | w processEvent: evt]].
 
  "Tackle mouse events and mouse wheel events first"
  (type = EventTypeMouse or: [type = EventTypeMouseWheel])
  ifTrue: [buttons := (ButtonDecodeTable at: (evt at: 5) + 1).
  evt at: 5 put: (Smalltalk platformName = 'Mac OS'
  ifTrue: [ buttons ]
  ifFalse: [ self mapButtons: buttons modifiers: (evt at: 6) ]).
  self queueEvent: evt.
  type = EventTypeMouse ifTrue: [self processMouseEvent: evt].
  type = EventTypeMouseWheel ifTrue: [self processMouseWheelEvent: evt].
  ^self].
 
  "Store the event in the queue if there's any"
  type = EventTypeKeyboard
  ifTrue: [ "Check if the event is a user interrupt"
  ((evt at: 4) = EventKeyChar
  and: [((evt at: 3)
  bitOr: (((evt at: 5)
  bitAnd: 8)
  bitShift: 8))
  = interruptKey])
  ifTrue: ["interrupt key is meta - not reported as event"
  ^ interruptSemaphore signal].
  "Decode keys for characters (i.e., duplicate or swap, ctrl <-> alt/cmd)."
  (evt at: 4) = EventKeyChar
+ ifTrue: [ | unicode ascii |
+ "Copy lookup key first in case of key swap."
+ unicode := {evt at: 6. evt at: 5}.
+ ascii := {evt at: 3. evt at: 5}.
- ifTrue: [
  KeyDecodeTable "Unicode character first"
+ at: unicode
- at: {evt at: 6. evt at: 5}
  ifPresent: [:a | evt at: 6 put: a first;
  at: 5 put: a second].
  KeyDecodeTable "ASCII character second"
+ at: ascii
- at: {evt at: 3. evt at: 5}
  ifPresent: [:a | evt at: 3 put: a first;
  at: 5 put: a second]].
  self queueEvent: evt.
  self processKeyboardEvent: evt .
  ^self ].
 
  "Handle all events other than Keyboard or Mouse."
  self queueEvent: evt.
  !


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-mt.1289.mcz

Nicolas Cellier


Le jeu. 19 déc. 2019 à 11:46, <[hidden email]> a écrit :
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1289.mcz

==================== Summary ====================

Name: Kernel-mt.1289
Author: mt
Time: 19 December 2019, 11:45:58.637761 am
UUID: e9f9d6a0-0ce8-114e-b3d2-26b481f590a1
Ancestors: Kernel-mt.1288

- fixes ctrl <-> alt key swapping bug in #processEvent:
- fixes ctrl <-> alt key swapping by extending the range to the same range as for "duplicate *all*"
- LINUX ONLY: fixes swapping and duplication of ctrl/alt keys
- LINUX ONLY: maps controls keys that arrive as ASCII 64 to 127 down to ASCII 0 to 31
- document that other (older) "duplicate keys" preference to be deprecated after the 5.3 release

So, the current VM 201911282316 should be fine for all platforms for Squeak 5.3 at the moment.

=============== Diff against Kernel-mt.1288 ===============

Item was added:
+ ----- Method: EventSensor class>>installControlKeyEntryFor: (in category 'key decode table') -----
+ installControlKeyEntryFor: aPrintableCharacter
+       
+       | upper lower |
+       self assert: (aPrintableCharacter asInteger between: 64 and: 95).
+       
+       upper := aPrintableCharacter asInteger.
+       lower := aPrintableCharacter asInteger bitOr: 16r20.
+       
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!
We can remove that hack if we adopt the VM at SHA 83e43ee7138f8a1b76ed774c3972f2691776778a as I suggested (after mouse wheel fixes https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/461 and https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/462)
IMO, we should adopt that VM, it restores compatibility with older ones.


Item was changed:
  ----- Method: EventSensor class>>installDuplicateKeyEntryFor: (in category 'key decode table') -----
  installDuplicateKeyEntryFor: aPrintableCharacter
        "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
        Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."

        | upper lower |
        upper := aPrintableCharacter asUppercase asInteger.
        lower := aPrintableCharacter asLowercase asInteger.

        KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
        KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
- !

Item was changed:
  ----- Method: EventSensor class>>installKeyDecodeTable (in category 'class initialization') -----
  installKeyDecodeTable
+       "Create a decode table that swaps or duplicates some keys if the respective preference is set."
+
-       "Create a decode table that swaps some keys if
-       Preferences swapControlAndAltKeys is set"
        KeyDecodeTable := Dictionary new.
+
+       "In any case, ensure that control keys are mapped correctly."
+       self flag: #toRemove. "mt: If all VMs send the correct control keys on all platforms, we will remove this mapping."
+       64 "$@" to: 95 "$_"do: [:keyCode | self installControlKeyEntryFor: keyCode asCharacter].
+
-       Preferences duplicateControlAndAltKeys
-               ifTrue: [ self defaultCrossPlatformKeys do:
-                               [ :c | self installDuplicateKeyEntryFor: c ] ].
        Preferences swapControlAndAltKeys
+               ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
-               ifTrue: [ self defaultCrossPlatformKeys do:
                                [ :c | self installSwappedKeyEntryFor: c ] ].
        Preferences duplicateAllControlAndAltKeys
                ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
                                [ :c | self installDuplicateKeyEntryFor: c ] ].
+
+       self flag: #toDeprecate. "mt: This mapping should be deprecated in the future."
+       Preferences duplicateControlAndAltKeys
+               ifTrue: [ self defaultCrossPlatformKeys do:
+                               [ :c | self installDuplicateKeyEntryFor: c ] ].
  !

Item was changed:
  ----- Method: EventSensor class>>installSwappedKeyEntryFor: (in category 'key decode table') -----
  installSwappedKeyEntryFor: aPrintableCharacter
        "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
        Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."

        | upper lower |
        upper := aPrintableCharacter asUppercase asInteger.
        lower := aPrintableCharacter asLowercase asInteger.

        KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
        KeyDecodeTable at: { lower . 8 "cmd/alt" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
        KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+       KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.
+       
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
-       KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!

Item was changed:
  ----- Method: EventSensor>>processEvent: (in category 'private-I/O') -----
  processEvent: evt
        "Process a single event. This method is run at high priority."
        | type buttons window |
        type := evt at: 1.

        "Only process main window events, forward others to host window proxies"
        window := evt at: 8.
        (window isNil or: [window isZero]) ifTrue:
                [window := 1.
                evt at: 8 put: window].
        window = 1 ifFalse: [
                ^Smalltalk at: #HostWindowProxy ifPresent: [:w | w processEvent: evt]].

        "Tackle mouse events and mouse wheel events first"
        (type = EventTypeMouse or: [type = EventTypeMouseWheel])
                ifTrue: [buttons := (ButtonDecodeTable at: (evt at: 5) + 1).
                                evt at: 5 put: (Smalltalk platformName = 'Mac OS'
                                                        ifTrue: [ buttons ]
                                                        ifFalse: [ self mapButtons: buttons modifiers: (evt at: 6) ]).
                                self queueEvent: evt.
                                type = EventTypeMouse ifTrue: [self processMouseEvent: evt].
                                type = EventTypeMouseWheel ifTrue: [self processMouseWheelEvent: evt].                         
                                ^self].

        "Store the event in the queue if there's any"
        type = EventTypeKeyboard
                ifTrue: [ "Check if the event is a user interrupt"
                        ((evt at: 4) = EventKeyChar
                                and: [((evt at: 3)
                                                bitOr: (((evt at: 5)
                                                        bitAnd: 8)
                                                        bitShift: 8))
                                                        = interruptKey])
                                        ifTrue: ["interrupt key is meta - not reported as event"
                                                        ^ interruptSemaphore signal].
                        "Decode keys for characters (i.e., duplicate or swap, ctrl <-> alt/cmd)."
                        (evt at: 4) = EventKeyChar
+                               ifTrue: [ | unicode ascii |
+                                       "Copy lookup key first in case of key swap."
+                                       unicode := {evt at: 6. evt at: 5}.
+                                       ascii := {evt at: 3. evt at: 5}.
-                               ifTrue: [
                                        KeyDecodeTable "Unicode character first"
+                                               at: unicode
-                                               at: {evt at: 6. evt at: 5}
                                                ifPresent: [:a | evt at: 6 put: a first;
                                                                 at: 5 put: a second].
                                        KeyDecodeTable "ASCII character second"
+                                               at: ascii
-                                               at: {evt at: 3. evt at: 5}
                                                ifPresent: [:a | evt at: 3 put: a first;
                                                                 at: 5 put: a second]].
                        self queueEvent: evt.
                        self processKeyboardEvent: evt .
                        ^self ].

        "Handle all events other than Keyboard or Mouse."
        self queueEvent: evt.
        !




Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Kernel-mt.1289.mcz

marcel.taeumel
We can remove that hack if we adopt the VM at SHA 83e43ee7138f8a1b76ed774c3972f2691776778a as I suggested

Okay, but please leave the key-swap part to swap all kinds of printable characters. Not just that ancient edit-key selection. :-)

Best,
Marcel

Am 28.12.2019 16:52:44 schrieb Nicolas Cellier <[hidden email]>:



Le jeu. 19 déc. 2019 à 11:46, <[hidden email]> a écrit :
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1289.mcz

==================== Summary ====================

Name: Kernel-mt.1289
Author: mt
Time: 19 December 2019, 11:45:58.637761 am
UUID: e9f9d6a0-0ce8-114e-b3d2-26b481f590a1
Ancestors: Kernel-mt.1288

- fixes ctrl <-> alt key swapping bug in #processEvent:
- fixes ctrl <-> alt key swapping by extending the range to the same range as for "duplicate *all*"
- LINUX ONLY: fixes swapping and duplication of ctrl/alt keys
- LINUX ONLY: maps controls keys that arrive as ASCII 64 to 127 down to ASCII 0 to 31
- document that other (older) "duplicate keys" preference to be deprecated after the 5.3 release

So, the current VM 201911282316 should be fine for all platforms for Squeak 5.3 at the moment.

=============== Diff against Kernel-mt.1288 ===============

Item was added:
+ ----- Method: EventSensor class>>installControlKeyEntryFor: (in category 'key decode table') -----
+ installControlKeyEntryFor: aPrintableCharacter
+       
+       | upper lower |
+       self assert: (aPrintableCharacter asInteger between: 64 and: 95).
+       
+       upper := aPrintableCharacter asInteger.
+       lower := aPrintableCharacter asInteger bitOr: 16r20.
+       
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!
We can remove that hack if we adopt the VM at SHA 83e43ee7138f8a1b76ed774c3972f2691776778a as I suggested (after mouse wheel fixes https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/461 and https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/462)
IMO, we should adopt that VM, it restores compatibility with older ones.


Item was changed:
  ----- Method: EventSensor class>>installDuplicateKeyEntryFor: (in category 'key decode table') -----
  installDuplicateKeyEntryFor: aPrintableCharacter
        "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
        Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."

        | upper lower |
        upper := aPrintableCharacter asUppercase asInteger.
        lower := aPrintableCharacter asLowercase asInteger.

        KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
        KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
- !

Item was changed:
  ----- Method: EventSensor class>>installKeyDecodeTable (in category 'class initialization') -----
  installKeyDecodeTable
+       "Create a decode table that swaps or duplicates some keys if the respective preference is set."
+
-       "Create a decode table that swaps some keys if
-       Preferences swapControlAndAltKeys is set"
        KeyDecodeTable := Dictionary new.
+
+       "In any case, ensure that control keys are mapped correctly."
+       self flag: #toRemove. "mt: If all VMs send the correct control keys on all platforms, we will remove this mapping."
+       64 "$@" to: 95 "$_"do: [:keyCode | self installControlKeyEntryFor: keyCode asCharacter].
+
-       Preferences duplicateControlAndAltKeys
-               ifTrue: [ self defaultCrossPlatformKeys do:
-                               [ :c | self installDuplicateKeyEntryFor: c ] ].
        Preferences swapControlAndAltKeys
+               ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
-               ifTrue: [ self defaultCrossPlatformKeys do:
                                [ :c | self installSwappedKeyEntryFor: c ] ].
        Preferences duplicateAllControlAndAltKeys
                ifTrue: [ (Character allByteCharacters select: [:ea | ea isAlphaNumeric]) do:
                                [ :c | self installDuplicateKeyEntryFor: c ] ].
+
+       self flag: #toDeprecate. "mt: This mapping should be deprecated in the future."
+       Preferences duplicateControlAndAltKeys
+               ifTrue: [ self defaultCrossPlatformKeys do:
+                               [ :c | self installDuplicateKeyEntryFor: c ] ].
  !

Item was changed:
  ----- Method: EventSensor class>>installSwappedKeyEntryFor: (in category 'key decode table') -----
  installSwappedKeyEntryFor: aPrintableCharacter
        "Updates the key-decode table, which maps between pairs of {character code . modifier code}. See the class comment for more information.
        Note that the bitmask 16r9F removes the high bits, which subtracts 64 from the key code for (upper) $A to $Z and 96 for (lower) $a to $z. The VM sends non-printable control characters for [ctrl]+[A-Za-Z] in ASCII < 32, but the given character is expected to be ASCII >= 32 and thus printable. So we have to convert printable characters to control characters in this mapping table."

        | upper lower |
        upper := aPrintableCharacter asUppercase asInteger.
        lower := aPrintableCharacter asLowercase asInteger.

        KeyDecodeTable at: { lower bitAnd: 16r9F . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
        KeyDecodeTable at: { lower . 8 "cmd/alt" } put: { lower bitAnd: 16r9F . 2 "ctrl" }.
        KeyDecodeTable at: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.
+       KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.
+       
+       "For Unix/Linux VMs as of version 201911282316, no control characters will be sent from the VM. Avoid check for #platformName because the extra mapping will not affect others anyway."
+       self flag: #unixOnly.
+       KeyDecodeTable at: { lower . 2 "ctrl" } put: { lower . 8 "cmd/alt" }.
+       KeyDecodeTable at: { upper . 2 bitOr: 1 "ctrl+shift" } put: { upper . 8 bitOr: 1 "cmd/alt+shift" }.!
-       KeyDecodeTable at: { upper . 8 bitOr: 1 "cmd/alt+shift" } put: { upper bitAnd: 16r9F . 2 bitOr: 1 "ctrl+shift" }.!

Item was changed:
  ----- Method: EventSensor>>processEvent: (in category 'private-I/O') -----
  processEvent: evt
        "Process a single event. This method is run at high priority."
        | type buttons window |
        type := evt at: 1.

        "Only process main window events, forward others to host window proxies"
        window := evt at: 8.
        (window isNil or: [window isZero]) ifTrue:
                [window := 1.
                evt at: 8 put: window].
        window = 1 ifFalse: [
                ^Smalltalk at: #HostWindowProxy ifPresent: [:w | w processEvent: evt]].

        "Tackle mouse events and mouse wheel events first"
        (type = EventTypeMouse or: [type = EventTypeMouseWheel])
                ifTrue: [buttons := (ButtonDecodeTable at: (evt at: 5) + 1).
                                evt at: 5 put: (Smalltalk platformName = 'Mac OS'
                                                        ifTrue: [ buttons ]
                                                        ifFalse: [ self mapButtons: buttons modifiers: (evt at: 6) ]).
                                self queueEvent: evt.
                                type = EventTypeMouse ifTrue: [self processMouseEvent: evt].
                                type = EventTypeMouseWheel ifTrue: [self processMouseWheelEvent: evt].                         
                                ^self].

        "Store the event in the queue if there's any"
        type = EventTypeKeyboard
                ifTrue: [ "Check if the event is a user interrupt"
                        ((evt at: 4) = EventKeyChar
                                and: [((evt at: 3)
                                                bitOr: (((evt at: 5)
                                                        bitAnd: 8)
                                                        bitShift: 8))
                                                        = interruptKey])
                                        ifTrue: ["interrupt key is meta - not reported as event"
                                                        ^ interruptSemaphore signal].
                        "Decode keys for characters (i.e., duplicate or swap, ctrl <-> alt/cmd)."
                        (evt at: 4) = EventKeyChar
+                               ifTrue: [ | unicode ascii |
+                                       "Copy lookup key first in case of key swap."
+                                       unicode := {evt at: 6. evt at: 5}.
+                                       ascii := {evt at: 3. evt at: 5}.
-                               ifTrue: [
                                        KeyDecodeTable "Unicode character first"
+                                               at: unicode
-                                               at: {evt at: 6. evt at: 5}
                                                ifPresent: [:a | evt at: 6 put: a first;
                                                                 at: 5 put: a second].
                                        KeyDecodeTable "ASCII character second"
+                                               at: ascii
-                                               at: {evt at: 3. evt at: 5}
                                                ifPresent: [:a | evt at: 3 put: a first;
                                                                 at: 5 put: a second]].
                        self queueEvent: evt.
                        self processKeyboardEvent: evt .
                        ^self ].

        "Handle all events other than Keyboard or Mouse."
        self queueEvent: evt.
        !