Bug 213594 - SWTEventDispatcher: requestRemoveFocus called by removeNotify removes focus for any figure.
Summary: SWTEventDispatcher: requestRemoveFocus called by removeNotify removes focus f...
Status: NEW
Alias: None
Product: GEF
Classification: Tools
Component: GEF-Legacy Draw2d (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: gef-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-12-20 10:33 EST by Heiko Böttger CLA
Modified: 2007-12-20 10:33 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Heiko Böttger CLA 2007-12-20 10:33:24 EST
Build ID: M20070212-1330

Steps To Reproduce:
When a figure is removed from its parent, it invokes the requestRemoveFocus method of the EventDispatcher. In case of the SWTEventDispatcher this results in the focus to be lost when the FigureCanvas loses and gains it's focus:

  public void testDraw2D() {
    Shell shell = new Shell();
    
    // setup 
    
    FigureCanvas figureCanvas=new FigureCanvas(shell, SWT.NONE);
    Figure root = new Figure();
    figureCanvas.getViewport().setContents(root);
    
    Figure label1 = createFigureAndAdd(root);
    Figure label2 = createFigureAndAdd(root);
    Figure label3 = createFigureAndAdd(root);
    
    // test
    
    label2.requestFocus();
    
    root.remove(label3); 
    //or figureCanvas.getViewport().internalGetEventDispatcher().requestRemoveFocus(label2);
    System.out.println(label1.hasFocus() == false);
    System.out.println(label2.hasFocus() == true);
    
    figureCanvas.getViewport().internalGetEventDispatcher().dispatchFocusLost(null);
    figureCanvas.getViewport().internalGetEventDispatcher().dispatchFocusGained(null);
    
    System.out.println(label1.hasFocus() == false);
    System.out.println(label2.hasFocus() == true);
    
    shell.dispose();
  }



More information:
The current implementation of SWTEventDispatcher.requestRemoveFocus looks like this:

/**
 * @see EventDispatcher#requestRemoveFocus(IFigure)
 */
public void requestRemoveFocus(IFigure fig) {
	if (getFocusOwner() == fig)
		setFocus(null);
	if (mouseTarget == fig)
		mouseTarget = null;
	if (cursorTarget == fig)
		cursorTarget = null;
	if (hoverSource == fig)
		hoverSource = null;
	getFocusTraverseManager().setCurrentFocusOwner(null);
}

The last line should test if the figure that lost focus was the owner:

/**
 * @see EventDispatcher#requestRemoveFocus(IFigure)
 */
public void requestRemoveFocus(IFigure fig) {
	boolean wasOwner = (getFocusOwner() == fig);
	if (wasOwner) setFocus(null);
	if (mouseTarget == fig)
		mouseTarget = null;
	if (cursorTarget == fig)
		cursorTarget = null;
	if (hoverSource == fig)
		hoverSource = null;
	if (wasOwner) getFocusTraverseManager().setCurrentFocusOwner(null);
}