I'm seeing a problem in one of my applications where Cursor>>showWhile is
not displaying a wait cursor while the block (just loading in the contents of a file) is executing. It also happens in the default image when filing in a package, D4 used to display the hourglass, D5 doesn't. I tracked this behaviour down to being something to do with FileDialog but I suspect the real problem is a bit deeper? Demo pathname := SessionManager current imagePath , '.sml'. Cursor wait showWhile: [| fs | fs := FileStream read: pathname. [fs atEnd] whileFalse: [c := fs next]]. Sound bell This shows the hourglass for the duration of the load. However, getting the pathname through a dialog doesn't dialog := FileOpenDialog on: '*.sml'. pathname := dialog showModal. Cursor wait showWhile: [| fs | fs := FileStream read: pathname. [fs atEnd] whileFalse: [c := fs next]]. Sound bell I tried a number of thing but, other than splitting it up into two doIts, I can't seem to get the cursor to show. -- Ian reply-to address is valid and mail is read - until it starts getting spammed |
"Ian Bartholomew" <[hidden email]> wrote in message
news:YkRA8.72362$51.621255@wards... > I'm seeing a problem in one of my applications where Cursor>>showWhile is > not displaying a wait cursor while the block (just loading in the contents > of a file) is executing. It also happens in the default image when filing in > a package, D4 used to display the hourglass, D5 doesn't. I tracked this > behaviour down to being something to do with FileDialog but I suspect the > real problem is a bit deeper? The basic problem here is that Cursor>>showWhile: won't actually have any effect if issued when the "global" cursor is set to the same cursor - it is relying on the message loop running and Windows being able to send WM_SETCURSOR enquiries to the view, which will pick up the global cursor (if set). Your first case works as the nothing has instructed windows to change the cursor by the time you get to your lengthy operation, and therefore the wait cursor would have been displayed anyway. The second case fails because the display of the file dialog (or any dialog) will reset the cursor. Even though the global wait cursor remains set when the dialog closes, because control is not returned to the message loop the wait cursor is not restored. I've attached a preliminary patch which will correct this issue. Should it prove satisfactory then we'll role it into the first patch level. Regards Blair ------------------ !View methodsFor! wmSetCursor: message wParam: wParam lParam: lParam "Private - Handle the Win32 WM_SETCURSOR message. Implementation Note: Delegates determination of desired cursor to the interactor. If a specific cursor is returned, then answers true to suppress default processing, otherwise answers nil to invoke default window processing." | hitType | hitType := #(#transparent #nowhere #client #caption #sysMenu #size #menu #hscroll #vscroll #minimize #maximize #left #right #top #topLeft #topRight #bottom #bottomLeft #bottomRight #border #object #close #help) at: lParam lowSWord + 2 ifAbsent: [#error]. ^(self interactor onGetCursor: hitType) ifNotNil: [:myCursor | myCursor setCursor. true]! ! !View categoriesFor: #wmSetCursor:wParam:lParam:!event handling-win32!private! ! !Cursor methodsFor! showWhile: aBlock "Maintain the wait cursor while aBlock is executed, answering the result of the block. The actual cursor which was current is restored (rather than the one we think is Current)." | previous actual | previous := Current. Current := self. actual := self setCursor. ^aBlock ensure: [Current := previous. UserLibrary default setCursor: actual]! ! !Cursor categoriesFor: #showWhile:!operations!public! ! |
Blair,
> I've attached a preliminary patch which will correct this issue. Should it > prove satisfactory then we'll role it into the first patch level. Thanks, both for the patch and the speed of the response. FWIW, it works fine for me and cures the "real life" problem I was seeing. Ian |
In reply to this post by Blair McGlashan
Blair McGlashan wrote:
> I've attached a preliminary patch which will correct this issue. Should it > prove satisfactory then we'll role it into the first patch level. This patch helps, but doesn't completely cure the problem. I was going to report that doing a "Save Image As" doesn't show the wait cursor. The patch does fix it for the usual case of saving to a new file. But, it doesn't work when doing a "Save Image As" and then merely accepting the current image name. ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
Bill
You wrote in message news:[hidden email]... > Blair McGlashan wrote: > > > I've attached a preliminary patch which will correct this issue. Should it > > prove satisfactory then we'll role it into the first patch level. > > This patch helps, but doesn't completely cure the problem. I was going to report > that doing a "Save Image As" doesn't show the wait cursor. The patch does fix it > for the usual case of saving to a new file. But, it doesn't work when doing a > "Save Image As" and then merely accepting the current image name. Below find a second cut of the patch. With this version you should find that Ian's original example doesn't even need the explicit wait cursor management. Regards Blair -------------------------- !CommonDialog methodsFor! showModal "Create and show the receiver's modal dialog. Answer the 'result' (as defined by the subclass) or nil if no selection was made. Implemenation Note: The common dialogs steal the message loop and send WM_ENTERIDLE messages only erratically. We therefore start up the idle timer to allow us to run background processes now and again." | apiResult owner wasEnabled hitType | self prepareStruct. owner := self ownerView ifNil: [View active]. wasEnabled := owner isEnabled. [SessionManager inputState startIdleTimer: owner. apiResult := self basicShowModal] ensure: [SessionManager inputState stopIdleTimer: owner]. hitType := wasEnabled ifTrue: [HTCLIENT] ifFalse: [owner isEnabled: false. HTERROR]. "Reset the view's cursor in case control does not return to message loop" UserLibrary default sendMessage: owner asParameter msg: WM_SETCURSOR wParam: 0 lParam: hitType. self extractResult: apiResult. ^self answer! ! !CommonDialog categoriesFor: #showModal!public!realizing/unrealizing! ! !DialogView methodsFor! showModalTo: aView "Private - Show the (already created) receiver as a dialog modal to aView." | enableOwningView owningView | owningView := aView = self class desktop ifTrue: [self class active] ifFalse: [aView]. "Allow the create to fail, in which case return nil as the result" self handle isNil ifTrue: [^nil]. (enableOwningView := owningView isEnabled) ifTrue: [owningView isEnabled: false]. ["Only now can we adjust the position of the dialog (if required)." self isInitiallyCentered ifTrue: [self position: (self centerExtent: self extent within: creationParent)]. self layout; show. self runModalLoop] ensure: ["Seems windows may re-enable a disabled view itself, so we re-establish enablement state regardless" owningView isEnabled: enableOwningView. enableOwningView ifTrue: [owningView beActive]. "Force the owning view to re-paint and update its cursor in case actions following closure of the dialog are lengthy" owningView update. UserLibrary default sendMessage: owningView asParameter msg: WM_SETCURSOR wParam: 0 lParam: (enableOwningView ifTrue: [HTCLIENT] ifFalse: [HTERROR]). owningView := nil. "We do not destroy the dialog until its owningView is re-enabled to prevent another window coming to the front." self basicDestroy]. ^self answer! ! !DialogView categoriesFor: #showModalTo:!private!realizing/unrealizing! ! !View methodsFor! wmSetCursor: message wParam: wParam lParam: lParam "Private - Handle the Win32 WM_SETCURSOR message." | myCursor hitType | hitType := #(#transparent #nowhere #client #caption #sysMenu #size #menu #hscroll #vscroll #minimize #maximize #left #right #top #topLeft #topRight #bottom #bottomLeft #bottomRight #border #object #close #help) at: lParam lowSWord + 2 ifAbsent: [#error]. myCursor := self interactor onGetCursor: hitType. ^myCursor isNil ifFalse: [myCursor setCursor. true]! ! !View categoriesFor: #wmSetCursor:wParam:lParam:!event handling-win32!private! ! !Cursor methodsFor! showWhile: aBlock "Maintain the wait cursor while aBlock is executed, answering the result of the block. The actual cursor which was current is restored (rather than the one we think is Current)." | previous actual | previous := Current. Current := self. actual := self setCursor. ^aBlock ensure: [Current := previous. UserLibrary default setCursor: actual]! ! !Cursor categoriesFor: #showWhile:!operations!public! ! |
Blair McGlashan wrote:
> Below find a second cut of the patch. With this version you should find that > Ian's original example doesn't even need the explicit wait cursor > management. Look good from here. It takes care of the cursor for the various "Image Save As" scenarios that I tried. ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
Free forum by Nabble | Edit this page |