[squeak-dev] Freezing UI issue

Jaromir Matas mail at jaromir.net
Mon Jul 4 13:08:59 UTC 2022

Hi Jakob,
Thanks for your explanation; The idea of manipulating the stack sounds like an interesting exercise :) Ideally I’d like to find a simple solution, we’ll see; but thanks a lot for the inspiration.

From: Jakob Reschke<mailto:jakres+squeak at gmail.com>
Sent: Sunday, July 3, 2022 14:14
To: The general-purpose Squeak developers list<mailto:squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Freezing UI issue

Hi Jaromir,

Am So., 3. Juli 2022 um 13:08 Uhr schrieb Jaromir Matas <mail at jaromir.net<mailto: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 time.

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/20220704/7dd17c97/attachment-0001.html>

More information about the Squeak-dev mailing list