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 |
"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. |
"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 |
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] |
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 |
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] |
Free forum by Nabble | Edit this page |