[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [albireo-dev] Traversing out of embedded SwingControls on Windows

Gordon Hirsch wrote:

I'm discovering that Windows does not report the current focus state reliably when there are embedded AWT frames in the focus cycle.

This problem affects some of the code from my initial commit as well (in particular, the code handling this test case: http://wiki.eclipse.org/Albireo_Focus_Management_Test_Cases#Keep_focus_when_clicking_on_parent_view_tab).


I was relying on the accuracy of Display.getFocusControl to decide whether to manually reactivate the SwingControl.

The original code also had a bug in that it did not check whether another window altogether had taken the focus before manually reactivating.






### Eclipse Workspace Patch 1.0
#P org.eclipse.albireo.core
Index: src/org/eclipse/albireo/internal/FocusHandler.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/internal/FocusHandler.java,v
retrieving revision 1.9
diff -u -r1.9 FocusHandler.java
--- src/org/eclipse/albireo/internal/FocusHandler.java	21 Feb 2008 21:18:55 -0000	1.9
+++ src/org/eclipse/albireo/internal/FocusHandler.java	22 Feb 2008 04:13:35 -0000
@@ -243,10 +243,22 @@
         if (!display.isDisposed()) {
             ThreadingHandler.getInstance().asyncExec(display, new Runnable() {
                 public void run() {
-                    if (!display.isDisposed() && (swingControl == display.getFocusControl())) {
+                    if (!swingControl.isDisposed() &&
+                            
+                        // Make sure that this control is in the active shell, so focus is not stolen from other windows    
+                        (display.getActiveShell() == swingControl.getShell()) && 
+                        
+                        // Check that this control still the focus control, despite the recent deactivation.
+                        // BUT... Display.getFocusControl is unreliable when another embedded AWT window has 
+                        // become active, so to be safe, make sure that no other Swing control has been activated
+                        // (otherwise we will steal focus from some other active SwingControl)
+                        (swingControl == display.getFocusControl() && (activeSwingControl == null))) {
+                        
                         if (verboseFocusEvents) {
                             trace("Manually reactivating " + swingControl);
                         }
+                        // Ideally, we would directly activate SwingControl here, but there seems to be 
+                        // no way to do that, so activate the underlying AWT embedded frame
                         synthesizeWindowActivation(true);
                     }
                 }
@@ -325,7 +337,7 @@
     // ========== Listener implementations
     
     protected class SwtEventFilter implements Listener {
-
+        
         public void handleEvent(Event event) {
             if (event.widget != swingControl) {
                 return;