| Eclipse 3.0 - Responsiveness Plan Item |
This document outlines the initial thoughts on progress support in Eclipse 3.0. It's basically a summary of the discussions we have had around this subject.
By: Jean-Michel Lemieux, 2003-09-24
Participants: Mike Wilson, Nick Edgar, John Arthorne, Tod Creasey
In Eclipse 2.1 long running operations blocked the user interface via a progress dialog, busy cursor, or a progress indicator shown in another context (e.g. workbench, wizard). There are several APIs used by plugin developers for this purpose. There are actually too many choices for plugin developers to make in deciding how to show progress. This has resulted in the following symptoms:
/************************ * Modal Progress APIs ************************/ /* Shows a busy cursor and runs the runnable in the current thread. */ org.eclipse.swt.custom.BusyIndicator::showWhile(Display display, Runnable runnable); /* Allows an operation to run either in the current thread or in another thread. If the current thread is the UI thread the event queue is read and dispatched. */ org.eclipse.jface.operations.ModalContext::run(run(IRunnableWithProgress operation, boolean fork, IProgressMonitor monitor, Display display); /* Is implemented by several contexts: workbench window, progress dialog, busy indicator wizards. Allows to run an operation in the current thread or in another thread while showing progress in the given context. The user can decide if the operation can be cancelled. */ org.eclipse.jface.operations.IRunnableContext::run(boolean fork, boolean cancelable, IRunnableWithProgress runnable); /************************ * Non-Modal Progress APIs ************************/ /* Runs an operation in a separate thread showing progress via a registered progress service. The Job can be cancelled via the progress monitor. */ org.eclipse.runtime.jobs.Job::run(IProgressMonitor monitor);
Here is a list of progress issues that we would like to address in 3.0.
Instead of the user having to decide where and how to show progress, the platform should provide a single method for displaying modal progress. This single progress API could enforce that work is never performed in the UI thread, fine grain cancellation is supported, and progress is shown consistently.
Summary: We would require a single API for running a modal operation. Can have the same parameters as IRunnableContext and existing implementations of IRunnableContext could delegate to a new progress service. In addition, wizards could continue to be a IRunnableContext but should support showing the fine grain cancellation hint. A single API would allow the platform UI team to experiment with different ways of showing progress and have it apply to all operations. For example, you could imagine that a good solution for a common progress story to include a combined busy cursor with a delayed progress indicator.
It's now possible to any operation that modifies the workspace to block for an unknown amount of time while a non-modal operation has a lock on the workspace or resources required by the modal operation. The user should minimally:
The notification of a modal operation being blocked by a non-modal must be smart and non-intrusive. It is quite possible that blocking is resolved quickly and the user should not have to know that there was a small delay in starting the operation. For example, it wouldn't be good to pop-up a dialog every time a modal operation is blocked.
To support this an extension to IProgressMonitor will have to be created to allow the resources plugin to notify the progress service that an operation is being blocked.
With more plugins using non-modal operations to update views and editors it is useful for the user to understand when a view/editors content is being changed by a non-modal operation. We should add an API for associated a non-modal operation (e.g. a org.eclipse.runtime.Job) with a IWorkbenchPartSite. This would allow the platform UI team to experiment with methods of showing non-modal progress in a view or editor.
For scheduling a non-modal operation the developer would have to decide if the job affects a view. And if it does than call something similar to:
view.getSite().schedule(aJob); editorPart.getSite().schedule(aJob);
And if a non-modal operation doesn't affect a particular view, it would be scheduled and progress shown via the standard non-modal progress support:
aJob.schedule();
When a non-modal operation is populating a viewer (e.g. fetching children for a tree node, or fetching members for a table) it may be useful to show the user a hint that the viewer is not showing the complete results. For a tree viewer it may be useful to show the progress hint for each sub-folder (e.g. the 'pending' placeholder in the CVS repositories view) and for a table viewer simply clearing the view than showing the non-modal progress for a view/editor.
If the work can be run in under 100ms and there are no workspace changes made. If either of these requirements are not met, than work should be performed in another thread. For this reason, I recommend that the new progress API remove the fork option and automatically run the operation in another thread while processing the SWT events queue. This implies that the operations that satisfy the conditions for running in the UI thread can continue to use the org.eclipse.swt.custom.BusyIndicator.showWhile() method for displaying progress.