Community
Participate
Working Groups
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.
Is there some way of using postEvent to do this? I notice that deferredEvents get dispatched immediately after "real" events.
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?
Not that I know of.
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.
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.
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.
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.
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.
see bug 103863
>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.
(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?
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)?
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).
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. --