You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/06/23 16:27:59 UTC

svn commit: r787688 - in /incubator/pivot/trunk/wtk: src/org/apache/pivot/wtk/ src/org/apache/pivot/wtk/skin/ test/org/apache/pivot/wtk/test/

Author: gbrown
Date: Tue Jun 23 14:27:59 2009
New Revision: 787688

URL: http://svn.apache.org/viewvc?rev=787688&view=rev
Log:
Fix bug in Container#requestFocus(); allow any window's most recently focused component to be restored when it is moved to front, not just when a window's active state changes.

Added:
    incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/WindowFocusTest.java
Modified:
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Container.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Window.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/DisplaySkin.java

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java?rev=787688&r1=787687&r2=787688&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java Tue Jun 23 14:27:59 2009
@@ -2004,7 +2004,7 @@
     /**
      * Requests that focus be given to this component.
      */
-    public void requestFocus() {
+    public final void requestFocus() {
         requestFocus(false);
     }
 
@@ -2136,13 +2136,6 @@
     }
 
     /**
-     * Returns the component dictionary.
-     */
-    public static ComponentDictionary getComponents() {
-        return componentDictionary;
-    }
-
-    /**
      * Clears the focus.
      *
      * @param temporary
@@ -2153,6 +2146,13 @@
     }
 
     /**
+     * Returns the component dictionary.
+     */
+    public static ComponentDictionary getComponents() {
+        return componentDictionary;
+    }
+
+    /**
      * Copies bound values from the bind context to the component. This
      * functionality must be provided by the subclass; the base implementation
      * is a no-op.

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Container.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Container.java?rev=787688&r1=787687&r2=787688&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Container.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Container.java Tue Jun 23 14:27:59 2009
@@ -445,22 +445,64 @@
      }
 
     /**
+     * Tests for the existence of any focusable descendants in this container.
+     *
      * @return
-     * <tt>false</tt>; containers are not focusable.
+     * <tt>true</tt> if this container has any focusable descedants;
+     * <tt>false</tt>, otherwise.
      */
     @Override
     public final boolean isFocusable() {
-        return false;
+        boolean focusable = false;
+
+        if (isShowing()
+            && !isBlocked()) {
+            for (int i = 0, n = getLength(); i < n; i++) {
+                Component component = components.get(i);
+                focusable = component.isFocusable();
+
+                if (focusable) {
+                    break;
+                }
+            }
+        }
+
+        return focusable;
     }
 
-    @Override
     /**
-     * Requests that focus be set to the first focusable component in this
+     * Requests that focus be set to the first focusable descendant in this
      * container.
      */
-    public void requestFocus() {
-        if (getLength() > 0) {
-            get(0).requestFocus();
+    @Override
+    protected void requestFocus(boolean temporary) {
+        if (!isShowing()) {
+            throw new IllegalArgumentException("Container is not showing.");
+        }
+
+        if (isBlocked()) {
+            throw new IllegalArgumentException("Container is blocked.");
+        }
+
+        for (int i = 0, n = getLength(); i < n; i++) {
+            Component component = components.get(i);
+
+            if (component instanceof Container) {
+                Container container = (Container)component;
+                if (container.isShowing()
+                    && !container.isBlocked()) {
+                    container.requestFocus();
+                    if (container.containsFocus()) {
+                        break;
+                    }
+                }
+            } else {
+                if (component.isFocusable()
+                    && component.isShowing()
+                    && !component.isBlocked()) {
+                    component.requestFocus();
+                }
+            }
         }
     }
 

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java?rev=787688&r1=787687&r2=787688&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java Tue Jun 23 14:27:59 2009
@@ -177,7 +177,8 @@
                 // Disabling the owner tree also disabled this dialog; re-enable it
                 // and make it the active window
                 setEnabled(true);
-                setActiveWindow(this);
+                requestActive();
+                requestFocus(true);
             }
         }
     }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Window.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Window.java?rev=787688&r1=787687&r2=787688&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Window.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Window.java Tue Jun 23 14:27:59 2009
@@ -240,7 +240,7 @@
 
         if (parent == null
             && isActive()) {
-            setActiveWindow(null);
+            clearActive();
         }
 
         super.setParent(parent);
@@ -271,12 +271,6 @@
     public void setDisplayable(boolean displayable) {
         super.setDisplayable(displayable);
 
-        if (!displayable) {
-            if (isActive()) {
-                setActiveWindow(null);
-            }
-        }
-
         // Show/hide owned windows
         for (Window ownedWindow : ownedWindows) {
             ownedWindow.setDisplayable(displayable);
@@ -299,7 +293,7 @@
             if (isEnabled() == enabled) {
                 if (!enabled
                     && isActive()) {
-                    setActiveWindow(null);
+                    clearActive();
                 }
 
                 // Enable/disable owned windows
@@ -506,7 +500,7 @@
                 closing = true;
 
                 if (isActive()) {
-                    setActiveWindow(null);
+                    clearActive();
                 }
 
                 // Close all owned windows (create a copy of the owned window
@@ -653,7 +647,7 @@
      * <tt>true</tt> if the window is active; <tt>false</tt>; otherwise.
      */
     public boolean isActive() {
-        return activeWindow == this;
+        return (activeWindow == this);
     }
 
     /**
@@ -662,25 +656,26 @@
      * @param active
      */
     protected void setActive(boolean active) {
-        if (active) {
-            // If this window is still an ancestor of the active descendant
-            // and the active descendant can be focused, restore focus to it;
-            // otherwise, clear the active descendant
-            if (activeDescendant != null) {
-                if (isAncestor(activeDescendant)
-                    && !activeDescendant.isBlocked()
-                    && activeDescendant.isShowing()) {
-                    activeDescendant.requestFocus(true);
-                } else {
-                    activeDescendant = null;
-                }
-            }
-        } else {
-            // Temporarily clear the focus
-            clearFocus(true);
+        windowListeners.activeChanged(this);
+    }
+
+    /**
+     * Requests that this window become active.
+     */
+    public void requestActive() {
+        if (isAuxilliary()) {
+            throw new IllegalArgumentException("Window is auxilliary.");
         }
 
-        windowListeners.activeChanged(this);
+        if (!isOpen()) {
+            throw new IllegalArgumentException("Window is not open.");
+        }
+
+        if (!isEnabled()) {
+            throw new IllegalArgumentException("Window is not enabled.");
+        }
+
+        setActiveWindow(this);
     }
 
     /**
@@ -702,24 +697,10 @@
      * @param activeWindow
      * The window to activate, or <tt>null</tt> to clear the active window.
      */
-    public static void setActiveWindow(Window activeWindow) {
+    private static void setActiveWindow(Window activeWindow) {
         Window previousActiveWindow = Window.activeWindow;
 
         if (previousActiveWindow != activeWindow) {
-            if (activeWindow != null) {
-                if (activeWindow.isAuxilliary()) {
-                    throw new IllegalArgumentException("activeWindow is auxilliary.");
-                }
-
-                if (!activeWindow.isOpen()) {
-                    throw new IllegalArgumentException("activeWindow is not open.");
-                }
-
-                if (!activeWindow.isEnabled()) {
-                    throw new IllegalArgumentException("activeWindow is not enabled.");
-                }
-            }
-
             // Set the active window
             Window.activeWindow = activeWindow;
 
@@ -738,6 +719,13 @@
     }
 
     /**
+     * Clears the active window.
+     */
+    public static void clearActive() {
+        setActiveWindow(null);
+    }
+
+    /**
      * Returns the window descendant that currently has the focus.
      */
     public Component getActiveDescendant() {
@@ -754,6 +742,23 @@
         this.activeDescendant = activeDescendant;
     }
 
+    @Override
+    protected void requestFocus(boolean temporary) {
+        // If this window is still an ancestor of the active descendant
+        // and the active descendant can be focused, restore focus to it;
+        // otherwise, clear the active descendant
+        if (activeDescendant != null
+            && isAncestor(activeDescendant)
+            && !activeDescendant.isBlocked()
+            && activeDescendant.isShowing()) {
+            activeDescendant.requestFocus(temporary);
+        } else {
+            activeDescendant = null;
+
+            super.requestFocus(temporary);
+        }
+    }
+
     /**
      * Returns the global action map for this window.
      */
@@ -814,9 +819,14 @@
                 }
             } else {
                 // Activate the window
-                if (window.isEnabled()
-                    && !window.isAuxilliary()) {
-                    setActiveWindow(window);
+                if (window.isShowing()
+                    && !window.isBlocked()) {
+                    if (!window.isAuxilliary()) {
+                        window.requestActive();
+                    }
+
+                    // Restore focus to the window
+                    window.requestFocus(true);
                 }
 
                 // This was the last owned window for the current window; move
@@ -850,7 +860,8 @@
         }
 
         if (isActive()) {
-            setActiveWindow(null);
+            clearActive();
+            clearFocus(true);
         }
 
         Display display = getDisplay();

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/DisplaySkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/DisplaySkin.java?rev=787688&r1=787687&r2=787688&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/DisplaySkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/DisplaySkin.java Tue Jun 23 14:27:59 2009
@@ -92,7 +92,7 @@
             if (window != null
                 && window.isEnabled()
                 && !window.isAuxilliary()) {
-                Window.setActiveWindow(window);
+                window.requestActive();
             }
         }
 

Added: incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/WindowFocusTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/WindowFocusTest.java?rev=787688&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/WindowFocusTest.java (added)
+++ incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/WindowFocusTest.java Tue Jun 23 14:27:59 2009
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.wtk.test;
+
+import org.apache.pivot.collections.Map;
+import org.apache.pivot.wtk.Application;
+import org.apache.pivot.wtk.DesktopApplicationContext;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.FlowPane;
+import org.apache.pivot.wtk.Frame;
+import org.apache.pivot.wtk.TextInput;
+
+public class WindowFocusTest implements Application {
+    private Frame frame1;
+    private Frame frame2;
+
+    @Override
+    public void startup(Display display, Map<String, String> properties) throws Exception {
+        FlowPane flowPane1 = new FlowPane();
+        flowPane1.add(new TextInput());
+        frame1 = new Frame(flowPane1);
+        frame1.setPreferredSize(320, 240);
+        frame1.open(display);
+
+        FlowPane flowPane2 = new FlowPane();
+        flowPane2.add(new TextInput());
+        frame2 = new Frame(flowPane2);
+        frame2.setPreferredSize(320, 240);
+        frame2.open(display);
+    }
+
+    @Override
+    public boolean shutdown(boolean optional) throws Exception {
+        if (frame1 != null) {
+            frame1.close();
+        }
+
+        frame1 = null;
+
+        if (frame2 != null) {
+            frame2.close();
+        }
+
+        frame2 = null;
+
+        return true;
+    }
+
+    @Override
+    public void suspend() {
+    }
+
+    @Override
+    public void resume() {
+    }
+
+    public static void main(String[] args) {
+        DesktopApplicationContext.main(WindowFocusTest.class, args);
+    }
+}