Bug 468848 - Implement a new Display.greedyExec method
Summary: Implement a new Display.greedyExec method
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.5   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-29 14:19 EDT by Stefan Xenos CLA
Modified: 2015-06-01 08:18 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Xenos CLA 2015-05-29 14:19:53 EDT
This bug requests two new methods on Display (suggested names: greedyExec and layoutExec).

greedyExec will invoke a Runnable after the current pass through the event loop and before any asyncExec, layoutExec, or paints. It would be used for posting asynchronous model updates or invoking setters on SWT controls.

layoutExec would be run after any greedyExec but before the next pass through the event loop or paint, and should be used for calling Composite.layout or setting the position of SWT controls.


An alternative would be to add a two-argument variant of asyncExec that accepts a priority argument which can be NORMAL (runs first - for model changes or setting SWT properties), LAYOUT (for layouts only), or LEGACY (for the current asyncExec behavior). NORMAL and LAYOUT priorities would always run before paints or user events.



Justification:

Currently, Display.asyncExec queues all Runnables at the same priority, and at the same priority as user events, layouts, and paints. This means that there is no appropriate place to run asynchronous code that updates models and invoke setters on controls. 

Without such a system, anything that wants to run asynchronous code will also trigger unnecessary layouts and create flicker due to paints happening while application code is still midway through a model update.


For context, see bug 103863, comment 10 and bug 149830.
Comment 1 Stefan Xenos CLA 2015-05-29 15:05:39 EDT
Actually, layoutExec may not be necessary since we now have Composite.layout(Control[], SWT.DEFER), which pretty much handles that use case.

Display.greedyExec would be sufficient.
Comment 2 Andrey Loskutov CLA 2015-05-29 15:15:34 EDT
(In reply to Stefan Xenos from comment #0)
> An alternative would be to add a two-argument variant of asyncExec that
> accepts a priority argument which can be NORMAL (runs first - for model
> changes or setting SWT properties), LAYOUT (for layouts only), or LEGACY
> (for the current asyncExec behavior). NORMAL and LAYOUT priorities would
> always run before paints or user events.

This sounds better as other proposals. What I would like to see is something which would allow us to identify and skip identical async requests. Might be asyncExec(KindOfJobRunnable).
Comment 3 Stefan Xenos CLA 2015-05-30 19:54:09 EDT
> This sounds better as other proposals.

Actually now that I think about it, I'm not sure we actually need the LAYOUT priority, since the SWT.DEFER flag already covers that use case... and if we only need the one priority level, then a new greedyExec(Runnable) method may be the simplest alternative.

So the execution order would be:

1. Any work scheduled by greedyExec(...)
2. Any work deferred by SWT.DEFER (ie: layouts)
3. Paint events

User events and work scheduled by asyncExec could actually come at any point here without breaking things.

If a modal event loop is triggered by any event, it should continue processing events in the order shown above. A greedyExec that was scheduled by an outer context might be executed by an inner event loop.