Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 1078 Details for
Bug 2229
Usability: Progress Dialog on Save is distracting (1GEAR0D)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Implementation Issues
delay.html (text/html), 7.12 KB, created by
Adam Schlegel
on 2002-05-27 16:38:58 EDT
(
hide
)
Description:
Implementation Issues
Filename:
MIME Type:
Creator:
Adam Schlegel
Created:
2002-05-27 16:38:58 EDT
Size:
7.12 KB
patch
obsolete
><html> ><head> ><title>Delaying ProgressMonitorDialog Open</title> ></head> ><body> ><h1>Delaying <code>ProgressMonitorDialog</code> Open</h1> >May 27, 2002 > ><h2>The Problem</h2> ><p> >Short operations that pop up a <code>ProgressMonitorDialog</code> do >not keep the dialog open long enough for it to be useful. Further, the >rapid open/close of the dialog is distracting for the user. ></p> ><p> >We want to show progress in a less invasive way for short running >operations, while keeping the operation as is for long running >operations. Possible solutions are to have ><code>ProgressMonitorDialog</code> use a delay before it opens, or >to use <code>ApplicationWindow</code> to run the >operation and report the progress on the status line. ></p> > ><h2>The <code>fork</code> Parameter</h2> ><p> >Currently, a parameter is passed to ><code>ProgressMonitorDialog.run</code> to indicate whether or not to >fork a background thread on which to run the >operation. As a rule of thumb <code>run</code> should be called with ><code>fork = true</code> if it is being called from the UI thread, and ><code>fork = false</code> otherwise. However, this is not always >true. Editor saves are saved on the UI thread with <code>fork = false</code> >due to a hack put in late in the 1.0 release cycle. Editors keep the >UI responsive by spinning the SWT event loop manually. ></p> ><p> >In many solutions, calling <code>run</code> with <code>fork = >false</code> on the UI thread will cause the ><code>ProgressMonitorDialog</code> to *never* open, since the UI is >unresponsive during that time. This behaviour is acceptable, provided >that there is a workaround for the editor save case, since we want to >discourage blocking the UI thread whenever possible. ></p> ><h2>Deadlock</h2> ><p> >Eclipse is not currently written to allow progress to be reported to >the UI asynchronously. It is easy to cause Eclipse to deadlock if the >user is allowed to work while there is an operation running in the >background, due to the way that the workspace lock is allocated/freed. ></p> ><p> >The simplest deadlock to explain occurs when, while in the process of >saving a file, a file is deleted. The save is called with <code>fork = >false</code>, but is a special case since it spins its own event >loop. Save acquires the workspace lock when it starts, and doesn't >release it until it is done. The event loop is run while the UI thread >holds the workspace lock. During this time, the delete gets >processed. Delete is run with <code>fork = true</code> so it starts a >new <code>ModalContextThread</code> to run the operation, and then >spins the event loop. This time, the event loop is spinning tightly, >and *not* working on the save operation. The ><code>ModalContextThread</code> that is created almost immediately >requests the workspace lock, which is held by the UI thread stuck in >the event loop. The delete cannot start until the save is done, but >the save cannot finish until the UI thread breaks out of the event >loop. ></p> ><p> >It is not possible to cancel the delete operation since the ><code>ModalContextThread</code> is blocked and cannot check ><code>isCancelled</code> until it is unblocked. Eclipse is deadlocked, >but the event loop is dunning, so the UI appears responsive, with a >modal dialog preventing the user from working. ></p> > ><h2>Solutions</h2> ><p> >Two possible solutions were considered. The call to ><code>ProgressMonitorDialog.open</code> could be put on a timer and run >after a specified delay. Otherwise, we could avoid spinning the event >loop until the delay is over. ></p> ><h3>Timers</h3> ><p> >To prevent the user from interacting with the workbench before the >window opens, the workbench needs to be disabled manually. The >modality of the <code>ProgressMonitorDialog</code> is only in effect >while the dialog is open, so it must be simulated. Opening the dialog >off-screen and then moving it is not supported on all platforms. ></p> ><p> >Given the current API, it is not possible to disable the entire >workbench from within <code>ProgessMonitorDialog</code>. At that >level, there is no notion of the shortcut bar, nor is there a >reference to the coolbar. It is possible to work around this problem >by adding API to enable/disable the entire window. ></p> ><p> >Currently, enabling and disabling the various toolbars is done with a >call to <code>setEnabled</code>. However on Windows, for a >control with keyboard focus, <code>setEnabled(false)</code> followed >by <code>setEnabled(true)</code> will lose the keyboard focus. It does >not look like SWT supports querying the focus status of a widget to >programmatically restore state. ></p> ><p> >Some operations pop up a dialog to prompt the user for input after the >operation has been started. When the ><code>ProgressMonitorDialog</code> is opening on a timer, it can open >in front of the dialog that is asking for input. Windows gives focus >to the <code>ProgressMonitorDialog</code> in this case, which is >modal, so the user cannot interact with the other window. It is not >always possible to cancel the operation at this point, since most >implementations do not check <code>isCancelled</code> while waiting >for user input to a modal dialog. ></p> > ><h3>Event Loop</h3> ><p> >The UI is unresponsive when the event loop is not spinning. This can >cause problems if left too long, so the delay here is bounded above in >practice. ></p> ><p> ><code>ProgressMonitorDialog.open</code> must be called from the UI >thread, so it must occur during a ><code>asyncExec</code>/<code>syncExec</code>, which are only >processed after all queued events have been dispatched. It is important >to process the <code>open</code> before any other dialog gets opened, >to avoid the problems encountered in the first solution. ></p> ><p> >Unfortunately, any accelerators that are pressed while the event loop >is not running are queued until it starts up again. Accelerators are >processed before <code>syncExec</code> and <code>asyncExec</code> >so it is possible to start another operation while still >running the first. The second operation is not queued, and will run in >the first operation's event loop. The second operation can pop up a >modal dialog, making the <code>ProgressMonitorDialog</code> >inaccessible, or could even deadlock Eclipse. ></p> ><p> >To avoid this case, it would be necessary to disable all accelerators >while the event loop is stopped. Since mouse clicks are queued as >well, it is necessary to disable the toolbar, menubar, and shortcut >bar as well. In other words, it is still necessary to disable the >entire workbench, even though the event loop is not running. ></p> > ><h2><code>ApplicationWindow.run</code></h2> ><p> >It is not possible to start running using ><code>ApplicationWindow.run</code> and pop up a dialog after a >specified delay for longer running operations. This is the case when >the save of a small file invokes a complete rebuild for a project. In >this case, all progress is reported to the same progress monitor, >which would end up in the status bar only. ></p> ><p> >This solution also has to disable the workbench manually. It shares >the <code>setEnabled</code> and keyboard focus problems mentioned above. ></p> ></body> ></title>
<html> <head> <title>Delaying ProgressMonitorDialog Open</title> </head> <body> <h1>Delaying <code>ProgressMonitorDialog</code> Open</h1> May 27, 2002 <h2>The Problem</h2> <p> Short operations that pop up a <code>ProgressMonitorDialog</code> do not keep the dialog open long enough for it to be useful. Further, the rapid open/close of the dialog is distracting for the user. </p> <p> We want to show progress in a less invasive way for short running operations, while keeping the operation as is for long running operations. Possible solutions are to have <code>ProgressMonitorDialog</code> use a delay before it opens, or to use <code>ApplicationWindow</code> to run the operation and report the progress on the status line. </p> <h2>The <code>fork</code> Parameter</h2> <p> Currently, a parameter is passed to <code>ProgressMonitorDialog.run</code> to indicate whether or not to fork a background thread on which to run the operation. As a rule of thumb <code>run</code> should be called with <code>fork = true</code> if it is being called from the UI thread, and <code>fork = false</code> otherwise. However, this is not always true. Editor saves are saved on the UI thread with <code>fork = false</code> due to a hack put in late in the 1.0 release cycle. Editors keep the UI responsive by spinning the SWT event loop manually. </p> <p> In many solutions, calling <code>run</code> with <code>fork = false</code> on the UI thread will cause the <code>ProgressMonitorDialog</code> to *never* open, since the UI is unresponsive during that time. This behaviour is acceptable, provided that there is a workaround for the editor save case, since we want to discourage blocking the UI thread whenever possible. </p> <h2>Deadlock</h2> <p> Eclipse is not currently written to allow progress to be reported to the UI asynchronously. It is easy to cause Eclipse to deadlock if the user is allowed to work while there is an operation running in the background, due to the way that the workspace lock is allocated/freed. </p> <p> The simplest deadlock to explain occurs when, while in the process of saving a file, a file is deleted. The save is called with <code>fork = false</code>, but is a special case since it spins its own event loop. Save acquires the workspace lock when it starts, and doesn't release it until it is done. The event loop is run while the UI thread holds the workspace lock. During this time, the delete gets processed. Delete is run with <code>fork = true</code> so it starts a new <code>ModalContextThread</code> to run the operation, and then spins the event loop. This time, the event loop is spinning tightly, and *not* working on the save operation. The <code>ModalContextThread</code> that is created almost immediately requests the workspace lock, which is held by the UI thread stuck in the event loop. The delete cannot start until the save is done, but the save cannot finish until the UI thread breaks out of the event loop. </p> <p> It is not possible to cancel the delete operation since the <code>ModalContextThread</code> is blocked and cannot check <code>isCancelled</code> until it is unblocked. Eclipse is deadlocked, but the event loop is dunning, so the UI appears responsive, with a modal dialog preventing the user from working. </p> <h2>Solutions</h2> <p> Two possible solutions were considered. The call to <code>ProgressMonitorDialog.open</code> could be put on a timer and run after a specified delay. Otherwise, we could avoid spinning the event loop until the delay is over. </p> <h3>Timers</h3> <p> To prevent the user from interacting with the workbench before the window opens, the workbench needs to be disabled manually. The modality of the <code>ProgressMonitorDialog</code> is only in effect while the dialog is open, so it must be simulated. Opening the dialog off-screen and then moving it is not supported on all platforms. </p> <p> Given the current API, it is not possible to disable the entire workbench from within <code>ProgessMonitorDialog</code>. At that level, there is no notion of the shortcut bar, nor is there a reference to the coolbar. It is possible to work around this problem by adding API to enable/disable the entire window. </p> <p> Currently, enabling and disabling the various toolbars is done with a call to <code>setEnabled</code>. However on Windows, for a control with keyboard focus, <code>setEnabled(false)</code> followed by <code>setEnabled(true)</code> will lose the keyboard focus. It does not look like SWT supports querying the focus status of a widget to programmatically restore state. </p> <p> Some operations pop up a dialog to prompt the user for input after the operation has been started. When the <code>ProgressMonitorDialog</code> is opening on a timer, it can open in front of the dialog that is asking for input. Windows gives focus to the <code>ProgressMonitorDialog</code> in this case, which is modal, so the user cannot interact with the other window. It is not always possible to cancel the operation at this point, since most implementations do not check <code>isCancelled</code> while waiting for user input to a modal dialog. </p> <h3>Event Loop</h3> <p> The UI is unresponsive when the event loop is not spinning. This can cause problems if left too long, so the delay here is bounded above in practice. </p> <p> <code>ProgressMonitorDialog.open</code> must be called from the UI thread, so it must occur during a <code>asyncExec</code>/<code>syncExec</code>, which are only processed after all queued events have been dispatched. It is important to process the <code>open</code> before any other dialog gets opened, to avoid the problems encountered in the first solution. </p> <p> Unfortunately, any accelerators that are pressed while the event loop is not running are queued until it starts up again. Accelerators are processed before <code>syncExec</code> and <code>asyncExec</code> so it is possible to start another operation while still running the first. The second operation is not queued, and will run in the first operation's event loop. The second operation can pop up a modal dialog, making the <code>ProgressMonitorDialog</code> inaccessible, or could even deadlock Eclipse. </p> <p> To avoid this case, it would be necessary to disable all accelerators while the event loop is stopped. Since mouse clicks are queued as well, it is necessary to disable the toolbar, menubar, and shortcut bar as well. In other words, it is still necessary to disable the entire workbench, even though the event loop is not running. </p> <h2><code>ApplicationWindow.run</code></h2> <p> It is not possible to start running using <code>ApplicationWindow.run</code> and pop up a dialog after a specified delay for longer running operations. This is the case when the save of a small file invokes a complete rebuild for a project. In this case, all progress is reported to the same progress monitor, which would end up in the status bar only. </p> <p> This solution also has to disable the workbench manually. It shares the <code>setEnabled</code> and keyboard focus problems mentioned above. </p> </body> </title>
View Attachment As Raw
Actions:
View
Attachments on
bug 2229
: 1078