Squeak SmalltalkJoker Squeak Smalltalk : Morphic : prevnext Containerless Morphs Replace System Windows

> It has strange windows management.

The windows in Morphic are not really the primary objects like they are in 
most UI systems. As far as I can tell, they were made so that the existing 
tools in the MVC environment could be ported quickly to Morphic. That's 
the origin of all the Pluggable* components; you will see that there are 
pairs of them with similar APIs for MVC and Morphic.

> Inactive windows disable all its components (look at Zurgle to see it).

Zurgle has, as I recall, its own idea of focus and window activity.

> You can't switch
> between submorphs using Tab key etc.

We have had this working from time to time.

> One of the most strange features of Morphic and MVC is the single world
> cycle. One long computation can make whole GUI unusable.

How is this different from what was done in Mac OS 7 or Windows 3.1? I 
recall many applications that would make the whole GUI unusable by doing 
just what you describe in response to a UI action.

Later operating systems tended to assign a separate thread per 
application; they could easily maintain the behavior of the rest of the 
system by using message queues.

In fact, if you look at Squeak as a single application (which it is, 
despite the windows) ours is a fairly typical architecture. Events come up 
from the VM and are dispatched in a single loop.

There is enough shared state in Squeak that having multiple GUI processes 
would require quite a bit of work for little benefit if you wanted 
anything more interesting than a "windowing system". I want to have live 
objects in my world, and I don't particularly want them confined 
exclusively to windows. As soon as morphs need to talk to each other 
(which is not generally the case with windows but is essential for pretty 
much everything else we do with Morphic) you wouldn't be able to call the 
methods of other morphs directly any more, which would require a number of 
changes. You'd probably have to distinguish between top-level morphs and 
other morphs; the top-level ones would have their own message queue, etc. 
But then there would be a difference between (say) a RectangleMorph loose 
in the World and one that was embedded in a window or other top-level 
container: the one in the window could have its methods called directly 
and would be a "second class citizen" intended only for embedding, and the 
one loose in the World would not be able to have its methods called 
directly. This would be like the distinction between "widgets" and 
"windows" in many windowing systems.

I agree that mixing models has led to strangeness; the attempts to make 
the SystemWindows behave more and more like operating-system windows 
despite their existence alongside other non-window morphs have not always 
resulted in consistent behavior. But at least it got the MVC tools working 
in Morphic. One example of this strangeness is the "topmost window" 
concept which is completely at odds with the existing Morphic layering; 
another is the concept of "window focus". Morphic itself doesn't have 
focus other than the halos, but the concept was added to the windows. So 
if you have a mixture of windows and non-windows in the world, you will 
sometimes see situations where the Z-ordering will suddenly be reorganized 
(for instance, after you enter a new project or save the image).

As it is now, it's quite simple to put long-running computations in 
background threads; you just don't let the background threads call methods 
directly on Morphs. We have addDeferredUIMessage: to queue up action from 
the background threads for later execution in the UI thread during the 
next window cycle.

> It's not a feature
> of Squeak's process scheduler. I have created an experimental window
> manager with separated message passing cycles, all GUI messages were sent
> through shared queues and it has worked perfectly.

But Squeak isn't a window manager (despite the things that look somewhat 
like UI windows), and the things in the World (windows or other morphs) 
aren't separate applications. Or, looked at another way, every morph is a 
separate application whether or not it is a top-level morph (they each 
have their own step methods), but then there is still no distinction 
between top-level morphs (well, other than the World itself) and embedded 
morphs. Top-level morphs are just submorphs of the World, and a lowly 
StringMorph or RectangleMorph deep in a construction somewhere inside a 
window is no less live than the window itself.

If you wanted to make a UI in the style you describe -- merely concerned 
with standard kinds of windows and UI elements inside them -- many of the 
issues around intra-Morph communication would not be a problem. But you're 
missing the point, I think; Morphic was not intended (as far as I know) as 
a windowing system. As you point out, the MVC system is much closer to 
this model, with its controllers that are associated with things that look 
like windows on the desktop.

Whether Morphic is the right design for the kinds of things *you* want to 
build, I don't know. Maybe it isn't a good fit.

However, there is nothing that I can think of in Squeak that would prevent 
you from writing a completely different UI system fairly easily. In fact, 
there have been several of these already: the Parks PDA that John Maloney 
did had one, his Scratch system has another, Andreas' Tweak system has 
another, Croquet has another, and so on.

The co-existence of MVC and Morphic shows that it is possible to make a 
completely different UI model and still re-use the basic UI system 
(events, canvases, invalidation, etc.). We could probably make the work 
required to add different kinds of Projects/Worlds a bit easier, though; 
there's a fair amount of code at the project level that assumes that 
projects are either MVC or Morphic.

> That's a very interesting statement.  How do you imagine this working?
> Do you mean getting rid of all the UI that currently uses SystemWindow
> (Browsers, Debuggers, etc), replacing them with Self-style outliners?
> Or do you just mean making SystemWindows be morphs like any others and
> getting rid of all the special cases around them?

I meant that as soon as developers see things that look like windows (and 
menus, I suppose):

- they have certain expectations as to how they should act and feel, which 
  is not unreasonable since they look familiar.

- they associate their previous concepts of "window", "widget", "event 
  loop", etc. with the Morphic artifacts that appear to correspond to 
  those concepts.

- they then get frustrated when they run into differences between how 
  these familiar user interface elements act (and look) in Squeak and how 
  they act and look in the operating system with which they're most 
  familiar.

- they also miss the design philosophy which doesn't differentiate between 
  submorphs of the World and submorphs of those morphs. There is no 
  distinction in Morphic between a "widget" and a "top level Morph".

I'm not saying that the tools that we have in Morphic that happen to live 
in windows aren't useful. It's just that there's this disconnect between 
things that want to be their own mini-worlds with an idea of focus and 
locality (i.e. windows and their embedded morphs) and things that don't.

I'm also not arguing that Morphic has the best solutions to the problems 
of event routing, layout, drawing, etc.. As someone who has done a fair 
amount of Morphic programming, I feel strongly that we can make Morphic 
better than it is now. However, I'm not sure that a wholesale refactoring 
of Morphic would be worth the time at this point, as there are a couple of 
important new UI systems in the works (Tweak and Croquet), and I also 
think that the desire for a cleaner, more "standard" user interface that 
includes the elements that people are used to is not necessarily best met 
by Morphic.

As you know, there's lots of stuff in Morphic (and Squeak in general) that 
is a result of its focus on being the platform for EToys. I think that 
much of the current complexity of Morphic is due to design decisions (made 
under time pressure, of course) from EToys (and Alan's various demos) 
creeping into what started out as a much simpler system.

For example, looking at different historical versions we see:

v 1.31 (before EToys): Morph selectors size 231 Morph withAllSubclasses 
size 101

v 2.0 (the dawn of EToys): Morph selectors size 347 Morph 
withAllSubclasses size 129

v 2.1 Morph selectors size 357 Morph withAllSubclasses size 138

v 2.8 Morph selectors size 540 Morph withAllSubclasses size  269

v 3.0 Morph selectors size  924 Morph withAllSubclasses size   343

v 3.6 full Morph selectors size   1090 Morph withAllSubclasses size    394

the Squeakland developer's image that I'm working on right now, with m17n 
and Connectors in it: Morph selectors size  1258 Morph withAllSubclasses 
size  444

An example of this effect is that there are two different and conflicting 
idioms (well, three if you count my work in Connectors) for associating 
behavior with UI events:

* You can override #mouseDown:, etc. to get the behavior you want
* You can plug the EventHandler by using #on:send:to: (I think that this 
  may have been added for triggering EToys scripts from UI events)
* You can override #processEvent:using: for more control over how things 
  are handled (I do this in my QHSMMorph which is the basis for my new 
  Connectors)

And there's also one-off variations on this, like (some of the) buttons 
that give you a different way to plug the behavior.

> It would be nice to see some kind of proof of concept of a
> Morphic-without-windows, even a very rough one...

We have one. It's called EToys.

I use Morphic all the time with Connectors and its various morphs and 
menus without ever having to see windows.

> It would be nice to see some kind of proof of concept of a
> Morphic-without-windows, even a very rough one...

If you think about what windows do for us, you'll see that there have to 
be other ways to do what they do.

What overlapping windows do (off the top of my head):

* they provide single grabbable object that acts as a container and may be 
  moved or overlapped with others to save pixels and limit what you have 
  to look at at any instant

* they bundle several related UI elements together and often let you 
  resize the areas that those elements occupy

This isn't really very much.

We've seen many environments that don't use overlapping windows at all, 
ranging from the very task specific (CAD programs, etc.) to different user 
interface models (like the visual languages) to all-text environments like 
some versions of Emacs.

If the problem is just being able to re-use pixels and organize what you 
see at any instant, then all we need is some facile way to remember the 
various arrangements of things that we've constructed, rearranged, or had 
pre-constructed.

Instead of having to stick things in windows (or other containers), if 
there was a more general way to specify the arrangement constraints of UI 
elements (along with wiring up the events, etc.) then that could be used 
both to glue UI elements together into tools and to glue those tools into 
task-oriented snapshots of a workbench or desktop configuration. Windows 
themselves aren't needed for this purpose, though it is nice to have 
common UI elements for resizing and grabbing.

The ownership relationship in Morphic is an example of a global policy for 
such constraints that mostly seems to work well but can be limiting 
sometimes. I just added the ability for Connectors to attach to submorphs; 
this introduced the necessity to add new accessors to EToys so that the 
embedded pins and their owners could talk with each other.

-- Ned Konz