This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gui][PATCH] window focus fixes


Hi,

I checked this in on java-gui-branch.  When a window loses then regains
the top-level focus, the same child component that had the keyboard
focus before the top-level focus change should regain the focus.

Tom

2004-07-10  Thomas Fitzsimmons  <fitzsim@redhat.com>

	* java/awt/DefaultKeyboardFocusManager.java (dispatchEvent):
	Set window's focus owner upon receiving a FOCUS_LOST event.
	* java/awt/Window.java (Window()): Refocus the previously
	focused component within the window when the window regains the
	top-level focus.
	(setFocusOwner): New method.
	* java/awt/Component.java (requestFocus): Add FIXME.

Index: java/awt/Component.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Component.java,v
retrieving revision 1.37.2.14
diff -u -r1.37.2.14 Component.java
--- java/awt/Component.java	10 Jul 2004 05:15:41 -0000	1.37.2.14
+++ java/awt/Component.java	11 Jul 2004 03:03:34 -0000
@@ -3648,6 +3648,8 @@
                   // This call will cause a FOCUS_GAINED event to be
                   // posted to the system event queue if the native
                   // windowing system grants the focus request.
+                  // FIXME: need to have peers post FOCUS_LOST events
+                  // too.
                   peer.requestFocus ();
                 else
                   {
Index: java/awt/DefaultKeyboardFocusManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/DefaultKeyboardFocusManager.java,v
retrieving revision 1.1.54.5
diff -u -r1.1.54.5 DefaultKeyboardFocusManager.java
--- java/awt/DefaultKeyboardFocusManager.java	10 Jul 2004 05:15:41 -0000	1.1.54.5
+++ java/awt/DefaultKeyboardFocusManager.java	11 Jul 2004 03:03:34 -0000
@@ -171,6 +171,26 @@
           }
         else if (e.id == FocusEvent.FOCUS_LOST)
           {
+            // We need to set the window's focus owner here; we can't
+            // set it when the window loses focus because by that time
+            // the previous focus owner has already lost focus
+            // (FOCUS_LOST events are delivered before
+            // WINDOW_LOST_FOCUS events).
+
+            // Find the target Component's top-level ancestor.
+            Container parent = target.getParent ();
+
+            while (parent != null
+                   && !(parent instanceof Window))
+              parent = parent.getParent ();
+
+            Window toplevel = parent == null ?
+              (Window) target : (Window) parent;
+
+            Component focusOwner = getFocusOwner ();
+            if (focusOwner != null)
+              toplevel.setFocusOwner (focusOwner);
+
             if (((FocusEvent) e).isTemporary ())
               setGlobalFocusOwner (null);
             else
Index: java/awt/Window.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Window.java,v
retrieving revision 1.32.12.8
diff -u -r1.32.12.8 Window.java
--- java/awt/Window.java	10 Jul 2004 05:15:41 -0000	1.32.12.8
+++ java/awt/Window.java	11 Jul 2004 03:03:34 -0000
@@ -39,6 +39,8 @@
 package java.awt;
 
 import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowFocusListener;
 import java.awt.event.WindowListener;
@@ -85,6 +87,8 @@
 
   private transient boolean shown;
 
+  private transient Component windowFocusOwner;
+
   /** 
    * This (package access) constructor is used by subclasses that want
    * to build windows that do not have parents.  Eg. toplevel
@@ -98,6 +102,33 @@
     // cycle roots.
     focusCycleRoot = true;
     setLayout(new BorderLayout());
+
+    addWindowFocusListener (new WindowAdapter ()
+      {
+        public void windowGainedFocus (WindowEvent event)
+        {
+          if (windowFocusOwner != null)
+            {
+              // FIXME: move this section and the other similar
+              // sections in Component into a separate method.
+              EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+              synchronized (eq)
+                {
+                  KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                  Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                  if (currentFocusOwner != null)
+                    {
+                      eq.postEvent (new FocusEvent (currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                                    false, windowFocusOwner));
+                      eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED,
+                                                    false, currentFocusOwner));
+                    }
+                  else
+                    eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED, false));
+                }
+            }
+        }
+      });
   }
 
   Window(GraphicsConfiguration gc)
@@ -659,7 +690,21 @@
     if (activeWindow == this)
       return manager.getFocusOwner ();
     else
-      return null;
+      return windowFocusOwner;
+  }
+
+  /**
+   * Set the focus owner for this window.  This method is used to
+   * remember which component was focused when this window lost
+   * top-level focus, so that when it regains top-level focus the same
+   * child component can be refocused.
+   *
+   * @param windowFocusOwner the component in this window that owns
+   * the focus.
+   */
+  void setFocusOwner (Component windowFocusOwner)
+  {
+    this.windowFocusOwner = windowFocusOwner;
   }
 
   /**

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]