lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] wxProgressDialog resists interruption with Cancel


From: Greg Chicares
Subject: Re: [lmi] wxProgressDialog resists interruption with Cancel
Date: Sat, 16 Nov 2013 15:55:37 +0000
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20100101 Thunderbird/24.1.0

On 2013-11-15 19:24Z, Vadim Zeitlin wrote:
[...]
>  The important thing, however, is the other bug or, if you want, a
> peculiarity of wxMSW implementation. For a lot of complicated reasons,
> wxMSW creates a dialog window, positioned off screen, so it's never visible
> to the user, while looping in wxExecute(wxEXEC_SYNC). And so any events,
> whether normal keyboard ones or mouse ones, such as are generated when
> clicking on the button, are actually sent to this hidden dialog and not to
> the progress dialog, where they are simply ignored. So this is, just as you
> surmised, the case of wxExecute() "eating" all the events, although it does
> it in the rather indirect way. And, because of the previous bug, lets Esc
> key events through.

Then isn't wxEXEC_NODISABLE the perfect solution? A tentative experiment
seems to give promising results. But am I missing some danger that would
make this a bad idea?

(I think the wxProgressDialog already disables all windows except itself, and
the only events it can receive are Cancel and Close--which is what we want.)

>  Now that we understand what is going on, a more interesting question is
> what can we do. The minimal change I'd recommend would be to put
> reflect_progress() call before the call to wxExecute() and remove the
> explicit calls to YieldFor() from system_command_wx(), please see the
> minimal patch below [*].

I tested this; it doesn't work well in practice. To interrupt with Esc,
I had to hold the Esc key down firmly. I was unable to interrupt it at
all by clicking the Cancel button, because I can't click fast enough,
even with my non-broken left hand. Here's why:

http://lists.nongnu.org/archive/html/lmi/2013-11/msg00012.html
|
|  wxProgressDialog progress(...);
|  for(i = 0; ...)
|    {
|    // calling YieldFor() on this line here is ineffective
|    do_something_within_lmi();       // step 1: takes ~0.75 seconds
|    call YieldFor(wxEVT_CATEGORY_UI) // step 2  (this works)
|    wxExecute(...);                  // step 3: takes ~1.00 seconds
|    progress.Update(...);            // step 4
|    }

That example was overly simplified. What actually happens is this:

  wxProgressDialog progress(...);
  for(i = 0; ...)
    {
    // calling YieldFor() on this line here is ineffective
!   do_a_little_housekeeping();      // step 0: takes a few milliseconds
!   // calling Update here, as in your patch, is almost ineffective
!   call emit_ledger(), which performs the following three indented steps:
      do_something_within_lmi();       // step 1: takes ~0.75 seconds
      call YieldFor(wxEVT_CATEGORY_UI) // step 2  (this works)
      wxExecute(...);                  // step 3: takes ~1.00 seconds
    progress.Update(...);            // step 4
    }

With your patch, we have only a few milliseconds (in step 0) to accept
a Cancel event. Holding down Esc generates a blizzard of Cancel events,
of which one will probably get through. But you have to be very quick
on the mouse to cancel within this short window of time. If we want
to yield (with Update() or with YieldFor()), the best time to do it
is right before wxExecute() (in step 2): then we have a 0.75-second
window (steps 0 and 1) for cancellation in each 1.75-second iteration.

But the wxEXEC_NODISABLE technique, if that's a good idea, lets us
cancel at any time, with keyboard or mouse.

>  Another thing which would help would be, perhaps surprisingly, upgrading
> to a newer MinGW version and running the program under Windows Vista or
> later. [...] Of course, this would only help users
> under Windows Vista and later, so if LMI is still used under XP, this isn't
> as interesting.

I'm using XP. I wouldn't be surprised if some end users in remote
offices are, too.

> [...] rewrite the code using asynchronous wxExecute() if the behaviour is
> still unsatisfactory.

Here's a description of the problem we're currently trying to solve
(by adding dawdle() to the progress-dialog loop):

| The "Print case" census command sends illustrations to a printer
| in census order. But network printers often print the lives in a
| different order. And sorting them manually is a pain. Apparently
| lmi spits PDFs out so fast that the printer gets confused. Now we
| pause for a few seconds between printouts, and that seems to take
| care of the problem.

Users require that output emerge from the printer in the expected order.
If "asynchronous" execution could impair that (e.g., causing shorter
PDFs to be printed before longer ones), then this can't be considered.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]