[net.micro.mac] Application State & Desk Accessories

dubois@uwmacc.UUCP (Paul DuBois) (10/20/86)

Program state changes often result from a change in the currently
active window, and are often reflected by changes in the states of the
application's menus.  For the most part, such state changes are
detected easily simply by monitoring activate and deactivate events.
The presence of desk accessory windows complicates things a bit, but
bringing a DA window in front of an application window results in a
deactivate event for that window, and so can be detected indirectly.
This suffices for applications that always keep at least one window
visible, since it can use activate/deactivate events on application
windows to trigger detection of activate/deactivate events on DA
windows.

If the application can exist in a state where no application windows
are visible, it becomes more difficult to make sure the menus always
reflect the program's state.  (At least, I think it becomes more
difficult, which is why I'm writing this note.)  For instance, if the
application maintains a File menu with a Close item, that item is
typically enabled when an application window is open (so the window can
be closed) and disabled when no application windows are open.  But the
item should also be enabled when a DA window is active.  It's easy to
know what to do with the item when a DA window is brought up in front
of an application window; this can be detected since the latter
receives a deactivate event.  It's not so easy to tell, when there
aren't any application windows, that a DA window has come up (so that
Close should be enabled) or the last DA has gone away (so that Close
should be disabled).

I notice that Knaster (How to Write Macintosh Software, pp. 308ff)
tackled this problem.  What he did was to make sure the state got
checked whenever a DA was opened, and after SystemClick was called,
since each of these has the potential of changing the active window.

Is this scheme sufficient?  I don't think so.  Consider the existence
of such things as Other... and Double Apple, which can themselves open
and close DA's, in a manner that the host may remain entirely oblivious
to.

What might a general solution be?  I don't know, but one possibility is
to constantly check what the front window is, and respond accordingly.
This can be done in the idle loop (or in the SkelBackground procedure,
in TransSkel terms).  That can get pretty ugly.  The menus could be set
every pass through the loop, which would guarantee accuracy, but might
involve a lot of overhead, and is probably not a good general solution.
Better, perhaps, would be to keep track of which window was active on
the last pass though the loop, and reset the menus only when it changes.

How do you others approach this problem?  Or don't you find this a
problem?
-- 
Paul DuBois     UUCP: {allegra,ihnp4,seismo}!uwvax!uwmacc!dubois    |
                ARPA: dubois@easter                               --+--
                      dubois@rhesus (no kidding)                    |
                                                                    |
"If it works, I didn't write it."
"That's for sure!"

guido@mcvax.uucp (Guido van Rossum) (11/01/86)

>From: dubois@uwmacc.UUCP (Paul DuBois)
>[...] It's not so easy to tell, when there
>aren't any application windows, that a DA window has come up (so that
>Close should be enabled) or the last DA has gone away (so that Close
>should be disabled).

I suspect that there are a lot of applications out there that completely
reconstruct their menus whenever a mouse click in the menu bar is
received.  In particular I think MacWrite does this, because it takes
extraordinarily long (about a second?) from the mouse click till the
menu falls down.  It might be that most of the time is spent in the
AddResMenu call for the Font menu.

A different obeservation regarding the "Close" item in most File menus
is that I never use them.  I always click the close box.  I believe this
is true for most, even very novice Mac users: the close box is about the
first shorthand you learn to use, and soon you'll forget it has an alias
as a menu item...  Therefore it would not be a big loss if your Close
menu item were deactivated when a DA window was on top.  In fact a DA
might choose to have a window without a close box, which makes your
decision to activate the Close menu item equally wrong.  I believe that
in principle, an application cannot know enough about a DA to know which
menu items to (de)activate; the only rule is that the Edit menu should
have Undo, Cut, Copy, Paste and Clear, even though not all DA's actually
respond to these (the highlighted Undo is particularly bad, since it
makes novice users believe that they can Undo their actions).

Straying away further from the subject, often I miss a *keyboard*
equivalent to clicking the close box.  Now that Standard File Dialogs
can be operated completely from the keyboard, and so many other
operations have keyboard shortcuts, it is annoying to have to grab the
mouse to close a window.

And, finally, on keyboard equivalents: when a DA is active, key presses
are generally processed by the DA, not by the application.  This means
that the application, if it wants to be super-correct, should remove the
shortcuts from its menus -- *except* ^Z, ^X, ^C, ^V for the edit menu!
So here you have a reason why you *do* want to detect wheter a DA is
active, even if you don't want to activate Close, and we're back to the
original question: how to detect it and when to changes the menus?
The proper thing to do in my opinion is to check continuously in the
main loop, but update the menus only when a change is detected.
-- 
	Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>