src/share/classes/java/awt/KeyboardFocusManager.java

Print this page




 635     }
 636     private void _clearGlobalFocusOwner() {
 637         Window activeWindow = markClearGlobalFocusOwner();
 638         peer.clearGlobalFocusOwner(activeWindow);
 639     }
 640 
 641     void clearGlobalFocusOwnerPriv() {
 642         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 643             public Void run() {
 644                 clearGlobalFocusOwner();
 645                 return null;
 646             }
 647         });
 648     }
 649 
 650     Component getNativeFocusOwner() {
 651         return peer.getCurrentFocusOwner();
 652     }
 653 
 654     void setNativeFocusOwner(Component comp) {
 655         if (focusLog.isLoggable(PlatformLogger.FINEST)) {
 656             focusLog.finest("Calling peer {0} setCurrentFocusOwner for {1}",
 657                             String.valueOf(peer), String.valueOf(comp));
 658         }
 659         peer.setCurrentFocusOwner(comp);
 660     }
 661 
 662     Window getNativeFocusedWindow() {
 663         return peer.getCurrentFocusedWindow();
 664     }
 665 
 666     /**
 667      * Returns the permanent focus owner, if the permanent focus owner is in
 668      * the same context as the calling thread. The permanent focus owner is
 669      * defined as the last Component in an application to receive a permanent
 670      * FOCUS_GAINED event. The focus owner and permanent focus owner are
 671      * equivalent unless a temporary focus change is currently in effect. In
 672      * such a situation, the permanent focus owner will again be the focus
 673      * owner when the temporary focus change ends.
 674      *
 675      * @return the permanent focus owner, or null if the permanent focus owner


 944      * @param activeWindow the active Window
 945      * @see #getActiveWindow
 946      * @see #getGlobalActiveWindow
 947      * @see Component#requestFocus()
 948      * @see Component#requestFocusInWindow()
 949      * @throws SecurityException if this KeyboardFocusManager is not the
 950      *         current KeyboardFocusManager for the calling thread's context
 951      *         and if the calling thread does not have "replaceKeyboardFocusManager"
 952      *         permission
 953      * @beaninfo
 954      *       bound: true
 955      */
 956     protected void setGlobalActiveWindow(Window activeWindow)
 957         throws SecurityException
 958     {
 959         Window oldActiveWindow;
 960         synchronized (KeyboardFocusManager.class) {
 961             checkKFMSecurity();
 962 
 963             oldActiveWindow = getActiveWindow();
 964             if (focusLog.isLoggable(PlatformLogger.FINER)) {
 965                 focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow);
 966             }
 967 
 968             try {
 969                 fireVetoableChange("activeWindow", oldActiveWindow,
 970                                    activeWindow);
 971             } catch (PropertyVetoException e) {
 972                 // rejected
 973                 return;
 974             }
 975 
 976             KeyboardFocusManager.activeWindow = activeWindow;
 977         }
 978 
 979         firePropertyChange("activeWindow", oldActiveWindow, activeWindow);
 980     }
 981 
 982     /**
 983      * Returns the default FocusTraversalPolicy. Top-level components
 984      * use this value on their creation to initialize their own focus traversal


2179         public String toString() {
2180             return "LightweightFocusRequest[component=" + component +
2181                 ",temporary=" + temporary + ", cause=" + cause + "]";
2182         }
2183     }
2184 
2185     private static final class HeavyweightFocusRequest {
2186         final Component heavyweight;
2187         final LinkedList<LightweightFocusRequest> lightweightRequests;
2188 
2189         static final HeavyweightFocusRequest CLEAR_GLOBAL_FOCUS_OWNER =
2190             new HeavyweightFocusRequest();
2191 
2192         private HeavyweightFocusRequest() {
2193             heavyweight = null;
2194             lightweightRequests = null;
2195         }
2196 
2197         HeavyweightFocusRequest(Component heavyweight, Component descendant,
2198                                 boolean temporary, CausedFocusEvent.Cause cause) {
2199             if (log.isLoggable(PlatformLogger.FINE)) {
2200                 if (heavyweight == null) {
2201                     log.fine("Assertion (heavyweight != null) failed");
2202                 }
2203             }
2204 
2205             this.heavyweight = heavyweight;
2206             this.lightweightRequests = new LinkedList<LightweightFocusRequest>();
2207             addLightweightRequest(descendant, temporary, cause);
2208         }
2209         boolean addLightweightRequest(Component descendant,
2210                                       boolean temporary, CausedFocusEvent.Cause cause) {
2211             if (log.isLoggable(PlatformLogger.FINE)) {
2212                 if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
2213                     log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed");
2214                 }
2215                 if (descendant == null) {
2216                     log.fine("Assertion (descendant != null) failed");
2217                 }
2218             }
2219 
2220             Component lastDescendant = ((lightweightRequests.size() > 0)
2221                 ? lightweightRequests.getLast().component
2222                 : null);
2223 
2224             if (descendant != lastDescendant) {
2225                 // Not a duplicate request
2226                 lightweightRequests.add
2227                     (new LightweightFocusRequest(descendant, temporary, cause));
2228                 return true;
2229             } else {
2230                 return false;
2231             }


2369      * pending, native focus request. Before changing the focus at the native
2370      * level, the AWT implementation should always call this function for
2371      * permission. This function will reject the request if a duplicate request
2372      * preceded it, or if the specified heavyweight Component already owns the
2373      * focus and no native focus changes are pending. Otherwise, the request
2374      * will be approved and the focus request list will be updated so that,
2375      * if necessary, the proper descendant will be focused when the
2376      * corresponding FOCUS_GAINED event on the heavyweight is received.
2377      *
2378      * An implementation must ensure that calls to this method and native
2379      * focus changes are atomic. If this is not guaranteed, then the ordering
2380      * of the focus request list may be incorrect, leading to errors in the
2381      * type-ahead mechanism. Typically this is accomplished by only calling
2382      * this function from the native event pumping thread, or by holding a
2383      * global, native lock during invocation.
2384      */
2385     static int shouldNativelyFocusHeavyweight
2386         (Component heavyweight, Component descendant, boolean temporary,
2387          boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
2388     {
2389         if (log.isLoggable(PlatformLogger.FINE)) {
2390             if (heavyweight == null) {
2391                 log.fine("Assertion (heavyweight != null) failed");
2392             }
2393             if (time == 0) {
2394                 log.fine("Assertion (time != 0) failed");
2395             }
2396         }
2397 
2398         if (descendant == null) {
2399             // Focus transfers from a lightweight child back to the
2400             // heavyweight Container should be treated like lightweight
2401             // focus transfers.
2402             descendant = heavyweight;
2403         }
2404 
2405         KeyboardFocusManager manager =
2406             getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(descendant));
2407         KeyboardFocusManager thisManager = getCurrentKeyboardFocusManager();
2408         Component currentFocusOwner = thisManager.getGlobalFocusOwner();
2409         Component nativeFocusOwner = thisManager.getNativeFocusOwner();
2410         Window nativeFocusedWindow = thisManager.getNativeFocusedWindow();
2411         if (focusLog.isLoggable(PlatformLogger.FINER)) {
2412             focusLog.finer("SNFH for {0} in {1}",
2413                        String.valueOf(descendant), String.valueOf(heavyweight));
2414         }
2415         if (focusLog.isLoggable(PlatformLogger.FINEST)) {
2416             focusLog.finest("0. Current focus owner {0}",
2417                             String.valueOf(currentFocusOwner));
2418             focusLog.finest("0. Native focus owner {0}",
2419                             String.valueOf(nativeFocusOwner));
2420             focusLog.finest("0. Native focused window {0}",
2421                             String.valueOf(nativeFocusedWindow));
2422         }
2423         synchronized (heavyweightRequests) {
2424             HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
2425             if (focusLog.isLoggable(PlatformLogger.FINEST)) {
2426                 focusLog.finest("Request {0}", String.valueOf(hwFocusRequest));
2427             }
2428             if (hwFocusRequest == null &&
2429                 heavyweight == nativeFocusOwner)
2430             {
2431                 if (descendant == currentFocusOwner) {
2432                     // Redundant request.
2433                     if (focusLog.isLoggable(PlatformLogger.FINEST))
2434                         focusLog.finest("1. SNFH_FAILURE for {0}",
2435                                         String.valueOf(descendant));
2436                     return SNFH_FAILURE;
2437                 }
2438 
2439                 // 'heavyweight' owns the native focus and there are no pending
2440                 // requests. 'heavyweight' must be a Container and
2441                 // 'descendant' must not be the focus owner. Otherwise,
2442                 // we would never have gotten this far.
2443                 manager.enqueueKeyEvents(time, descendant);
2444 
2445                 hwFocusRequest =
2446                     new HeavyweightFocusRequest(heavyweight, descendant,
2447                                                 temporary, cause);
2448                 heavyweightRequests.add(hwFocusRequest);
2449 
2450                 if (currentFocusOwner != null) {
2451                     FocusEvent currentFocusOwnerEvent =
2452                         new CausedFocusEvent(currentFocusOwner,
2453                                        FocusEvent.FOCUS_LOST,
2454                                        temporary, descendant, cause);
2455                     // Fix 5028014. Rolled out.
2456                     // SunToolkit.postPriorityEvent(currentFocusOwnerEvent);
2457                     SunToolkit.postEvent(currentFocusOwner.appContext,
2458                                          currentFocusOwnerEvent);
2459                 }
2460                 FocusEvent newFocusOwnerEvent =
2461                     new CausedFocusEvent(descendant, FocusEvent.FOCUS_GAINED,
2462                                    temporary, currentFocusOwner, cause);
2463                 // Fix 5028014. Rolled out.
2464                 // SunToolkit.postPriorityEvent(newFocusOwnerEvent);
2465                 SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent);
2466 
2467                 if (focusLog.isLoggable(PlatformLogger.FINEST))
2468                     focusLog.finest("2. SNFH_HANDLED for {0}", String.valueOf(descendant));
2469                 return SNFH_SUCCESS_HANDLED;
2470             } else if (hwFocusRequest != null &&
2471                        hwFocusRequest.heavyweight == heavyweight) {
2472                 // 'heavyweight' doesn't have the native focus right now, but
2473                 // if all pending requests were completed, it would. Add
2474                 // descendant to the heavyweight's list of pending
2475                 // lightweight focus transfers.
2476                 if (hwFocusRequest.addLightweightRequest(descendant,
2477                                                          temporary, cause)) {
2478                     manager.enqueueKeyEvents(time, descendant);
2479                 }
2480 
2481                 if (focusLog.isLoggable(PlatformLogger.FINEST)) {
2482                     focusLog.finest("3. SNFH_HANDLED for lightweight" +
2483                                     descendant + " in " + heavyweight);
2484                 }
2485                 return SNFH_SUCCESS_HANDLED;
2486             } else {
2487                 if (!focusedWindowChangeAllowed) {
2488                     // For purposes of computing oldFocusedWindow, we should look at
2489                     // the second to last HeavyweightFocusRequest on the queue iff the
2490                     // last HeavyweightFocusRequest is CLEAR_GLOBAL_FOCUS_OWNER. If
2491                     // there is no second to last HeavyweightFocusRequest, null is an
2492                     // acceptable value.
2493                     if (hwFocusRequest ==
2494                         HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
2495                     {
2496                         int size = heavyweightRequests.size();
2497                         hwFocusRequest = (HeavyweightFocusRequest)((size >= 2)
2498                             ? heavyweightRequests.get(size - 2)
2499                             : null);
2500                     }
2501                     if (focusedWindowChanged(heavyweight,
2502                                              (hwFocusRequest != null)
2503                                              ? hwFocusRequest.heavyweight
2504                                              : nativeFocusedWindow)) {
2505                         if (focusLog.isLoggable(PlatformLogger.FINEST)) {
2506                             focusLog.finest("4. SNFH_FAILURE for " + descendant);
2507                         }
2508                         return SNFH_FAILURE;
2509                     }
2510                 }
2511 
2512                 manager.enqueueKeyEvents(time, descendant);
2513                 heavyweightRequests.add
2514                     (new HeavyweightFocusRequest(heavyweight, descendant,
2515                                                  temporary, cause));
2516                 if (focusLog.isLoggable(PlatformLogger.FINEST)) {
2517                     focusLog.finest("5. SNFH_PROCEED for " + descendant);
2518                 }
2519                 return SNFH_SUCCESS_PROCEED;
2520             }
2521         }
2522     }
2523 
2524     /**
2525      * Returns the Window which will be active after processing this request,
2526      * or null if this is a duplicate request. The active Window is useful
2527      * because some native platforms do not support setting the native focus
2528      * owner to null. On these platforms, the obvious choice is to set the
2529      * focus owner to the focus proxy of the active Window.
2530      */
2531     static Window markClearGlobalFocusOwner() {
2532         // need to call this out of synchronized block to avoid possible deadlock
2533         // see 6454631.
2534         final Component nativeFocusedWindow =
2535                 getCurrentKeyboardFocusManager().getNativeFocusedWindow();
2536 


2888                 // If top-level changed there might be no focus request in a list
2889                 // But we know the opposite, we now it is temporary - dispatch the event.
2890                 if (!fe.isTemporary() && currentFocusOwner != null) {
2891                     // Create copy of the event with only difference in temporary parameter.
2892                     fe = new CausedFocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
2893                                               true, opposite, CausedFocusEvent.Cause.ACTIVATION);
2894                 }
2895                 return fe;
2896             }
2897 
2898             return retargetUnexpectedFocusEvent(fe);
2899         }  // end synchronized(heavyweightRequests)
2900     }
2901 
2902     static AWTEvent retargetFocusEvent(AWTEvent event) {
2903         if (clearingCurrentLightweightRequests) {
2904             return event;
2905         }
2906 
2907         KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
2908         if (focusLog.isLoggable(PlatformLogger.FINER)) {
2909             if (event instanceof FocusEvent || event instanceof WindowEvent) {
2910                 focusLog.finer(">>> {0}", String.valueOf(event));
2911             }
2912             if (focusLog.isLoggable(PlatformLogger.FINER) && event instanceof KeyEvent) {
2913                 focusLog.finer("    focus owner is {0}",
2914                                String.valueOf(manager.getGlobalFocusOwner()));
2915                 focusLog.finer(">>> {0}", String.valueOf(event));
2916             }
2917         }
2918 
2919         synchronized(heavyweightRequests) {
2920             /*
2921              * This code handles FOCUS_LOST event which is generated by
2922              * DefaultKeyboardFocusManager for FOCUS_GAINED.
2923              *
2924              * This code based on knowledge of DefaultKeyboardFocusManager's
2925              * implementation and might be not applicable for another
2926              * KeyboardFocusManager.
2927              *
2928              * Fix for 4472032
2929              */
2930             if (newFocusOwner != null &&
2931                 event.getID() == FocusEvent.FOCUS_LOST)
2932             {


2979                 if (hwFocusRequest.lightweightRequests != null) {
2980                     for (Iterator lwIter = hwFocusRequest.lightweightRequests.
2981                              iterator();
2982                          lwIter.hasNext(); )
2983                     {
2984                         manager.dequeueKeyEvents
2985                             (-1, ((LightweightFocusRequest)lwIter.next()).
2986                              component);
2987                     }
2988                 }
2989             }
2990             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
2991             // We do it here because this method is called only when problems happen
2992             if (heavyweightRequests.size() == 0) {
2993                 manager.clearMarkers();
2994             }
2995             return (heavyweightRequests.size() > 0);
2996         }
2997     }
2998     static void removeLastFocusRequest(Component heavyweight) {
2999         if (log.isLoggable(PlatformLogger.FINE)) {
3000             if (heavyweight == null) {
3001                 log.fine("Assertion (heavyweight != null) failed");
3002             }
3003         }
3004 
3005         KeyboardFocusManager manager =
3006             KeyboardFocusManager.getCurrentKeyboardFocusManager();
3007         synchronized(heavyweightRequests) {
3008             HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
3009             if (hwFocusRequest != null &&
3010                 hwFocusRequest.heavyweight == heavyweight) {
3011                 heavyweightRequests.removeLast();
3012             }
3013             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
3014             // We do it here because this method is called only when problems happen
3015             if (heavyweightRequests.size() == 0) {
3016                 manager.clearMarkers();
3017             }
3018         }
3019     }




 635     }
 636     private void _clearGlobalFocusOwner() {
 637         Window activeWindow = markClearGlobalFocusOwner();
 638         peer.clearGlobalFocusOwner(activeWindow);
 639     }
 640 
 641     void clearGlobalFocusOwnerPriv() {
 642         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 643             public Void run() {
 644                 clearGlobalFocusOwner();
 645                 return null;
 646             }
 647         });
 648     }
 649 
 650     Component getNativeFocusOwner() {
 651         return peer.getCurrentFocusOwner();
 652     }
 653 
 654     void setNativeFocusOwner(Component comp) {
 655         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
 656             focusLog.finest("Calling peer {0} setCurrentFocusOwner for {1}",
 657                             String.valueOf(peer), String.valueOf(comp));
 658         }
 659         peer.setCurrentFocusOwner(comp);
 660     }
 661 
 662     Window getNativeFocusedWindow() {
 663         return peer.getCurrentFocusedWindow();
 664     }
 665 
 666     /**
 667      * Returns the permanent focus owner, if the permanent focus owner is in
 668      * the same context as the calling thread. The permanent focus owner is
 669      * defined as the last Component in an application to receive a permanent
 670      * FOCUS_GAINED event. The focus owner and permanent focus owner are
 671      * equivalent unless a temporary focus change is currently in effect. In
 672      * such a situation, the permanent focus owner will again be the focus
 673      * owner when the temporary focus change ends.
 674      *
 675      * @return the permanent focus owner, or null if the permanent focus owner


 944      * @param activeWindow the active Window
 945      * @see #getActiveWindow
 946      * @see #getGlobalActiveWindow
 947      * @see Component#requestFocus()
 948      * @see Component#requestFocusInWindow()
 949      * @throws SecurityException if this KeyboardFocusManager is not the
 950      *         current KeyboardFocusManager for the calling thread's context
 951      *         and if the calling thread does not have "replaceKeyboardFocusManager"
 952      *         permission
 953      * @beaninfo
 954      *       bound: true
 955      */
 956     protected void setGlobalActiveWindow(Window activeWindow)
 957         throws SecurityException
 958     {
 959         Window oldActiveWindow;
 960         synchronized (KeyboardFocusManager.class) {
 961             checkKFMSecurity();
 962 
 963             oldActiveWindow = getActiveWindow();
 964             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
 965                 focusLog.finer("Setting global active window to " + activeWindow + ", old active " + oldActiveWindow);
 966             }
 967 
 968             try {
 969                 fireVetoableChange("activeWindow", oldActiveWindow,
 970                                    activeWindow);
 971             } catch (PropertyVetoException e) {
 972                 // rejected
 973                 return;
 974             }
 975 
 976             KeyboardFocusManager.activeWindow = activeWindow;
 977         }
 978 
 979         firePropertyChange("activeWindow", oldActiveWindow, activeWindow);
 980     }
 981 
 982     /**
 983      * Returns the default FocusTraversalPolicy. Top-level components
 984      * use this value on their creation to initialize their own focus traversal


2179         public String toString() {
2180             return "LightweightFocusRequest[component=" + component +
2181                 ",temporary=" + temporary + ", cause=" + cause + "]";
2182         }
2183     }
2184 
2185     private static final class HeavyweightFocusRequest {
2186         final Component heavyweight;
2187         final LinkedList<LightweightFocusRequest> lightweightRequests;
2188 
2189         static final HeavyweightFocusRequest CLEAR_GLOBAL_FOCUS_OWNER =
2190             new HeavyweightFocusRequest();
2191 
2192         private HeavyweightFocusRequest() {
2193             heavyweight = null;
2194             lightweightRequests = null;
2195         }
2196 
2197         HeavyweightFocusRequest(Component heavyweight, Component descendant,
2198                                 boolean temporary, CausedFocusEvent.Cause cause) {
2199             if (log.isLoggable(PlatformLogger.Level.FINE)) {
2200                 if (heavyweight == null) {
2201                     log.fine("Assertion (heavyweight != null) failed");
2202                 }
2203             }
2204 
2205             this.heavyweight = heavyweight;
2206             this.lightweightRequests = new LinkedList<LightweightFocusRequest>();
2207             addLightweightRequest(descendant, temporary, cause);
2208         }
2209         boolean addLightweightRequest(Component descendant,
2210                                       boolean temporary, CausedFocusEvent.Cause cause) {
2211             if (log.isLoggable(PlatformLogger.Level.FINE)) {
2212                 if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
2213                     log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed");
2214                 }
2215                 if (descendant == null) {
2216                     log.fine("Assertion (descendant != null) failed");
2217                 }
2218             }
2219 
2220             Component lastDescendant = ((lightweightRequests.size() > 0)
2221                 ? lightweightRequests.getLast().component
2222                 : null);
2223 
2224             if (descendant != lastDescendant) {
2225                 // Not a duplicate request
2226                 lightweightRequests.add
2227                     (new LightweightFocusRequest(descendant, temporary, cause));
2228                 return true;
2229             } else {
2230                 return false;
2231             }


2369      * pending, native focus request. Before changing the focus at the native
2370      * level, the AWT implementation should always call this function for
2371      * permission. This function will reject the request if a duplicate request
2372      * preceded it, or if the specified heavyweight Component already owns the
2373      * focus and no native focus changes are pending. Otherwise, the request
2374      * will be approved and the focus request list will be updated so that,
2375      * if necessary, the proper descendant will be focused when the
2376      * corresponding FOCUS_GAINED event on the heavyweight is received.
2377      *
2378      * An implementation must ensure that calls to this method and native
2379      * focus changes are atomic. If this is not guaranteed, then the ordering
2380      * of the focus request list may be incorrect, leading to errors in the
2381      * type-ahead mechanism. Typically this is accomplished by only calling
2382      * this function from the native event pumping thread, or by holding a
2383      * global, native lock during invocation.
2384      */
2385     static int shouldNativelyFocusHeavyweight
2386         (Component heavyweight, Component descendant, boolean temporary,
2387          boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
2388     {
2389         if (log.isLoggable(PlatformLogger.Level.FINE)) {
2390             if (heavyweight == null) {
2391                 log.fine("Assertion (heavyweight != null) failed");
2392             }
2393             if (time == 0) {
2394                 log.fine("Assertion (time != 0) failed");
2395             }
2396         }
2397 
2398         if (descendant == null) {
2399             // Focus transfers from a lightweight child back to the
2400             // heavyweight Container should be treated like lightweight
2401             // focus transfers.
2402             descendant = heavyweight;
2403         }
2404 
2405         KeyboardFocusManager manager =
2406             getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(descendant));
2407         KeyboardFocusManager thisManager = getCurrentKeyboardFocusManager();
2408         Component currentFocusOwner = thisManager.getGlobalFocusOwner();
2409         Component nativeFocusOwner = thisManager.getNativeFocusOwner();
2410         Window nativeFocusedWindow = thisManager.getNativeFocusedWindow();
2411         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
2412             focusLog.finer("SNFH for {0} in {1}",
2413                        String.valueOf(descendant), String.valueOf(heavyweight));
2414         }
2415         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
2416             focusLog.finest("0. Current focus owner {0}",
2417                             String.valueOf(currentFocusOwner));
2418             focusLog.finest("0. Native focus owner {0}",
2419                             String.valueOf(nativeFocusOwner));
2420             focusLog.finest("0. Native focused window {0}",
2421                             String.valueOf(nativeFocusedWindow));
2422         }
2423         synchronized (heavyweightRequests) {
2424             HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
2425             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
2426                 focusLog.finest("Request {0}", String.valueOf(hwFocusRequest));
2427             }
2428             if (hwFocusRequest == null &&
2429                 heavyweight == nativeFocusOwner)
2430             {
2431                 if (descendant == currentFocusOwner) {
2432                     // Redundant request.
2433                     if (focusLog.isLoggable(PlatformLogger.Level.FINEST))
2434                         focusLog.finest("1. SNFH_FAILURE for {0}",
2435                                         String.valueOf(descendant));
2436                     return SNFH_FAILURE;
2437                 }
2438 
2439                 // 'heavyweight' owns the native focus and there are no pending
2440                 // requests. 'heavyweight' must be a Container and
2441                 // 'descendant' must not be the focus owner. Otherwise,
2442                 // we would never have gotten this far.
2443                 manager.enqueueKeyEvents(time, descendant);
2444 
2445                 hwFocusRequest =
2446                     new HeavyweightFocusRequest(heavyweight, descendant,
2447                                                 temporary, cause);
2448                 heavyweightRequests.add(hwFocusRequest);
2449 
2450                 if (currentFocusOwner != null) {
2451                     FocusEvent currentFocusOwnerEvent =
2452                         new CausedFocusEvent(currentFocusOwner,
2453                                        FocusEvent.FOCUS_LOST,
2454                                        temporary, descendant, cause);
2455                     // Fix 5028014. Rolled out.
2456                     // SunToolkit.postPriorityEvent(currentFocusOwnerEvent);
2457                     SunToolkit.postEvent(currentFocusOwner.appContext,
2458                                          currentFocusOwnerEvent);
2459                 }
2460                 FocusEvent newFocusOwnerEvent =
2461                     new CausedFocusEvent(descendant, FocusEvent.FOCUS_GAINED,
2462                                    temporary, currentFocusOwner, cause);
2463                 // Fix 5028014. Rolled out.
2464                 // SunToolkit.postPriorityEvent(newFocusOwnerEvent);
2465                 SunToolkit.postEvent(descendant.appContext, newFocusOwnerEvent);
2466 
2467                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST))
2468                     focusLog.finest("2. SNFH_HANDLED for {0}", String.valueOf(descendant));
2469                 return SNFH_SUCCESS_HANDLED;
2470             } else if (hwFocusRequest != null &&
2471                        hwFocusRequest.heavyweight == heavyweight) {
2472                 // 'heavyweight' doesn't have the native focus right now, but
2473                 // if all pending requests were completed, it would. Add
2474                 // descendant to the heavyweight's list of pending
2475                 // lightweight focus transfers.
2476                 if (hwFocusRequest.addLightweightRequest(descendant,
2477                                                          temporary, cause)) {
2478                     manager.enqueueKeyEvents(time, descendant);
2479                 }
2480 
2481                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
2482                     focusLog.finest("3. SNFH_HANDLED for lightweight" +
2483                                     descendant + " in " + heavyweight);
2484                 }
2485                 return SNFH_SUCCESS_HANDLED;
2486             } else {
2487                 if (!focusedWindowChangeAllowed) {
2488                     // For purposes of computing oldFocusedWindow, we should look at
2489                     // the second to last HeavyweightFocusRequest on the queue iff the
2490                     // last HeavyweightFocusRequest is CLEAR_GLOBAL_FOCUS_OWNER. If
2491                     // there is no second to last HeavyweightFocusRequest, null is an
2492                     // acceptable value.
2493                     if (hwFocusRequest ==
2494                         HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
2495                     {
2496                         int size = heavyweightRequests.size();
2497                         hwFocusRequest = (HeavyweightFocusRequest)((size >= 2)
2498                             ? heavyweightRequests.get(size - 2)
2499                             : null);
2500                     }
2501                     if (focusedWindowChanged(heavyweight,
2502                                              (hwFocusRequest != null)
2503                                              ? hwFocusRequest.heavyweight
2504                                              : nativeFocusedWindow)) {
2505                         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
2506                             focusLog.finest("4. SNFH_FAILURE for " + descendant);
2507                         }
2508                         return SNFH_FAILURE;
2509                     }
2510                 }
2511 
2512                 manager.enqueueKeyEvents(time, descendant);
2513                 heavyweightRequests.add
2514                     (new HeavyweightFocusRequest(heavyweight, descendant,
2515                                                  temporary, cause));
2516                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
2517                     focusLog.finest("5. SNFH_PROCEED for " + descendant);
2518                 }
2519                 return SNFH_SUCCESS_PROCEED;
2520             }
2521         }
2522     }
2523 
2524     /**
2525      * Returns the Window which will be active after processing this request,
2526      * or null if this is a duplicate request. The active Window is useful
2527      * because some native platforms do not support setting the native focus
2528      * owner to null. On these platforms, the obvious choice is to set the
2529      * focus owner to the focus proxy of the active Window.
2530      */
2531     static Window markClearGlobalFocusOwner() {
2532         // need to call this out of synchronized block to avoid possible deadlock
2533         // see 6454631.
2534         final Component nativeFocusedWindow =
2535                 getCurrentKeyboardFocusManager().getNativeFocusedWindow();
2536 


2888                 // If top-level changed there might be no focus request in a list
2889                 // But we know the opposite, we now it is temporary - dispatch the event.
2890                 if (!fe.isTemporary() && currentFocusOwner != null) {
2891                     // Create copy of the event with only difference in temporary parameter.
2892                     fe = new CausedFocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
2893                                               true, opposite, CausedFocusEvent.Cause.ACTIVATION);
2894                 }
2895                 return fe;
2896             }
2897 
2898             return retargetUnexpectedFocusEvent(fe);
2899         }  // end synchronized(heavyweightRequests)
2900     }
2901 
2902     static AWTEvent retargetFocusEvent(AWTEvent event) {
2903         if (clearingCurrentLightweightRequests) {
2904             return event;
2905         }
2906 
2907         KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
2908         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
2909             if (event instanceof FocusEvent || event instanceof WindowEvent) {
2910                 focusLog.finer(">>> {0}", String.valueOf(event));
2911             }
2912             if (focusLog.isLoggable(PlatformLogger.Level.FINER) && event instanceof KeyEvent) {
2913                 focusLog.finer("    focus owner is {0}",
2914                                String.valueOf(manager.getGlobalFocusOwner()));
2915                 focusLog.finer(">>> {0}", String.valueOf(event));
2916             }
2917         }
2918 
2919         synchronized(heavyweightRequests) {
2920             /*
2921              * This code handles FOCUS_LOST event which is generated by
2922              * DefaultKeyboardFocusManager for FOCUS_GAINED.
2923              *
2924              * This code based on knowledge of DefaultKeyboardFocusManager's
2925              * implementation and might be not applicable for another
2926              * KeyboardFocusManager.
2927              *
2928              * Fix for 4472032
2929              */
2930             if (newFocusOwner != null &&
2931                 event.getID() == FocusEvent.FOCUS_LOST)
2932             {


2979                 if (hwFocusRequest.lightweightRequests != null) {
2980                     for (Iterator lwIter = hwFocusRequest.lightweightRequests.
2981                              iterator();
2982                          lwIter.hasNext(); )
2983                     {
2984                         manager.dequeueKeyEvents
2985                             (-1, ((LightweightFocusRequest)lwIter.next()).
2986                              component);
2987                     }
2988                 }
2989             }
2990             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
2991             // We do it here because this method is called only when problems happen
2992             if (heavyweightRequests.size() == 0) {
2993                 manager.clearMarkers();
2994             }
2995             return (heavyweightRequests.size() > 0);
2996         }
2997     }
2998     static void removeLastFocusRequest(Component heavyweight) {
2999         if (log.isLoggable(PlatformLogger.Level.FINE)) {
3000             if (heavyweight == null) {
3001                 log.fine("Assertion (heavyweight != null) failed");
3002             }
3003         }
3004 
3005         KeyboardFocusManager manager =
3006             KeyboardFocusManager.getCurrentKeyboardFocusManager();
3007         synchronized(heavyweightRequests) {
3008             HeavyweightFocusRequest hwFocusRequest = getLastHWRequest();
3009             if (hwFocusRequest != null &&
3010                 hwFocusRequest.heavyweight == heavyweight) {
3011                 heavyweightRequests.removeLast();
3012             }
3013             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
3014             // We do it here because this method is called only when problems happen
3015             if (heavyweightRequests.size() == 0) {
3016                 manager.clearMarkers();
3017             }
3018         }
3019     }