[squeak-dev] Freezing UI issue

Jakob Reschke jakres+squeak at gmail.com
Sun Jul 3 12:14:27 UTC 2022

Hi Jaromir,

Am So., 3. Juli 2022 um 13:08 Uhr schrieb Jaromir Matas <mail at jaromir.net>:

> If you apply Morphic-mt.2016 the UI won't freeze but as you pointed out,
> it won't proceed. In the following example 'done' won't be printed:
> s := Semaphore new.
> [1/0. s signal] fork.
> s wait.
> Transcript cr; show: 'done'
> I understand juggling with two UIs, one blocked or busy and another one
> keeping the screen responsive isn't trivial; I remember your discussion
> with Jakob about what seems to me now a similar situation in Squot
> (SquotGUI>>#waitFor) where Jakob needs to keep the UI responsive while it's
> waiting on a resource or something; similar situation is dealt with in
> InstallerSqueakMap>>#update. I tried to apply the strategy here but failed
> miserably :D
> My question is: is the above example from Squot the same type of problem?
> Could it be solved similarly? Would such solution remove the need for an
> ad-hoc solution like in Squot? Sorry if this doesn't make much sense; I'm
> far from sure what I'm talking about :)

The purpose of the waitFor: in Squot, spawning a new UI process and later
terminating it to resume the original UI process, was not primarily meant
to keep the UI responsive. It is rather a workaround for the bad debugging
experience with Promises, or with workflows that have asynchronous steps in
general (such as requesting an interaction with the UI in the middle of the
workflow). With plain Promises callbacks, you lose the contexts leading up
to an asynchronous step. That means after the asynchronous step is done and
you notice an error later in the workflow, you cannot restart one of these
previous contexts in the debugger anymore to go back in the workflow. Also
you may not be able to edit&save in the debugger because the home context
of your callback block is already dead after the asynchronous step. To
hibernate the UI process in waitFor: and instead start a new UI process is
the workaround to preserve the stack in the hibernated UI process, and yet
to provide a running UI process so that the users can do what they are
being asked for. In fact, waitFor: simply waits if it is not invoked in the
current UI process. So waitFor: also allows you to wait for an object
without having to care whether it will freeze the UI or not; it never will.

Instead of messing with the UI processes, the simulating of a synchronous
workflow around asynchronous input could probably also be achieved by
context magic to implement continuations. Copy the relevant contexts before
you "wait" and re-insert them into the stack after the users have supplied
their asynchronous input. But I did not want to do stack splicing at the

The classical solution are modal dialogs, or rather to run another UI event
loop inside the existing one. This is what I originally had. But it breaks
if you interrupt and terminate the UI process for some reason, be it
related to the actual workflow or not. It is bad if the Save dialog simply
does nothing when you press "accept", after you previously encountered a
bug in the dialog's functionality and chose to abort in the debugger
that appeared.

So, while I do not want to see the current solution broken, of course, I do
not consider it to be a nice solution. Eventually it ought to be replaced.

Kind regards,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220703/5c400d71/attachment.html>

More information about the Squeak-dev mailing list