mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-11 03:49:40 +01:00
Compare commits
275 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93588d0738 | ||
|
|
c8de1037d6 | ||
|
|
431c07ac57 | ||
|
|
13dffb3db5 | ||
|
|
2ac546b054 | ||
|
|
1dcc612a81 | ||
|
|
bfd01081c3 | ||
|
|
a7d486ca3d | ||
|
|
37e6e8e616 | ||
|
|
b4d4104e40 | ||
|
|
9b5cfa7ac2 | ||
|
|
499d9f8e49 | ||
|
|
fb5f776caf | ||
|
|
067d4d500d | ||
|
|
76a279920c | ||
|
|
d1dda7f5a6 | ||
|
|
4c1030df6f | ||
|
|
6ae43c6a0e | ||
|
|
7e34e95d11 | ||
|
|
332b9ab801 | ||
|
|
e0b84005e4 | ||
|
|
471cfeb793 | ||
|
|
94ab10baf3 | ||
|
|
d60f0153e7 | ||
|
|
2b6110f6e3 | ||
|
|
63ddfb5221 | ||
|
|
4d1ff852af | ||
|
|
7db2687b73 | ||
|
|
59f4085080 | ||
|
|
9b94493edd | ||
|
|
c47f2057c5 | ||
|
|
ba539e832c | ||
|
|
f7ba738641 | ||
|
|
c00eb55594 | ||
|
|
a275ab6f48 | ||
|
|
27de8b0ff6 | ||
|
|
5d9d0a9a75 | ||
|
|
18a8fd31e5 | ||
|
|
faf6484a2b | ||
|
|
b59a15193e | ||
|
|
81c4587cf7 | ||
|
|
7ca96684b5 | ||
|
|
55d40c666d | ||
|
|
bd0b236c4a | ||
|
|
5acffe72ad | ||
|
|
fd3ce84413 | ||
|
|
3a700c8e6b | ||
|
|
2247fa9602 | ||
|
|
79d5f9c769 | ||
|
|
e6584954f5 | ||
|
|
0478b4e54c | ||
|
|
308ba715a8 | ||
|
|
60a9d39d0e | ||
|
|
201bc8380c | ||
|
|
0ed41e9ef2 | ||
|
|
0e3a3cc87a | ||
|
|
b85ab67807 | ||
|
|
a30e884f47 | ||
|
|
77447ab9da | ||
|
|
d649015cab | ||
|
|
1408d4104c | ||
|
|
2bce0bab8a | ||
|
|
bbc63ddc5a | ||
|
|
1a1cf92ea6 | ||
|
|
b40243f499 | ||
|
|
27130a7ad2 | ||
|
|
efe3d8c9fa | ||
|
|
afa82f7acd | ||
|
|
c465836189 | ||
|
|
07cb8849b7 | ||
|
|
7dbbb71015 | ||
|
|
008119aa29 | ||
|
|
6ea789002e | ||
|
|
e005989a5f | ||
|
|
33f88d585e | ||
|
|
3438de2060 | ||
|
|
cf77ddd67d | ||
|
|
382c68f8b6 | ||
|
|
abadd05c98 | ||
|
|
b61d1ec0b2 | ||
|
|
667524ec99 | ||
|
|
c7bb9526c4 | ||
|
|
1984e4ea7f | ||
|
|
7c8bed75ad | ||
|
|
d8f671e3ee | ||
|
|
ba42c17ea7 | ||
|
|
ce82bfa392 | ||
|
|
2624b2a7d7 | ||
|
|
974a06e94c | ||
|
|
ad3b5d11d7 | ||
|
|
b71bcabdc5 | ||
|
|
977d41835c | ||
|
|
c630859af5 | ||
|
|
63720c9e21 | ||
|
|
c65f7c3364 | ||
|
|
a64f9674c9 | ||
|
|
e929f1d15e | ||
|
|
733e2667a3 | ||
|
|
0979251517 | ||
|
|
bdc30661cb | ||
|
|
e7fb17ebca | ||
|
|
ade01055d1 | ||
|
|
3396a75ca7 | ||
|
|
bd91605174 | ||
|
|
24d2a6fe28 | ||
|
|
bd2a53a105 | ||
|
|
6e2ff8055d | ||
|
|
cdbcb46437 | ||
|
|
2bb749dca2 | ||
|
|
535c3bd567 | ||
|
|
03dd08df32 | ||
|
|
c6c1be68b6 | ||
|
|
b5cf4ef17e | ||
|
|
38ee00073d | ||
|
|
a7735759aa | ||
|
|
beb4d8cd85 | ||
|
|
c0c32d8bfe | ||
|
|
93606dbe3f | ||
|
|
1080bdd980 | ||
|
|
b3e3c0b89d | ||
|
|
830e654595 | ||
|
|
47e3150fad | ||
|
|
39608ad69a | ||
|
|
76e123778d | ||
|
|
4f61ac98d5 | ||
|
|
90e76c380b | ||
|
|
85a088f9f1 | ||
|
|
381de93173 | ||
|
|
5d2684022e | ||
|
|
49c77556ab | ||
|
|
7970c912fa | ||
|
|
897fed57dd | ||
|
|
6a6ae5c6ed | ||
|
|
89ec9bc1e2 | ||
|
|
5404c7fe70 | ||
|
|
1315b55c19 | ||
|
|
3a9131614b | ||
|
|
d0b370c6b8 | ||
|
|
e7bb9fd8d7 | ||
|
|
dc43f7063d | ||
|
|
d7e1f938e7 | ||
|
|
ad56416ad9 | ||
|
|
50412155f9 | ||
|
|
3e47d86db7 | ||
|
|
871cb53015 | ||
|
|
a7c4f72f75 | ||
|
|
1ee8a9a528 | ||
|
|
56c4e379af | ||
|
|
0535ead40d | ||
|
|
c64efbc559 | ||
|
|
d6f04ca27b | ||
|
|
13af04a640 | ||
|
|
893f2d4fbc | ||
|
|
63895cc7cd | ||
|
|
592583006f | ||
|
|
31344224c6 | ||
|
|
15123efa60 | ||
|
|
760f73a671 | ||
|
|
923bef0b1e | ||
|
|
39cd51acab | ||
|
|
c7afe8d09b | ||
|
|
ace76c89eb | ||
|
|
641d5af861 | ||
|
|
808c4a4a73 | ||
|
|
ff2f0003c3 | ||
|
|
3cd3b00fb7 | ||
|
|
64fe99dbec | ||
|
|
17b9e61404 | ||
|
|
c0e32c3fca | ||
|
|
2c9e087a17 | ||
|
|
dba304d265 | ||
|
|
2022e3d2f2 | ||
|
|
1f7b350fe7 | ||
|
|
eadcad1393 | ||
|
|
ec4b14d493 | ||
|
|
298401f392 | ||
|
|
29eed33b90 | ||
|
|
6cc66f7ff5 | ||
|
|
f5c06010c4 | ||
|
|
293045e187 | ||
|
|
886f5885ff | ||
|
|
05703a8824 | ||
|
|
27738b9bc1 | ||
|
|
4dc032eb32 | ||
|
|
ceb27707a6 | ||
|
|
fcce5a2b3c | ||
|
|
27fce84573 | ||
|
|
b50153e0b1 | ||
|
|
32ba7b1af9 | ||
|
|
67c4fc1a4d | ||
|
|
e612e43ec0 | ||
|
|
07bf95c9ad | ||
|
|
eef3676722 | ||
|
|
15b77b797b | ||
|
|
5cb1684f14 | ||
|
|
0a087ecb13 | ||
|
|
9c693b5575 | ||
|
|
30b018b55c | ||
|
|
7840ab7e3d | ||
|
|
0a4ab7ae9a | ||
|
|
4a9b9ddd48 | ||
|
|
f4c17f8b6c | ||
|
|
b868dea5db | ||
|
|
f0a90c039a | ||
|
|
f4615088ac | ||
|
|
838eb2387f | ||
|
|
76c6dc4591 | ||
|
|
07161d961a | ||
|
|
1b113cbc3f | ||
|
|
2892ad6bc0 | ||
|
|
3ab381bd9b | ||
|
|
55b5776d7f | ||
|
|
37e13f2348 | ||
|
|
f5a8794c07 | ||
|
|
61b424d747 | ||
|
|
a8560f5352 | ||
|
|
641a44d288 | ||
|
|
b406b996f9 | ||
|
|
1f189822f0 | ||
|
|
deeaf56fa3 | ||
|
|
ed04be67c7 | ||
|
|
5d54d23310 | ||
|
|
1f320da262 | ||
|
|
3fb01ee26b | ||
|
|
b8fc7b2e91 | ||
|
|
b8add67ee4 | ||
|
|
b00ea1cfbc | ||
|
|
d597ddafbd | ||
|
|
6625f22474 | ||
|
|
01f4133f22 | ||
|
|
b7bd90fe90 | ||
|
|
e5c9468191 | ||
|
|
6bb87f14a8 | ||
|
|
57a8722fbe | ||
|
|
436382c220 | ||
|
|
a826a12210 | ||
|
|
e7daf93c85 | ||
|
|
282a9485b8 | ||
|
|
f265ba1086 | ||
|
|
6644278e8a | ||
|
|
87ca21711a | ||
|
|
ba81371932 | ||
|
|
2c3cdba88b | ||
|
|
dc7595ea2b | ||
|
|
2dfaf4d229 | ||
|
|
0036e174ad | ||
|
|
073f57ae6d | ||
|
|
290bc74830 | ||
|
|
f5f49b6e44 | ||
|
|
06383fee91 | ||
|
|
7b69e23a4f | ||
|
|
046a5eca42 | ||
|
|
08ab93fe2b | ||
|
|
86c315b268 | ||
|
|
95ffcc0b19 | ||
|
|
c43bcc5456 | ||
|
|
ff0303d69c | ||
|
|
230e3ce141 | ||
|
|
8c83c11efa | ||
|
|
f5d030fee1 | ||
|
|
902d29380e | ||
|
|
f31624f8c4 | ||
|
|
f754b686b5 | ||
|
|
639d675ba3 | ||
|
|
072ee00a51 | ||
|
|
90c1966233 | ||
|
|
9fdc75969b | ||
|
|
c2cdacaddd | ||
|
|
2e925883d5 | ||
|
|
a156c6b9bf | ||
|
|
75335543f2 | ||
|
|
c9143a3b22 | ||
|
|
8361529140 | ||
|
|
2988403307 | ||
|
|
43fdd6cd26 |
21
README.md
21
README.md
@@ -9,22 +9,11 @@ It includes a number enhancements in font rendering, HiDPI support, ligatures, p
|
||||
Download the latest releases of JetBrains Runtime to use with JetBrains IDEs. The full list
|
||||
can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntime/releases).
|
||||
|
||||
### For 2021.2 IDEs
|
||||
|
||||
| Release/tag | Date |
|
||||
| --- | --- |
|
||||
| [jb11_0_11-b1504.12](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_11-b1504.12) | 12-Jul-2021 |
|
||||
| [jb11_0_11-b1504.8](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_11-b1504.8) | 06-Jul-2021 |
|
||||
| [jb11_0_11-b1504.5](https://confluence.jetbrains.com/pages/viewpage.action?pageId=221478946) | 29-Jun-2021 |
|
||||
| [jb11_0_11-b1504.3](https://confluence.jetbrains.com/pages/viewpage.action?pageId=218857540) | 15-Jun-2021 |
|
||||
|
||||
### For 2020.3 IDEs
|
||||
|
||||
| Release/tag | Date |
|
||||
| --- | --- |
|
||||
| [jb11_0_11-b1145.115](https://confluence.jetbrains.com/pages/viewpage.action?pageId=219349001) | 21-Jun-2021 |
|
||||
| [jb11_0_11-b1145.96](https://confluence.jetbrains.com/pages/viewpage.action?pageId=207519955) | 18-Feb-2021 |
|
||||
| [jb11_0_11-b1145.77](https://confluence.jetbrains.com/pages/viewpage.action?pageId=205389940) | 19-Jan-2021 |
|
||||
| IDE Version | Latest JBR | Date Released |
|
||||
| --- | --- | --- |
|
||||
| 2021.2 | [11_0_11-b1504.13](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_11-b1504.13) | 19-Jul-2021 |
|
||||
| 2021.1 | [11.0.11+9-b1341.60](https://confluence.jetbrains.com/pages/viewpage.action?pageId=218857477) | 15-Jun-2021 |
|
||||
| 2020.3 | [11_0_11-b1145.115](https://confluence.jetbrains.com/pages/viewpage.action?pageId=219349001) | 21-Jun-2021 |
|
||||
|
||||
## Contents
|
||||
- [Welcome to JetBrains Runtime](#jetbrains-runtime)
|
||||
|
||||
@@ -230,8 +230,8 @@ class LIR_OprDesc: public CompilationResourceObj {
|
||||
, is_xmm_bits = 1
|
||||
, last_use_bits = 1
|
||||
, is_fpu_stack_offset_bits = 1 // used in assertion checking on x86 for FPU stack slot allocation
|
||||
, non_data_bits = kind_bits + type_bits + size_bits + destroys_bits + last_use_bits +
|
||||
is_fpu_stack_offset_bits + virtual_bits + is_xmm_bits
|
||||
, non_data_bits = pointer_bits + kind_bits + type_bits + size_bits + destroys_bits + virtual_bits
|
||||
+ is_xmm_bits + last_use_bits + is_fpu_stack_offset_bits
|
||||
, data_bits = BitsPerInt - non_data_bits
|
||||
, reg_bits = data_bits / 2 // for two registers in one value encoding
|
||||
};
|
||||
@@ -648,6 +648,11 @@ class LIR_OprFact: public AllStatic {
|
||||
#endif // X86
|
||||
|
||||
static LIR_Opr virtual_register(int index, BasicType type) {
|
||||
if (index > LIR_OprDesc::vreg_max) {
|
||||
// Running out of virtual registers. Caller should bailout.
|
||||
return illegalOpr;
|
||||
}
|
||||
|
||||
LIR_Opr res;
|
||||
switch (type) {
|
||||
case T_OBJECT: // fall through
|
||||
|
||||
@@ -1047,20 +1047,21 @@ void LIRGenerator::move_to_phi(ValueStack* cur_state) {
|
||||
|
||||
|
||||
LIR_Opr LIRGenerator::new_register(BasicType type) {
|
||||
int vreg = _virtual_register_number;
|
||||
// add a little fudge factor for the bailout, since the bailout is
|
||||
// only checked periodically. This gives a few extra registers to
|
||||
// hand out before we really run out, which helps us keep from
|
||||
// tripping over assertions.
|
||||
if (vreg + 20 >= LIR_OprDesc::vreg_max) {
|
||||
bailout("out of virtual registers");
|
||||
if (vreg + 2 >= LIR_OprDesc::vreg_max) {
|
||||
// wrap it around
|
||||
int vreg_num = _virtual_register_number;
|
||||
// Add a little fudge factor for the bailout since the bailout is only checked periodically. This allows us to hand out
|
||||
// a few extra registers before we really run out which helps to avoid to trip over assertions.
|
||||
if (vreg_num + 20 >= LIR_OprDesc::vreg_max) {
|
||||
bailout("out of virtual registers in LIR generator");
|
||||
if (vreg_num + 2 >= LIR_OprDesc::vreg_max) {
|
||||
// Wrap it around and continue until bailout really happens to avoid hitting assertions.
|
||||
_virtual_register_number = LIR_OprDesc::vreg_base;
|
||||
vreg_num = LIR_OprDesc::vreg_base;
|
||||
}
|
||||
}
|
||||
_virtual_register_number += 1;
|
||||
return LIR_OprFact::virtual_register(vreg, type);
|
||||
LIR_Opr vreg = LIR_OprFact::virtual_register(vreg_num, type);
|
||||
assert(vreg != LIR_OprFact::illegal(), "ran out of virtual registers");
|
||||
return vreg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3884,8 +3884,8 @@ void MoveResolver::insert_move(Interval* from_interval, Interval* to_interval) {
|
||||
assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first");
|
||||
assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");
|
||||
|
||||
LIR_Opr from_opr = LIR_OprFact::virtual_register(from_interval->reg_num(), from_interval->type());
|
||||
LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type());
|
||||
LIR_Opr from_opr = get_virtual_register(from_interval);
|
||||
LIR_Opr to_opr = get_virtual_register(to_interval);
|
||||
|
||||
if (!_multiple_reads_allowed) {
|
||||
// the last_use flag is an optimization for FPU stack allocation. When the same
|
||||
@@ -3903,12 +3903,27 @@ void MoveResolver::insert_move(LIR_Opr from_opr, Interval* to_interval) {
|
||||
assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first");
|
||||
assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");
|
||||
|
||||
LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type());
|
||||
LIR_Opr to_opr = get_virtual_register(to_interval);
|
||||
_insertion_buffer.move(_insert_idx, from_opr, to_opr);
|
||||
|
||||
TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: inserted move from constant "); from_opr->print(); tty->print_cr(" to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));
|
||||
}
|
||||
|
||||
LIR_Opr MoveResolver::get_virtual_register(Interval* interval) {
|
||||
// Add a little fudge factor for the bailout since the bailout is only checked periodically. This allows us to hand out
|
||||
// a few extra registers before we really run out which helps to avoid to trip over assertions.
|
||||
int reg_num = interval->reg_num();
|
||||
if (reg_num + 20 >= LIR_OprDesc::vreg_max) {
|
||||
_allocator->bailout("out of virtual registers in linear scan");
|
||||
if (reg_num + 2 >= LIR_OprDesc::vreg_max) {
|
||||
// Wrap it around and continue until bailout really happens to avoid hitting assertions.
|
||||
reg_num = LIR_OprDesc::vreg_base;
|
||||
}
|
||||
}
|
||||
LIR_Opr vreg = LIR_OprFact::virtual_register(reg_num, interval->type());
|
||||
assert(vreg != LIR_OprFact::illegal(), "ran out of virtual registers");
|
||||
return vreg;
|
||||
}
|
||||
|
||||
void MoveResolver::resolve_mappings() {
|
||||
TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: resolving mappings for Block B%d, index %d", _insert_list->block() != NULL ? _insert_list->block()->block_id() : -1, _insert_idx));
|
||||
|
||||
@@ -430,6 +430,7 @@ class MoveResolver: public StackObj {
|
||||
void append_insertion_buffer();
|
||||
void insert_move(Interval* from_interval, Interval* to_interval);
|
||||
void insert_move(LIR_Opr from_opr, Interval* to_interval);
|
||||
LIR_Opr get_virtual_register(Interval* interval);
|
||||
|
||||
DEBUG_ONLY(void verify_before_resolve();)
|
||||
void resolve_mappings();
|
||||
|
||||
@@ -934,7 +934,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
|
||||
int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
|
||||
getTarget(), lightweightChild, temporary,
|
||||
focusedWindowChangeAllowed, time, cause, false);
|
||||
focusedWindowChangeAllowed, time, cause, true);
|
||||
switch (result) {
|
||||
case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
|
||||
return false;
|
||||
@@ -968,15 +968,22 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
return false;
|
||||
}
|
||||
|
||||
return parentPeer.requestWindowFocus(cause, () -> {
|
||||
boolean res = parentPeer.requestWindowFocus(cause);
|
||||
// If parent window can be made focused and has been made focused (synchronously)
|
||||
// then we can proceed with children, otherwise we retreat
|
||||
if (!res || !parentWindow.isFocused()) {
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
focusLog.fine("request rejected, res= " + res + ", parentWindow.isFocused()=" +
|
||||
parentWindow.isFocused());
|
||||
}
|
||||
LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
|
||||
}, () -> {
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
return false;
|
||||
}
|
||||
|
||||
Component focusOwner = kfmPeer.getCurrentFocusOwner();
|
||||
LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
|
||||
getTarget(), false, cause, focusOwner);
|
||||
});
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
Component focusOwner = kfmPeer.getCurrentFocusOwner();
|
||||
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
|
||||
getTarget(), true, cause, focusOwner);
|
||||
|
||||
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
|
||||
return true;
|
||||
@@ -1342,7 +1349,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
|
||||
public Point windowToLocal(Point p, LWWindowPeer wp) {
|
||||
LWComponentPeer<?, ?> cp = this;
|
||||
while (cp != wp) {
|
||||
while (cp != wp && cp != null) {
|
||||
Rectangle cpb = cp.getBounds();
|
||||
p.x -= cpb.x;
|
||||
p.y -= cpb.y;
|
||||
|
||||
@@ -61,18 +61,18 @@ public class LWLightweightFramePeer extends LWWindowPeer implements OverrideNati
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestWindowFocus(FocusEvent.Cause cause, Runnable r, Runnable lightweightRequest) {
|
||||
public boolean requestWindowFocus(FocusEvent.Cause cause) {
|
||||
if (!focusAllowedFor()) {
|
||||
return false;
|
||||
}
|
||||
/*if (getPlatformWindow().rejectFocusRequest(cause)) {
|
||||
if (getPlatformWindow().rejectFocusRequest(cause)) {
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
|
||||
Window opposite = LWKeyboardFocusManagerPeer.getInstance().
|
||||
getCurrentFocusedWindow();
|
||||
|
||||
changeFocusedWindow(true, opposite, () -> {});
|
||||
changeFocusedWindow(true, opposite);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -290,24 +290,14 @@ public class LWWindowPeer
|
||||
if (!getTarget().isAutoRequestFocus()) {
|
||||
return;
|
||||
} else {
|
||||
requestWindowFocus(FocusEvent.Cause.ACTIVATION, () -> {}, () -> {});
|
||||
requestWindowFocus(FocusEvent.Cause.ACTIVATION);
|
||||
}
|
||||
// Focus the owner in case this window is focused.
|
||||
} else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
|
||||
// Transfer focus to the owner.
|
||||
Window targetOwner = LWWindowPeer.this.getTarget().getOwner();
|
||||
|
||||
while (targetOwner != null && (targetOwner.getOwner() != null && !targetOwner.isFocusableWindow())) {
|
||||
targetOwner = targetOwner.getOwner();
|
||||
}
|
||||
|
||||
if (targetOwner != null) {
|
||||
|
||||
LWWindowPeer owner = (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(targetOwner);
|
||||
|
||||
if (owner != null) {
|
||||
owner.requestWindowFocus(FocusEvent.Cause.ACTIVATION, () -> {}, () -> {});
|
||||
}
|
||||
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
|
||||
if (owner != null) {
|
||||
owner.requestWindowFocus(FocusEvent.Cause.ACTIVATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +775,7 @@ public class LWWindowPeer
|
||||
@Override
|
||||
public void notifyActivation(boolean activation, LWWindowPeer opposite) {
|
||||
Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
|
||||
changeFocusedWindow(activation, oppositeWindow, () -> {});
|
||||
changeFocusedWindow(activation, oppositeWindow);
|
||||
}
|
||||
|
||||
// MouseDown in non-client area
|
||||
@@ -902,7 +892,7 @@ public class LWWindowPeer
|
||||
// 2. An active but not focused owner frame/dialog is clicked.
|
||||
// The mouse event then will trigger a focus request "in window" to the component, so the window
|
||||
// should gain focus before.
|
||||
requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT, () -> {}, () -> {});
|
||||
requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT);
|
||||
|
||||
mouseDownTarget[targetIdx] = targetPeer;
|
||||
} else if (id == MouseEvent.MOUSE_DRAGGED) {
|
||||
@@ -1258,19 +1248,17 @@ public class LWWindowPeer
|
||||
* Requests platform to set native focus on a frame/dialog.
|
||||
* In case of a simple window, triggers appropriate java focus change.
|
||||
*/
|
||||
public boolean requestWindowFocus(FocusEvent.Cause cause, Runnable rejectFocusRequest, Runnable lightweightRequest) {
|
||||
public boolean requestWindowFocus(FocusEvent.Cause cause) {
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
focusLog.fine("requesting native focus to " + this);
|
||||
}
|
||||
|
||||
if (!focusAllowedFor()) {
|
||||
focusLog.fine("focus is not allowed");
|
||||
rejectFocusRequest.run();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (platformWindow.rejectFocusRequest(cause)) {
|
||||
rejectFocusRequest.run();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1285,19 +1273,13 @@ public class LWWindowPeer
|
||||
|
||||
// In case the toplevel is active but not focused, change focus directly,
|
||||
// as requesting native focus on it will not have effect.
|
||||
if (getTarget() == currentActive && !getTarget().isFocused()) {
|
||||
changeFocusedWindow(true, opposite, lightweightRequest);
|
||||
if (getTarget() == currentActive && !getTarget().hasFocus()) {
|
||||
|
||||
changeFocusedWindow(true, opposite);
|
||||
return true;
|
||||
}
|
||||
|
||||
focusLog.fine("platformWindow.requestWindowFocus()");
|
||||
boolean requestFocusResult = platformWindow.requestWindowFocus();
|
||||
|
||||
if (requestFocusResult) {
|
||||
lightweightRequest.run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return platformWindow.requestWindowFocus();
|
||||
}
|
||||
|
||||
protected boolean focusAllowedFor() {
|
||||
@@ -1325,7 +1307,7 @@ public class LWWindowPeer
|
||||
|
||||
@Override
|
||||
public void emulateActivation(boolean activate) {
|
||||
changeFocusedWindow(activate, null, () -> {});
|
||||
changeFocusedWindow(activate, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -1344,7 +1326,7 @@ public class LWWindowPeer
|
||||
/*
|
||||
* Changes focused window on java level.
|
||||
*/
|
||||
protected void changeFocusedWindow(boolean becomesFocused, Window opposite, Runnable lightweightRequestRunnable) {
|
||||
protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
|
||||
}
|
||||
@@ -1383,22 +1365,19 @@ public class LWWindowPeer
|
||||
}
|
||||
|
||||
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
|
||||
|
||||
if (!becomesFocused && kfmPeer.getCurrentFocusedWindow() != getTarget()) {
|
||||
// late window focus lost event - ingoring
|
||||
return;
|
||||
}
|
||||
|
||||
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
|
||||
|
||||
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
|
||||
WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());
|
||||
|
||||
SunToolkit.setSystemGenerated(windowEvent);
|
||||
AWTAccessor.getAWTEventAccessor().setPosted(windowEvent);
|
||||
PeerEvent pe = new PeerEvent(getTarget(), () -> {
|
||||
((Component)windowEvent.getSource()).dispatchEvent(windowEvent);
|
||||
if (becomesFocused) {
|
||||
lightweightRequestRunnable.run();
|
||||
}
|
||||
}, PeerEvent.ULTIMATE_PRIORITY_EVENT);
|
||||
|
||||
// TODO: wrap in SequencedEvent
|
||||
postEvent(pe);
|
||||
SunToolkit.postPriorityEvent(windowEvent);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1519,4 +1498,4 @@ public class LWWindowPeer
|
||||
}
|
||||
return handle[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
@@ -42,9 +43,11 @@ import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessController;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
@@ -69,11 +72,8 @@ import sun.lwawt.LWToolkit;
|
||||
import sun.lwawt.LWWindowPeer;
|
||||
import sun.lwawt.LWWindowPeer.PeerType;
|
||||
import sun.lwawt.PlatformWindow;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.security.AccessController;
|
||||
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
|
||||
|
||||
@@ -107,6 +107,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
private static native void nativeEnterFullScreenMode(long nsWindowPtr);
|
||||
private static native void nativeExitFullScreenMode(long nsWindowPtr);
|
||||
static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
|
||||
private static native boolean nativeDelayShowing(long nsWindowPtr);
|
||||
|
||||
// Loger to report issues happened during execution but that do not affect functionality
|
||||
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
|
||||
@@ -733,6 +734,16 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
private static LWWindowPeer getBlockerFor(Window window) {
|
||||
if (window != null) {
|
||||
ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(window);
|
||||
if (peer instanceof LWWindowPeer) {
|
||||
return ((LWWindowPeer)peer).getBlocker();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override // PlatformWindow
|
||||
public void setVisible(boolean visible) {
|
||||
// Configure stuff
|
||||
@@ -749,7 +760,17 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
// Actually show or hide the window
|
||||
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
|
||||
if (blocker == null || !visible) {
|
||||
if (visible && delayShowing()) {
|
||||
if (blocker == null) {
|
||||
Window focusedWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
|
||||
LWWindowPeer focusedWindowBlocker = getBlockerFor(focusedWindow);
|
||||
if (focusedWindowBlocker == peer) {
|
||||
// try to switch to target space if we're adding a modal dialog
|
||||
// that would block currently focused window
|
||||
owner.execute(CWrapper.NSWindow::orderFront);
|
||||
}
|
||||
}
|
||||
} else if (blocker == null || !visible) {
|
||||
// If it ain't blocked, or is being hidden, go regular way
|
||||
if (visible) {
|
||||
boolean isPopup = (target.getType() == Window.Type.POPUP);
|
||||
@@ -844,7 +865,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
// Manage parent-child relationship when showing
|
||||
final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
|
||||
|
||||
if (visible) {
|
||||
if (visible && !delayShowing()) {
|
||||
// Order myself above my parent
|
||||
if (owner != null && owner.isVisible()) {
|
||||
owner.execute(ownerPtr -> {
|
||||
@@ -876,7 +897,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
// Deal with the blocker of the window being shown
|
||||
if (blocker != null && visible) {
|
||||
// Make sure the blocker is above its siblings
|
||||
((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
|
||||
CPlatformWindow blockerWindow = (CPlatformWindow) blocker.getPlatformWindow();
|
||||
if (!blockerWindow.delayShowing()) {
|
||||
blockerWindow.orderAboveSiblings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,6 +935,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
@Override // PlatformWindow
|
||||
public void toFront() {
|
||||
if (delayShowing()) return;
|
||||
LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
|
||||
Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
||||
final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
|
||||
@@ -965,6 +990,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
@Override
|
||||
public boolean requestWindowFocus() {
|
||||
if (delayShowing()) return false;
|
||||
execute(ptr -> {
|
||||
if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
|
||||
CWrapper.NSWindow.makeMainWindow(ptr);
|
||||
@@ -983,6 +1009,17 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
// We want a window to be always shown at the same space as its owning window.
|
||||
// But macOS doesn't have an API to control the target space for a window -
|
||||
// it's always shown at the active space. So if the target space isn't active now,
|
||||
// the only way to achieve our goal seems to be delaying the appearance of the
|
||||
// window till the target space becomes active.
|
||||
private boolean delayShowing() {
|
||||
AtomicBoolean ref = new AtomicBoolean(false);
|
||||
execute(ptr -> ref.set(nativeDelayShowing(ptr)));
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFocusableWindowState() {
|
||||
setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, getFocusableStyleBits()); // set both bits at once
|
||||
@@ -1101,7 +1138,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
}
|
||||
nativeSetEnabled(ptr, !blocked);
|
||||
});
|
||||
checkBlockingAndOrder();
|
||||
}
|
||||
|
||||
public final void invalidateShadow() {
|
||||
@@ -1279,29 +1315,32 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
isFocusable ? focusableStyleBits : 0); // set both bits at once
|
||||
}
|
||||
|
||||
private boolean checkBlockingAndOrder() {
|
||||
private void checkBlockingAndOrder() {
|
||||
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
|
||||
if (blocker == null) {
|
||||
return false;
|
||||
// If it's not blocked, make sure it's above its siblings
|
||||
orderAboveSiblings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (blocker instanceof CPrinterDialogPeer) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
CPlatformWindow pWindow = (CPlatformWindow)blocker.getPlatformWindow();
|
||||
|
||||
pWindow.orderAboveSiblings();
|
||||
if (!pWindow.delayShowing()) {
|
||||
pWindow.orderAboveSiblings();
|
||||
|
||||
pWindow.execute(ptr -> {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("Focus blocker " + Long.toHexString(ptr));
|
||||
}
|
||||
CWrapper.NSWindow.orderFrontRegardless(ptr);
|
||||
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
|
||||
CWrapper.NSWindow.makeMainWindow(ptr);
|
||||
});
|
||||
return true;
|
||||
pWindow.execute(ptr -> {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("Focus blocker " + Long.toHexString(ptr));
|
||||
}
|
||||
CWrapper.NSWindow.orderFrontRegardless(ptr);
|
||||
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
|
||||
CWrapper.NSWindow.makeMainWindow(ptr);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIconified() {
|
||||
@@ -1363,7 +1402,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
if (p instanceof LWWindowPeer) {
|
||||
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
|
||||
iconified = isIconified();
|
||||
if (pw != null && pw.isVisible() && !iconified) {
|
||||
if (pw != null && pw.isVisible() && !iconified && !pw.delayShowing()) {
|
||||
// If the window is one of ancestors of 'main window' or is going to become main by itself,
|
||||
// the window should be ordered above its siblings; otherwise the window is just ordered
|
||||
// above its nearest parent.
|
||||
@@ -1435,9 +1474,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
private void windowDidBecomeMain() {
|
||||
lastBecomeMainTime = System.currentTimeMillis();
|
||||
if (checkBlockingAndOrder()) return;
|
||||
// If it's not blocked, make sure it's above its siblings
|
||||
orderAboveSiblings();
|
||||
checkBlockingAndOrder();
|
||||
}
|
||||
|
||||
private void windowWillEnterFullScreen() {
|
||||
|
||||
@@ -376,9 +376,10 @@ AWT_NS_WINDOW_IMPLEMENTATION
|
||||
|
||||
if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {
|
||||
if (IS(bits, FULLSCREENABLE)) {
|
||||
[self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
|
||||
[self.nsWindow setCollectionBehavior:
|
||||
NSWindowCollectionBehaviorFullScreenPrimary | NSWindowCollectionBehaviorManaged];
|
||||
} else {
|
||||
[self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];
|
||||
[self.nsWindow setCollectionBehavior: NSWindowCollectionBehaviorManaged];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,10 +442,6 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
self.ownerWindow = owner;
|
||||
[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
|
||||
|
||||
if (IS(self.styleBits, IS_POPUP)) {
|
||||
[self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
|
||||
}
|
||||
|
||||
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
|
||||
self.isEnterFullScreen = NO;
|
||||
self.isJustCreated = YES;
|
||||
@@ -601,6 +598,61 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
- (BOOL) delayShowing {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
return ownerWindow != nil && ([ownerWindow delayShowing] || !ownerWindow.nsWindow.onActiveSpace)
|
||||
&& !nsWindow.visible;
|
||||
}
|
||||
|
||||
- (void) checkBlockingAndOrder {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
||||
if (platformWindow != NULL) {
|
||||
static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
|
||||
"checkBlockingAndOrder", "()V");
|
||||
JNFCallVoidMethod(env, platformWindow, jm_checkBlockingAndOrder);
|
||||
(*env)->DeleteLocalRef(env, platformWindow);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)activeSpaceDidChange {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
for (NSWindow* window in [NSApp windows]) {
|
||||
if (window.onActiveSpace && window.mainWindow && [AWTWindow isJavaPlatformWindowVisible:window]) {
|
||||
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
|
||||
// there can be only one current blocker per window hierarchy,
|
||||
// so we're checking just hierarchy root
|
||||
if (awtWindow.ownerWindow == nil) {
|
||||
// this should ensure that delayed blocking windows
|
||||
// show up on space activation
|
||||
[awtWindow checkBlockingAndOrder];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) processVisibleChildren:(void(^)(AWTWindow*))action {
|
||||
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
|
||||
NSWindow *window;
|
||||
while ((window = [windowEnumerator nextObject]) != nil) {
|
||||
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
|
||||
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
|
||||
AWTWindow *parent = awtWindow.ownerWindow;
|
||||
while (parent != nil) {
|
||||
if (parent == self) {
|
||||
action(awtWindow);
|
||||
break;
|
||||
}
|
||||
parent = parent.ownerWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Orders window's childs based on the current focus state
|
||||
- (void) orderChildWindows:(BOOL)focus {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
@@ -610,37 +662,28 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
return;
|
||||
}
|
||||
|
||||
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
|
||||
NSWindow *window;
|
||||
while ((window = [windowEnumerator nextObject]) != nil) {
|
||||
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
|
||||
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
|
||||
AWTWindow *owner = awtWindow.ownerWindow;
|
||||
if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {
|
||||
// Do not order 'always on top' windows
|
||||
continue;
|
||||
[self processVisibleChildren:^void(AWTWindow* child){
|
||||
// Do not order 'always on top' windows
|
||||
if (!IS(child.styleBits, ALWAYS_ON_TOP)) {
|
||||
NSWindow *window = child.nsWindow;
|
||||
NSWindow *owner = child.ownerWindow.nsWindow;
|
||||
if (focus) {
|
||||
// Move the childWindow to floating level
|
||||
// so it will appear in front of its
|
||||
// parent which owns the focus
|
||||
[window setLevel:NSFloatingWindowLevel];
|
||||
} else {
|
||||
// Focus owner has changed, move the childWindow
|
||||
// back to normal window level
|
||||
[window setLevel:NSNormalWindowLevel];
|
||||
}
|
||||
while (awtWindow.ownerWindow != nil) {
|
||||
if (awtWindow.ownerWindow == self) {
|
||||
if (focus) {
|
||||
// Move the childWindow to floating level
|
||||
// so it will appear in front of its
|
||||
// parent which owns the focus
|
||||
[window setLevel:NSFloatingWindowLevel];
|
||||
} else {
|
||||
// Focus owner has changed, move the childWindow
|
||||
// back to normal window level
|
||||
[window setLevel:NSNormalWindowLevel];
|
||||
}
|
||||
// The childWindow should be displayed in front of
|
||||
// its nearest parentWindow
|
||||
[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
|
||||
break;
|
||||
}
|
||||
awtWindow = awtWindow.ownerWindow;
|
||||
if (window.onActiveSpace && owner.onActiveSpace) {
|
||||
// The childWindow should be displayed in front of
|
||||
// its nearest parentWindow
|
||||
[window orderWindow:NSWindowAbove relativeTo:[owner windowNumber]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
// NSWindow overrides
|
||||
@@ -668,14 +711,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
// We should bring up the modal dialog manually
|
||||
[AWTToolkit eventCountPlusPlus];
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
||||
if (platformWindow != NULL) {
|
||||
static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
|
||||
"checkBlockingAndOrder", "()Z");
|
||||
JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder);
|
||||
(*env)->DeleteLocalRef(env, platformWindow);
|
||||
}
|
||||
[self checkBlockingAndOrder];
|
||||
}
|
||||
|
||||
return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
|
||||
@@ -754,24 +790,14 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
- (void) iconifyChildWindows:(BOOL)iconify {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
|
||||
NSWindow *window;
|
||||
while ((window = [windowEnumerator nextObject]) != nil) {
|
||||
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
|
||||
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
|
||||
while (awtWindow.ownerWindow != nil) {
|
||||
if (awtWindow.ownerWindow == self) {
|
||||
if (iconify) {
|
||||
[window orderOut:window];
|
||||
} else {
|
||||
[window orderFront:window];
|
||||
}
|
||||
break;
|
||||
}
|
||||
awtWindow = awtWindow.ownerWindow;
|
||||
}
|
||||
[self processVisibleChildren:^void(AWTWindow* child){
|
||||
NSWindow *window = child.nsWindow;
|
||||
if (iconify) {
|
||||
[window orderOut:window];
|
||||
} else {
|
||||
[window orderFront:window];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) _deliverIconify:(BOOL)iconify {
|
||||
@@ -974,10 +1000,22 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
}
|
||||
}
|
||||
|
||||
// this is required to move owned windows to the full-screen space when owner goes to full-screen mode
|
||||
- (void)allowMovingChildrenBetweenSpaces:(BOOL)allow {
|
||||
[self processVisibleChildren:^void(AWTWindow* child){
|
||||
NSWindow *window = child.nsWindow;
|
||||
NSWindowCollectionBehavior behavior = window.collectionBehavior;
|
||||
behavior &= !(NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorTransient);
|
||||
behavior |= allow ? NSWindowCollectionBehaviorTransient : NSWindowCollectionBehaviorManaged;
|
||||
window.collectionBehavior = behavior;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
||||
self.isEnterFullScreen = YES;
|
||||
|
||||
|
||||
[self allowMovingChildrenBetweenSpaces:YES];
|
||||
|
||||
static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
||||
@@ -990,7 +1028,9 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
|
||||
self.isEnterFullScreen = YES;
|
||||
|
||||
|
||||
[self allowMovingChildrenBetweenSpaces:NO];
|
||||
|
||||
static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
|
||||
@@ -1805,3 +1845,25 @@ JNF_COCOA_ENTER(env);
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: nativeDelayShowing
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDelayShowing
|
||||
(JNIEnv *env, jclass clazz, jlong windowPtr)
|
||||
{
|
||||
__block jboolean result = JNI_FALSE;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
NSWindow *nsWindow = (NSWindow *)jlong_to_ptr(windowPtr);
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
|
||||
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
|
||||
result = [window delayShowing];
|
||||
}];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#import "CMenuBar.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "NSApplicationAWT.h"
|
||||
|
||||
#import "AWTWindow.h"
|
||||
|
||||
#pragma mark App Menu helpers
|
||||
|
||||
@@ -258,6 +258,11 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
[ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil];
|
||||
[ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil];
|
||||
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:[AWTWindow class]
|
||||
selector:@selector(activeSpaceDidChange)
|
||||
name:NSWorkspaceActiveSpaceDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
NSUInteger childIndex = [self columnNumberInTable];
|
||||
|
||||
int inc = [(JavaTableAccessibility *)[self accessibilityParent] accessibleColCount] * 2;
|
||||
NSInteger i = childIndex * 2;
|
||||
for(NSInteger i; i < arrayLen; i += inc)
|
||||
for(NSInteger i = childIndex * 2; i < arrayLen; i += inc)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
@@ -545,11 +545,6 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
return size;
|
||||
}
|
||||
|
||||
- (id)getFocusedElement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (jobject)accessible {
|
||||
return fAccessible;
|
||||
}
|
||||
@@ -590,13 +585,13 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
if (axAction != NULL) {
|
||||
JNF_CLASS_CACHE(jc_AccessibleAction, "javax/accessibility/AccessibleAction");
|
||||
JNF_MEMBER_CACHE(jm_getAccessibleActionCount, jc_AccessibleAction, "getAccessibleActionCount", "()I");
|
||||
jint count = JNFCallObjectMethod(env, axAction, jm_getAccessibleActionCount);
|
||||
jint count = JNFCallIntMethod(env, axAction, jm_getAccessibleActionCount);
|
||||
fActions = [[NSMutableDictionary alloc] initWithCapacity:count];
|
||||
fActionSElectors = [[NSMutableArray alloc] initWithCapacity:count];
|
||||
for (int i =0; i < count; i++) {
|
||||
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:i withComponent:fComponent];
|
||||
if ([fParent isKindOfClass:[JavaComponentAccessibility class]] &&
|
||||
[fParent isMenu] &&
|
||||
[(JavaComponentAccessibility *)fParent isMenu] &&
|
||||
[[sActions objectForKey:[action getDescription]] isEqualToString:NSAccessibilityPressAction]) {
|
||||
[fActions setObject:action forKey:NSAccessibilityPickAction];
|
||||
[fActionSElectors addObject:[sActionSelectores objectForKey:NSAccessibilityPickAction]];
|
||||
@@ -878,16 +873,16 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
// cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
|
||||
if (isVertical(env, axContext, fComponent)) {
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return NSAccessibilityVerticalOrientationValue;
|
||||
return NSAccessibilityOrientationVertical;
|
||||
}
|
||||
|
||||
if (isHorizontal(env, axContext, fComponent)) {
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return NSAccessibilityHorizontalOrientationValue;
|
||||
return NSAccessibilityOrientationHorizontal;
|
||||
}
|
||||
|
||||
(*env)->DeleteLocalRef(env, axContext);
|
||||
return nil;
|
||||
return NSAccessibilityOrientationUnknown;
|
||||
}
|
||||
|
||||
- (NSPoint)accessibilityActivationPoint
|
||||
|
||||
@@ -56,7 +56,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
|
||||
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
|
||||
if (row < 0) return nil;
|
||||
if (row < 0) return 0;
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
|
||||
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
|
||||
if (row < 0) return nil;
|
||||
if (row < 0) return 0;
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,10 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
|
||||
// NSAccessibilityElement protocol methods
|
||||
|
||||
- (NSAccessibilitySubrole)accessibilitySubrole {
|
||||
return NSAccessibilityTabButtonSubrole;
|
||||
if (@available(macOS 10.13, *)) {
|
||||
return NSAccessibilityTabButtonSubrole;
|
||||
}
|
||||
return NSAccessibilityUnknownSubrole;
|
||||
}
|
||||
|
||||
- (id)accessibilityValue {
|
||||
|
||||
@@ -35,9 +35,8 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
|
||||
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
|
||||
|
||||
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *)parent accessibleColCount];
|
||||
NSInteger i = childIndex * 2;
|
||||
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *)parent accessibleColCount] * 2;
|
||||
for(i; i < n; i+=2)
|
||||
for (NSInteger i = childIndex * 2; i < n; i+=2)
|
||||
{
|
||||
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
|
||||
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
|
||||
|
||||
@@ -663,6 +663,13 @@ public class Dialog extends Window {
|
||||
public Dialog(Window owner, String title, ModalityType modalityType) {
|
||||
super(owner);
|
||||
|
||||
if ((owner != null) &&
|
||||
!(owner instanceof Frame) &&
|
||||
!(owner instanceof Dialog))
|
||||
{
|
||||
throw new IllegalArgumentException("Wrong parent window");
|
||||
}
|
||||
|
||||
this.title = title;
|
||||
setModalityType(modalityType);
|
||||
SunToolkit.checkAndSetPolicy(this);
|
||||
|
||||
@@ -1071,7 +1071,13 @@ public class Window extends Container implements Accessible {
|
||||
} else {
|
||||
// fix for 6532736: after this window is shown, its blocker
|
||||
// should be raised to front
|
||||
modalBlocker.toFront_NoClientCode();
|
||||
boolean storedValue = modalBlocker.isAutoRequestFocus();
|
||||
modalBlocker.setAutoRequestFocus(false);
|
||||
try {
|
||||
modalBlocker.toFront_NoClientCode();
|
||||
} finally {
|
||||
modalBlocker.setAutoRequestFocus(storedValue);
|
||||
}
|
||||
}
|
||||
if (this instanceof Frame || this instanceof Dialog) {
|
||||
updateChildFocusableWindowState(this);
|
||||
|
||||
4068
test/hotspot/jtreg/compiler/c1/TestTooManyVirtualRegisters.jasm
Normal file
4068
test/hotspot/jtreg/compiler/c1/TestTooManyVirtualRegisters.jasm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8261235
|
||||
* @requires vm.compiler1.enabled
|
||||
* @summary Tests custom bytecode which requires too many virtual registers in the linear scan of C1.
|
||||
* The test should bail out in C1.
|
||||
*
|
||||
* @compile TestTooManyVirtualRegisters.jasm
|
||||
* @run main/othervm -Xbatch -XX:CompileCommand=dontinline,compiler.c1.TestExceptionBlockWithPredecessors::*
|
||||
* compiler.c1.TestTooManyVirtualRegistersMain
|
||||
*/
|
||||
|
||||
package compiler.c1;
|
||||
|
||||
public class TestTooManyVirtualRegistersMain {
|
||||
public static void main(String[] args) {
|
||||
for (char i = 0; i < 10000; i++) {
|
||||
TestTooManyVirtualRegisters.test(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3662 Focus jumps to another project tab after closing modal dialog
|
||||
* @key headful
|
||||
*/
|
||||
|
||||
public class WrongFrameFocusedOnModalDialogClosing {
|
||||
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
|
||||
private static CompletableFuture<Boolean> result;
|
||||
private static Robot robot;
|
||||
private static JFrame frame1;
|
||||
private static JFrame frame2;
|
||||
private static JButton button;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(WrongFrameFocusedOnModalDialogClosing::initUI);
|
||||
robot.delay(1000); // wait for frames to appear
|
||||
clickOn(button);
|
||||
dialogShown.get(5, TimeUnit.SECONDS);
|
||||
if (result.get(5, TimeUnit.SECONDS)) {
|
||||
throw new RuntimeException("Wrong frame focused");
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(WrongFrameFocusedOnModalDialogClosing::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame1 = new JFrame("WFFOMDC 1");
|
||||
frame1.addWindowFocusListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowGainedFocus(WindowEvent e) {
|
||||
if (result != null) result.complete(false);
|
||||
}
|
||||
});
|
||||
button = new JButton("Open dialog");
|
||||
button.addActionListener(e -> {
|
||||
JDialog d = new JDialog(frame1, true);
|
||||
d.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
result = new CompletableFuture<>();
|
||||
dialogShown.complete(true);
|
||||
d.dispose();
|
||||
}
|
||||
});
|
||||
d.setVisible(true);
|
||||
});
|
||||
frame1.add(button);
|
||||
frame1.setSize(100, 100);
|
||||
frame1.setLocation(100, 100);
|
||||
frame1.setVisible(true);
|
||||
|
||||
frame2 = new JFrame("WFFOMDC 2");
|
||||
frame2.addWindowFocusListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowGainedFocus(WindowEvent e) {
|
||||
if (result != null) result.complete(true);
|
||||
}
|
||||
});
|
||||
frame2.setSize(100, 100);
|
||||
frame2.setLocation(300, 100);
|
||||
frame2.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame1 != null) frame1.dispose();
|
||||
if (frame2 != null) frame2.dispose();
|
||||
}
|
||||
|
||||
private static void clickAt(int x, int y) {
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
|
||||
private static void clickOn(Component component) {
|
||||
Point location = component.getLocationOnScreen();
|
||||
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2000-2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3671 Window order changes for a background app on macOS desktop space switch
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
*/
|
||||
|
||||
public class BackgroundWindowOrderOnSpaceChange {
|
||||
private static Robot robot;
|
||||
private static JFrame frame1;
|
||||
private static JFrame frame2;
|
||||
private static Process otherProcess;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(BackgroundWindowOrderOnSpaceChange::initUI);
|
||||
launchProcessWithWindow();
|
||||
switchToNextSpace();
|
||||
switchToPreviousSpace();
|
||||
Color color = robot.getPixelColor(400, 400);
|
||||
if (!Color.green.equals(color)) {
|
||||
throw new RuntimeException("Frame 1 isn't shown on top. Found color: " + color);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
SwingUtilities.invokeAndWait(BackgroundWindowOrderOnSpaceChange::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame1 = new JFrame("BackgroundWindowOrderOnSpaceChange 1");
|
||||
frame1.getContentPane().setBackground(Color.green);
|
||||
frame1.setBounds(100, 100, 400, 400);
|
||||
frame1.setVisible(true);
|
||||
frame2 = new JFrame("BackgroundWindowOrderOnSpaceChange 2");
|
||||
frame2.getContentPane().setBackground(Color.red);
|
||||
frame2.setBounds(300, 300, 400, 400);
|
||||
frame2.setVisible(true);
|
||||
frame1.toFront();
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame1 != null) frame1.dispose();
|
||||
if (frame2 != null) frame2.dispose();
|
||||
if (otherProcess != null) otherProcess.destroyForcibly();
|
||||
}
|
||||
|
||||
private static void launchProcessWithWindow() throws Exception {
|
||||
String javaPath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
|
||||
File tmpFile = File.createTempFile("BackgroundWindowOrderOnSpaceChange", ".java");
|
||||
tmpFile.deleteOnExit();
|
||||
Files.writeString(tmpFile.toPath(), "import javax.swing.*;\n" +
|
||||
"import java.awt.event.*;\n" +
|
||||
"\n" +
|
||||
"public class TestWindow {\n" +
|
||||
" public static void main(String[] args) {\n" +
|
||||
" SwingUtilities.invokeLater(() -> {\n" +
|
||||
" JFrame f = new JFrame(\"BackgroundWindowOrderOnSpaceChange 3\");\n" +
|
||||
" f.addWindowFocusListener(new WindowAdapter() {\n" +
|
||||
" @Override\n" +
|
||||
" public void windowGainedFocus(WindowEvent e) {\n" +
|
||||
" System.out.println();\n" +
|
||||
" }\n" +
|
||||
" });\n" +
|
||||
" f.setBounds(800, 100, 200, 200);\n" +
|
||||
" f.setVisible(true);\n" +
|
||||
" });\n" +
|
||||
" }\n" +
|
||||
"}\n");
|
||||
otherProcess = Runtime.getRuntime().exec(new String[]{javaPath, tmpFile.getAbsolutePath()});
|
||||
if (otherProcess.getInputStream().read() == -1) {
|
||||
throw new RuntimeException("Error starting process");
|
||||
}
|
||||
}
|
||||
|
||||
private static void switchToPreviousSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
|
||||
private static void switchToNextSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_RIGHT);
|
||||
robot.keyRelease(KeyEvent.VK_RIGHT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
}
|
||||
129
test/jdk/jb/java/awt/Window/FullScreenChildWindow.java
Normal file
129
test/jdk/jb/java/awt/Window/FullScreenChildWindow.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.apple.eawt.Application;
|
||||
import com.apple.eawt.FullScreenAdapter;
|
||||
import com.apple.eawt.FullScreenUtilities;
|
||||
import com.apple.eawt.event.FullScreenEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3611 Unexpected workspace switch with dialog in full-screen mode on macOS
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/com.apple.eawt
|
||||
* java.desktop/com.apple.eawt.event
|
||||
*/
|
||||
|
||||
public class FullScreenChildWindow {
|
||||
private static final CompletableFuture<Boolean> shownAtFullScreen = new CompletableFuture<>();
|
||||
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
|
||||
|
||||
private static Robot robot;
|
||||
private static JFrame frame2;
|
||||
private static JFrame frame1;
|
||||
private static JButton button;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(FullScreenChildWindow::initUI);
|
||||
shownAtFullScreen.get(5, TimeUnit.SECONDS);
|
||||
clickAt(button);
|
||||
dialogShown.get(5, TimeUnit.SECONDS);
|
||||
switchToPreviousSpace();
|
||||
robot.delay(2000);
|
||||
if (!frame1.isFocused()) {
|
||||
throw new RuntimeException("Unexpected state");
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(FullScreenChildWindow::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame1 = new JFrame("FullScreenChildWindow(1)");
|
||||
frame1.setSize(100, 100);
|
||||
frame1.setLocation(100, 100);
|
||||
frame1.setVisible(true);
|
||||
|
||||
frame2 = new JFrame("FullScreenChildWindow(2)");
|
||||
button = new JButton("Open dialog");
|
||||
button.addActionListener(e -> {
|
||||
JDialog d = new JDialog(frame2, "dialog", false);
|
||||
d.setSize(100, 100);
|
||||
d.setLocationRelativeTo(null);
|
||||
d.setAutoRequestFocus(false);
|
||||
d.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
dialogShown.complete(true);
|
||||
}
|
||||
});
|
||||
d.setVisible(true);
|
||||
});
|
||||
frame2.add(button);
|
||||
frame2.setSize(100, 100);
|
||||
frame2.setLocation(100, 300);
|
||||
frame2.setVisible(true);
|
||||
FullScreenUtilities.addFullScreenListenerTo(frame2, new FullScreenAdapter() {
|
||||
@Override
|
||||
public void windowEnteredFullScreen(FullScreenEvent e) {
|
||||
shownAtFullScreen.complete(true);
|
||||
}
|
||||
});
|
||||
Application.getApplication().requestToggleFullScreen(frame2);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame2 != null) frame2.dispose();
|
||||
if (frame1 != null) frame1.dispose();
|
||||
}
|
||||
|
||||
private static void clickAt(int x, int y) {
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
|
||||
private static void clickAt(Component component) {
|
||||
Point location = component.getLocationOnScreen();
|
||||
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
|
||||
}
|
||||
|
||||
private static void switchToPreviousSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.apple.eawt.Application;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3666 Child window stays on default space
|
||||
* when full-screen mode is activated for parent window on macOS
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/com.apple.eawt
|
||||
*/
|
||||
|
||||
public class FullScreenChildWindowShownBefore {
|
||||
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
|
||||
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static JDialog dialog;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(FullScreenChildWindowShownBefore::initUI);
|
||||
dialogShown.get(5, TimeUnit.SECONDS);
|
||||
SwingUtilities.invokeAndWait(() -> Application.getApplication().requestToggleFullScreen(frame));
|
||||
robot.delay(1000); // wait for transition to full screen to finish
|
||||
ensureVisible(frame);
|
||||
ensureVisible(dialog);
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(FullScreenChildWindowShownBefore::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("FullScreenChildWindowShownBefore");
|
||||
frame.getContentPane().setBackground(Color.green);
|
||||
frame.setSize(100, 100);
|
||||
frame.setLocation(100, 100);
|
||||
frame.setVisible(true);
|
||||
|
||||
dialog = new JDialog(frame, false);
|
||||
dialog.getContentPane().setBackground(Color.red);
|
||||
dialog.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
dialogShown.complete(true);
|
||||
}
|
||||
});
|
||||
dialog.setSize(100, 100);
|
||||
dialog.setLocation(100, 300);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void ensureVisible(Window window) {
|
||||
Rectangle bounds = window.getBounds();
|
||||
Insets insets = window.getInsets();
|
||||
bounds.x += insets.left;
|
||||
bounds.y += insets.top;
|
||||
bounds.width -= insets.left + insets.right;
|
||||
bounds.height -= insets.top + insets.bottom;
|
||||
Color colorAtCenter = robot.getPixelColor((int) bounds.getCenterX(), (int) bounds.getCenterY());
|
||||
if (!colorAtCenter.equals(((RootPaneContainer)window).getContentPane().getBackground())) {
|
||||
throw new RuntimeException(window + " isn't visible: unexpected color " + colorAtCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
145
test/jdk/jb/java/awt/Window/FullScreenInactiveDialog.java
Normal file
145
test/jdk/jb/java/awt/Window/FullScreenInactiveDialog.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.apple.eawt.Application;
|
||||
import com.apple.eawt.FullScreenAdapter;
|
||||
import com.apple.eawt.FullScreenUtilities;
|
||||
import com.apple.eawt.event.FullScreenEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3633 Modal dialog is shown not at the same space as its parent
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/com.apple.eawt
|
||||
* java.desktop/com.apple.eawt.event
|
||||
*/
|
||||
|
||||
public class FullScreenInactiveDialog {
|
||||
private static final CompletableFuture<Boolean> shownAtFullScreen = new CompletableFuture<>();
|
||||
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static JDialog dialog;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(FullScreenInactiveDialog::initUI);
|
||||
shownAtFullScreen.get(5, TimeUnit.SECONDS);
|
||||
switchToPreviousSpace();
|
||||
SwingUtilities.invokeLater(FullScreenInactiveDialog::openDialog);
|
||||
robot.delay(1000);
|
||||
if (isWindowReallyShowing(dialog)) {
|
||||
throw new RuntimeException("Dialog is showing earlier than expected");
|
||||
}
|
||||
activateApp(); // simulates clicking on app icon in dock or switch using Cmd+Tab
|
||||
if (!isWindowReallyShowing(dialog)) {
|
||||
throw new RuntimeException("Dialog isn't showing when expected");
|
||||
}
|
||||
if (!isWindowReallyShowing(frame)) {
|
||||
throw new RuntimeException("Frame isn't showing when expected");
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(FullScreenInactiveDialog::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("FullScreenInactiveDialog");
|
||||
frame.setSize(300, 100);
|
||||
frame.setVisible(true);
|
||||
|
||||
|
||||
FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() {
|
||||
@Override
|
||||
public void windowEnteredFullScreen(FullScreenEvent e) {
|
||||
shownAtFullScreen.complete(true);
|
||||
}
|
||||
});
|
||||
Application.getApplication().requestToggleFullScreen(frame);
|
||||
}
|
||||
|
||||
private static void openDialog() {
|
||||
dialog = new JDialog(frame);
|
||||
dialog.setSize(100, 100);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void switchToPreviousSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
|
||||
private static void activateApp() {
|
||||
Desktop.getDesktop().requestForeground(false);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
|
||||
private static boolean isWindowReallyShowing(Window window) throws Exception {
|
||||
Point[] location = new Point[1];
|
||||
AtomicBoolean movementDetected = new AtomicBoolean();
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
if (window.isVisible()) {
|
||||
Rectangle bounds = window.getBounds();
|
||||
Insets insets = window.getInsets();
|
||||
bounds.x += insets.left;
|
||||
bounds.y += insets.top;
|
||||
bounds.width -= insets.left + insets.right;
|
||||
bounds.height -= insets.top + insets.bottom;
|
||||
if (!bounds.isEmpty()) {
|
||||
location[0] = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
|
||||
window.addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
movementDetected.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Point target = location[0];
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
robot.mouseMove(target.x, target.y);
|
||||
robot.delay(100);
|
||||
robot.mouseMove(target.x + 1, target.y + 1);
|
||||
robot.delay(1000);
|
||||
return movementDetected.get();
|
||||
}
|
||||
}
|
||||
145
test/jdk/jb/java/awt/Window/FullScreenInactiveModalDialog.java
Normal file
145
test/jdk/jb/java/awt/Window/FullScreenInactiveModalDialog.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2000-2021 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.apple.eawt.Application;
|
||||
import com.apple.eawt.FullScreenAdapter;
|
||||
import com.apple.eawt.FullScreenUtilities;
|
||||
import com.apple.eawt.event.FullScreenEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-3633 Modal dialog is shown not at the same space as its parent
|
||||
* @key headful
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/com.apple.eawt
|
||||
* java.desktop/com.apple.eawt.event
|
||||
*/
|
||||
|
||||
public class FullScreenInactiveModalDialog {
|
||||
private static final CompletableFuture<Boolean> shownAtFullScreen = new CompletableFuture<>();
|
||||
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static JDialog dialog;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(FullScreenInactiveModalDialog::initUI);
|
||||
shownAtFullScreen.get(5, TimeUnit.SECONDS);
|
||||
switchToPreviousSpace();
|
||||
SwingUtilities.invokeLater(FullScreenInactiveModalDialog::openDialog);
|
||||
robot.delay(1000);
|
||||
if (isWindowReallyShowing(dialog)) {
|
||||
throw new RuntimeException("Dialog is showing earlier than expected");
|
||||
}
|
||||
switchToNextSpace();
|
||||
if (!isWindowReallyShowing(dialog)) {
|
||||
throw new RuntimeException("Dialog isn't showing when expected");
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(FullScreenInactiveModalDialog::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("FullScreenInactiveModalDialog");
|
||||
frame.setSize(300, 100);
|
||||
frame.setVisible(true);
|
||||
|
||||
|
||||
FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() {
|
||||
@Override
|
||||
public void windowEnteredFullScreen(FullScreenEvent e) {
|
||||
shownAtFullScreen.complete(true);
|
||||
}
|
||||
});
|
||||
Application.getApplication().requestToggleFullScreen(frame);
|
||||
}
|
||||
|
||||
private static void openDialog() {
|
||||
dialog = new JDialog(frame, true);
|
||||
dialog.setSize(100, 100);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void switchToPreviousSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_LEFT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
|
||||
private static void switchToNextSpace() {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_RIGHT);
|
||||
robot.keyRelease(KeyEvent.VK_RIGHT);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(1000); // wait for animation to finish
|
||||
}
|
||||
|
||||
private static boolean isWindowReallyShowing(Window window) throws Exception {
|
||||
Point[] location = new Point[1];
|
||||
AtomicBoolean movementDetected = new AtomicBoolean();
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
if (window.isVisible()) {
|
||||
Rectangle bounds = window.getBounds();
|
||||
Insets insets = window.getInsets();
|
||||
bounds.x += insets.left;
|
||||
bounds.y += insets.top;
|
||||
bounds.width -= insets.left + insets.right;
|
||||
bounds.height -= insets.top + insets.bottom;
|
||||
if (!bounds.isEmpty()) {
|
||||
location[0] = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
|
||||
window.addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
movementDetected.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Point target = location[0];
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
robot.mouseMove(target.x, target.y);
|
||||
robot.delay(100);
|
||||
robot.mouseMove(target.x + 1, target.y + 1);
|
||||
robot.delay(1000);
|
||||
return movementDetected.get();
|
||||
}
|
||||
}
|
||||
@@ -1275,6 +1275,5 @@ jb/java/jcef/MouseEventTest.java
|
||||
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750 linux-all
|
||||
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTest.java nobug windows-6.1 not supported on Windows 7
|
||||
jb/java/awt/Focus/ChainOfPopupsFocusTest.java JBR-1518 linux-all
|
||||
jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-2768 macosx-all
|
||||
|
||||
java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java JBR-2842 macosx-10.14,macosx-10.15,macosx-10.16
|
||||
|
||||
@@ -211,7 +211,6 @@ jb/javax/swing/JDialog/JDialog705.java
|
||||
jb/javax/swing/JDialog/JDialog741/JDialog741.html nobug macosx-all,linux-all,windows-all
|
||||
jb/sun/awt/macos/KeyPressAndHoldTest.java nobug macosx-all
|
||||
jb/sun/lwawt/macosx/NSEvent/nsevent422.sh nobug macosx-all
|
||||
jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-2768 macosx-all
|
||||
|
||||
jb/java/jcef/MouseEventTest.java JBR-2750 linux-all
|
||||
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750 linux-all
|
||||
Reference in New Issue
Block a user