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: Vadim Zeitlin
Subject: Re: [lmi] wxProgressDialog resists interruption with Cancel
Date: Sat, 16 Nov 2013 23:54:01 +0100

On Sat, 16 Nov 2013 15:55:37 +0000 Greg Chicares <address@hidden> wrote:

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

 I'm a bit ashamed of not thinking about this one myself but you're right,
this should indeed work (I didn't have time to test it myself though).
Usually using wxEXEC_NODISABLE would be a very dangerous idea, but as all
the other windows are already disabled in this case, it is fine here.

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

 This is strange, it did work for me. The only difference I can see is that
I configured the fop command to actually be just "sleep 2" as I don't have
fop installed here, but I don't see how could it change anything here.

GC> That example was overly simplified. What actually happens is this:
GC> 
GC>   wxProgressDialog progress(...);
GC>   for(i = 0; ...)
GC>     {
GC>     // calling YieldFor() on this line here is ineffective
GC> !   do_a_little_housekeeping();      // step 0: takes a few milliseconds
GC> !   // calling Update here, as in your patch, is almost ineffective

 For me the calls here, i.e. run() + PlusEq() take noticeable amount of
time (in the seconds range). I can measure it more precisely if necessary
but it probably isn't, as wxEXEC_NODISABLE provides a solution in any case.

GC> >  Another thing which would help would be, perhaps surprisingly, upgrading
GC> > to a newer MinGW version and running the program under Windows Vista or
GC> > later. [...] Of course, this would only help users under Windows
GC> > Vista and later, so if LMI is still used under XP, this isn't as
GC> > interesting.
GC> 
GC> I'm using XP. I wouldn't be surprised if some end users in remote
GC> offices are, too.

 Using a newer MinGW version with task dialog support would still improve
the UI responsiveness for the people running under later Windows versions
even if it doesn't change anything for the XP users, so it still might be
worth doing...

GC> > [...] rewrite the code using asynchronous wxExecute() if the behaviour is
GC> > still unsatisfactory.
GC> 
GC> Here's a description of the problem we're currently trying to solve
GC> (by adding dawdle() to the progress-dialog loop):
GC> 
GC> | The "Print case" census command sends illustrations to a printer
GC> | in census order. But network printers often print the lives in a
GC> | different order. And sorting them manually is a pain. Apparently
GC> | lmi spits PDFs out so fast that the printer gets confused. Now we
GC> | pause for a few seconds between printouts, and that seems to take
GC> | care of the problem.
GC> 
GC> Users require that output emerge from the printer in the expected order.
GC> If "asynchronous" execution could impair that (e.g., causing shorter
GC> PDFs to be printed before longer ones), then this can't be considered.

 No, I don't think an async solution would go against this goal. Async
doesn't mean out of order, just that you need to impose the order
explicitly. I.e. you could launch the child process to generate each PDF
(potentially several of them at once to speed things up on the modern multi
core machines), then wait for its completion, then wait for N seconds, all
while showing the GUI explaining what's going on and allowing to cancel
this at any stage, and only then send the file to the printer.

 Alternatively, and even better IMO, you could make the entire experience
non-modal, i.e. implement what is usually called "background printing":
just launch the child processes, then start a timer on their termination
and then send the PDFs to the printer after the timer expiration. All while
allowing the user to continue using LMI normally.

 Of course, this would require quite extensive changes to the code, so I
don't necessarily recommend doing it, especially if the users don't
complain about the current behaviour. But generally speaking using async
execution is a much better idea.

 Regards,
VZ

reply via email to

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