Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 511983

Summary: Ensure FXCanvasEx forwards "consumed" SWT keyboard events to JavaFX
Product: [Tools] GEF Reporter: Matthias Wienand <matthias.wienand>
Component: GEF FXAssignee: gef-inbox <gef-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: 1.1.0   
Target Milestone: 5.0.0 (Oxygen) M6   
Hardware: All   
OS: All   
Whiteboard:

Description Matthias Wienand CLA 2017-02-09 10:35:54 EST
Eclipse registers event filters at the SWT Display. For some events, processing is interrupted by setting the "doit" flag to true or the event "type" to None. Consequently, these events do not reach FXCanvas.

If processing of a key down event is interrupted, but the corresponding key up event is forwarded to FXCanvas, then FXCanvasEx expects an unprocessed key down event which it tries to remove. This is problematic when multiple SWT keyboard events are accumulated before dispatching them to JavaFX. Then, unprocessed events are removed although they should later be dispatched.

The following listing illustrates the problem:

[SWT Event Handler]
1: SWT.KeyDown CTRL  -> add unprocssed key down event (count=1)
   SWT.KeyDown A     -> does not reach FXCanvas
[JavaFX Event Dispatcher]
1: KEY_PRESSED CTRL  -> do not alter unprocessed events
[SWT Event Handler]
2: SWT.KeyUp A       -> add unprocessed key up event
3: SWT.KeyUp CTRL    -> add unprocessed key up event
4: SWT.KeyDown CTRL  -> add unprocessed key down event (count=2)
   SWT.KeyDown A     -> does not reach FXCanvas
5: SWT.KeyUp A       -> add unprocessed key up event
[JavaFX Event Dispatcher]
2: KEY_RELEASED A    -> remove unprocessed events (key-down-count=1)
3: KEY_RELEASED CTRL -> remove unprocessed events (key-down-count=0)
4: KEY_PRESSED CTRL  -> error: no more unprocessed key down events (count==0)

When a JavaFX KEY_PRESSED event is consumed, the corresponding KEY_RELEASED event is not automatically consumed, i.e. it will still be processed. Therefore, a proper fix should grab all SWT keyboard events and record for which events processing is interrupted by observing the events that do reach FXCanvas. The missing events should also be dispatched to JavaFX, but the corresponding JavaFX events should be consumed.
Comment 1 Matthias Wienand CLA 2017-02-10 06:01:46 EST
I implemented the proposed fix as follows:

1) The event filters are queried from the Display (containing the ones registered by Eclipse).
2) The queried filters are removed from the EventTable.
3) A custom filter that tracks all SWT keyboard events is added to the EventTable.
4) The previously removed filters are re-added to the EventTable.

As soon as a keyboard event reaches FXCanvasEx, all missing events (i.e. the ones that did not reach FXCanvasEx, but were recorded by the filter) are dispatched to JavaFX (with "doit" set to false) before the event that reached FXCanvasEx is dispatched.

The code is published on the master branch, therefore, I resolve this ticket as fixed for 5.0.0 M6.