Bug 104851 - DCR - Display.postEvent(Runnable)
Summary: DCR - Display.postEvent(Runnable)
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Steve Northover CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2005-07-22 14:08 EDT by Randy Hudson CLA
Modified: 2019-09-04 02:59 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 Randy Hudson CLA 2005-07-22 14:08:44 EDT
For Draw2d to finally get rid of its custom painting mechanism, we would like to
have a way of laying out when the current UI event has finished doing whatever
it is going to do. Then, we could do our layout, and use the native repaint call
to ask for the damage to be repaired.

Also, this allow us to stop using asyncExec, which is giving us problem on the
Mac because it doesn't get called often enough.
Comment 1 Randy Hudson CLA 2005-07-22 14:11:35 EDT
Is there some way of using postEvent to do this? I notice that deferredEvents
get dispatched immediately after "real" events.
Comment 2 David Williams CLA 2005-07-22 15:08:12 EDT
BTW ... asyncExec runnables are also sensitive to being re-ordered by the Job
managers logic to handle ILock's. Is that an issue for GEF? 
Comment 3 Randy Hudson CLA 2005-07-22 15:32:02 EDT
Not that I know of.
Comment 4 Randy Hudson CLA 2005-09-16 13:29:17 EDT
We would like to have this function early in 3.2 if that's possible. I would 
like to switch to using SWT's DOUBLE_BUFFER style, and get rid of our creation 
of GC's that don't come from paint events, and remove any use of asyncExec.
Comment 5 Steve Northover CLA 2005-09-23 19:30:35 EDT
I don't think this will help you.  You need to run inside of SWT.Paint to be 
double buffered.  Can you please post a small example where the current 
behavior is causing you trouble?  That way we will have something to 
test/debug.
Comment 6 Randy Hudson CLA 2005-09-25 17:30:11 EDT
The current behavior is that we are calling asyncExec(Runnable) in response to 
user input, and we would like to have our Runnable run sooner, so that we could 
damage regions sooner.

Stefan Xenos had requested this function too.
Comment 7 Steve Northover CLA 2005-09-26 10:38:30 EDT
He's not on the bug report.  In any case, we still need some code to 
debug/test/fix.

>so that we could damage regions sooner.

FYI:  This is not what the operating systems do.  For example, on Windows, 
WM_PAINT is not normally posted to the queue.  Rather, it is manufactured when 
the application gets the next event from the operating system, there is none 
available and there is outstanding damage.
Comment 8 Randy Hudson CLA 2005-09-26 11:28:16 EDT
As we update each of our figures, we defer the layout so that many updates 
result in just one layout. The current mechanism for deferring is to call 
asyncExec(). This is not reliable on slow systems because real events can 
preempt async runnables from getting any priority.

double buffering is a red herring. We just need to run some code after the 
client has made all of the changes that he is going to make.

If you really need a test case, imagine you have 20 SWT Labels in a vertical 
row, and you update all 20 Labels' text. You then want to resize their parent 
so that it is the minimum width to display the widest label.
Comment 9 Randy Hudson CLA 2005-09-26 11:29:42 EDT
see bug 103863
Comment 10 Steve Northover CLA 2005-09-26 12:57:40 EDT
>This is not reliable on slow systems because real events can 
>preempt async runnables from getting any priority.

Isn't this exactly what you want?  If there are real events, then shouldn't 
they be serviced before your deferred update layout strategy.  If there is a 
bug on the Mac, please enter a bug report.

>If you really need a test case, imagine you have 20 SWT Labels in a vertical
>row, and you update all 20 Labels' text. You then want to resize their parent
>so that it is the minimum width to display the widest label.

I would just write the code that measured the labels and resized the parent.  
If a layout was involved, I could fake a deferred strategy by async'ing the 
layout().  Obviously, this is more or less what Draw2d is doing.

Here is the original feature request:

"For Draw2d to finally get rid of its custom painting mechanism, we would like 
to have a way of laying out when the current UI event has finished doing 
whatever it is going to do. Then, we could do our layout, and use the native 
repaint call to ask for the damage to be repaired."

In order to implement this, I will need something to test/debug.
Comment 11 Randy Hudson CLA 2005-09-26 15:06:30 EDT
(In reply to comment #10)
> >This is not reliable on slow systems because real events can 
> >preempt async runnables from getting any priority.
> Isn't this exactly what you want?

No, because in some cases the UI would become unresponsive. What we want to do 
is after some reasonable amount of changes, we want to reposition things, and 
then calculate some rectangle and call Control#redraw(int,int,int,int).

> If there are real events, then shouldn't 
> they be serviced before your deferred update layout strategy.

No, because we'd never be able to call redraw(). It seems that readAndDispatch 
returns true without running asyncMessages whenever there are real events, so 
if the user is constantly dragging the mouse, asyncs never get processed. Let 
me know if this is not the correct interpretation of that method.

> I would just write the code that measured the labels and resized the parent.

In an open system, you never know how many changes are going to be caused by 
the current event.

Can you give me an example example? Perhaps the test case used when 
Display.addFilter() was introduced? Would a draw2d example be OK?
Comment 12 Randy Hudson CLA 2005-10-21 11:11:25 EDT
After thinking about this some more, my request is not going to help me. If you
consider the case of typing in characters, under the proposed request we would
attempt to layout after every character typed. If the user is typing faster than
we can layout, things are BAD.

So obviously we would need to layout less often than after every character
typed. But, we can't wait forever either which is what asyncExec *could* do if
events never stopped coming in.

So I've changed my mind. We need our Runnables to have equal priority to UI
events, and to be able to post them at the end of whatever is currently on the
queue.

Here's a use case:
1) KeyDown "A"
   - GEF receives A and asks to "layout" as a result
2) "Layout Event"
   - GEF lays out, which takes too long.
   - During which time user presses keys "B", "C", and "D".
3) KeyDown "B" (Pending on queueu, "C" and "D")
   - GEF receives "B" and needs to layout again. Layout event is queued, but
comes after the pending "D" KeyDown event.
4) KeyDown "C"
5) KeyDown "D"
6) "Layout Event"
   - GEF lays out B,C,&D edits.

Perhaps this capability already exists. What happens if I invoke
Display.timerExec(0, runnable)?
Comment 13 Steve Northover CLA 2005-10-24 17:30:16 EDT
The thing that you are missing is that UI events have different priorities on 
different operating systems.  For example, on Windows, WM_PAINT only occurs 
when there are no other events pending.  Do you mean that you want equal 
priority to input events (ie. mouse and keyboard)?

Anyway, you should be able to get what you want by using both asyncExec() and 
timerExec().  Use asyncExec() to run work when the user interface is idle and 
timerExec() to force an update if there is a pending update and nothing has 
happened in an arbitrary time interval (say 100ms).
Comment 14 Lars Vogel CLA 2019-09-04 02:59:59 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it and remove the stalebug whiteboard tag. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--