[comp.sys.mac] TransSkel: Proposed Changes

dubois@uwmacc.UUCP (02/11/87)

Proposal for Changes to TransSkel

1. Introduction

This document proposes a set of modifications to be made to the
TransSkel transportable application skeleton.  The purpose of the
modifications is to correct a design deficiency in port-setting
behavior.  To motivate the discussion, a model of "proper" port
behavior shall be specified, followed by a list of the changes
necessary to bring TransSkel into congruence with this model.  This
list shall indicate how the current version violates the model and the
changes necessary to rectify the violation.

The fact that such a model has never been made explicit is itself a
deficiency.  Had my thinking not been muddy in the first place, this
proposal might not have been necessary.  My thanks to Duane Williams
for first pointing out my departure from orthodoxy.

As the proposed changes lead to some incompatibilities with existing
applications, I am requesting comment before proceeding.  I should
emphasize that the incompatibities are well-localized, though, and host
applications are generally easily made compatible.

Readers who object to any or all of the proposed changes should say so,
and say why.  Silence shall be taken as implicit assent.


The model is quite simple:  The current port shall always be associated
with the frontmost (or active) window.  This implies that persistant
changes to the current port are made only when a different window
becomes active, and that all other port changes take place purely
locally (i.e., the current port is saved before and restored after the
local port change).

The association of the current port with the active window is congruent
with the user's perception of the way the application works:  most
actions are performed in the active window and those that aren't are
usually such as to bring another window forward.  (From the user's
point of view, the port is changed by clicking in a window to bring it
to the front.)  The local-changes-only clause of the model follows from
the description of SetPort in Inside Macintosh, which says:  "Only
SetPort (and OpenPort and InitPort, which call it) changes the current
port.  All the other routines in the Toolbox and Operating System (even
those that call SetPort, OpenPort, or InitPort) leave the current port
set to what it was when they were called."

I propose to make TransSkel adhere to this standard.  Naturally,
TransSkel cannot do so without the cooperation of the host application.
As matters stand now, however, the host cannot follow the model whether
it wants to or not, because TransSkel itself violates it.  This is an
unintended side effect of the guarantee TransSkel makes to window
handling routines that the port shall always be set to the affected
window when the routines are called.  It turns out that if TransSkel
follows the model, the effect of the guarantee (to make sure the port
is set to the affected window) follows naturally, IF the host does not
itself gratuitously change the port.  That is, those hosts that wish to
follow the model will be able to.


2. Description of Proposed Changes

2.1. Menu Handling Routines

No changes shall be made, as these do not directly affect the current
port.

2.2. Window Handling Routines - Non-dialog Windows

Each window handler comprises a set of routines for handling mouse, key
and closebox clicks, activate and update events, window disposal and
idle time.  In addition, TransSkel's general event procedure
generically handles window growing and zooming.

Some of the changes below rely implicitly on the understanding that a
window is not deactivated until after it is activated and that activate
events have the highest priority.

2.2.1. Activate event handler

Current:  If the window hander has a non-nil activate event handler, it
sets the port to the window and calls the procedure with an indication
of whether the window is coming active or going inactive.

Proposed:  The port shall be set to the window if it is coming active,
whether the activate handling procedure is nil or not.  Thus the
current port shall be set to that window, regardless of the action the
host takes in response to the event.

2.2.2. Update event handler

Current:  Since updates may occur for any window (not just the active
one), the current port is saved prior to setting the port to the window
to be updated, and restored after calling the window's update
procedure.

Proposed:  No change; the current behavior is correct.

2.2.3. Mouse click handler

Current:  The mouse click handler is only invoked for clicks in the
content region of the active window.  The port is set to the window in
which the click occurred, then the window's click handler is called.

Proposed:  As the port has already been set to the window when it came
active, setting the port again is superfluous and shall not be done.

2.2.4. Key click handler

Current:  Key clicks are passed to the key click procedure for the
frontmost window.  The port is set to the frontmost window, then the
window's click handler is called.

Proposed:  As the frontmost window is the active window, the port has
already been set to it when it came active.  Setting the port again is
superfluous and shall not be done.

2.2.5. Closebox click handler

Current:  The port is first set to the window in which the closebox
click occurred.  If the window has a closebox handler, it is invoked,
otherwise the window is just hidden.  The port is then set to the
screenport to avoid a dangling port.

Proposed:  As only the closebox of the frontmost (active) window can be
clicked, the port is already set properly.  Setting the port again is
superfluous and shall not be done.  It is also unnecessary to avoid a
dangling port:  if there is another window behind the one being closed,
it will come active and the port will be set to it.  If not, there are
no windows, so it does not matter what the port is set to.

2.2.6. Window clobber handler

Current:  This procedure is called by SkelRmveWind to dispose of the
window.  The port is set to the window to be disposed of, and to the
screen port after disposal to avoid a dangling port.

Proposed:  Since any window (not just the active one) may be disposed
of at any time, the current port shall be saved prior to setting the
port to the window to be disposed of, and restored after calling the
window's clobber procedure.  In the case that the front window is being
disposed of, saving and restoring the port is harmless:  if there is
another window behind the one being closed, it will come active and the
port will be set to it.  If not, there are no windows, so it does not
matter what the port is set to.

2.2.7. Idle time procedure

Current:  Since the idle procedure may be invoked for any window (not
just the active one), the port is set to the affected window before
calling its idle routine.  The current port is saved before and
restored after doing so.

Proposed:  No change; the current behavior is correct.

2.2.8. Window growing

Current:  The window is grown, then the port is set to the window and
invalidated to generate an update event.

Proposed:  A click in the grow region can only occur for the active
window, to which the port shall have already been set.  Setting the
port again is superfluous and shall not be done.

2.2.9. Window zooming

Current:  The port is set to the window to be zoomed before zooming it.
(ZoomWindow requires this.)  Then the port is invalidated to generate
an update event.

Proposed:  A click in the zoombox region can only occur for the active
window, to which the port shall have already been set.  Setting the
port again is superfluous and shall not be done.


2.2.10. Summary

Only activate events shall set the port and leave it set.  Mouse, key,
closebox, grow region and zoombox clicks shall not cause the port to be
set, as they are only relevant to the active window, to which the port
has already been set by the previous activate.  Update, idle and
clobber procedures may be called for any window, so the port shall be
saved before and restored after setting the port to the affected window
and calling the handler routine.


2.3. Window Handling Routines - Dialog Windows

Dialog window handlers are comprised of event, closebox and clobber
procedures.

Dialog windows introduce a complication:  The model relies on activate
events for proper port-switching, but activate events for dialog
windows are not seen directly (the Toolbox routine DialogSelect handles
them automatically with no explicit indication that it has done so).
Therefore, after IsDialogEvent is called but before DialogSelect is
called, the event must be checked and the port set if a dialog is
coming active.  I assume that for other events, DialogSelect takes care
of saving and restoring the port properly itself.


2.4. Window Handler Installation

Current:  When a handler for a window is installed, SkelWindow sets the
port to the window.  SkelDialog calls SkelWindow, so the port is set to
any dialog for which a handler is installed.

Proposed:  The port shall not be set.

         *****************************************************
This change will make TransSkel incompatible with previous releases,
and will break existing applications built on top of it, if they draw
into a window or dialog immediately after installing its handler (i.e.,
if they rely on the port being set).  The host shall be required to set
the port itself if it wishes to draw into the window before it comes
active.
         *****************************************************

The proposed change will break, in particular, most of the demos
distributed with TransSkel, as well as TransDisplay and TransEdit.

---
Paul DuBois     UUCP: {allegra,ihnp4,seismo}!uwvax!uwmacc!dubois    |
                ARPA: dubois@easter                               --+--
                      dubois@rhesus                                 |
                                                                    |
"My help does not come from the hills"
                      Psalm 121:1