59 import sun.awt.AppContext; |
59 import sun.awt.AppContext; |
60 import sun.awt.HeadlessToolkit; |
60 import sun.awt.HeadlessToolkit; |
61 import sun.awt.SunToolkit; |
61 import sun.awt.SunToolkit; |
62 import sun.awt.CausedFocusEvent; |
62 import sun.awt.CausedFocusEvent; |
63 import sun.awt.KeyboardFocusManagerPeerProvider; |
63 import sun.awt.KeyboardFocusManagerPeerProvider; |
|
64 import sun.awt.AWTAccessor; |
64 |
65 |
65 /** |
66 /** |
66 * The KeyboardFocusManager is responsible for managing the active and focused |
67 * The KeyboardFocusManager is responsible for managing the active and focused |
67 * Windows, and the current focus owner. The focus owner is defined as the |
68 * Windows, and the current focus owner. The focus owner is defined as the |
68 * Component in an application that will typically receive all KeyEvents |
69 * Component in an application that will typically receive all KeyEvents |
116 /* ensure that the necessary native libraries are loaded */ |
117 /* ensure that the necessary native libraries are loaded */ |
117 Toolkit.loadLibraries(); |
118 Toolkit.loadLibraries(); |
118 if (!GraphicsEnvironment.isHeadless()) { |
119 if (!GraphicsEnvironment.isHeadless()) { |
119 initIDs(); |
120 initIDs(); |
120 } |
121 } |
|
122 AWTAccessor.setKeyboardFocusManagerAccessor( |
|
123 new AWTAccessor.KeyboardFocusManagerAccessor() { |
|
124 public int shouldNativelyFocusHeavyweight(Component heavyweight, |
|
125 Component descendant, |
|
126 boolean temporary, |
|
127 boolean focusedWindowChangeAllowed, |
|
128 long time, |
|
129 CausedFocusEvent.Cause cause) |
|
130 { |
|
131 return KeyboardFocusManager.shouldNativelyFocusHeavyweight( |
|
132 heavyweight, descendant, temporary, focusedWindowChangeAllowed, time, cause); |
|
133 } |
|
134 public boolean processSynchronousLightweightTransfer(Component heavyweight, |
|
135 Component descendant, |
|
136 boolean temporary, |
|
137 boolean focusedWindowChangeAllowed, |
|
138 long time) |
|
139 { |
|
140 return KeyboardFocusManager.processSynchronousLightweightTransfer( |
|
141 heavyweight, descendant, temporary, focusedWindowChangeAllowed, time); |
|
142 } |
|
143 public void removeLastFocusRequest(Component heavyweight) { |
|
144 KeyboardFocusManager.removeLastFocusRequest(heavyweight); |
|
145 } |
|
146 } |
|
147 ); |
121 } |
148 } |
122 |
149 |
123 transient KeyboardFocusManagerPeer peer; |
150 transient KeyboardFocusManagerPeer peer; |
124 |
151 |
125 /** |
152 /** |
2441 focusLog.finest("5. SNFH_PROCEED for " + descendant); |
2468 focusLog.finest("5. SNFH_PROCEED for " + descendant); |
2442 return SNFH_SUCCESS_PROCEED; |
2469 return SNFH_SUCCESS_PROCEED; |
2443 } |
2470 } |
2444 } |
2471 } |
2445 } |
2472 } |
2446 static void heavyweightButtonDown(Component heavyweight, long time) { |
2473 |
2447 heavyweightButtonDown(heavyweight, time, false); |
|
2448 } |
|
2449 static void heavyweightButtonDown(Component heavyweight, long time, boolean acceptDuplicates) { |
|
2450 if (log.isLoggable(Level.FINE)) { |
|
2451 if (heavyweight == null) { |
|
2452 log.log(Level.FINE, "Assertion (heavyweight != null) failed"); |
|
2453 } |
|
2454 if (time == 0) { |
|
2455 log.log(Level.FINE, "Assertion (time != 0) failed"); |
|
2456 } |
|
2457 } |
|
2458 KeyboardFocusManager manager = getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(heavyweight)); |
|
2459 |
|
2460 synchronized (heavyweightRequests) { |
|
2461 HeavyweightFocusRequest hwFocusRequest = getLastHWRequest(); |
|
2462 Component currentNativeFocusOwner = (hwFocusRequest == null) |
|
2463 ? manager.getNativeFocusOwner() |
|
2464 : hwFocusRequest.heavyweight; |
|
2465 |
|
2466 // Behavior for all use cases: |
|
2467 // 1. Heavyweight leaf Components (e.g., Button, Checkbox, Choice, |
|
2468 // List, TextComponent, Canvas) that respond to button down. |
|
2469 // |
|
2470 // Native platform will generate a FOCUS_GAINED if and only if |
|
2471 // the Component is not the focus owner (or, will not be the |
|
2472 // focus owner when all outstanding focus requests are |
|
2473 // processed). |
|
2474 // |
|
2475 // 2. Panel with no descendants. |
|
2476 // |
|
2477 // Same as (1). |
|
2478 // |
|
2479 // 3. Panel with at least one heavyweight descendant. |
|
2480 // |
|
2481 // This function should NOT be called for this case! |
|
2482 // |
|
2483 // 4. Panel with only lightweight descendants. |
|
2484 // |
|
2485 // Native platform will generate a FOCUS_GAINED if and only if |
|
2486 // neither the Panel, nor any of its recursive, lightweight |
|
2487 // descendants, is the focus owner. However, we want a |
|
2488 // requestFocus() for any lightweight descendant to win out over |
|
2489 // the focus request for the Panel. To accomplish this, we |
|
2490 // differ from the algorithm for shouldNativelyFocusHeavyweight |
|
2491 // as follows: |
|
2492 // a. If the requestFocus() for a lightweight descendant has |
|
2493 // been fully handled by the time this function is invoked, |
|
2494 // then 'hwFocusRequest' will be null and 'heavyweight' |
|
2495 // will be the native focus owner. Do *not* synthesize a |
|
2496 // focus transfer to the Panel. |
|
2497 // b. If the requestFocus() for a lightweight descendant has |
|
2498 // been recorded, but not handled, then 'hwFocusRequest' |
|
2499 // will be non-null and 'hwFocusRequest.heavyweight' will |
|
2500 // equal 'heavyweight'. Do *not* append 'heavyweight' to |
|
2501 // hwFocusRequest.lightweightRequests. |
|
2502 // c. If the requestFocus() for a lightweight descendant is |
|
2503 // yet to be made, then post a new HeavyweightFocusRequest. |
|
2504 // If no lightweight descendant ever requests focus, then |
|
2505 // the Panel will get focus. If some descendant does, then |
|
2506 // the descendant will get focus by either a synthetic |
|
2507 // focus transfer, or a lightweightRequests focus transfer. |
|
2508 |
|
2509 if (acceptDuplicates || heavyweight != currentNativeFocusOwner) { |
|
2510 getCurrentKeyboardFocusManager |
|
2511 (SunToolkit.targetToAppContext(heavyweight)). |
|
2512 enqueueKeyEvents(time, heavyweight); |
|
2513 heavyweightRequests.add |
|
2514 (new HeavyweightFocusRequest(heavyweight, heavyweight, |
|
2515 false, CausedFocusEvent.Cause.MOUSE_EVENT)); |
|
2516 } |
|
2517 } |
|
2518 } |
|
2519 /** |
2474 /** |
2520 * Returns the Window which will be active after processing this request, |
2475 * Returns the Window which will be active after processing this request, |
2521 * or null if this is a duplicate request. The active Window is useful |
2476 * or null if this is a duplicate request. The active Window is useful |
2522 * because some native platforms do not support setting the native focus |
2477 * because some native platforms do not support setting the native focus |
2523 * owner to null. On these platforms, the obvious choice is to set the |
2478 * owner to null. On these platforms, the obvious choice is to set the |