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 }
|