[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [albireo-dev] Focus Management Test Cases
|
Hi Gordon,
> I've started to think about merging the two contributions for focus
> management. It is a daunting task.
Yes, especially with the many actors involved: focus management on SWT side,
AWT focus manager, platform behaviour, the notions of "focus in window" etc.
I would take the bug list at http://wiki.eclipse.org/Albireo_SWT_AWT_bugs
and start with that. Also, I would concentrate on JDK 1.5 in the first time.
JDK 1.4 behaves the same regarding focus, but JDK 1.6 is different.
Can you please mark the focus-related hacks with isWin32() and isGtk()?
It's likely that a hack for Windows gets in the way on Gtk and vice versa,
because the underlying platforms are so different.
> The comments in IlvFocusDebugging and other ILOG files refer to a set of
> problems labeled A through E. I assume the test case code that
> demonstrates these problems includes proprietary ILOG code, so it can't
> itself be contributed? Is there any chance we could create a set of
> equivalent EPL test cases?
The test cases indeed involve some ILOG products and therefore are not
usable. But I can create a test code with pure Eclipse and Swing.
I'm committing the FocusDebugging class, so use can use that easily for
the analysis.
Bruno
Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.27
diff -c -3 -r1.27 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java 12 Feb 2008 14:51:30 -0000 1.27
--- src/org/eclipse/albireo/core/SwingControl.java 12 Feb 2008 15:09:03 -0000
***************
*** 26,31 ****
--- 26,32 ----
import javax.swing.plaf.FontUIResource;
import org.eclipse.albireo.internal.CleanResizeListener;
+ import org.eclipse.albireo.internal.FocusDebugging;
import org.eclipse.albireo.internal.Platform;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
***************
*** 48,53 ****
--- 49,57 ----
// and layout.
private static final boolean verboseSizeLayout = false;
+ // Whether to print debugging information regarding focus events.
+ private static final boolean verboseFocusEvents = false;
+
private Listener settingsListener = new Listener() {
public void handleEvent(Event event) {
handleSettingsChange();
***************
*** 155,160 ****
--- 159,167 ----
AwtEnvironment.getInstance(display);
frame = SWT_AWT.new_Frame(this);
+
+ if (verboseFocusEvents)
+ FocusDebugging.addFocusDebugListeners(this, frame);
}
protected void scheduleComponentCreation() {
================== src/org/eclipse/albireo/internal/FocusDebugging.java =======
/*******************************************************************************
* Copyright (c) 2007-2008 SAS Institute Inc., ILOG S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAS Institute Inc. - initial API and implementation
* ILOG S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.albireo.internal;
import java.awt.Component;
import java.awt.Container;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
/**
* This class contains utility functions for debugging focus issues relating
* to the SWT_AWT bridge.
* <p>
* Debugging focus issues cannot be done in a debugger running on the same
* machine, because the interactions with the debugger often cause the
* application window to be deactivated. Therefore a println based approach
* has been adopted.
* <p>
* There are three kinds of events:
* <ul>
* <li>SWT focus events relating to the IlvSwingControl.</li>
* <li>AWT window focus events relating to the topmost window under the
* IlvSwingControl.</li>
* <li>AWT focus events relating to components inside that window.</li>
* </ul>
*/
public class FocusDebugging {
/**
* Adds listeners for debugging all kinds of focus events.
*/
public static void addFocusDebugListeners(org.eclipse.swt.widgets.Composite control,
Container topLevelComponent) {
control.addFocusListener(_SWTFocusListener);
if (topLevelComponent instanceof Window)
((Window)topLevelComponent).addWindowFocusListener(_AWTWindowFocusListener);
addFocusListenerToTree(topLevelComponent);
}
/**
* Shows focus events on the SWT side.
*/
private static class SWTFocusListener implements org.eclipse.swt.events.FocusListener {
public void focusGained(org.eclipse.swt.events.FocusEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" SWT focus gained "+event.getSource().hashCode());
}
public void focusLost(org.eclipse.swt.events.FocusEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" SWT focus lost "+event.getSource().hashCode());
}
}
private static SWTFocusListener _SWTFocusListener = new SWTFocusListener();
/**
* Shows focus events on the top-level window on the AWT side.
*/
private static class AWTWindowFocusListener implements WindowFocusListener {
public void windowGainedFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus gained by window "+event.getWindow());
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
System.err.println("owner1: "+kfm.getPermanentFocusOwner());
System.err.println("owner2: "+kfm.getFocusOwner());
System.err.println("owner3: "+event.getWindow().getFocusOwner());
}
public void windowLostFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus lost by window "+event.getWindow());
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
System.err.println("owner1: "+kfm.getPermanentFocusOwner());
System.err.println("owner2: "+kfm.getFocusOwner());
System.err.println("owner3: "+event.getWindow().getFocusOwner());
}
}
private static AWTWindowFocusListener _AWTWindowFocusListener = new AWTWindowFocusListener();
/**
* Shows focus events on a given component on the AWT side.
*/
private static class AWTFocusListener implements FocusListener {
public void focusGained(FocusEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus gained "+event.getComponent());
}
public void focusLost(FocusEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus lost "+event.getComponent());
}
}
private static AWTFocusListener _AWTFocusListener = new AWTFocusListener();
/**
* Attaches the AWTFocusListener on each of the components in the component
* tree under the given component.
*/
private static class AWTContainerListener implements ContainerListener {
public void componentAdded(ContainerEvent event) {
addFocusListenerToTree(event.getChild());
}
public void componentRemoved(ContainerEvent event) {
removeFocusListenerFromTree(event.getChild());
}
}
private static AWTContainerListener _AWTContainerListener = new AWTContainerListener();
static void addFocusListenerToTree(Component comp) {
comp.addFocusListener(_AWTFocusListener);
if (comp instanceof Container) {
Container cont = (Container)comp;
// Remember to add the listener to child components that are added later.
cont.addContainerListener(_AWTContainerListener);
// Recurse across all child components that are already in the tree now.
int n = cont.getComponentCount();
for (int i = 0; i < n; i++)
addFocusListenerToTree(cont.getComponent(i));
}
}
static void removeFocusListenerFromTree(Component comp) {
// The exact opposite of addFocusListenerToTree.
comp.removeFocusListener(_AWTFocusListener);
if (comp instanceof Container) {
Container cont = (Container)comp;
cont.removeContainerListener(_AWTContainerListener);
int n = cont.getComponentCount();
for (int i = 0; i < n; i++)
removeFocusListenerFromTree(cont.getComponent(i));
}
}
}