Community
Participate
Working Groups
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.
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
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.