[comp.sys.mac] Window Manager problem

thomas@uvabick.UUCP (Thomas Fruin) (07/10/87)

Thought  I'd try  my luck on  Usenet too,  after not  hearing from
Info-Mac for about two weeks...

I'm confused by a Window Manager problem I've run into. Maybe I've
even found an error in Inside Macintosh.  Let me  explain what I'm
trying to do:

The program I'm working on will have a "palette" window similar to
those windows in FullPaint: a window that always stays on top, but
doesn't act as the active window.  My  program  will have  several
document windows below this palette that  should  behave as normal
as possible to the user.

This  means  that  when a user  clicks  in a window that isn't the
active one, that window should be brought to the front,  BUT  stay
below the palette window.  Obviously I cannot use SelectWindow for
this.  Instead I use  SendBehind, which seems exactly the function
for this purpose (forget about highlighting for now).

Here is where the problem occurs.  Inside  Macintosh tells me that
if I use SendBehind to move a window closer to the front, I should
make  some  extra low-level  Window  Manager  calls  after calling
SendBehind.  Specifically a call to PaintOne and one to CalcVis.

But I don't think these  are  sufficient.  Whenever I try this out
by  clicking in one of my  windows to bring it to the "front", the
visRgn  of  the  window  that  used  to be in front is screwed up.
Anything  I  draw  in  it doesn't stay in its visible  region, but
flows into the window I just brought to the front. See the figure.
It shows two windows before and after the SendBehind, PaintOne and
CalcVis calls, when I start drawing into one of them.

    --------------------          --------------------
    |behind            |          |in front          |
    |   -------------------       |                  |---
    |   |I am drawing text|       |    I am drawing text|
    ----|into lower right |       -----into-lower-right |
        |window only.     |           |window only.     |
        -------------------           -------------------

By  changing  the  CalcVis call to a CalcVisBehind  things go back
to normal.  So it  seems  to me  SendBehind  is not  updating  the
visRgn of the  window(s) it is  covering up.  Of course it should.
The Apple traplist in the Sybex book  Using the Mac Toolbox with C
says that SendBehind already calls CalcVisBehind...

Can  anyone help me with this one?  If I'm doing things all wrong,
I'd also welcome suggestions to other and better ways to implement
such a palette window.

-- Thomas Fruin

   fruin@hlerul5.BITNET
   thomas@uvabick.UUCP

   Leiden University, Netherlands

oster@dewey.soe.berkeley.edu (David Phillip Oster) (07/13/87)

The current issue of MacTutor magazine has a good article on
implementing pallette windows, and in particular it discusses the
window manager issues involved.
--- David Phillip Oster            --My Good News: "I'm a perfectionist."
Arpa: oster@dewey.soe.berkeley.edu --My Bad News: "I don't charge by the hour."
Uucp: {seismo,decvax,...}!ucbvax!oster%dewey.soe.berkeley.edu

drc@dbase.UUCP (Dennis Cohen) (07/13/87)

The proper way to create palettes is via the "GhostWindow", not through the use
of SendBehind, etc as described in your posting.

Dennis Cohen
Ashton-Tate Glendale Development Center
dBASE Mac Development Team

gjs@k.cs.cmu.edu (Gregory Stein) (07/14/87)

I have implemented a palette with LSC.  I found that keeping the
window in the BACK rather than the front is painless and avoids
many of the problems of trying to hide it in the front.  The Toolbox
has nothing against handling clicks in windows that aren't in the
front.  Just keep everything the same, but don't do a SelectWindow
on the palette's window when you click in it.  Also, since you'll
probably be using a plain dialog box for the palette, you won't have
worry about any hiliting effects.

The code, depending on what it has to do, should not run you more
than 100 lines, tops.  To make it nice and flexible, you might want
to read a list of PICT resources and position information from your
resource file.

---------

Greg Stein
ARPA:	gjs@k.cs.cmu.edu

	"There can be only one"
		-- from the movie, "The Highlander"

thomas@uvabick.UUCP (Thomas Fruin) (07/17/87)

There have been several replies and suggestions after my Window Manager
query.  Thanks to everyone.  However, the question still stands.

Let me first state that I _have_ implemented multiple palette/ghostwindows
in Aztec C.  Everything works fine.  My code supports several palettes that
always lie on top, except when a desk accessory gets opened or clicked.
Then the disk accessory gets put on top.  The "top" document window gets
highlighted and activated normally.  All windows can be dragged in their
own plane, or are brought to the position just behind the last ghostwindow
and then dragged.

Several people suggested using the GhostWindow global.  I've found it to be
quite useless, because 1) its mechanism only supports ONE ghostwindow and
2) it does very little.  Inside Macintosh says that GhostWindow can be made
to point to a window that's not to be considered frontmost even if it is.
Read those words carefully.  It says nothing about what to do when you want
to change the ordering of windows behind it.

MacTutor's article about Palette windows is nice, but doesn't really help in
this situation.  It describes one popup window and only works when the
windows below it don't change while the popup is visible.  Thanks for the
pointer though.

Someone also mentioned that the low-level Window Manager calls I was using
weren't preserving the current port.  Fortunately I never ran into that
problem.

Gregory Stein writes:
> I have implemented a palette with LSC.  I found that keeping the
> window in the BACK rather than the front is painless and avoids
> many of the problems of trying to hide it in the front.  The Toolbox
> has nothing against handling clicks in windows that aren't in the
> front.  Just keep everything the same, but don't do a SelectWindow
> on the palette's window when you click in it.  Also, since you'll
> probably be using a plain dialog box for the palette, you won't have
> worry about any hiliting effects.

We probably have very similar code.  I don't call SelectWindow either to
bring a window to the "front" (just behind my ghostwindows).  This is where
I use SendBehind.  And being a good boy, I called PaintOne and CalcVis after-
wards (see Inside Macintosh, I-286).  This is where I think IM fails.  It
makes a genuine suggestion, but it is wrong here.  Change CalcVis to
CalcVisBehind and and everything works as it should.  So this particular
question remains: I am right in assuming this and is Inside Macintosh wrong?

When I have my code cleaned up and commented, I'll be happy to post it.
For now, see my modified SelectWindow.  For simplicity I'm assuming there
is only one ghostwindow, there are no desk accessories and every window is
visible:

  /* Unhighlight and deactivate the current "front" window */

  HiliteWindow( myGhostWindow->nextWindow, FALSE );
  curDeactive = myGhostWindow->nextWindow );

  /* Bring myWindow to "front", redraw it, recalculate its visible region
     and the regions of the windows behind it, highlight and activate it.*/

  SendBehind   ( myWindow, myGhostWindow );
  PaintOne     ( myWindow, myWindow->strucRgn );
  CalcVisBehind( myWindow, myWindow->strucRgn );
  HiliteWindow ( myWindow, TRUE );
  curActivate = whichWindow;

That's all folks!

-- Thomas Fruin

   fruin@hlerul5.BITNET
   thomas@uvabick.UUCP

   Leiden University, Netherlands