Cursor showWhile

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

Cursor showWhile

Ian Bartholomew-9
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


Reply | Threaded
Open this post in threaded view
|

Re: Cursor showWhile

Blair McGlashan
"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! !


Reply | Threaded
Open this post in threaded view
|

Re: Cursor showWhile

Ian Bartholomew-9
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


Reply | Threaded
Open this post in threaded view
|

Re: Cursor showWhile

Bill Dargel
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


Reply | Threaded
Open this post in threaded view
|

Re: Cursor showWhile

Blair McGlashan
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! !


Reply | Threaded
Open this post in threaded view
|

Re: Cursor showWhile

Bill Dargel
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