This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gui][PATCH] window focus fixes
- From: Thomas Fitzsimmons <fitzsim at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Sat, 10 Jul 2004 23:12:03 -0400
- Subject: [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;
}
/**