Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1181.mcz
==================== Summary ====================
Name: Morphic-mt.1181
Author: mt
Time: 15 June 2016, 11:20:40.050378 am
UUID: 855f8338-73de-5947-9dc5-99e912d115a2
Ancestors: Morphic-mt.1180
ixes regression in event dispatching and coordinate transformations. Do not reset transformation in the event copy delivered to submorphs. They need those for, e.g., double click, drag-and-drop, etc.
Our events do, more or less, not change after being created and initialized. The only exception is #wasHandled, #wasIgnored, and #position during event dispatching. Keep it that way. If you plan to change some event state in an event filter, create a new event instead and do not mess around with the current one.
=============== Diff against Morphic-mt.1180 ===============
Item was changed:
----- Method: MorphicEventDispatcher>>dispatchEvent:toSubmorphsOf: (in category 'private') -----
dispatchEvent: anEvent toSubmorphsOf: aMorph
+ "Dispatch the given event to the submorphs of the given morph. For coordinate transformations, work only with copies. Either return the given event or a copy of any filtered event to employ immutability to some extent. --- PRIVATE!!"
- "Dispatch the given event to the submorphs of the given morph. --- PRIVATE!!"
+ | localEvent filteredEvent |
- | filteredEvent |
aMorph submorphsDo: [:child |
+ localEvent := anEvent transformedBy: (child transformedFrom: aMorph).
filteredEvent := child
+ processEvent: localEvent
- processEvent: (anEvent transformedBy: (child transformedFrom: aMorph))
using: self. "use same dispatcher"
+ filteredEvent == #rejected ifFalse: [ "some event or #rejected symbol"
+ self flag: #overlappingChildren. "mt: We cannot give two overlapping siblings the chance to handle the event!!"
+ filteredEvent == localEvent
+ ifTrue: [
+ localEvent wasHandled ifTrue: [anEvent copyHandlerState: localEvent].
+ anEvent wasIgnored: localEvent wasIgnored.
+ ^ anEvent]
+ ifFalse: [
+ filteredEvent := filteredEvent copy.
+ filteredEvent translateTo: anEvent position. "restore to untransformed coordinates"
+ filteredEvent wasHandled ifFalse: [filteredEvent copyHandlerState: anEvent]. "restore handler if needed"
+ ^ filteredEvent]]].
- filteredEvent == #rejected ifFalse: [ "filteredEvent or #rejected"
- filteredEvent translateTo: anEvent position. "restore to untransformed coordinates"
- filteredEvent wasHandled ifFalse: [filteredEvent copyHandlerState: anEvent]. "restore handler if needed"
- self flag: #overlappingChildren. "mt: We cannot give two overlapping siblings the chance to handle the event!!"
- ^ filteredEvent]].
^ #rejected!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1180.mcz
==================== Summary ====================
Name: Morphic-mt.1180
Author: mt
Time: 15 June 2016, 10:37:35.384378 am
UUID: 82bb6072-42a5-7d45-afb0-f324d6604079
Ancestors: Morphic-mt.1179
Fixes a regression with event filterung and bubbling in general, which affects events sent to morphs that are submorphs of the hand. Escaping drag-and-drop, for example, where events are sent to the TransferMorph.
=============== Diff against Morphic-mt.1179 ===============
Item was changed:
----- Method: Morph>>handleFocusEvent: (in category 'events-processing') -----
handleFocusEvent: anEvent
"Handle the given event. This message is sent if the receiver currently has the focus and is therefore receiving events directly from some hand.
1) Event bubbling. Do event bubbling known from MorphicEventDispatcher by calling #handleEvent: also on all owners.
2) Event capture filters. Walk along the owner chain in reverse order and apply capture filters as known from MorphicEventDispatcher.
If you want to overwrite this in a subclass (for example to implement modal dialogs) ensure to call super instead if #handleEvent: directly."
| filteredEvent |
filteredEvent := anEvent.
"TODO: Add a check to ensure that our event dispatcher is actually of kind MorphicEventDispatcher?!! We do copy its behavior though... like self defaultEventDispatcher class == MorphicEventDispatcher? Or #isKindOf:? Anyway, the outermost morph determines the event dispatcher. See HandMorph >> #sendEvent:focus:clear: and PasteUpMorph >> #processEvent:."
"Event capturing. Filters only because the capturing phase was bypassed by using the keyboard/mouse focus."
self withAllOwners reverseDo: [:morph | "reverse order to comply with default MorphEventDispatcher"
+ morph == anEvent hand ifFalse: [ "Fixes drag-and-drop bug."
+ filteredEvent := morph sendFilterEventCapture: filteredEvent for: morph.
+ filteredEvent wasIgnored ifTrue: [^ filteredEvent]]].
- filteredEvent := morph sendFilterEventCapture: filteredEvent for: morph.
- filteredEvent wasIgnored ifTrue: [^ filteredEvent]].
"Event bubbling. Filters are processed in #handleEvent:."
self withAllOwnersDo: [:morph |
+ morph == anEvent hand ifFalse: [ "Fixes drag-and-drop bug."
+ filteredEvent := morph handleEvent: filteredEvent.
+ filteredEvent wasIgnored ifTrue: [^ filteredEvent]]].
- filteredEvent := morph handleEvent: filteredEvent.
- filteredEvent wasIgnored ifTrue: [^ filteredEvent]].
^ filteredEvent!
Marcel Taeumel uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-mt.349.mcz
==================== Summary ====================
Name: Graphics-mt.349
Author: mt
Time: 15 June 2016, 10:17:51.81283 am
UUID: d844e07e-8a5e-584b-9705-c09c8a6b34a4
Ancestors: Graphics-topa.348
Improves dark-map rendering of DejaVu Sans. Now, it does not look so bold anymore but is still way more readable on darker backgrounds than the bitmap version is.
=============== Diff against Graphics-topa.348 ===============
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark12Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark14Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark17Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark20Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark7Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldDark9Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark12Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark14Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark17Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark20Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark7Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBoldObliqueDark9Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark12Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark14Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark17Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark20Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark7Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansBookDark9Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark12Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark14Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark17Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark20Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark7Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
----- Method: StrikeFont class>>dejaVuSansObliqueDark9Form (in category 'dejaVu font data') -----
(excessive size, no diff calculated)
Item was changed:
(PackageInfo named: 'Graphics') postscript: '
" Reset DejaVu to current version "
+ StrikeFont initialize.'!
- [StrikeFont initialize] value.'!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.833.mcz
==================== Summary ====================
Name: System-mt.833
Author: mt
Time: 15 June 2016, 8:28:35.974896 am
UUID: 16d33125-ba8d-6844-b266-b5a4556d16c2
Ancestors: System-mt.832
Make it possible to access the common request strings from other applications.
=============== Diff against System-mt.832 ===============
Item was added:
+ ----- Method: Utilities class>>commonRequestStrings (in category 'common requests') -----
+ commonRequestStrings
+
+ (CommonRequestStrings == nil or: [CommonRequestStrings isKindOf: Array])
+ ifTrue: [self initializeCommonRequestStrings].
+ ^ CommonRequestStrings!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1028.mcz
==================== Summary ====================
Name: Kernel-mt.1028
Author: mt
Time: 15 June 2016, 7:55:24.868664 am
UUID: ef9df82a-545e-b44a-9084-8b608be6ce69
Ancestors: Kernel-mt.1027
Extends EventSensor to be prepared for VMs to really send mouse-wheel events.
(Merges several peek* and prim* methods in EventSensor as a clean-up from the former InputSensor days.)
=============== Diff against Kernel-mt.1027 ===============
Item was changed:
Object subclass: #EventSensor
+ instanceVariableNames: 'mouseButtons mousePosition mouseWheelDelta keyboardBuffer interruptKey interruptSemaphore eventQueue inputSemaphore lastEventPoll hasInputSemaphore'
- instanceVariableNames: 'mouseButtons mousePosition keyboardBuffer interruptKey interruptSemaphore eventQueue inputSemaphore lastEventPoll hasInputSemaphore'
classVariableNames: 'ButtonDecodeTable EventPollPeriod EventTicklerProcess InterruptSemaphore InterruptWatcherProcess KeyDecodeTable'
poolDictionaries: 'EventSensorConstants'
category: 'Kernel-Processes'!
!EventSensor commentStamp: 'dtl 1/30/2016 14:44' prior: 0!
An EventSensor is an interface to the user input devices.
There is at least one instance of EventSensor named Sensor in the system.
EventSensor is a replacement for the earlier InputSensor implementation based on a set of (optional) event primitives. An EventSensor updates its state when events are received so that all state based users of Sensor (e.g., Sensor keyboard, Sensor leftShiftDown, Sensor mouseButtons) will work exactly as before, by moving the current VM mechanisms into EventSensor itself. An optional input semaphore is part of the new design.
For platforms that support true asynchronous event notification, the semaphore will be signaled to indicate pending events.
On platforms that do not support asynchronous notifications about events, the UI will have to poll EventSensor periodically to read events from the VM.
Instance variables:
mouseButtons <Integer> - mouse button state as replacement for primMouseButtons
mousePosition <Point> - mouse position as replacement for primMousePt
keyboardBuffer <SharedQueue> - keyboard input buffer
interruptKey <Integer> - currently defined interrupt key
interruptSemaphore <Semaphore> - the semaphore signaled when the interruptKey is detected
eventQueue <SharedQueue> - an optional event queue for event driven applications
inputSemaphore <Semaphore>- the semaphore signaled by the VM if asynchronous event notification is supported
lastEventPoll <Integer> - the last millisecondClockValue at which we called fetchMoreEvents
hasInputSemaphore <Boolean> - true if my inputSemaphore has actually been signaled at least once.
Class variables:
ButtonDecodeTable <ByteArray> - maps mouse buttons as reported by the VM to ones reported in the events.
KeyDecodeTable <Dictionary<SmallInteger->SmallInteger>> - maps some keys and their modifiers to other keys (used for instance to map Ctrl-X to Alt-X)
InterruptSemaphore <Semaphore> - signalled by the the VM and/or the event loop upon receiving an interrupt keystroke.
InterruptWatcherProcess <Process> - waits on the InterruptSemaphore and then responds as appropriate.
EventPollPeriod <Integer> - the number of milliseconds to wait between polling for more events in the userInterruptHandler.
EventTicklerProcess <Process> - the process that makes sure that events are polled for often enough (at least every EventPollPeriod milliseconds).
Event format:
The current event format is very simple. Each event is recorded into an 8 element array. All events must provide some SmallInteger ID (the first field in the event buffer) and a time stamp (the second field in the event buffer), so that the difference between the time stamp of an event and the current time can be reported.
Currently, the following events are defined:
Null event
=============
The Null event is returned when the ST side asks for more events but no more events are available.
Structure:
[1] - event type 0
[2-8] - unused
Mouse event structure
==========================
Mouse events are generated when mouse input is detected.
Structure:
[1] - event type 1
[2] - time stamp
[3] - mouse x position
[4] - mouse y position
[5] - button state; bitfield with the following entries:
1 - yellow (e.g., right) button
2 - blue (e.g., middle) button
4 - red (e.g., left) button
[all other bits are currently undefined]
[6] - modifier keys; bitfield with the following entries:
1 - shift key
2 - ctrl key
4 - (Mac specific) option key
8 - Cmd/Alt key
[all other bits are currently undefined]
[7] - reserved.
[8] - reserved.
Keyboard events
====================
Keyboard events are generated when keyboard input is detected.
[1] - event type 2
[2] - time stamp
[3] - character code
For now the character code is in Mac Roman encoding.
[4] - press state; integer with the following meaning
0 - character
1 - key press (down)
2 - key release (up)
[5] - modifier keys (same as in mouse events)
[6] - reserved.
[7] - reserved.
[8] - reserved.
!
Item was changed:
----- Method: EventSensor>>anyButtonPressed (in category 'mouse') -----
anyButtonPressed
"Answer whether at least one mouse button is currently being pressed."
+ ^ self peekButtons anyMask: 7
- ^ self primMouseButtons anyMask: 7
!
Item was changed:
----- Method: EventSensor>>anyModifierKeyPressed (in category 'modifier keys') -----
anyModifierKeyPressed
"ignore, however, the shift keys 'cause that's not REALLY a command key"
+ ^ self peekButtons anyMask: 16r70 "cmd | opt | ctrl"!
- ^ self primMouseButtons anyMask: 16r70 "cmd | opt | ctrl"!
Item was changed:
----- Method: EventSensor>>blueButtonPressed (in category 'mouse') -----
blueButtonPressed
"Answer whether only the blue mouse button is being pressed.
This is the third mouse button or cmd+click on the Mac."
+ ^ (self peekButtons bitAnd: 7) = 1
- ^ (self primMouseButtons bitAnd: 7) = 1
!
Item was changed:
----- Method: EventSensor>>commandKeyPressed (in category 'modifier keys') -----
commandKeyPressed
"Answer whether the command key on the keyboard is being held down."
+ ^ self peekButtons anyMask: 64!
- ^ self primMouseButtons anyMask: 64!
Item was changed:
----- Method: EventSensor>>controlKeyPressed (in category 'modifier keys') -----
controlKeyPressed
"Answer whether the control key on the keyboard is being held down."
+ ^ self peekButtons anyMask: 16!
- ^ self primMouseButtons anyMask: 16!
Item was changed:
----- Method: EventSensor>>createMouseEvent (in category 'mouse') -----
createMouseEvent
"create and return a new mouse event from the current mouse
position; this is useful for restarting normal event queue
processing after manual polling"
| buttons modifiers pos mapped eventBuffer |
eventBuffer := Array new: 8.
+ buttons := self peekButtons.
+ pos := self peekPosition.
- buttons := self primMouseButtons.
- pos := self primMousePt.
modifiers := buttons bitShift: -3.
buttons := buttons bitAnd: 7.
mapped := self mapButtons: buttons modifiers: modifiers.
eventBuffer
at: 1
put: EventTypeMouse;
at: 2 put: Time eventMillisecondClock;
at: 3 put: pos x;
at: 4 put: pos y;
at: 5 put: mapped;
at: 6 put: modifiers.
^ eventBuffer!
Item was changed:
----- Method: EventSensor>>initialize (in category 'initialize') -----
initialize
"Initialize the receiver"
mouseButtons := 0.
mousePosition := 0 @ 0.
+ mouseWheelDelta := 0 @ 0.
keyboardBuffer := SharedQueue new.
self setInterruptKey: (interruptKey ifNil: [$. asciiValue bitOr: 16r0800 ]). "cmd-."
interruptSemaphore := (Smalltalk specialObjectsArray at: 31) ifNil: [Semaphore new].
self flushAllButDandDEvents.
inputSemaphore := Semaphore new.
hasInputSemaphore := false.!
Item was changed:
----- Method: EventSensor>>keyboard (in category 'keyboard') -----
keyboard
"Answer the next character from the keyboard."
| firstCharacter secondCharactor stream multiCharacter converter |
firstCharacter := self characterForKeycode: self primKbdNext.
+ secondCharactor := self peekKeyboard.
- secondCharactor := self characterForKeycode: self primKbdPeek.
secondCharactor isNil
ifTrue: [^ firstCharacter].
converter := TextConverter defaultSystemConverter.
converter isNil
ifTrue: [^ firstCharacter].
stream := ReadStream
on: (String with: firstCharacter with: secondCharactor).
multiCharacter := converter nextFromStream: stream.
multiCharacter isOctetCharacter
ifTrue: [^ multiCharacter].
self primKbdNext.
^ multiCharacter
!
Item was removed:
- ----- Method: EventSensor>>keyboardPeek (in category 'keyboard') -----
- keyboardPeek
- "Answer the next character in the keyboard buffer without removing it, or nil if it is empty."
-
- ^ self characterForKeycode: self primKbdPeek!
Item was changed:
----- Method: EventSensor>>keyboardPressed (in category 'keyboard') -----
keyboardPressed
"Answer true if keystrokes are available."
+ ^self peekKeyboard notNil!
- ^self primKbdPeek notNil!
Item was changed:
----- Method: EventSensor>>leftShiftDown (in category 'modifier keys') -----
leftShiftDown
"Answer whether the shift key on the keyboard is being held down. The name of this message is a throwback to the Alto, which had independent left and right shift keys."
+ ^ self peekButtons anyMask: 8!
- ^ self primMouseButtons anyMask: 8!
Item was changed:
----- Method: EventSensor>>mouseButtons (in category 'mouse') -----
mouseButtons
"Answer a number from 0 to 7 that encodes the state of the three mouse buttons in its lowest 3 bits."
+ ^ self peekButtons bitAnd: 7
- ^ self primMouseButtons bitAnd: 7
!
Item was changed:
----- Method: EventSensor>>nextEventSynthesized (in category 'private') -----
nextEventSynthesized
"Return a synthesized event. This method is called if an event driven client wants to receive events but the primary user interface is not event-driven (e.g., the receiver does not have an event queue but only updates its state). This can, for instance, happen if a Morphic World is run in an MVC window. To simplify the clients work this method will always return all available keyboard events first, and then (repeatedly) the mouse events. Since mouse events come last, the client can assume that after one mouse event has been received there are no more to come. Note that it is impossible for EventSensor to determine if a mouse event has been issued before so the client must be aware of the possible problem of getting repeatedly the same mouse events. See HandMorph>>processEvents for an example on how to deal with this."
| kbd array buttons pos modifiers mapped |
"First check for keyboard"
array := Array new: 8.
kbd := self primKbdNext.
kbd ifNotNil:
["simulate keyboard event"
array at: 1 put: EventTypeKeyboard. "evt type"
array at: 2 put: Time eventMillisecondClock. "time stamp"
array at: 3 put: (kbd bitAnd: 255). "char code"
array at: 4 put: EventKeyChar. "key press/release"
array at: 5 put: (kbd bitShift: -8). "modifier keys"
^ array].
"Then check for mouse"
+ pos := self peekPosition.
- pos := self primMousePt.
buttons := mouseButtons.
modifiers := buttons bitShift: -3.
buttons := buttons bitAnd: 7.
mapped := self mapButtons: buttons modifiers: modifiers.
array
at: 1 put: EventTypeMouse;
at: 2 put: Time eventMillisecondClock;
at: 3 put: pos x;
at: 4 put: pos y;
at: 5 put: mapped;
at: 6 put: modifiers.
^ array
!
Item was changed:
----- Method: EventSensor>>peekButtons (in category 'accessing') -----
peekButtons
self fetchMoreEvents.
+ self flushNonKbdEvents.
+ ^ mouseButtons!
- ^mouseButtons!
Item was added:
+ ----- Method: EventSensor>>peekKeyboard (in category 'keyboard') -----
+ peekKeyboard
+ "Answer the next character in the keyboard buffer without removing it, or nil if it is empty."
+
+ | char |
+ self fetchMoreEvents.
+ keyboardBuffer isEmpty ifFalse: [^ self characterForKeycode: keyboardBuffer peek].
+ char := nil.
+ self eventQueue ifNotNil: [:queue |
+ queue nextOrNilSuchThat: "NOTE: must not return out of this block, so loop to end"
+ [:buf | (self isKbdEvent: buf) ifTrue: [char ifNil: [char := buf at: 3]].
+ false "NOTE: block value must be false so Queue won't advance"]].
+ ^ self characterForKeycode: char!
Item was changed:
----- Method: EventSensor>>peekPosition (in category 'accessing') -----
peekPosition
+ self fetchMoreEvents.
+ "self flushNonKbdEvents. -- mt: Should not be necessary here."
+ ^ mousePosition!
- ^ self primMousePt!
Item was added:
+ ----- Method: EventSensor>>peekWheelDelta (in category 'accessing') -----
+ peekWheelDelta
+ self fetchMoreEvents.
+ ^ mouseWheelDelta!
Item was changed:
----- Method: EventSensor>>primKbdNext (in category 'private') -----
primKbdNext
"Allows for use of old Sensor protocol to get at the keyboard,
as when running kbdTest or the InterpreterSimulator in Morphic"
| evtBuf |
+
+ self flag: #refactor. "mt: Suspiciously similar to #peekKeyboardEvent"
self fetchMoreEvents.
keyboardBuffer isEmpty ifFalse:[^ keyboardBuffer next].
self eventQueue ifNotNil: [:queue |
evtBuf := queue nextOrNilSuchThat: [:buf | self isKbdEvent: buf].
self flushNonKbdEvents].
^ evtBuf ifNotNil: [evtBuf at: 3]
!
Item was removed:
- ----- Method: EventSensor>>primKbdPeek (in category 'private') -----
- primKbdPeek
- "Allows for use of old Sensor protocol to get at the keyboard,
- as when running kbdTest or the InterpreterSimulator in Morphic"
- | char |
- self fetchMoreEvents.
- keyboardBuffer isEmpty ifFalse: [^ keyboardBuffer peek].
- char := nil.
- self eventQueue ifNotNil: [:queue |
- queue nextOrNilSuchThat: "NOTE: must not return out of this block, so loop to end"
- [:buf | (self isKbdEvent: buf) ifTrue: [char ifNil: [char := buf at: 3]].
- false "NOTE: block value must be false so Queue won't advance"]].
- ^ char!
Item was removed:
- ----- Method: EventSensor>>primMouseButtons (in category 'private') -----
- primMouseButtons
- self fetchMoreEvents.
- self flushNonKbdEvents.
- ^ mouseButtons!
Item was removed:
- ----- Method: EventSensor>>primMousePt (in category 'private') -----
- primMousePt
- self fetchMoreEvents.
- "self flushNonKbdEvents. -- mt: Should not be necessary here."
- ^ mousePosition!
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])
- "Tackle mouse events first"
- type = EventTypeMouse
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 processMouseEvent: 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) = 0
and: [((evt at: 3)
bitOr: (((evt at: 5)
bitAnd: 8)
bitShift: 8))
= interruptKey])
ifTrue: ["interrupt key is meta - not reported as event"
^ interruptSemaphore signal].
"Else swap ctrl/alt keys if neeeded.
Look at the Unicode char first, then ascii."
KeyDecodeTable
at: {evt at: 6. evt at: 5}
ifPresent: [:a | evt at: 6 put: a first;
at: 5 put: a second].
KeyDecodeTable
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 Keyborad or Mouse."
self queueEvent: evt.
!
Item was added:
+ ----- Method: EventSensor>>processMouseWheelEvent: (in category 'private-I/O') -----
+ processMouseWheelEvent: evt
+ "process a mouse wheel event, updating EventSensor state"
+
+ | modifiers buttons mapped |
+ mouseWheelDelta := (evt at: 3) @ (evt at: 4).
+ buttons := evt at: 5.
+ modifiers := evt at: 6.
+ mapped := self mapButtons: buttons modifiers: modifiers.
+ mouseButtons := mapped bitOr: (modifiers bitShift: 3).!
Item was changed:
----- Method: EventSensor>>rawMacOptionKeyPressed (in category 'modifier keys') -----
rawMacOptionKeyPressed
"Answer whether the option key on the Macintosh keyboard is being held down. Macintosh specific. Clients are discouraged from calling this directly, since it circumvents bert's attempt to eradicate option-key checks"
+ ^ self peekButtons anyMask: 32!
- ^ self primMouseButtons anyMask: 32!
Item was changed:
----- Method: EventSensor>>redButtonPressed (in category 'mouse') -----
redButtonPressed
"Answer true if only the red mouse button is being pressed.
This is the first mouse button, usually the left one."
+ ^ (self peekButtons bitAnd: 7) = 4
- ^ (self primMouseButtons bitAnd: 7) = 4
!
Item was changed:
----- Method: EventSensor>>shiftPressed (in category 'modifier keys') -----
shiftPressed
"Answer whether the shift key on the keyboard is being held down."
+ ^ self peekButtons anyMask: 8
- ^ self primMouseButtons anyMask: 8
!
Item was changed:
----- Method: EventSensor>>yellowButtonPressed (in category 'mouse') -----
yellowButtonPressed
"Answer whether only the yellow mouse button is being pressed.
This is the second mouse button or option+click on the Mac."
+ ^ (self peekButtons bitAnd: 7) = 2
- ^ (self primMouseButtons bitAnd: 7) = 2
!
Item was changed:
SharedPool subclass: #EventSensorConstants
instanceVariableNames: ''
+ classVariableNames: 'BlueButtonBit CommandKeyBit CtrlKeyBit EventKeyChar EventKeyDown EventKeyUp EventTouchCancelled EventTouchDown EventTouchMoved EventTouchStationary EventTouchUp EventTypeComplex EventTypeDragDropFiles EventTypeKeyboard EventTypeMenu EventTypeMouse EventTypeMouseWheel EventTypeNone EventTypeWindow OptionKeyBit RedButtonBit ShiftKeyBit TouchPhaseBegan TouchPhaseCancelled TouchPhaseEnded TouchPhaseMoved TouchPhaseStationary WindowEventActivated WindowEventClose WindowEventIconise WindowEventMetricChange WindowEventPaint WindowEventStinks YellowButtonBit'
- classVariableNames: 'BlueButtonBit CommandKeyBit CtrlKeyBit EventKeyChar EventKeyDown EventKeyUp EventTouchCancelled EventTouchDown EventTouchMoved EventTouchStationary EventTouchUp EventTypeComplex EventTypeDragDropFiles EventTypeKeyboard EventTypeMenu EventTypeMouse EventTypeNone EventTypeWindow OptionKeyBit RedButtonBit ShiftKeyBit TouchPhaseBegan TouchPhaseCancelled TouchPhaseEnded TouchPhaseMoved TouchPhaseStationary WindowEventActivated WindowEventClose WindowEventIconise WindowEventMetricChange WindowEventPaint WindowEventStinks YellowButtonBit'
poolDictionaries: ''
category: 'Kernel-Processes'!
Item was changed:
----- Method: EventSensorConstants class>>initialize (in category 'pool initialization') -----
initialize
"EventSensorConstants initialize"
RedButtonBit := 4.
BlueButtonBit := 2.
YellowButtonBit := 1.
ShiftKeyBit := 1.
CtrlKeyBit := 2.
OptionKeyBit := 4.
CommandKeyBit := 8.
"Types of events"
EventTypeNone := 0.
EventTypeMouse := 1.
EventTypeKeyboard := 2.
EventTypeDragDropFiles := 3.
EventTypeMenu := 4.
EventTypeWindow := 5.
EventTypeComplex := 6.
+ EventTypeMouseWheel := 7.
"Press codes for keyboard events"
EventKeyChar := 0.
EventKeyDown := 1.
EventKeyUp := 2.
"Host window events"
WindowEventMetricChange := 1.
WindowEventClose := 2.
WindowEventIconise := 3.
WindowEventActivated := 4.
WindowEventPaint := 5.
WindowEventStinks := 6.
"types for touch events"
EventTouchDown := 1.
EventTouchUp := 2.
EventTouchMoved := 3.
EventTouchStationary := 4.
EventTouchCancelled := 5.
"iOS touch phase constants"
TouchPhaseBegan := 0.
TouchPhaseMoved := 1.
TouchPhaseStationary := 2.
TouchPhaseEnded := 3.
TouchPhaseCancelled := 4.
!
Tobias Pape uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-topa.348.mcz
==================== Summary ====================
Name: Graphics-topa.348
Author: topa
Time: 13 June 2016, 5:06:06.327909 pm
UUID: c1b49cca-982f-4f98-998d-2f0df96fcdd8
Ancestors: Graphics-topa.347
Very Small fonts do no longer need descender adjustment
=============== Diff against Graphics-topa.347 ===============
Item was changed:
----- Method: StrikeFont>>descent (in category 'accessing') -----
descent
"Answer the receiver's maximum extent of characters below the baseline."
+ ^descent!
- ^pointSize < 9
- ifTrue: [descent-1]
- ifFalse: [descent]!
Item was changed:
(PackageInfo named: 'Graphics') postscript: '
" Reset DejaVu to current version "
+ [StrikeFont initialize] value.'!
- StrikeFont initialize'!