jackiw@cs.swarthmore.edu (Nick Jackiw) (01/12/89)
In article <482@pyuxf.UUCP> asg@pyuxf.UUCP (alan geller) writes: > > My question, though, is: > WHY can't layer switches happen when a modal dialog is displayed? > Or, alternatively, would it be possible to create a type of dialog > that would be 'layer modal' rather than 'system modal'; > that is, if such a dialog were displayed, then no other > window/dialog/menu/control/etc. in the owning layer and > task would be available to the user, but the user could > switch layers (to a different task) if so desired? > > Alan Geller > Bellcore > ...!{princeton|rutgers}!bcr!asg Mostly the answer to (A) concerns the event-driven programming model of Mac programs. Someone else has already pointed out that (B) is easy to do IF you're writing your own programs, but it's difficult to modify existing programs to give you what you want (layer-switching from beneath modals). Well-written Mac programs have a "main event loop" from which they can dispatch to various operating system or user requests to take some action, including (and this is a biggie for MultiFinder) redrawing their windows if necessary (because some other window's blocked them). At the beginning of the event loop, the program asks the system for an event. This is where MultiFinder might switch the layer out: the event-request never returns. Then, when MultiF needs to switch the layer back in, either to resume its topmost status or just to force it to redraw its corrupted windows, this pending event-request returns, and the program never needs to know it just spent some time in limbo. Enter the modal dialog difficulty. Modal dialogs are treated differently by apps than other windows, because there is a toolbox call (_ModalDialog) which will process all events pertaining TO THAT DIALOG ALONE. A mini-event loop, as it were. Now, imagine if MF were to snatch control out from the get-event-requests which are presumably buried in the call to _ModalDialog. There are no problems giving time to other tasks, and this is what MF does. If, however, it allowed another layer to come frontmost, that would corrupt the windows in the _ModalDialog layer. Now if User drags or resizes or closes a top-layer window, portions of the windows in the layer with the modal are going to be exposed, and consequently require updating in their back layer. Normally, MultiFinder would (TASK-)switch the app in, feed it its update events, and (TASK-)switch back to the frontmost layer. THE WHOLE PROBLEM: The modal app CAN'T PROCESS ITS UPDATES, or provide other key functionality, because it's not in its main event loop, it's only in the mini-event loop of the specific call to _ModalDialog. (Remember, this loop can't do anything but maintain the dialog.) So, if MF switched out from under a modal, that layer's windows would progressively deteriorate, until they were all just empty window frames (except for the modal window, which would get updated because _ModalDialog can process THOSE updates). Time for my disclaimer: this is all guesswork. I've never traced the code, and I have only a dim knowledge of the bowels of MultiFinder. I DO know that MF can't access your main-event-loop from within the ModalEventLoop, however: programs have to be explicitly coded to support that sort of re-entrancy, and most aren't. Programmers could easily design layer-switchable modals that resembled real ones, it would just require integrating modal-event handling with regular-event handling (and maintaining an internal flag indicating that USER- [vs. SYSTEM-] events which don't pertain to the pseudomodalwindow should be ignored. Sorry to be so longwinded. I knew there had to be a better reason than "it was a user-interface decision." This is my guess at one. No flames, thank you. -- +-------------------+-jackiw@cs.swarthmore.edu / !rutgers!bpa!swatsun!jackiw-+ | nicholas jackiw | jackiw%campus.swarthmore.edu@swarthmr.bitnet | +-------------------+-VGP/MathDept/Swarthmore College, Swarthmore, PA 19081--+ PER ASPERA AD ASTRA -- +-------------------+-jackiw@cs.swarthmore.edu / !rutgers!bpa!swatsun!jackiw-+ | nicholas jackiw | jackiw%campus.swarthmore.edu@swarthmr.bitnet | +-------------------+-VGP/MathDept/Swarthmore College, Swarthmore, PA 19081--+ PER ASPERA AD ASTRA
beard@ux1.lbl.gov (Patrick C Beard) (01/13/89)
In article <2299@ilium.cs.swarthmore.edu> jackiw@swatsun.UUCP () writes: >In article <482@pyuxf.UUCP> asg@pyuxf.UUCP (alan geller) writes: >> >> My question, though, is: >> WHY can't layer switches happen when a modal dialog is displayed? > >Now, imagine if MF were to snatch control out from the >get-event-requests which are presumably buried in the call to _ModalDialog. >There are no problems giving time to other tasks, and this is what MF does. >If, however, it allowed another layer to come frontmost, that would corrupt >the windows in the _ModalDialog layer. Now if User drags or resizes or closes >a top-layer window, portions of the windows in the layer with the modal are >going to be exposed, and consequently require updating in their back layer. >Normally, MultiFinder would (TASK-)switch the app in, feed it its update >events, and (TASK-)switch back to the frontmost layer. THE WHOLE PROBLEM: >The modal app CAN'T PROCESS ITS UPDATES... Untrue. You are forgetting the parameters that are passed to ModalDialog: pascal void filterProc(); short int itemHit; ModalDialog(filterProc, &itemHit); ^^^^^^^^^^ All normal event processing can be done from within this code. If you write your application like this: main() { EventRecord evt; StartupMac(); /* init managers */ do { if(GetNextEvent(everyEvent, &evt)) { ProcessEvents(&evt); } else { IdleAwayTheHours(); } SystemTask(); /* of course it's easier to call WaitNextEvent... */ } while(!quit); CloseUpShop(); /* deallocate everything */ } Then from within your filterProc you just call ProcessEvents() when appropriate. Sorry for my longwindedness. Patrick Beard Berkeley Systems, Berkeley CA
jackiw@cs.swarthmore.edu (Nick Jackiw) (01/17/89)
In article <1678@helios.ee.lbl.gov> beard@ux1.lbl.gov (Patrick C Beard) writes: > In article <2299@ilium.cs.swarthmore.edu> jackiw@swatsun.UUCP () writes: > >In article <482@pyuxf.UUCP> asg@pyuxf.UUCP (alan geller) writes: > >> WHY can't layer switches happen when a modal dialog is displayed? > >THE WHOLE PROBLEM: > >The modal app CAN'T PROCESS ITS UPDATES... > Untrue. You are forgetting the parameters that are passed to ModalDialog: > pascal void filterProc(); > short int itemHit; > ModalDialog(filterProc, &itemHit); > ^^^^^^^^^^ > Then from within your filterProc you just call ProcessEvents() when > appropriate. > Patrick Beard You're right, but what I wrote IS true. Of course it's possible to code an app so that MF can switch out from modal situations. Elsewhere in my article I mentioned exactly that possibility. The vast majority of apps written in Multifinder times and ALL apps written before it, however, are NOT going to implement a filterProc to process updates for non-modal windows. Before Multifinder, this was considered an impossible occurence. We were talking about why MFinder's backward-compatibility enforces total modality, not about what tricks wonder-boy can teach wonder-app with total retrospective knowledge of the inner workings of an elaborate and elegant multiprocessing kludge. Follow before ya flame. -- +-------------------+-jackiw@cs.swarthmore.edu / !rutgers!bpa!swatsun!jackiw-+ | nicholas jackiw | jackiw%campus.swarthmore.edu@swarthmr.bitnet | +-------------------+-VGP/MathDept/Swarthmore College, Swarthmore, PA 19081--+ PER ASPERA AD ASTRA
wdh@well.UUCP (Bill Hofmann) (01/19/89)
In article <2311@ilium.cs.swarthmore.edu> jackiw@ilium.UUCP (Nick Jackiw) writes: >In article <1678@helios.ee.lbl.gov> beard@ux1.lbl.gov (Patrick C Beard) writes: >> In article <2299@ilium.cs.swarthmore.edu> jackiw@swatsun.UUCP () writes: >> >In article <482@pyuxf.UUCP> asg@pyuxf.UUCP (alan geller) writes: >> >> WHY can't layer switches happen when a modal dialog is displayed? Because Multifinder won't switch when a window of type dBoxProc, the standard modal dialog or alert window, is frontmost. As I understand it, this was a deliberate decision to improve backward compatability. >You're right, but what I wrote IS true. Of course it's possible to code an >app so that MF can switch out from modal situations. Elsewhere in my article >I mentioned exactly that possibility. The vast majority of apps written in >Multifinder times and ALL apps written before it, however, are NOT going to >implement a filterProc to process updates for non-modal windows. Before >Multifinder, this was considered an impossible occurence. Beg to differ. If your modal dialog does something like put up an SFGet or SFPut, you could easily have to deal (or want to deal) with update events. My standard filterproc handles updates. -Bill Hofmann