Newsgroups: comp.windows.interviews
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!snorkelwacker.mit.edu!stanford.edu!AKBAR.TELEOS.COM!neil
From: neil@AKBAR.TELEOS.COM
Subject: MOdal Dialogs/ G++
Message-ID: <9106061529.AA29233@shelby.Stanford.EDU>
Sender: neil@akbar.teleos.com
Organization: Internet-USENET Gateway at Stanford University
References: <1991Jun5.141228@Pkg.Mcc.COM>
Date: Thu, 6 Jun 1991 15:29:18 GMT
Lines: 51

IV2.6
=====

    Here at MCC one of our programmers created
    a new kind of dialog that does not allow any
    other interactors to receive events while it
    is "popped up".  We call this a Modal Dialog.

    What we had to do was to take over the run
    operation during display of the MD and refuse
    to pass on any events occurring outside the
    bounds of the local scene to their targets.

I had the same problem.  In fact, with the non modal dialogs, it was
easy to invoke the same dialog box twice, leaving internal variables
in a bad state.  I came up with the same solution as you: checking the
bounding box of the Dialog and only passing on events inside.

However, there is a fatal flaw with that approach as well.  If the
window manager buries the dialog window (e.g. if you click on the boundary
of an overlapping window initially behind the dialog), the dialog box
will be partly or completely obscured, potentially by another window of the
same application.  Now an event read in the Dialog::Run for this other window
may be within the Dialog bounding box, but not destined for a subwindow
of the Dialog.  Same problem occurrs, and it is not as unlikely as it sounds!

My solution - actually check the target interactor for having the dialog
as an ancestor:

    /*
     * Loop reading events.
     */
    int v;
    do
    {
	Read(e);

	// Only handle events for interactors whose ancestors include this.
	for(Interactor *i = e.target; i; i = i->Parent())
	{
	    if(i == this)
	    {
		e.target->Handle(e);
		break;
	    }
	}

	state->GetValue(v);
    } while(v == 0);

Neil/.	    Neil@teleos.com
