[Cuis-dev] CoreUpdate 4548

Pat Foley whatispatsemail at gmail.com
Sun Apr 4 08:45:15 PDT 2021


On Apr 4 2021, at 8:50 am, Graham Kelly via Cuis-dev
<cuis-dev at lists.cuis.st> wrote:

> Here's what I think is the issue:
> 
> The variable
> 
> halo  
> 
> is not initialized before returning
> 
> halo
> 
> 
> | halo |
> self whenUIinSafeState: [
> self displayBoundsForHalo ifNotNil: [ :r |
> halo _ HaloMorph new.
> halo popUpFor: self event: evt.
> halo morphBounds: r ].
> self redrawNeeded].
> ^halo

The previous version of Morph>>addHalo: was

addHalo: evt
	| halo |
	self displayBoundsForHalo ifNotNil: [ :r |
		halo _ HaloMorph new.
		halo popUpFor: self event: evt.
		halo morphBounds: r ].
	self whenUIinSafeState: [self redrawNeeded].
	^halo

But Luciano had a use case this didn't work for: 'BrowserWindow
openBrowser addHalo' gives you a browser without halos. But it used to
work, so what was the previous version? It was

addHalo: evt
	| halo |
	self displayBoundsForHalo ifNotNil: [ :r |
		halo _ HaloMorph new.
		halo popUpFor: self event: evt.
		halo morphBounds: r ].
	^halo

In December, Juan added the line

	self whenUIinSafeState: [self redrawNeeded].

which breaks Luciano's code, and then in March pushed up the
#whenUIinSafeState: to enclose the halo-creating block and the redraw.

So what does #whenUIinSafeState: do, and why is it there? It finds the
morph's world and passes the evaluable block along to it to be added to
the WorldMorph's list (kept in an instance variable) of
deferredUIMessages. That list is stepped through by
WorldMorph>>doOneCycle and WorldMorph>>runStepMethods.

So how does that work here? Here's Juan's comment with the latest
version (4548):
	"Defer execution until next cycle, so if you evaluate
	BrowserWindow openBrowser addHalo
	the window is in the world and with proper bounds, before adding the halo.
	"
That is, defer execution of #addHalo. Before it was only the redraw that
was deferred, not the creation of the halos. Now you wait, let the
window get drawn, then add halos and redraw.

That should be fine, right? But evidently menus work differently, or at
least TheWorldMenu does. 

System windows eventually call #openInWorld (setting some stuff and then
calling Morph>>openInWorld, which itself includes #whenUIinSafeState)
but menus do not. Neither do they call #openInHand. Menus instead have
#popUpInWorld and friends (which use the current hand's position but
open not attached to it).

That's sadly as far as I've gotten. Menus take a different route to
appearing in the world than windows, and that's enough to change when
and how you can add halos, but I don't get why.

If you do something like this in a workspace

  w _ TheWorldMenu new buildWorldMenu.
  w popUpInWorld addHalo.

you first get a world menu (missing its title and stayups) with
unresponsive halos drawn in weird places. You can get them to be where
they should be by middle-clicking the MenuMorph, but they remain
unusable (and middle-clicking doesn't select submorphs) just like with
CoreUpdate 4548. That seems interesting.

I'm sure this would be nearly 3 minutes of work for Juan to fix, but
he's busy inventing the future, so I'm just digging around in his code
so maybe someday I can help him a little.


More information about the Cuis-dev mailing list