I've often wondered why, when I search for some string that isn't there, I see the text morph flash sometimes, but not always. Here's a fix.
Cheers, Bob
'From Squeak4.4 of 1 March 2013 [latest update: #12489] on 18 August 2013 at 11:49:45 am'!
!Morph methodsFor: 'macpal' stamp: 'raa 8/18/2013 06:44'! flash | originalColor | originalColor := self color. [ self color: (originalColor ifNil: [ Color black ] ifNotNil: [ (originalColor alpha: 1) negated ]) ] ensure: [ self world ifNotNil: [ : w | w displayWorldSafely. (Delay forMilliseconds: 100) wait ]. self color: originalColor ]! !
I see you added the 100ms delay. I'll put that into trunk.
Are you interested in registering at source.squeak.org? You should be in the core-dev group so you can commit to trunk directly.
On Sun, Aug 18, 2013 at 10:52 AM, Bob Arning arning315@comcast.net wrote:
I've often wondered why, when I search for some string that isn't there, I see the text morph flash sometimes, but not always. Here's a fix.
Cheers, Bob
'From Squeak4.4 of 1 March 2013 [latest update: #12489] on 18 August 2013 at 11:49:45 am'!
!Morph methodsFor: 'macpal' stamp: 'raa 8/18/2013 06:44'! flash | originalColor | originalColor := self color. [ self color: (originalColor ifNil: [ Color black ] ifNotNil: [ (originalColor alpha: 1) negated ]) ] ensure: [ self world ifNotNil: [ : w | w displayWorldSafely. (Delay forMilliseconds: 100) wait ]. self color: originalColor ]! !
Well, I don't think you should block the event loop with this kind of feedback. 100 milliseconds are quite many... Maybe just use Morphic Alarms:
flash self color in: [:c | self color: ((c ifNil: [Color white]) alpha: 1) negated. self addAlarm: #color: with: c after: 100].
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704075.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On Sun, 18 Aug 2013, Bob Arning wrote:
I've often wondered why, when I search for some string that isn't there, I see the text morph flash sometimes, but not always. Here's a fix.
Cheers, Bob
'From Squeak4.4 of 1 March 2013 [latest update: #12489] on 18 August 2013 at 11:49:45 am'!
!Morph methodsFor: 'macpal' stamp: 'raa 8/18/2013 06:44'! flash | originalColor | originalColor := self color. [ self color: (originalColor ifNil: [ Color black ] ifNotNil: [ (originalColor alpha: 1) negated ]) ] ensure: [ self world ifNotNil: [ : w | w displayWorldSafely. (Delay forMilliseconds: 100) wait ].
Is this really a good idea? What if multiple morphs get flashed?
Levente
self color: originalColor ]! !
Yup, not the best idea. That's why I voted for the use of Morphic Alarms. :)
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704077.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
The trouble with using an alarm is if #flash gets called again before the alarm fires, it will think its negated color is its normal color and add yet another alarm to reverse it again, leaving it in the flashed color.
Could you (or Levente) elaborate by why it might not be a good idea?
I think describing use-cases really helps understand context. For me, I use flash as a debugging tool, I open an inspector on a Morph and type "self flash" and press and hold Command+d to DoIt. I don't really need the Delay since the key-repeat takes care of it..
On Sun, Aug 18, 2013 at 3:32 PM, Marcel Taeumel marcel.taeumel@student.hpi.uni-potsdam.de wrote:
Yup, not the best idea. That's why I voted for the use of Morphic Alarms. :)
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704077.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On Sun, 18 Aug 2013, Chris Muller wrote:
The trouble with using an alarm is if #flash gets called again before the alarm fires, it will think its negated color is its normal color and add yet another alarm to reverse it again, leaving it in the flashed color.
Could you (or Levente) elaborate by why it might not be a good idea?
IIUC if you flash multiple Morphs, the delays will stack. So flashing 10 morphs will cause a second delay.
Levente
I think describing use-cases really helps understand context. For me, I use flash as a debugging tool, I open an inspector on a Morph and type "self flash" and press and hold Command+d to DoIt. I don't really need the Delay since the key-repeat takes care of it..
On Sun, Aug 18, 2013 at 3:32 PM, Marcel Taeumel marcel.taeumel@student.hpi.uni-potsdam.de wrote:
Yup, not the best idea. That's why I voted for the use of Morphic Alarms. :)
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704077.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
I'm not clear on who wants to flash 10 morphs, but if you do this
m _ (1 to: 10) collect: [ :i | Morph new position: (i@i*75); openInWorld]
then try this:
m do: [ :e | e flash]
The standard version of #flash *occasionally* causes a visible change in the first morph, but I never notice a change in any of the others.
The 100 ms delay version makes all of the flashes clearly noticeable, in sequence.
A 10 ms delay in #flash makes them mostly (but briefly) detectable.
I suspect if you really want to flash 10 morphs, you may do well with a rather different approach.
Cheers, Bob
On 8/18/13 9:10 PM, Levente Uzonyi wrote:
On Sun, 18 Aug 2013, Chris Muller wrote:
The trouble with using an alarm is if #flash gets called again before the alarm fires, it will think its negated color is its normal color and add yet another alarm to reverse it again, leaving it in the flashed color.
Could you (or Levente) elaborate by why it might not be a good idea?
IIUC if you flash multiple Morphs, the delays will stack. So flashing 10 morphs will cause a second delay.
Levente
I think describing use-cases really helps understand context. For me, I use flash as a debugging tool, I open an inspector on a Morph and type "self flash" and press and hold Command+d to DoIt. I don't really need the Delay since the key-repeat takes care of it..
On Sun, Aug 18, 2013 at 3:32 PM, Marcel Taeumel marcel.taeumel@student.hpi.uni-potsdam.de wrote:
Yup, not the best idea. That's why I voted for the use of Morphic Alarms. :)
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704077.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
Here a better version:
(self valueOfProperty: #colorBeforeFlashing ifAbsent: [self color]) in: [:c | self setProperty: #colorBeforeFlashing toValue: c. self color: ((c ifNil: [Color white]) alpha: 1) negated. ActiveWorld displayWorldSafely. self removeAlarm: #color:; removeAlarm: #removeProperty:. self addAlarm: #color: with: c after: 100; addAlarm: #removeProperty: with: #colorBeforeFlashing after: 100].
I am not exactly sure, why an explicit call to the render loop is needed... But this way, it works without blocking the event loop. This "ActiveWorld displayWorldSafely" is still annoying...
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704117.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
This is just waaay too much.
- It makes little sense to talk about a "public API" in Squeak. All methods are visible and executable from anywhere. To think that some subset of all methods have been vetted and will never do anything unpleasant is not supported by the facts.
- If you look at the senders of flash in the image, it pretty much all about , "I just asked a tool to do something and it could not. Oops!" No need for anything fancy here - just DTSTTCPW.
- The introduction of alarms made me nervous. I understand delays, but alarms are a gray area. How do they work? Will they do what I think they will? In this case, they do *not*. If we go back to my example:
m _ (1 to: 10) collect: [ :i | Morph new position: (i@i*75); openInWorld]
m do: [ :e | e flash]
Using the alarming version of #flash, we see the first morph flash ever so briefly. Each successive morph flashes for a longer time, until the last one stays inverted for 600 ms. Huh!
If you look at: WorldState>>triggerAlarmsBefore:, you see the claim:
"Trigger all pending alarms that are to be executed before nowTime."
when, in fact, it triggers one at most:
triggered := OrderedCollection new. self lockAlarmsDuring: [:pending | (pending isEmpty not and: [pending first scheduledTime < nowTime]) ifTrue: [triggered add: pending removeFirst]]. triggered do: [:alarm | alarm value: nowTime].
makes me want to
Smalltalk destroyAllComments ;-)
Cheers, Bob
On 8/19/13 5:56 AM, Marcel Taeumel wrote:
Hi! :)
One point against blocking the event loop: You never know who will call #flash as it is public API. It is not guaranteed that the flashing morph is "visible" at all and not occluded by some other morph. Then, strange short image freezes will be noticed.
On 8/19/13 6:07 AM, Marcel Taeumel wrote:
Here a better version:
(self valueOfProperty: #colorBeforeFlashing ifAbsent: [self color]) in: [:c | self setProperty: #colorBeforeFlashing toValue: c. self color: ((c ifNil: [Color white]) alpha: 1) negated. ActiveWorld displayWorldSafely. self removeAlarm: #color:; removeAlarm: #removeProperty:. self addAlarm: #color: with: c after: 100; addAlarm: #removeProperty: with: #colorBeforeFlashing after: 100].
I am not exactly sure, why an explicit call to the render loop is needed... But this way, it works without blocking the event loop. This "ActiveWorld displayWorldSafely" is still annoying...
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704117.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On Mon, Aug 19, 2013 at 08:02:02AM -0400, Bob Arning wrote:
This is just waaay too much.
+1
- It makes little sense to talk about a "public API" in Squeak. All
methods are visible and executable from anywhere. To think that some subset of all methods have been vetted and will never do anything unpleasant is not supported by the facts.
- If you look at the senders of flash in the image, it pretty much all
about , "I just asked a tool to do something and it could not. Oops!" No need for anything fancy here - just DTSTTCPW.
- The introduction of alarms made me nervous. I understand delays, but
alarms are a gray area. How do they work? Will they do what I think they will? In this case, they do *not*. If we go back to my example:
m _ (1 to: 10) collect: [ :i | Morph new position: (i@i*75); openInWorld]
m do: [ :e | e flash]
Using the alarming version of #flash, we see the first morph flash ever so briefly. Each successive morph flashes for a longer time, until the last one stays inverted for 600 ms. Huh!
If you look at: WorldState>>triggerAlarmsBefore:, you see the claim:
"Trigger all pending alarms that are to be executed before nowTime."
when, in fact, it triggers one at most:
triggered := OrderedCollection new. self lockAlarmsDuring: [:pending | (pending isEmpty not and: [pending first scheduledTime < nowTime]) ifTrue: [triggered add: pending removeFirst]]. triggered do: [:alarm | alarm value: nowTime].
makes me want to
Smalltalk destroyAllComments ;-)
Cheers, Bob
Class MorphicAlarm does not even *have* a comment. MorphicAlarmQueue has a comment, but the comment only describes its internal implementation, nothing about why it exists or what it is supposed to do. If Morphic alarms are a good thing, then perhaps someone could (please?) take the time to provide some class comments with a clear explanation of what they are and how they are supposed to work.
Dave
On 8/19/13 5:56 AM, Marcel Taeumel wrote:
Hi! :)
One point against blocking the event loop: You never know who will call #flash as it is public API. It is not guaranteed that the flashing morph is "visible" at all and not occluded by some other morph. Then, strange short image freezes will be noticed.
On 8/19/13 6:07 AM, Marcel Taeumel wrote:
Here a better version:
(self valueOfProperty: #colorBeforeFlashing ifAbsent: [self color]) in: [:c | self setProperty: #colorBeforeFlashing toValue: c. self color: ((c ifNil: [Color white]) alpha: 1) negated. ActiveWorld displayWorldSafely. self removeAlarm: #color:; removeAlarm: #removeProperty:. self addAlarm: #color: with: c after: 100; addAlarm: #removeProperty: with: #colorBeforeFlashing after: 100].
I am not exactly sure, why an explicit call to the render loop is needed... But this way, it works without blocking the event loop. This "ActiveWorld displayWorldSafely" is still annoying...
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704117.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 19.08.2013 um 14:21 schrieb "David T. Lewis" lewis@mail.msen.com:
On Mon, Aug 19, 2013 at 08:02:02AM -0400, Bob Arning wrote: This is just waaay too much.
+1
- -1
Out of principle, I am against any change that adds Delays to the ui. I consider that plain wrong (<-personal opinion). IMHO, flashing is an animation that should not use plain Delays directly. While alarms may be insufficiently documented (as is the vast majority of Morphic…), I think it is the proper level of abstraction.
Best -Tobias
Seems to me there are two rather different usages here a) an alert within the normal UI, to let you know something odd happened b) a diagnostic when debugging where you need a 'bigger' alert.
For b) a 100mS simple delay is probably perfectly fine. I've done debugging where it would be really nice for there to be a good way of 'interrupting the delay' to get in to the problem process; an associated visual widget to click on or something.
For a) a delay that holds up everything is not a good idea. Some form of alarm (like the morphicalarm is supposed to be) that keeps the UI moving is going to be least annoying. I think it's likely that there are better feedback concepts than simply flashing the morph.
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim A paperless office has about as likely as a paperless bathroom.
Think about where it's used in the image now. I search for some text and it's not found. The screen flashes to let me know. I can't think of *anything* I want the UI process to be doing for the next 100ms while I wait for the photons to hit my retina. I'm even thinking a bit longer delay might even be better. Here are some experiments:
Make a morph.
m _ Morph new openInWorld.
Then try this, with different proposed #flash implementations.
m flash; delete.
Another experiment. How low can you set the delay and still reliably see red? Try this in a completely empty project.
m color: Color red. World displayWorldSafely. (Delay forMilliseconds: 20) wait. m color: Color blue. World displayWorldSafely.
I think the senders of #flash want it to be seen and I don't think the UI needs to do anything else while the message is being received by the user (the U in UI).
Cheers, Bob
On 8/19/13 12:58 PM, tim Rowledge wrote:
Seems to me there are two rather different usages here a) an alert within the normal UI, to let you know something odd happened b) a diagnostic when debugging where you need a 'bigger' alert.
For b) a 100mS simple delay is probably perfectly fine. I've done debugging where it would be really nice for there to be a good way of 'interrupting the delay' to get in to the problem process; an associated visual widget to click on or something.
For a) a delay that holds up everything is not a good idea. Some form of alarm (like the morphicalarm is supposed to be) that keeps the UI moving is going to be least annoying. I think it's likely that there are better feedback concepts than simply flashing the morph.
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim A paperless office has about as likely as a paperless bathroom.
I agree with Bob. 100ms only "slows the UI" down to 10 fps for one "frame." By holding everything else static for that one frame, it reinforces the purpose of flash which is to draw the users attention to that one particular morph.
In an extremely busy-animated UI, flash might otherwise not fulfill this goal as effectively.
Animation in morphic is normally handled by implementing #step and #stepTime, not alarms. But #flash is not animation, it's like #beep. It's a user poke, not program output.
On Mon, Aug 19, 2013 at 1:34 PM, Bob Arning arning315@comcast.net wrote:
Think about where it's used in the image now. I search for some text and it's not found. The screen flashes to let me know. I can't think of *anything* I want the UI process to be doing for the next 100ms while I wait for the photons to hit my retina. I'm even thinking a bit longer delay might even be better. Here are some experiments:
Make a morph.
m _ Morph new openInWorld.
Then try this, with different proposed #flash implementations.
m flash; delete.
Another experiment. How low can you set the delay and still reliably see red? Try this in a completely empty project.
m color: Color red. World displayWorldSafely. (Delay forMilliseconds: 20) wait. m color: Color blue. World displayWorldSafely.
I think the senders of #flash want it to be seen and I don't think the UI needs to do anything else while the message is being received by the user (the U in UI).
Cheers, Bob
On 8/19/13 12:58 PM, tim Rowledge wrote:
Seems to me there are two rather different usages here a) an alert within the normal UI, to let you know something odd happened b) a diagnostic when debugging where you need a 'bigger' alert.
For b) a 100mS simple delay is probably perfectly fine. I've done debugging where it would be really nice for there to be a good way of 'interrupting the delay' to get in to the problem process; an associated visual widget to click on or something.
For a) a delay that holds up everything is not a good idea. Some form of alarm (like the morphicalarm is supposed to be) that keeps the UI moving is going to be least annoying. I think it's likely that there are better feedback concepts than simply flashing the morph.
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim A paperless office has about as likely as a paperless bathroom.
What does the protocol "macpal", where #flash is located, mean?
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704256.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
Well, google offered up this:
http://comments.gmane.org/gmane.comp.lang.smalltalk.squeak.general/55749
On 8/20/13 2:55 AM, Marcel Taeumel wrote:
What does the protocol "macpal", where #flash is located, mean?
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704256.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On 2013-08-20, at 08:55, Marcel Taeumel marcel.taeumel@student.hpi.uni-potsdam.de wrote:
What does the protocol "macpal", where #flash is located, mean?
Best, Marcel
MacPal was one of the projects Alan Kay's group did at Apple. Others were Fabrik, Constructo, Playground, etc.
- Bert -
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 19.08.2013 um 20:53 schrieb Chris Muller asqueaker@gmail.com:
I agree with Bob. 100ms only "slows the UI" down to 10 fps for one "frame." By holding everything else static for that one frame, it reinforces the purpose of flash which is to draw the users attention to that one particular morph.
what if the morph is behind another one? Then the UI goes halt for no apparent reason.
In an extremely busy-animated UI, flash might otherwise not fulfill this goal as effectively.
Animation in morphic is normally handled by implementing #step and #stepTime, not alarms. But #flash is not animation, it's like #beep. It's a user poke, not program output.
Which should be non-blocking nonetheless. When my terminal on OSX flashes (visual bell, the exact same concept), it does not do it in a blocking fashion, all other UI stuff continues to work. Again, I am strongly opposed agains any change that introduces blocking into the UI. It just does not belong there. Modal dialogs that also draw the attention to the current screen activity also do not block the UI. The same way, a #beep should not block the UI. Think of a typical Game loop that adjusts its calculation based on the measured fps (for example by adjusting stepping time). This would introduce unwanted jumps in that game loop just because some morph somewhere flashed.
I agree that a #flash like a #beep should be always noticeable[1] but I think a Delay for: whatevernumber is the wrong way.
I just tested Bobs fix and then did the following: Open a browser, focus the Protocol pane, start typing like crazy (say 50 character in very short time). The effect was that my UI was blocked for more than thee (3) seconds. This should really not happen.
Best -Tobias
[1] side note: there should be a preference to turn a #beep into a #flash automatically, akin to a terminal’s infamous visual bell, and probably vice versa.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 21.08.2013 um 16:05 schrieb Tobias Pape Das.Linux@gmx.de: Am 19.08.2013 um 20:53 schrieb Chris Muller asqueaker@gmail.com: […] Think of a typical Game loop that adjusts its calculation based
would introduce unwanted jumps in that game loop just because some morph somewhere flashed.
I agree that a #flash like a #beep should be always noticeable[1] but I think a Delay for: whatevernumber is the wrong way.
I just tested Bobs fix and then did the following: Open a browser, focus the Protocol pane, start typing like crazy (say 50 character in very short time). The effect was that my UI was blocked for more than thee (3) seconds. This should really not happen.
Interestingly, repeatedly flashing a UserDialogBoxMorph does _not_ block the UI _although_ it is implemented using two delays; you can drag the box around while it is flashing. I think this is due to the modality implementation using the doOneSubCycle (which I frankly do not yet understand)
Best -Tobias
On 8/21/13 10:14 AM, Tobias Pape wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 21.08.2013 um 16:05 schrieb Tobias Pape Das.Linux@gmx.de: Am 19.08.2013 um 20:53 schrieb Chris Muller asqueaker@gmail.com: […] Think of a typical Game loop that adjusts its calculation based
would introduce unwanted jumps in that game loop just because some morph somewhere flashed.
I'm not sure how timing-critical games relate to the current users of #flash. I can't really get my head around playing such a game *while* typing 50 characters really fast in a browser pane. The delay, introduced in direct response to user input, is probably a good bit less that that for searching all methods with "foo" in their source or adding an instance variable to a class with 50 subclasses. If you are programming while gaming, both may suffer. Note that none of this prevents someone from creating a gentler #flashEverSoDiscreetly for special cases where you don't want to cause offense.
I agree that a #flash like a #beep should be always noticeable[1] but I think a Delay for: whatevernumber is the wrong way.
I just tested Bobs fix and then did the following: Open a browser, focus the Protocol pane, start typing like crazy (say 50 character in very short time). The effect was that my UI was blocked for more than thee (3) seconds. This should really not happen.
One thing that helps is if senders of #flash like this one also flushed any pending input events. If you are really that fast a typist and do
<cmd-f>foo<return>bar
and "foo" is not found, then "bar" gets entered at the previous selection, not replacing "foo" as desired. #flash means the last thing you did didn't work and there's a strong possibility any stuff you already types in is wrong.
Interestingly, repeatedly flashing a UserDialogBoxMorph does _not_ block the UI _although_ it is implemented using two delays; you can drag the box around while it is flashing. I think this is due to the modality implementation using the doOneSubCycle (which I frankly do not yet understand)
It's just a recursion into event processing. It allows the world to display, but also user input to be processed and #step processing. In my #flash, try using #doOneCycleNow in place of #displayWorldSafely. You may be a bit happier with the results.
Cheers, Bob
Best -Tobias -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.20 (Darwin)
iEYEARECAAYFAlIUy0IACgkQcPVIrP6PLKt4PQCggapRrM5yo4Brj+XVOO0/+jov L6EAn39Zw1Fpu8PN3i83Lcc5U201oEMp =QU+5 -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 21.08.2013 um 17:03 schrieb Bob Arning arning315@comcast.net:
On 8/21/13 10:14 AM, Tobias Pape wrote: - -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 21.08.2013 um 16:05 schrieb Tobias Pape Das.Linux@gmx.de: Am 19.08.2013 um 20:53 schrieb Chris Muller asqueaker@gmail.com: […] Think of a typical Game loop that adjusts its calculation based
would introduce unwanted jumps in that game loop just because some morph somewhere flashed. I'm not sure how timing-critical games relate to the current users of #flash. I can't really get my head around playing such a game *while* typing 50 characters really fast in a browser pane. The delay, introduced in direct response to user input, is probably a good bit less that that for searching all methods with "foo" in their source or adding an instance variable to a class with 50 subclasses. If you are programming while gaming, both may suffer. Note that none of this prevents someone from creating a gentler #flashEverSoDiscreetly for special cases where you don't want to cause offense.
Well it was just being an example :) But to give a typical scenario: you have some sort of list morph that supports filtering (nearly every PluggableListMorph…) let it be a browser pane or whatever; you play your high-performance game (lets say you have to hit some keys as fast as you can), and accidentally lose input focus to the list while still hitting the keys. Thats how I imagine such things come into being.
I agree that a #flash like a #beep should be always noticeable[1] but I think a Delay for: whatevernumber is the wrong way.
I just tested Bobs fix and then did the following: Open a browser, focus the Protocol pane, start typing like crazy (say 50 character in very short time). The effect was that my UI was blocked for more than thee (3) seconds. This should really not happen. One thing that helps is if senders of #flash like this one also flushed any pending input events. If you are really that fast a typist and do
<cmd-f>foo<return>bar
and "foo" is not found, then "bar" gets entered at the previous selection, not replacing "foo" as desired. #flash means the last thing you did didn't work and there's a strong possibility any stuff you already types in is wrong.
Interestingly, repeatedly flashing a UserDialogBoxMorph does _not_ block the UI _although_ it is implemented using two delays; you can drag the box around while it is flashing. I think this is due to the modality implementation using the doOneSubCycle (which I frankly do not yet understand) It's just a recursion into event processing. It allows the world to display, but also user input to be processed and #step processing. In my #flash, try using #doOneCycleNow in place of #displayWorldSafely. You may be a bit happier with the results.
Probably. What if we forked the delay?
Best -Tobias
On 2013-08-22, at 11:19, Tobias Pape Das.Linux@gmx.de wrote:
What if we forked the delay?
Then you need to resync with the UI thread using addDeferredUIMessage:. Much simpler to use a future/alarm directly.
FWIW, I'm normally using #flashBounds to find any morph on the screen, which also works when it's hidden:
World allMorphs atRandom flashBounds
Yes, this is low-level and blocking, but I only use it interactively anyway.
- Bert -
Tobias, when we use reasons like "should" and "does not belong", I understand you're saying how it feels in your guts, but unfortunately it does not provide a basis for us to engage in logical debate and decision making.
You raise a good point about it possibly being covered by another Morph. No answer for that other than the user could instruct the morph they're about to flash (its parent-most Morph under the World) to comeToFront first..
I think most of us agree we don't normally want to "block" the UI and doing so certainly goes against Morphic principles. But this is just #flash so -- 1) the blockage is for one "frame", what are we going to miss? 2) the blockage reinforces it's function -- because what if there are 100 Morphs already on the screen (perhaps as part of the Game loop you mentioned), which all have a flashing-effect as part of their stepping. It would be difficult to see the 101st one I'm flashing deliberately. So, one could argue, blocking the UI pausing briefly is actually *by design* for the flash function. Finally, 3) a Delay is simply TSTTCPW. Sure we could introduce a complicated stepping / alarms, whatever, but at the end of the day, what have we gained by that?
Right now #flash doesn't really work at all so our choices are to 1) leave it broken, 2) put in a brief Delay, or 3) something else. Keeping in mind, until someone DOES the "something else" it's essentially the same as (1).
On Wed, Aug 21, 2013 at 9:05 AM, Tobias Pape Das.Linux@gmx.de wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 19.08.2013 um 20:53 schrieb Chris Muller asqueaker@gmail.com:
I agree with Bob. 100ms only "slows the UI" down to 10 fps for one "frame." By holding everything else static for that one frame, it reinforces the purpose of flash which is to draw the users attention to that one particular morph.
what if the morph is behind another one? Then the UI goes halt for no apparent reason.
In an extremely busy-animated UI, flash might otherwise not fulfill this goal as effectively.
Animation in morphic is normally handled by implementing #step and #stepTime, not alarms. But #flash is not animation, it's like #beep. It's a user poke, not program output.
Which should be non-blocking nonetheless. When my terminal on OSX flashes (visual bell, the exact same concept), it does not do it in a blocking fashion, all other UI stuff continues to work. Again, I am strongly opposed agains any change that introduces blocking into the UI. It just does not belong there. Modal dialogs that also draw the attention to the current screen activity also do not block the UI. The same way, a #beep should not block the UI. Think of a typical Game loop that adjusts its calculation based on the measured fps (for example by adjusting stepping time). This would introduce unwanted jumps in that game loop just because some morph somewhere flashed.
I agree that a #flash like a #beep should be always noticeable[1] but I think a Delay for: whatevernumber is the wrong way.
I just tested Bobs fix and then did the following: Open a browser, focus the Protocol pane, start typing like crazy (say 50 character in very short time). The effect was that my UI was blocked for more than thee (3) seconds. This should really not happen.
Best -Tobias
[1] side note: there should be a preference to turn a #beep into a #flash automatically, akin to a terminal’s infamous visual bell, and probably vice versa. -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.20 (Darwin)
iEYEARECAAYFAlIUyUYACgkQcPVIrP6PLKsOCgCdFoODDTV0QuZDr+xesVResYeb K7gAniOwZnUwUB26w0QEkJ9xlSjT9wWV =5Nkq -----END PGP SIGNATURE-----
On Monday, Bob Arning wrote:
If you look at: WorldState>>triggerAlarmsBefore:, you see the claim:
"Trigger all pending alarms that are to be executed before nowTime."
when, in fact, it triggers one at most:
triggered := OrderedCollection new. self lockAlarmsDuring: [:pending | (pending isEmpty not and: [pending first scheduledTime < nowTime]) ifTrue: [triggered add: pending removeFirst]]. triggered do: [:alarm | alarm value: nowTime].
makes me want to
Smalltalk destroyAllComments ;-)
Cheers, Bob
Whoops! That ifTrue: should be whileTrue:
John
On 8/19/13 5:56 AM, Marcel Taeumel wrote:
Hi! :)
One point against blocking the event loop: You never know who will call #flash as it is public API. It is not guaranteed that the flashing morph
is
"visible" at all and not occluded by some other morph. Then, strange short image freezes will be noticed.
On 8/19/13 6:07 AM, Marcel Taeumel wrote:
Here a better version:
(self valueOfProperty: #colorBeforeFlashing ifAbsent: [self color]) in: [:c | self setProperty: #colorBeforeFlashing toValue: c. self color: ((c ifNil: [Color white]) alpha: 1) negated. ActiveWorld displayWorldSafely.
self removeAlarm: #color:; removeAlarm: #removeProperty:. self addAlarm: #color: with: c after: 100; addAlarm: #removeProperty: with: #colorBeforeFlashing after:
100].
I am not exactly sure, why an explicit call to the render loop is
needed...
But this way, it works without blocking the event loop. This "ActiveWorld displayWorldSafely" is still annoying...
Best, Marcel
-- View this message in context:
http://forum.world.st/computers-too-fast-these-days-tp4704067p4704117.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 21.08.2013 um 15:30 schrieb John McKeon p3anoman@gmail.com:
On Monday, Bob Arning wrote:
If you look at: WorldState>>triggerAlarmsBefore:, you see the claim:
"Trigger all pending alarms that are to be executed before nowTime."
when, in fact, it triggers one at most:
triggered := OrderedCollection new. self lockAlarmsDuring: [:pending | (pending isEmpty not and: [pending first scheduledTime < nowTime]) ifTrue: [triggered add: pending removeFirst]]. triggered do: [:alarm | alarm value: nowTime].
makes me want to
Smalltalk destroyAllComments ;-)
Cheers, Bob
Whoops! That ifTrue: should be whileTrue:
John
I'll fix that.
Best -Tobias
Hi! :)
One point against blocking the event loop: You never know who will call #flash as it is public API. It is not guaranteed that the flashing morph is "visible" at all and not occluded by some other morph. Then, strange short image freezes will be noticed.
Best, Marcel
-- View this message in context: http://forum.world.st/computers-too-fast-these-days-tp4704067p4704116.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
squeak-dev@lists.squeakfoundation.org