<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        Finally! A name for that magic number. ^__^<div class="mb_sig"></div><blockquote class='history_container' type='cite' style='border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;'>
                        <p style='color: #AAAAAA; margin-top: 10px;'>Am 04.03.2021 22:13:24 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style='font-family:Arial,Helvetica,sans-serif'>Eliot Miranda uploaded a new version of Morphic to project The Trunk:<br>http://source.squeak.org/trunk/Morphic-eem.1735.mcz<br><br>==================== Summary ====================<br><br>Name: Morphic-eem.1735<br>Author: eem<br>Time: 4 March 2021, 1:13:03.650992 pm<br>UUID: 7ba0bde5-351e-b94c-a4b5-a4846f3f907c<br>Ancestors: Morphic-eem.1734<br><br>Use the constants on the class side of MouseEvent (adding numButtons to them) when creating the button field that (incredibly annoyingly) combines mouse buttons and modifier keys.  This is a necessary first step to increasing the nu,ber of buttons to include the moveLeft and moveRight buttons on modern gaming mice.<br><br>=============== Diff against Morphic-eem.1734 ===============<br><br>Item was changed:<br>  ----- Method: HandMorph>>generateDropFilesEvent: (in category 'private events') -----<br>  generateDropFilesEvent: evtBuf <br>      "Generate the appropriate mouse event for the given raw event buffer."<br>  <br>          | position buttons modifiers stamp numFiles dragType |<br>        stamp := evtBuf second.<br>       stamp = 0 ifTrue: [stamp := Time eventMillisecondClock].<br>      dragType := evtBuf third.<br>     position := evtBuf fourth @ evtBuf fifth.<br>     buttons := MouseEvent redButton. "hacked because necessary for correct mouseMoveDragging handling"<br>          modifiers := evtBuf sixth.<br>+   buttons := buttons bitOr: (modifiers bitShift: MouseEvent numButtons).<br>-       buttons := buttons bitOr: (modifiers bitShift: 3).<br>    numFiles := evtBuf seventh.<br>   <br>      dragType caseOf: {<br>            [1] -> [ "dragEnter"<br>                     externalDropMorph := TransferMorph new<br>                                dragTransferType: #filesAndDirectories;<br>                               source: self;<br>                                 passenger: (numFiles = 0 "Usually, numFiles and drop paths are delivered on dragDrop only. Still reserving this possibility for able host implementations."<br>                                         ifTrue: [self flag: #vmCapabilityMissing. 'Unknown host content' translated]<br>                                          ifFalse: [FileDirectory dropFilesAndDirectories: numFiles]);<br>                                  yourself.<br>                     <br>                      "During the drag operation, the host system is responsible for displaying the cursor."<br>                      self grabMorph: externalDropMorph.<br>                    self showTemporaryCursor: Cursor blank.<br>                       externalDropMorph bottomRight: self topLeft. "Southeast area of the cursor is blocked by drawings from the source application. Display our drop morph at the opposite corner of the cursor." ].<br>             [2] -> [ "dragMove"<br>                      ^ MouseMoveEvent new <br>                                 setType: #mouseMove<br>                           startPoint: self position<br>                             endPoint: position<br>                            trail: "{self position. position}"(self mouseDragTrailFrom: evtBuf)<br>                                 buttons: buttons<br>                              hand: self<br>                            stamp: stamp ].<br>               [3]  -> [ "dragLeave"<br>                    externalDropMorph ifNotNil: #abandon.<br>                         externalDropMorph := nil.<br>                     self showTemporaryCursor: nil ].<br>              [4] -> [ "dragDrop"<br>                      | oldButtons |<br>                        externalDropMorph ifNil: [<br>                            "dragDrop has been sent without prior dragging. This happens when the VM is configured as singleton application and has been called again (aka #launchDrop)."<br>                               ^ self error: 'Launch drop for singleton Squeak         not yet implemented.'].<br>                       <br>                      self showTemporaryCursor: nil.<br>                        externalDropMorph passenger isString ifTrue: [<br>                                self flag: #vmCapabilityMissing. "See above."<br>                               externalDropMorph passenger: (FileDirectory dropFilesAndDirectories: numFiles)].<br>                      externalDropMorph := nil.<br>                     <br>                      (Smalltalk classNamed: #DropFilesEvent) ifNotNil: [:eventClass |<br>                              | classicEvent |<br>                              "Generate classic DropFilesEvent, providing backward compatibility."<br>                                classicEvent := eventClass new<br>                                        setPosition: position<br>                                         contents: numFiles<br>                                    hand: self.<br>                           self processEvent: classicEvent.<br>                              classicEvent wasHandled ifTrue: [^ nil]].<br>                     <br>                      oldButtons := lastEventBuffer fifth<br>+                          bitOr: (lastEventBuffer sixth bitShift: MouseEvent numButtons).<br>-                              bitOr: (lastEventBuffer sixth bitShift: 3).<br>                   ^ MouseButtonEvent new <br>                               setType: #mouseUp<br>                             position: position<br>                            which: (oldButtons bitXor: buttons)<br>                           buttons: buttons<br>                              nClicks: 0<br>                            hand: self<br>                            stamp: stamp ].<br>               [5] -> [ "drag request"<br>                          "For dnd out. Not properly implemented at the moment."<br>                      self shouldBeImplemented] }.<br>          ^ nil!<br><br>Item was changed:<br>  ----- Method: HandMorph>>generateKeyboardEvent: (in category 'private events') -----<br>  generateKeyboardEvent: evtBuf<br>    "Generate the appropriate mouse event for the given raw event buffer"<br>  <br>   | buttons modifiers type pressType stamp keyValue |<br>   stamp := evtBuf second.<br>       stamp = 0 ifTrue: [stamp := Sensor eventTimeNow].<br>     pressType := evtBuf fourth.<br>   pressType = EventKeyDown ifTrue: [type := #keyDown].<br>          pressType = EventKeyUp ifTrue: [type := #keyUp].<br>      pressType = EventKeyChar ifTrue: [type := #keystroke].<br>        modifiers := evtBuf fifth.<br>+   buttons := (modifiers bitShift: MouseEvent numButtons) bitOr: (lastMouseEvent buttons bitAnd: MouseEvent anyButton).<br>-         buttons := (modifiers bitShift: 3) bitOr: (lastMouseEvent buttons bitAnd: 7).<br>         type = #keystroke<br>             ifTrue: [keyValue := (self keyboardInterpreter nextCharFrom: Sensor firstEvt: evtBuf) asInteger]<br>              ifFalse: [keyValue := evtBuf third].<br>          ^ KeyboardEvent new<br>           setType: type<br>                 buttons: buttons<br>              position: self position<br>               keyValue: keyValue<br>            hand: self<br>            stamp: stamp.<br>  !<br><br>Item was changed:<br>  ----- Method: HandMorph>>generateMouseEvent: (in category 'private events') -----<br>  generateMouseEvent: evtBuf <br>     "Generate the appropriate mouse event for the given raw event buffer"<br>  <br>   | position buttons modifiers type trail stamp oldButtons evtChanged |<br>         evtBuf first = lastEventBuffer first <br>                 ifTrue: <br>                      ["Workaround for Mac VM bug, *always* generating 3 events on clicks"<br>  <br>                    evtChanged := false.<br>                          3 to: evtBuf size<br>                             do: [:i | (lastEventBuffer at: i) = (evtBuf at: i) ifFalse: [evtChanged := true]].<br>                    evtChanged ifFalse: [^nil]].<br>          stamp := evtBuf second.<br>       stamp = 0 ifTrue: [stamp := Sensor eventTimeNow].<br>     position := evtBuf third @ evtBuf fourth.<br>     buttons := evtBuf fifth.<br>      modifiers := evtBuf sixth.<br>  <br>        type := buttons = 0 <br>+                         ifTrue:<br>+                              [lastEventBuffer fifth = 0              <br>+                                     ifTrue: [#mouseMove]            "this time no button and previously no button .. just mouse move"<br>+                                  ifFalse: [#mouseUp]]            "this time no button but previously some button ... therefore button was released"<br>+                         ifFalse:<br>+                             [buttons = lastEventBuffer fifth<br>+                                             ifTrue: [#mouseMove]    "button states are the same .. now and past .. therfore a mouse movement"<br>+                                          ifFalse:                                        "button states are different .. button was pressed or released"<br>+                                                    [buttons > lastEventBuffer fifth<br>-          ifTrue:[<br>-                             lastEventBuffer fifth = 0               <br>-                                     ifTrue: [#mouseMove]    "this time no button and previously no button .. just mouse move"<br>-                                  ifFalse: [#mouseUp]             "this time no button but previously some button ... therefore button was released"<br>-                 ]<br>-            ifFalse:[<br>-                            buttons = lastEventBuffer fifth<br>-                                              ifTrue: [#mouseMove]            "button states are the same .. now and past .. therfore a mouse movement"<br>-                                          ifFalse: [                                      "button states are different .. button was pressed or released"<br>-                                                    buttons > lastEventBuffer fifth<br>                                                            ifTrue: [#mouseDown]<br>+                                                                 ifFalse:[#mouseUp]]].<br>+        buttons := buttons bitOr: (modifiers bitShift: MouseEvent numButtons).<br>+       oldButtons := lastEventBuffer fifth bitOr: (lastEventBuffer sixth bitShift: MouseEvent numButtons).<br>-                                                          ifFalse:[#mouseUp].<br>-                                          ].<br>-           ].<br>-   buttons := buttons bitOr: (modifiers bitShift: 3).<br>-   oldButtons := lastEventBuffer fifth <br>-                                 bitOr: (lastEventBuffer sixth bitShift: 3).<br>   lastEventBuffer := evtBuf.<br>+   type == #mouseMove ifTrue: <br>+          [trail := self mouseTrailFrom: evtBuf.<br>+               ^MouseMoveEvent new <br>+                         setType: type<br>+                        startPoint: self position<br>+                    endPoint: trail last<br>+                         trail: trail<br>+                         buttons: buttons<br>+                     hand: self<br>+                   stamp: stamp].<br>-       type == #mouseMove <br>-          ifTrue: <br>-                     [trail := self mouseTrailFrom: evtBuf.<br>-                       ^MouseMoveEvent new <br>-                                 setType: type<br>-                                startPoint: (self position)<br>-                          endPoint: trail last<br>-                                 trail: trail<br>-                                 buttons: buttons<br>-                             hand: self<br>-                           stamp: stamp].<br>        ^MouseButtonEvent new <br>                setType: type<br>                 position: position<br>            which: (oldButtons bitXor: buttons)<br>           buttons: buttons<br>              nClicks: (evtBuf seventh ifNil: [0])<br>                  hand: self<br>            stamp: stamp!<br><br>Item was changed:<br>  ----- Method: HandMorph>>showEvent: (in category 'events-debugging') -----<br>  showEvent: anEvent<br>          "Show details about the event on the display form. Useful for debugging."<br>+  "ShowEvents := true"<br>+       "ShowEvents := false"<br>-      <br>      | message borderWidth |<br>       ShowEvents == true ifFalse: [^ self].<br>         <br>      borderWidth := 5.<br>     message := String streamContents: [:strm |<br>            strm<br>                          nextPutAll: '[HandMorph >> #showEvent:]'; cr;<br>                   nextPutAll: 'event'; tab; tab; tab; tab; nextPutAll: anEvent printString; cr;<br>                         nextPutAll: 'keyboard focus'; tab; tab; nextPutAll: self keyboardFocus printString; cr;<br>                       nextPutAll: 'mouse focus'; tab; tab; nextPutAll: self mouseFocus printString].<br>                <br>      message := message asDisplayText<br>              foregroundColor: Color black<br>                  backgroundColor: Color white.<br>         <br>      "Offset to support multiple hands debugging."<br>       Display fill: (0 @ 0 extent: message form extent + (borderWidth asPoint * 2)) rule: Form over fillColor: Color white.<br>         message displayOn: Display at: borderWidth asPoint + (0 @  ((owner hands indexOf: self) - 1 * message form height)).!<br><br>Item was added:<br>+ ----- Method: MouseEvent class>>numButtons (in category 'constants') -----<br>+ numButtons<br>+   "We support three button mice."<br>+    ^3!<br><br><br></div></blockquote>
                                        </div></body>