The close of a Splash is forcing the close of a dialog

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

The close of a Splash is forcing the close of a dialog

Sebastián Sastre
Hi there,

  anybody knows how to avoid a situation in wich the close of a Splash
is forcing the close of a dialog?

  I have a code like this:
XXXApplicationShell>>initializeUser

| dialog |

        login := self applicationLoaderSupport createOn: self newUser.
        login
                userSession: userSession ;
                validationBlock:[:candidate| blah blah... true or false];
                userGetterBlock: [:candidate| the fresh user object from repository];
                loginAllowedBlock: [:user|];
                loginNotAllowedBlock: [:candidate|blah blah... you cannot login];
                yourself.

        self trigger: #aboutToLogin.

        ^ login showModalTo: self view

1. The triggered #aboutToLogin is cached by the splash and it uses it
to close itself (#forceClose).
2. The #showModalTo: is to ensure that the dialog is related to the
application shell (and not the splash).
3. In that point, the application shell is instantiated but not visible
yet.

  I've put a halt on the close of the dialog and saw that the #close
message cames from a windows message (event) and I don't know how to
prevent it. Going back in that stack shows that the close of the Splash
implies somehow the sending of that windows event. I've also check that
the #basicDestroy where the handle of the Splash and not other and, as
expected, it was.
I can't say what is happening in ProcessorScheduler>>callback:evaluate:
but debugger reveals that it enters to execute the ifCurtailed: block
wich derivates in the dispatching of the window event that sends
#onDestroyed to the poor dialog.

  It is curious that in
XXXApplicationShell(ApplicationShell)>>initializeUser, one line after
the #trigger: #aboutToLogin, the #showModalTo: is called but it is not
seen in the process. Its behavior is like it is closing a window (the
dialog) that nobody has opened (yet).

  The semaphore that the splash uses can being noisely interfering
here?

  I'll appreciate any help, thanks,

Sebastian
PD: I'll put a trace of that debugging situation below this line:
____________________________________________________________
XXXApplicationLoaderDialog(SystemLoaderDialog)>>onViewClosed
DialogView(View)>>onDestroyed
DialogView(View)>>wmDestroy:wParam:lParam:
DialogView(View)>>dispatchMessage:wParam:lParam:
[] in InputState>>wndProc:message:wParam:lParam:cookie:
BlockClosure>>ifCurtailed:
ProcessorScheduler>>callback:evaluate:
InputState>>wndProc:message:wParam:lParam:cookie:
Splash(View)>>basicDestroy
Splash(View)>>destroy
Splash(Splash)>>forceClose
EventMessageSend>>forwardTo:withArguments:
EventMessageSend>>value
[] in MessageSequenceAbstract>>value
EventMessageSequence>>messagesDo:
EventMessageSequence(MessageSequenceAbstract)>>value
EventsCollection>>triggerEvent:
XXXApplicationShell(Object)>>trigger:
XXXApplicationShell(ApplicationShell)>>initializeUser
XXXApplicationShell(ApplicationShell)>>initializeUserSession
XXXApplicationShell(ApplicationShell)>>onViewOpened
XXXApplicationShell(Shell)>>view:
XXXApplicationShell(Shell)>>createView:
XXXApplicationShell class(ApplicationShell class)>>create:on:for:
XXXApplicationShell class(ApplicationShell class)>>showFor:
[] in TrayApplicationLoaderShell>>onViewOpened
ExceptionHandler(ExceptionHandlerAbstract)>>markAndTry
[] in ExceptionHandler(ExceptionHandlerAbstract)>>try:
BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
ExceptionHandler(ExceptionHandlerAbstract)>>try:
BlockClosure>>on:do:
[] in BlockClosure>>newProcess


Reply | Threaded
Open this post in threaded view
|

Re: The close of a Splash is forcing the close of a dialog

Support at Object Arts
"Sebastián" <[hidden email]> wrote in message
news:[hidden email]...
> Hi there,
>
>  anybody knows how to avoid a situation in wich the close of a Splash
> is forcing the close of a dialog?
>

Let us try and understand why it is happening first, then we can avoid the
need to try and block it. To be honest it is pretty difficult to help with
these sort of problems from a description and code snippets, but we'll
try...

>  I have a code like this:
>... [ code snipped ]...
> 1. The triggered #aboutToLogin is cached by the splash and it uses it
> to close itself (#forceClose).
> 2. The #showModalTo: is to ensure that the dialog is related to the
> application shell (and not the splash).
> 3. In that point, the application shell is instantiated but not visible
> yet.
>
>  I've put a halt on the close of the dialog and saw that the #close
> message cames from a windows message (event) and I don't know how to
> prevent it. ....

Can't say for sure from this information, but two scenarios spring to mind:
1) The splash shell is somehow the owner of the login dialog so when the
splash closes, it closes its owned windows, and the dialog is closed too.
2) Your session is being shutdown by keep alive processing.

You can investigate the former by using a tool such as Spy++ in the Windows
SDK. Obviously you'll need to make the splash stay up long enough so that
you can check the ownership of your logon dialog.

You can exclude (2) by overriding SessionManager>>keepAlive with a simple
method that does nothing. You will also need to explicitly terminate your
application when the main shell window is closed by adding a
#onViewDestroyed on the Shell (presenter) that looks like this:

    onViewDestroyed
         super onViewDestroyed.
         (SessionManager current isRuntime)
              ifTrue: [SessionManager current exit]

BTW: This is the recommended practice for shutting down a GUI app.

> ....snip...
>  It is curious that in
> XXXApplicationShell(ApplicationShell)>>initializeUser, one line after
> the #trigger: #aboutToLogin, the #showModalTo: is called but it is not
> seen in the process. Its behavior is like it is closing a window (the
> dialog) that nobody has opened (yet).

Well actually that suggests another scenario. It may be that Windows API
call is failing.

>
>  The semaphore that the splash uses can being noisely interfering
> here?
>
>  I'll appreciate any help, thanks,
>
> Sebastian
> PD: I'll put a trace of that debugging situation below this line:
> ____________________________________________________________
> XXXApplicationLoaderDialog(SystemLoaderDialog)>>onViewClosed
> DialogView(View)>>onDestroyed
> DialogView(View)>>wmDestroy:wParam:lParam:
>...

Unfortunately there is fairly little one can deduce from a bare walkback. We
could probably tell a lot more from a VM "crash dump" since it includes
details of all the argument values, etc.


Reply | Threaded
Open this post in threaded view
|

Re: The close of a Splash is forcing the close of a dialog

Chris Uppal-3
"Support", Sebastián,

>     onViewDestroyed
>          super onViewDestroyed.
>          (SessionManager current isRuntime)
>               ifTrue: [SessionManager current exit]
>
> BTW: This is the recommended practice for shutting down a GUI app.

Only for single-window applications, surely ?

Also you (whoever you are) seem to be assuming that this is happening in a
deployed app, but since Sebastián mentions tracing though under the debugger, I
suspect he hasn't reached that stage yet,

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: The close of a Splash is forcing the close of a dialog

Schwab,Wilhelm K
Chris,

> "Support", Sebastián,
>
>>     onViewDestroyed
>>          super onViewDestroyed.
>>          (SessionManager current isRuntime)
>>               ifTrue: [SessionManager current exit]
>>
>> BTW: This is the recommended practice for shutting down a GUI app.
>
> Only for single-window applications, surely ?
>
> Also you (whoever you are) seem to be assuming that this is happening in a
> deployed app, but since Sebastián mentions tracing though under the debugger, I
> suspect he hasn't reached that stage yet,

Good point.  FWIW, this had me thinking of deployement too - it's
probably the splash screen.  Beyond that, could this simply be a problem
with sending a dialog to do a shell's job?

Have a good one,

Bill


--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: The close of a Splash is forcing the close of a dialog

Sebastián Sastre
Hi there,

  I do confirm it was in Develpment but that is irrelevant in this
problem. Bill, the dialog is for the user's login, so it *has* to be a
dialog. That *LoginDialog*  is shown by the main application's shell
that is not visible yet.

  Dear *Support at Object Arts* I can send the VM crash dump but I
think it also cant help too much. I've ensured that the splash has as
parentView the desktop and that the dialog has as parent view the main
application's shell. So there is no mistake there.

  The debugger brings once and again the situation in wich the splash
is destroyed and then *somehow* a windows event, I mean a

 [] in InputState>>wndProc:message:wParam:lParam:cookie:

  message, is going directly to destroy the dialog. So... I've decided
not to enter into the Windows domains and disencouraged that strategy
to show the splash.

  My solution was that I've simply set an instVar #splash, lazily
initialized, in the main shell, wich is shown as desired, and that is
hided just before opening the LoginDialog. When the dialog is closed
the #splash is destroyed and released. It worked just as I espected.

  cheers,

Sebastian


Reply | Threaded
Open this post in threaded view
|

Re: The close of a Splash is forcing the close of a dialog

Steve Alan Waring
Hi Sebastián,

My 2c ...

> parentView the desktop and that the dialog has as parent view the main
> application's shell. So there is no mistake there.

Both the Dialog and Splash are probably top level windows, therefore
the parentView instance variable in both, will be used by Windows as
the owner, not the parent.

Raymond Chen gave a great talk at PDC05 (which has unfortunately been
removed from the web) on the difference between parents and owners. He
said that Windows can end up giving a view a different owner to what is
passed in (ie the parentView). The main situation that I can recall is
that if parentView is not itself a top level window, Windows will find
the parentView's owner and use that as your view's owner.

IMO, the evidence in your situation suggests that the Splash ended up
as the owner of the dialog. To rule this out, you can't rely on
checking the parentView instance variable. As OA suggested, use a tool
like Spy (I use http://www.windows-spy.com/ ), or use the method
View>>getParent (which confusingly answers the actual parent or owner).

>  My solution was that I've simply set an instVar #splash, lazily
> initialized, in the main shell, wich is shown as desired, and that is
> hided just before opening the LoginDialog. When the dialog is closed
> the #splash is destroyed and released. It worked just as I espected.

FWIW: This sounds like a good solution to me!

Steve
 --
[hidden email]