Marcel Taeumel uploaded a new version of ShoutCore to project The Trunk:
http://source.squeak.org/trunk/ShoutCore-mt.83.mcz
==================== Summary ====================
Name: ShoutCore-mt.83
Author: mt
Time: 17 June 2020, 11:19:27.180028 am
UUID: d7c366fe-a8d5-ea46-a84b-2846be0998e6
Ancestors: ShoutCore-mt.82
Since the compiler can handle classes as shared pools already, move Shout support up to Behavior.
Note that I chose Behavior over ClassDescription because there is Shout support already. We might want to push both #shoutParserClass and this one down to ClassDescription some day...
=============== Diff against ShoutCore-mt.82 ===============
Item was added:
+ ----- Method: Behavior>>hasBindingThatBeginsWith: (in category '*ShoutCore-Parsing') -----
+ hasBindingThatBeginsWith: aString
+ "Answer true if the receiver has a binding that begins with aString, false otherwise"
+
+ "First look in classVar dictionary."
+ (self classPool hasBindingThatBeginsWith: aString) ifTrue:[^true].
+ "Next look in shared pools."
+ self sharedPools do:[:pool |
+ (pool hasBindingThatBeginsWith: aString) ifTrue: [^true]].
+ ^false!
Item was removed:
- ----- Method: SharedPool class>>hasBindingThatBeginsWith: (in category '*ShoutCore') -----
- hasBindingThatBeginsWith: aString
- "Answer true if the receiver has a binding that begins with aString, false otherwise"
-
- "First look in classVar dictionary."
- (self classPool hasBindingThatBeginsWith: aString) ifTrue:[^true].
- "Next look in shared pools."
- self sharedPools do:[:pool |
- (pool hasBindingThatBeginsWith: aString) ifTrue: [^true]].
- ^false!
Chris Cunningham uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ct.1666.mcz
==================== Summary ====================
Name: Morphic-ct.1666
Author: ct
Time: 6 June 2020, 2:20:38.028259 pm
UUID: 8476dcc1-0e3b-cd44-98bd-997fd6ead0fe
Ancestors: Morphic-cbc.1664
Another proposal for dealing with keyboard focus in diaog windows: Introduce #needsClickToFocus property. If enabled, message body must be clicked before key events go to the text morph instead of the dialog window.
Very kindly protest against Morphic-cbc.1665 (inbox) which would forbid any possible useful keyboard interaction with the message text, for example <cmd>a or <cmd>c. :-)
=============== Diff against Morphic-cbc.1664 ===============
Item was changed:
----- Method: DialogWindow>>createMessage: (in category 'initialization') -----
createMessage: aString
messageMorph := aString asText asMorph.
messageMorph
name: 'Message';
readOnly: true;
setProperty: #indicateKeyboardFocus toValue: #never;
+ setProperty: #needsClickToFocus toValue: true.
- lock.
self setMessageParameters.
^ messageMorph!
Item was changed:
----- Method: TextMorph>>handlesKeyboard: (in category 'event handling') -----
+ handlesKeyboard: anEvent
+
+ ^ ((self valueOfProperty: #needsClickToFocus ifAbsent: [false]) ==> [
+ anEvent hand keyboardFocus = self])!
- handlesKeyboard: evt
- ^true!
Chris Cunningham uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-cbc.1668.mcz
==================== Summary ====================
Name: Morphic-cbc.1668
Author: cbc
Time: 16 June 2020, 8:36:04.285918 pm
UUID: 9e2392ae-55f6-9748-b55f-263f9b440d47
Ancestors: Morphic-mt.1666, Morphic-ct.1666
Merging Morphic-ct.1666 into the main line. Fixes dialog boxes so that we can interact with the message after clicking on the text - but still allowing keyboard control with keys prior to mouse interaction.
=============== Diff against Morphic-mt.1666 ===============
Item was changed:
----- Method: DialogWindow>>createMessage: (in category 'initialization') -----
createMessage: aString
messageMorph := aString asText asMorph.
messageMorph
name: 'Message';
readOnly: true;
setProperty: #indicateKeyboardFocus toValue: #never;
+ setProperty: #needsClickToFocus toValue: true.
- lock.
self setMessageParameters.
^ messageMorph!
Item was changed:
----- Method: TextMorph>>handlesKeyboard: (in category 'event handling') -----
+ handlesKeyboard: anEvent
+
+ ^ ((self valueOfProperty: #needsClickToFocus ifAbsent: [false]) ==> [
+ anEvent hand keyboardFocus = self])!
- handlesKeyboard: evt
- ^true!
Marcel Taeumel uploaded a new version of Monticello to project The Trunk:
http://source.squeak.org/trunk/Monticello-mt.724.mcz
==================== Summary ====================
Name: Monticello-mt.724
Author: mt
Time: 16 June 2020, 2:06:17.310762 pm
UUID: a6026367-76f2-d84d-9fd2-2a829c174d64
Ancestors: Monticello-mt.723
Also check the package cache when looking for a new unique version name because that cache may hold local experiments.
=============== Diff against Monticello-mt.723 ===============
Item was changed:
----- Method: MCWorkingCopy>>uniqueVersionName (in category 'private') -----
uniqueVersionName
|versionName|
counter := nil.
[versionName := self nextVersionName.
+ (MCRepository packageCache includesVersionNamed: versionName)
+ or: [self repositoryGroup includesVersionNamed: versionName]] whileTrue.
- self repositoryGroup includesVersionNamed: versionName] whileTrue.
^ versionName!
Marcel Taeumel uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-mt.898.mcz
==================== Summary ====================
Name: Collections-mt.898
Author: mt
Time: 16 June 2020, 8:55:38.416917 am
UUID: 89207449-befb-f84f-83a0-ff0d727d40bc
Ancestors: Collections-mt.896, Collections-ul.897
Merges ancestry.
Does somebody know where to find Collections-ul.896?
=============== Diff against Collections-mt.896 ===============
Item was removed:
- ----- Method: ByteArray>>atAllPut: (in category 'accessing') -----
- atAllPut: value
- "Fill the receiver with the given value"
-
- <primitive: 145>
- super atAllPut: value!
Item was changed:
----- Method: String>>< (in category 'comparing') -----
< aString
"Answer whether the receiver sorts before aString.
The collation order is simple ascii (with case differences)."
+ ^(self compareWith: aString) < 0!
- ^ (self compare: self with: aString collated: AsciiOrder) = 1!
Item was changed:
----- Method: String>><= (in category 'comparing') -----
<= aString
"Answer whether the receiver sorts before or equal to aString.
The collation order is simple ascii (with case differences)."
+ ^(self compareWith: aString) <= 0!
- ^ (self compare: self with: aString collated: AsciiOrder) <= 2!
Item was changed:
----- Method: String>>= (in category 'comparing') -----
= aString
"Answer whether the receiver sorts equally as aString.
The collation order is simple ascii (with case differences)."
self == aString ifTrue: [ ^true ].
aString isString ifFalse: [ ^false ].
self size = aString size ifFalse: [ ^false ].
+ ^ (self compareWith: aString) = 0!
- ^ (self compare: self with: aString collated: AsciiOrder) = 2!
Item was changed:
----- Method: String>>> (in category 'comparing') -----
> aString
"Answer whether the receiver sorts after aString.
The collation order is simple ascii (with case differences)."
+ ^(self compareWith: aString) > 0!
- ^ (self compare: self with: aString collated: AsciiOrder) = 3!
Item was changed:
----- Method: String>>>= (in category 'comparing') -----
>= aString
"Answer whether the receiver sorts after or equal to aString.
The collation order is simple ascii (with case differences)."
+ ^(self compareWith: aString) >= 0!
- ^ (self compare: self with: aString collated: AsciiOrder) >= 2!
Item was changed:
----- Method: String>>compare:caseSensitive: (in category 'comparing') -----
compare: aString caseSensitive: aBool
"Answer a comparison code telling how the receiver sorts relative to aString:
1 - before
2 - equal
3 - after.
"
| map |
map := aBool ifTrue:[CaseSensitiveOrder] ifFalse:[CaseInsensitiveOrder].
+ ^(self compareWith: aString collated: map) + 2!
- ^self compare: self with: aString collated: map!
Item was added:
+ ----- Method: String>>compareWith: (in category 'comparing') -----
+ compareWith: aString
+
+ "<primitive: 158>"
+ ^(self compare: self with: aString collated: AsciiOrder) - 2!
Item was added:
+ ----- Method: String>>compareWith:collated: (in category 'comparing') -----
+ compareWith: aString collated: collation
+
+ "<primitive: 158>"
+ ^(self compare: self with: aString collated: collation) - 2!
Item was removed:
- ----- Method: WeakIdentityDictionary>>cleanupIndex: (in category 'private') -----
- cleanupIndex: anInteger
- array at: anInteger put: vacuum.
- tally := tally - 1.
- self fixCollisionsFrom: anInteger.!
Item was changed:
----- Method: WeakIdentityDictionary>>fixCollisionsFrom: (in category 'private') -----
fixCollisionsFrom: start
"The element at start has been removed and replaced by vacuum.
This method moves forward from there, relocating any entries
that had been placed below due to collisions with this one."
| element index |
index := start.
[ (element := array at: (index := index \\ array size + 1)) == vacuum ] whileFalse: [
element
ifNil:
[ "The binding at this slot was reclaimed - finish the cleanup"
array at: index put: vacuum.
tally := tally - 1 ]
ifNotNil:
[| newIndex |
+ (newIndex := self scanFor: element key) = index ifFalse: [
- (newIndex := self scanWithoutGarbagingFor: element key) = index ifFalse: [
array
at: newIndex put: element;
at: index put: vacuum ] ] ]!
Item was changed:
----- Method: WeakIdentityDictionary>>removeKey:ifAbsent: (in category 'removing') -----
removeKey: key ifAbsent: aBlock
"Remove key (and its associated value) from the receiver. If key is not in
the receiver, answer the result of evaluating aBlock. Otherwise, answer
the value externally named by key."
| index association |
index := self scanFor: key.
(association := (array at: index)) == vacuum ifTrue: [ ^aBlock value ].
+ array at: index put: vacuum.
+ tally := tally - 1.
+ self fixCollisionsFrom: index.
- self cleanupIndex: index.
^association value!
Item was changed:
----- Method: WeakIdentityDictionary>>scanFor: (in category 'private') -----
scanFor: anObject
"Scan the array for the first slot containing either
- a vacuum object indicating an empty slot
- or a binding whose key matches anObject.
+ Answer the index of that slot or raise an error if no slot is found which should never happen."
- Answer the index of that slot or raise an error if no slot is found.
- When garbage collected slots are encountered, perform a clean-up."
+ | index start size |
+ index := start := anObject scaledIdentityHash \\ (size := array size) + 1.
+ [
+ (array at: index) ifNotNil: [ :element |
+ (element == vacuum or: [ element key == anObject ])
+ ifTrue: [ ^index ] ].
+ (index := index \\ size + 1) = start ] whileFalse.
- | index start rescan |
- [
- rescan := false.
- index := start := anObject scaledIdentityHash \\ array size + 1.
- [
- (array at: index)
- ifNil:
- ["Object at this slot has been garbage collected.
- A rescan is necessary because fixing collisions
- might have moved the target before current index."
- self cleanupIndex: index.
- rescan := true]
- ifNotNil:
- [:element | (element == vacuum or: [ element key == anObject ])
- ifTrue: [ ^index ].
- (index := index \\ array size + 1) = start ] ] whileFalse.
- rescan ] whileTrue.
self errorNoFreeSpace!
Item was changed:
----- Method: WeakIdentityDictionary>>scanForEmptySlotFor: (in category 'private') -----
scanForEmptySlotFor: anObject
+ "Scan the array for the first empty slot marked by vacuum object or nil.
+ Answer the index of that slot or raise an error if no slot is found, which should never happen."
- "Scan the array for the first empty slot marked by vacuum object.
- Answer the index of that slot or raise an error if no slot is found.
- Ignore the slots that have been garbage collected (those containing nil)."
| index start |
index := start := anObject scaledIdentityHash \\ array size + 1.
[
+ | element |
+ ((element := array at: index) == vacuum or: [ element == nil ]) ifTrue: [ ^index ].
- (array at: index)
- ifNotNil:
- [:element | element == vacuum ifTrue: [ ^index ] ].
(index := index \\ array size + 1) = start ] whileFalse.
self errorNoFreeSpace!
Item was removed:
- ----- Method: WeakIdentityDictionary>>scanWithoutGarbagingFor: (in category 'private') -----
- scanWithoutGarbagingFor: anObject
- "Scan the array for the first slot containing either
- - a vacuum object indicating an empty slot
- - or a binding whose key matches anObject.
- Answer the index of that slot or raise an error if no slot is found.
- Ignore the slots that have been garbage collected (those containing nil)"
-
- | index start |
- index := start := anObject scaledIdentityHash \\ array size + 1.
- [
- (array at: index)
- ifNotNil:
- [:element | (element == vacuum or: [ element key == anObject ])
- ifTrue: [ ^index ] ].
- (index := index \\ array size + 1) = start ] whileFalse.
- self errorNoFreeSpace!
Karl Ramberg uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-kfr.276.mcz
==================== Summary ====================
Name: MorphicExtras-kfr.276
Author: kfr
Time: 15 June 2020, 10:06:41.338203 pm
UUID: 8a39f5e1-becc-1043-afb0-4adcc47d3266
Ancestors: MorphicExtras-kfr.275
Speed up search for transparent color in gif animation.
This is not the best solution since animated gifs use transparent colors differently. But untill someone fixes the way we handles the transparent colors in the gif reader this will give the overall best experience.
See https://graphicdesign.stackexchange.com/questions/113306/why-does-enabling-…
=============== Diff against MorphicExtras-kfr.275 ===============
Item was changed:
----- Method: AnimatedImageMorph>>fromReader: (in category 'private') -----
fromReader: reader
images := reader forms.
delays := reader delays.
+ (images anySatisfy:[:each|(each colors includes: Color transparent)]) ifTrue:[self isOpaque: true].
- images do:[: each | (each colors includes: Color transparent) ifTrue:[self isOpaque: true]].
self reset.!
Marcel Taeumel uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-mt.439.mcz
==================== Summary ====================
Name: Compiler-mt.439
Author: mt
Time: 15 June 2020, 7:14:22.86019 pm
UUID: fe605039-7601-ad4d-9a16-4d86b168d33e
Ancestors: Compiler-mt.438
Like in ShoutCore-mt.82, improve readability of code for dispatching to custom pragma parsers.
=============== Diff against Compiler-mt.438 ===============
Item was changed:
----- Method: Parser>>pragmaStatement (in category 'pragmas') -----
pragmaStatement
+ "Parse a pragma statement. The leading '<' has already been consumed. The 'here' token is the first one in the pragma. Use that token to dispatch to a custom pragma-parsing method if one can be found with a selector that matches it.
- "Read a single pragma statement. Dispatch to the first available pragma parser using the current token as a simple getter to be called on self. If no pragma parser can be found, parse it as usual in the keywords form.
Note that custom pragma parsers need to fulfill two requirements:
+ - method selector must match the current token as simple getter,
- (1) method selector must match the current token as simple getter,
e.g., <apicall: ...> matches #apicall or <primitive: ...> matches #primitive
+ - method must have pragma <pragmaParser> to be called."
- (2) method must declare <pragmaParser> to be called.
- This is for the protection of the parser's (message) namespace."
+ "0) Early exit"
- | parserSelector |
(hereType = #keyword or: [ hereType = #word or: [ hereType = #binary ] ])
ifFalse: [ ^ self expected: 'pragma declaration' ].
+ "1) Do not consider one-word pragmas such as <primitive> and <foobar>. Only keyword pragmas."
+ here last == $: ifTrue: [
+ "2) Avoid interning new symbols for made-up pragmas such as #my for <my: 1 pragma: 2>."
+ (Symbol lookup: here allButLast) ifNotNil: [:parserSelector |
+ Parser methodDict at: parserSelector ifPresent: [:parserMethod |
+ "3) Only call methods that claim to be a custom pragma parser via <pragmaParser>."
+ (parserMethod hasPragma: #pragmaParser)
+ ifTrue: [^ self executeMethod: parserMethod]]]].
- (here last == $:
- and: [(parserSelector := Symbol lookup: here allButLast) notNil])
- ifFalse: ["Quick exit to not break one-word pragmas such as <primitive> and <foobar>; also avoid interning new symbols for made-up pragmas such as for <my: 1 new: 2 pragma: 3> not interning #my."
- ^ self pragmaStatementKeywords].
+ "X) No custom pragma parser found. Use the default one."
- Parser methodDict
- at: parserSelector
- ifPresent: [:parserMethod |
- (parserMethod pragmas
- anySatisfy: [:pragma | pragma keyword == #pragmaParser])
- ifTrue: [^ self executeMethod: parserMethod]].
-
^ self pragmaStatementKeywords!