Bug 4479 - getFocusControl inside FocusOut event inconsistent (1FMITIE)
Summary: getFocusControl inside FocusOut event inconsistent (1FMITIE)
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Steve Northover CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2001-10-11 14:17 EDT by James Moody CLA
Modified: 2004-08-05 16:51 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description James Moody CLA 2001-10-11 14:17:30 EDT
If you ask the display for getFocusWindow() while inside
a callback for FocusOut, on windows you get the new window
which has gained focus, while on unix you get the old window
that is losing focus.

NOTES:

KR (5/8/00 5:34:14 PM)
	This feature just got me again. 
	I changed the focus out listener of Tree to force an update after the selection was 
	redrawn. 
	This is intended to fix repaint behavior that previously left the focus item blank while 
	the application did a time consuming operation in its own focus out listener.
	However, the Tree does not know that it no longer has the focus because, during the 
	repaint, getFocusControl() still returns the Tree since the focus event processing is 
	not complete at that point.
	Bottom line: This PR needs to be fixed.

SN (5/9/00 2:43:40 PM)
	This is super hard to fix without "faking out" the OS.  All we do is query the OS
	so as the real focus widget at that time is different on the different platforms.
	So, if we try and fake it, we open ourselves up for bizzare bugs and behavior
	because we no longer match reality.

	I understand why this is a problem for you.  Focus events are "sent" on all platforms.
	We cannot post them because, if we wait for the event loop, you'll get weird behavior
	For example, if you open a bunch of windows and then fall back to the event loop,
	the windows will have opened, changed focus from one to the other etc. and then you'll
	start getting the callbacks, not actually at the time that the focus was changed.

	I am open to suggestions.  On possibility is to use a slot in the event to contain
	the correct value.  BTW:  What should the value be?

KR (5/10/00 10:25:26 AM)
	getFocusControl() should return the widget that actually has focus at that time.
	If Motif sends the focus out event when the old widget still has focus (ie. AboutToLooseFocus)
	then SWT would be lying if getFocusControl() returned the new focus widget. 
	The best solution would be to do some magic so that the new widget already has focus 
	when the FocusOut event is sent.
	If you provide the focus widget in a slot (or somewhere else) it should be the new focus widget.
	In the FocusOut listener you know the widget that lost focus - in most cases it's the receiver.
	(or you can check the event.widget field). There's no other way of finding out the new focus 
	widget 	though, so that should be provided somewhere else. It would also be consistent with 
	the FocusIn event - both focus events would then provide the 	new focus widget.
	You don't necessarily have to provide the new focus widget at all. You could just doc in
	getFocusControl that the return value is platform specific if used within a focus listener.
	I could store the focus state in a field of my own to work around this.

DR (5/10/00 11:56:14 AM)
	Unfortunately there is no good way for us to fix getFocusControl().  
	The OS will simply not provide the required information.  
	We will have to comment getFocusControl() that the return value is 
	platform specific when inside a LoseFocus event.

	If you are looking for a path to consistant code between 
	the two platforms the event widget is consistant between the two platforms.  
	The widget in the LoseFocus event is the widget that is really losing focus, 
	the widget in the GainFocus event is really the widget gaining focus.

	SN (2/1/01 2:51:43 PM) -
		SN to investigate further.

	McQ (26/06/2001 10:03:59 AM) -
		SN to add comments as indicated above by DR.
Comment 1 Veronika Irvine CLA 2003-02-11 14:03:29 EST
More info for this bug report (from 29607).

Investigated differences between FocusIn and FocusOut on different platforms.

Test Case:

import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class Bug29607 {

public static void main(String[] args) {

	final Display display = new Display();
	Shell shell = new Shell(display, SWT.SHELL_TRIM);
	shell.setLayout(new RowLayout());
	Text b = new Text(shell, SWT.BORDER);
	b.setText("text 1");
	b.addFocusListener(new FocusAdapter() {
		public void focusGained(FocusEvent e) {
			System.out.println("Focus Gained "+e.widget+" control 
= "+display.getFocusControl());
		}
		public void focusLost(FocusEvent e) {
			System.out.println("Focus Lost "+e.widget+" control 
= "+display.getFocusControl());
		}		
	});
	b = new Text(shell, SWT.BORDER);
	b.setText("text 2");
	b.addFocusListener(new FocusAdapter() {
		public void focusGained(FocusEvent e) {
			System.out.println("Focus Gained "+e.widget+" control 
= "+display.getFocusControl());
		}
		public void focusLost(FocusEvent e) {
			System.out.println("Focus Lost "+e.widget+" control 
= "+display.getFocusControl());
		}		
	});
	shell.pack();
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}
}

Results:

GTK Send:                               GTK Post:

FocusGained T1 control = T1             FocusGained T1 control = T1
FocusLost   T1 control = T1             FocusLost   T1 control = T2
FocusGained T2 control = T2             FocusGained T2 control = T2

Motif Send:                             Motif Post:

FocusGained T1 control = T1             FocusGained T1 control = T1
FocusLost   T1 control = T1             FocusLost   T1 control = T2
FocusGained T2 control = T2             FocusGained T2 control = T2

Windows Send:                           Windows Post:

FocusGained T1 control = T1             FocusGained T1 control = T1
FocusLost   T1 control = T2             FocusLost   T1 control = T2
FocusGained T2 control = T2             FocusGained T2 control = T2

Mac Send:                               Mac Post:

(no widget has focus to start with)     (no widget has focus to start with)
FocusGained T1 control = null           FocusGained T1 control = T1
FocusLost   T1 control = T1             FocusLost   T1 control = T2
FocusGained T2 control = null           FocusGained T2 control = T2
Comment 2 Steve Northover CLA 2004-08-05 16:51:16 EDT
Fixed > 20040805

Display.getFocusControl() now answers the same thing on all platforms during 
focus out.  This is the control that got the SWT.FocusOut event.  The behavior 
follows the Mac, Motif and GTK.  To implement the Windows behavior would mean 
abandoning the native focus out notification.