mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-08 09:31:42 +01:00
Compare commits
19 Commits
jbr17.878
...
mkartash/J
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c2694813a | ||
|
|
321f596b6f | ||
|
|
914b709227 | ||
|
|
166aaec4ee | ||
|
|
7c8f279144 | ||
|
|
4568e0f575 | ||
|
|
1c659bb0c6 | ||
|
|
d14715d9cb | ||
|
|
2fbcefc34d | ||
|
|
c3dff36d30 | ||
|
|
9186cd0af3 | ||
|
|
544c64bea6 | ||
|
|
66db1e3a7a | ||
|
|
1cb0c9e5f3 | ||
|
|
40f71a4331 | ||
|
|
de919cc050 | ||
|
|
420aa78847 | ||
|
|
bb5aaad31f | ||
|
|
e06fc3ca97 |
@@ -160,13 +160,19 @@ public final class UnixDomainSocketAddress extends SocketAddress {
|
||||
* @throws NullPointerException if path is {@code null}
|
||||
*/
|
||||
public static UnixDomainSocketAddress of(Path path) {
|
||||
FileSystem fs = path.getFileSystem();
|
||||
if (fs != FileSystems.getDefault()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (fs.getClass().getModule() != Object.class.getModule()) {
|
||||
throw new IllegalArgumentException();
|
||||
final FileSystem fs = path.getFileSystem();
|
||||
final FileSystem defaultFS = sun.nio.fs.DefaultFileSystemProvider.theFileSystem();
|
||||
if (fs != defaultFS || fs.getClass().getModule() != Object.class.getModule()) {
|
||||
try {
|
||||
// Check if we'll be able to create a socket from this Path later on by
|
||||
// testing for the presence of a method identical to
|
||||
// AbstractFileSystemProvider.getSunPathForSocketFile()
|
||||
fs.provider().getClass().getMethod("getSunPathForSocketFile", Path.class);
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
return new UnixDomainSocketAddress(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,8 +99,22 @@ class UnixDomainSockets {
|
||||
}
|
||||
|
||||
static byte[] getPathBytes(Path path) {
|
||||
FileSystemProvider provider = FileSystems.getDefault().provider();
|
||||
return ((AbstractFileSystemProvider) provider).getSunPathForSocketFile(path);
|
||||
java.nio.file.FileSystem fs = path.getFileSystem();
|
||||
FileSystemProvider provider = fs.provider();
|
||||
if (fs == sun.nio.fs.DefaultFileSystemProvider.theFileSystem()) {
|
||||
return ((AbstractFileSystemProvider) provider).getSunPathForSocketFile(path);
|
||||
} else {
|
||||
try {
|
||||
java.lang.reflect.Method method = provider.getClass().getMethod("getSunPathForSocketFile", Path.class);
|
||||
Object result = method.invoke(provider, path);
|
||||
return (byte[]) result;
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
// This should've been verified when UnixDomainSocketAddress was created
|
||||
throw new Error("Can't find getSunPathForSocketFile(Path) in the non-default file system provider " + provider.getClass());
|
||||
} catch (java.lang.reflect.InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Can't invoke getSunPathForSocketFile(Path) from a non-default file system provider", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor socket() throws IOException {
|
||||
@@ -140,7 +154,7 @@ class UnixDomainSockets {
|
||||
} catch (InvalidPathException e) {
|
||||
throw new BindException("Invalid temporary directory");
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new UnsupportedOperationException("Unix Domain Sockets not supported on non-default file system");
|
||||
throw new UnsupportedOperationException("Unix Domain Sockets not supported on non-default file system without method getSunPathForSocketFile(Path)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.awt.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.print.*;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
@@ -184,6 +185,15 @@ public final class CPrinterJob extends RasterPrinterJob {
|
||||
if (attributes == null) {
|
||||
return;
|
||||
}
|
||||
if (getPrintService() == null && isPrintToFile) {
|
||||
Destination destination = (Destination)attributes.get(Destination.class);
|
||||
if (destination != null) {
|
||||
try {
|
||||
destinationAttr = "" + new File(destination.getURI().getSchemeSpecificPart());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Attribute attr = attributes.get(Media.class);
|
||||
if (attr instanceof CustomMediaTray) {
|
||||
CustomMediaTray customTray = (CustomMediaTray) attr;
|
||||
|
||||
@@ -64,139 +64,140 @@ static struct _key
|
||||
{
|
||||
unsigned short keyCode;
|
||||
BOOL postsTyped;
|
||||
BOOL variesBetweenLayouts;
|
||||
jint javaKeyLocation;
|
||||
jint javaKeyCode;
|
||||
}
|
||||
const keyTable[] =
|
||||
{
|
||||
{0x00, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_A},
|
||||
{0x01, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_S},
|
||||
{0x02, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_D},
|
||||
{0x03, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_F},
|
||||
{0x04, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_H},
|
||||
{0x05, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_G},
|
||||
{0x06, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Z},
|
||||
{0x07, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_X},
|
||||
{0x08, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_C},
|
||||
{0x09, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_V},
|
||||
{0x0A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
|
||||
{0x0B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_B},
|
||||
{0x0C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Q},
|
||||
{0x0D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_W},
|
||||
{0x0E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_E},
|
||||
{0x0F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_R},
|
||||
{0x10, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Y},
|
||||
{0x11, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_T},
|
||||
{0x12, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_1},
|
||||
{0x13, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_2},
|
||||
{0x14, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_3},
|
||||
{0x15, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_4},
|
||||
{0x16, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_6},
|
||||
{0x17, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_5},
|
||||
{0x18, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_EQUALS},
|
||||
{0x19, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_9},
|
||||
{0x1A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_7},
|
||||
{0x1B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_MINUS},
|
||||
{0x1C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_8},
|
||||
{0x1D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_0},
|
||||
{0x1E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_CLOSE_BRACKET},
|
||||
{0x1F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_O},
|
||||
{0x20, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_U},
|
||||
{0x21, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_OPEN_BRACKET},
|
||||
{0x22, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_I},
|
||||
{0x23, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_P},
|
||||
{0x24, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x25, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_L},
|
||||
{0x26, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_J},
|
||||
{0x27, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_QUOTE},
|
||||
{0x28, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_K},
|
||||
{0x29, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SEMICOLON},
|
||||
{0x2A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH},
|
||||
{0x2B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_COMMA},
|
||||
{0x2C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SLASH},
|
||||
{0x2D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_N},
|
||||
{0x2E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_M},
|
||||
{0x2F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_PERIOD},
|
||||
{0x30, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_TAB},
|
||||
{0x31, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SPACE},
|
||||
{0x32, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
|
||||
{0x33, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SPACE},
|
||||
{0x34, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x35, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ESCAPE},
|
||||
{0x36, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x37, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_META}, // ****
|
||||
{0x38, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_SHIFT}, // ****
|
||||
{0x39, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_CAPS_LOCK},
|
||||
{0x3A, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_ALT}, // ****
|
||||
{0x3B, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_CONTROL}, // ****
|
||||
{0x3C, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x3D, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_ALT_GRAPH},
|
||||
{0x3E, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x3F, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED}, // the 'fn' key on PowerBooks
|
||||
{0x40, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F17},
|
||||
{0x41, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_DECIMAL},
|
||||
{0x42, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x43, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_MULTIPLY},
|
||||
{0x44, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x45, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ADD},
|
||||
{0x46, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x47, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_CLEAR},
|
||||
{0x48, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x49, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4A, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4B, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_DIVIDE},
|
||||
{0x4C, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x4D, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4E, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_SUBTRACT},
|
||||
{0x4F, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F18},
|
||||
{0x50, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F19},
|
||||
{0x51, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_EQUALS},
|
||||
{0x52, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD0},
|
||||
{0x53, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD1},
|
||||
{0x54, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD2},
|
||||
{0x55, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD3},
|
||||
{0x56, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD4},
|
||||
{0x57, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD5},
|
||||
{0x58, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD6},
|
||||
{0x59, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD7},
|
||||
{0x5A, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F20},
|
||||
{0x5B, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD8},
|
||||
{0x5C, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD9},
|
||||
{0x5D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH}, // This is a combo yen/backslash on JIS keyboards.
|
||||
{0x5E, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_UNDERSCORE},
|
||||
{0x5F, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_COMMA},
|
||||
{0x60, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F5},
|
||||
{0x61, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F6},
|
||||
{0x62, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F7},
|
||||
{0x63, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F3},
|
||||
{0x64, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F8},
|
||||
{0x65, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F9},
|
||||
{0x66, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_ALPHANUMERIC},
|
||||
{0x67, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F11},
|
||||
{0x68, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_KATAKANA},
|
||||
{0x69, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F13},
|
||||
{0x6A, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F16},
|
||||
{0x6B, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F14},
|
||||
{0x6C, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x6D, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F10},
|
||||
{0x6E, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x6F, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F12},
|
||||
{0x70, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x71, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F15},
|
||||
{0x72, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HELP},
|
||||
{0x73, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HOME},
|
||||
{0x74, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_UP},
|
||||
{0x75, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_DELETE},
|
||||
{0x76, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F4},
|
||||
{0x77, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_END},
|
||||
{0x78, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F2},
|
||||
{0x79, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_DOWN},
|
||||
{0x7A, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F1},
|
||||
{0x7B, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_LEFT},
|
||||
{0x7C, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_RIGHT},
|
||||
{0x7D, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_DOWN},
|
||||
{0x7E, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_UP},
|
||||
{0x7F, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x00, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_A},
|
||||
{0x01, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_S},
|
||||
{0x02, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_D},
|
||||
{0x03, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_F},
|
||||
{0x04, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_H},
|
||||
{0x05, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_G},
|
||||
{0x06, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Z},
|
||||
{0x07, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_X},
|
||||
{0x08, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_C},
|
||||
{0x09, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_V},
|
||||
{0x0A, YES, YES, KL_STANDARD, 0x1000000 + 0x00A7},
|
||||
{0x0B, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_B},
|
||||
{0x0C, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Q},
|
||||
{0x0D, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_W},
|
||||
{0x0E, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_E},
|
||||
{0x0F, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_R},
|
||||
{0x10, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Y},
|
||||
{0x11, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_T},
|
||||
{0x12, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_1},
|
||||
{0x13, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_2},
|
||||
{0x14, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_3},
|
||||
{0x15, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_4},
|
||||
{0x16, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_6},
|
||||
{0x17, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_5},
|
||||
{0x18, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_EQUALS},
|
||||
{0x19, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_9},
|
||||
{0x1A, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_7},
|
||||
{0x1B, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_MINUS},
|
||||
{0x1C, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_8},
|
||||
{0x1D, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_0},
|
||||
{0x1E, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_CLOSE_BRACKET},
|
||||
{0x1F, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_O},
|
||||
{0x20, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_U},
|
||||
{0x21, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_OPEN_BRACKET},
|
||||
{0x22, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_I},
|
||||
{0x23, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_P},
|
||||
{0x24, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x25, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_L},
|
||||
{0x26, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_J},
|
||||
{0x27, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_QUOTE},
|
||||
{0x28, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_K},
|
||||
{0x29, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SEMICOLON},
|
||||
{0x2A, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH},
|
||||
{0x2B, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_COMMA},
|
||||
{0x2C, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SLASH},
|
||||
{0x2D, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_N},
|
||||
{0x2E, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_M},
|
||||
{0x2F, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_PERIOD},
|
||||
{0x30, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_TAB},
|
||||
{0x31, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_SPACE},
|
||||
{0x32, YES, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
|
||||
{0x33, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SPACE},
|
||||
{0x34, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x35, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_ESCAPE},
|
||||
{0x36, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x37, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_META}, // ****
|
||||
{0x38, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_SHIFT}, // ****
|
||||
{0x39, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_CAPS_LOCK},
|
||||
{0x3A, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_ALT}, // ****
|
||||
{0x3B, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_CONTROL}, // ****
|
||||
{0x3C, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x3D, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_ALT_GRAPH},
|
||||
{0x3E, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x3F, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED}, // the 'fn' key on PowerBooks
|
||||
{0x40, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F17},
|
||||
{0x41, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_DECIMAL},
|
||||
{0x42, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x43, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_MULTIPLY},
|
||||
{0x44, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x45, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_ADD},
|
||||
{0x46, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x47, NO, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_CLEAR},
|
||||
{0x48, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x49, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4A, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4B, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_DIVIDE},
|
||||
{0x4C, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
|
||||
{0x4D, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x4E, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_SUBTRACT},
|
||||
{0x4F, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F18},
|
||||
{0x50, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F19},
|
||||
{0x51, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_EQUALS},
|
||||
{0x52, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD0},
|
||||
{0x53, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD1},
|
||||
{0x54, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD2},
|
||||
{0x55, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD3},
|
||||
{0x56, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD4},
|
||||
{0x57, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD5},
|
||||
{0x58, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD6},
|
||||
{0x59, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD7},
|
||||
{0x5A, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F20},
|
||||
{0x5B, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD8},
|
||||
{0x5C, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD9},
|
||||
{0x5D, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH}, // This is a combo yen/backslash on JIS keyboards.
|
||||
{0x5E, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_UNDERSCORE},
|
||||
{0x5F, YES, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_COMMA},
|
||||
{0x60, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F5},
|
||||
{0x61, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F6},
|
||||
{0x62, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F7},
|
||||
{0x63, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F3},
|
||||
{0x64, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F8},
|
||||
{0x65, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F9},
|
||||
{0x66, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_ALPHANUMERIC},
|
||||
{0x67, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F11},
|
||||
{0x68, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_KATAKANA},
|
||||
{0x69, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F13},
|
||||
{0x6A, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F16},
|
||||
{0x6B, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F14},
|
||||
{0x6C, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x6D, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F10},
|
||||
{0x6E, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x6F, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F12},
|
||||
{0x70, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
{0x71, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F15},
|
||||
{0x72, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HELP},
|
||||
{0x73, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HOME},
|
||||
{0x74, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_UP},
|
||||
{0x75, YES, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_DELETE},
|
||||
{0x76, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F4},
|
||||
{0x77, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_END},
|
||||
{0x78, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F2},
|
||||
{0x79, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_DOWN},
|
||||
{0x7A, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F1},
|
||||
{0x7B, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_LEFT},
|
||||
{0x7C, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_RIGHT},
|
||||
{0x7D, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_DOWN},
|
||||
{0x7E, NO, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_UP},
|
||||
{0x7F, NO, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -497,6 +498,7 @@ NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
|
||||
unichar *deadChar)
|
||||
{
|
||||
static const size_t keyTableSize = sizeof(keyTable) / sizeof(struct _key);
|
||||
|
||||
NSInteger offset;
|
||||
|
||||
// If the key without modifiers generates a dead char, then this is the character
|
||||
@@ -526,6 +528,24 @@ NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
|
||||
}
|
||||
}
|
||||
|
||||
if (key < keyTableSize) {
|
||||
// US physical key -> character mapping
|
||||
*postsTyped = keyTable[key].postsTyped;
|
||||
*keyCode = keyTable[key].javaKeyCode;
|
||||
*keyLocation = keyTable[key].javaKeyLocation;
|
||||
|
||||
if (!keyTable[key].variesBetweenLayouts) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Should we report this? This means we've got a keyboard
|
||||
// we don't know about...
|
||||
*postsTyped = NO;
|
||||
*keyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
|
||||
|
||||
// Whether this is a latin-based keyboard layout (English, German, French, etc)
|
||||
@@ -534,11 +554,17 @@ NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
|
||||
|
||||
unichar testLowercaseChar = tolower(ch);
|
||||
|
||||
if (useNationalLayouts && asciiCapable) {
|
||||
if (!useNationalLayouts || asciiCapable) {
|
||||
// If national layouts are enabled and the current keyboard is latin-based then
|
||||
// we try to look up a character in a table first, before falling back to looking up
|
||||
// the virtual key code from macOS's hardware key code, since hardware key codes
|
||||
// don't respect the specific keyboard layout the user uses.
|
||||
// The same happens when the national layouts are disabled to be consistent
|
||||
// with the default behavior of OpenJDK.
|
||||
|
||||
// Together with the following two checks (letters and digits) this table
|
||||
// properly handles all keys that have corresponding VK_ codes.
|
||||
// Unfortunately not all keys are like that. They are handled separately.
|
||||
|
||||
for (const struct CharToVKEntry *map = extraCharToVKTable; map->c != 0; ++map) {
|
||||
if (map->c == testLowercaseChar) {
|
||||
@@ -550,62 +576,43 @@ NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
|
||||
}
|
||||
}
|
||||
|
||||
if ((!useNationalLayouts || asciiCapable) && [[NSCharacterSet letterCharacterSet] characterIsMember:ch]) {
|
||||
// Let's convert the received letter to a key code.
|
||||
// If national layouts are enabled, then the letter must be (extended) latin.
|
||||
// Otherwise, we will look up the key code from the key location further down below.
|
||||
|
||||
// key is an alphabetic character
|
||||
offset = testLowercaseChar - 'a';
|
||||
if (offset >= 0 && offset <= 25) {
|
||||
// checking for A-Z characters
|
||||
*postsTyped = YES;
|
||||
// do quick conversion
|
||||
*keyCode = java_awt_event_KeyEvent_VK_A + offset;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
} else {
|
||||
// checking for non-english characters
|
||||
// this value comes from ExtendedKeyCodes.java
|
||||
offset += 0x01000000;
|
||||
*postsTyped = YES;
|
||||
// do quick conversion
|
||||
// the keyCode is off by 32, so adding it here
|
||||
*keyCode = java_awt_event_KeyEvent_VK_A + offset + 32;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
}
|
||||
|
||||
if (testLowercaseChar >= 'a' && testLowercaseChar <= 'z') {
|
||||
// key is a basic latin letter
|
||||
*postsTyped = YES;
|
||||
*keyCode = java_awt_event_KeyEvent_VK_A + testLowercaseChar - 'a';
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
return;
|
||||
}
|
||||
|
||||
if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:ch]) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
// key is a digit
|
||||
// numpad digits are already handled, since they don't vary between layouts
|
||||
offset = ch - '0';
|
||||
// make sure in range for decimal digits
|
||||
if (offset >= 0 && offset <= 9) {
|
||||
jboolean numpad = ((flags & NSNumericPadKeyMask) &&
|
||||
(key > 81 && key < 93));
|
||||
*postsTyped = YES;
|
||||
if (numpad) {
|
||||
*keyCode = offset + java_awt_event_KeyEvent_VK_NUMPAD0;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;
|
||||
} else {
|
||||
*keyCode = offset + java_awt_event_KeyEvent_VK_0;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
}
|
||||
return;
|
||||
}
|
||||
*keyCode = offset + java_awt_event_KeyEvent_VK_0;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
return;
|
||||
}
|
||||
|
||||
if (key < keyTableSize) {
|
||||
*postsTyped = keyTable[key].postsTyped;
|
||||
*keyCode = keyTable[key].javaKeyCode;
|
||||
*keyLocation = keyTable[key].javaKeyLocation;
|
||||
} else {
|
||||
// Should we report this? This means we've got a keyboard
|
||||
// we don't know about...
|
||||
*postsTyped = NO;
|
||||
*keyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
|
||||
BOOL isLetter = [[NSCharacterSet letterCharacterSet] characterIsMember:ch];
|
||||
BOOL needExtendedKeyCodeConversion = useNationalLayouts ? asciiCapable : isLetter;
|
||||
|
||||
if (needExtendedKeyCodeConversion) {
|
||||
// If useNationalLayouts = false, then we only convert the key codes for letters here.
|
||||
// This is the default behavior in OpenJDK and I don't think it's a good idea to change that.
|
||||
|
||||
// If useNationalLayouts = true but the keyboard is not ASCII-capable then this conversion
|
||||
// doesn't happen, meaning that key codes remain in the US layout.
|
||||
|
||||
// Otherwise we also need to report characters other than letters.
|
||||
// If we ended up in this branch, this means that the character doesn't have its own VK_ code.
|
||||
// Apart from letters, this is the case for characters like the Section Sign (U+00A7) on the
|
||||
// US ISO English keyboard or the Left-Pointing Double Angle Quotation Mark (U+00AB) found on the
|
||||
// Canadian French - PC (ISO) keyboard. I couldn't find examples of ANSI keyboards that have non-letter
|
||||
// characters that don't have a VK_ code.
|
||||
|
||||
*postsTyped = YES;
|
||||
*keyCode = 0x01000000 + testLowercaseChar;
|
||||
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -606,7 +606,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
[self setUpCustomTitleBar];
|
||||
}
|
||||
|
||||
self.currentDisplayID = nil;
|
||||
self.currentDisplayID = [AWTWindow getNSWindowDisplayID_AppKitThread:nsWindow];;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -969,8 +969,7 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
}
|
||||
|
||||
if (self.currentDisplayID == nil) {
|
||||
// Do not trigger notification at first appearance
|
||||
// to avoid flickering on popups
|
||||
// Do not trigger notification at first initialization
|
||||
self.currentDisplayID = newDisplayID;
|
||||
return;
|
||||
}
|
||||
@@ -1626,6 +1625,8 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
|
||||
self.customTitleBarHeightConstraint,
|
||||
]];
|
||||
|
||||
self.nsWindow.movable = NO;
|
||||
|
||||
AWTWindowDragView* windowDragView = [[AWTWindowDragView alloc] initWithPlatformWindow:self.javaPlatformWindow];
|
||||
[titlebar addSubview:windowDragView positioned:NSWindowBelow relativeTo:closeButtonView];
|
||||
|
||||
@@ -1712,6 +1713,8 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
|
||||
|
||||
[self setWindowControlsHidden:NO];
|
||||
[self updateCustomTitleBarInsets:NO];
|
||||
|
||||
self.nsWindow.movable = YES;
|
||||
}
|
||||
|
||||
- (void) setWindowControlsHidden: (BOOL) hidden
|
||||
@@ -1869,10 +1872,6 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
|
||||
return hitTest <= java_awt_Window_CustomTitleBar_HIT_TITLEBAR;
|
||||
}
|
||||
|
||||
- (BOOL) mouseDownCanMoveWindow {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstMouse:(NSEvent *)event {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import "JNIUtilities.h"
|
||||
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
#import "CRobotKeyCode.h"
|
||||
#import "LWCToolkit.h"
|
||||
@@ -333,7 +334,26 @@ Java_sun_lwawt_macosx_CRobot_keyEvent
|
||||
autoDelay(NO);
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGKeyCode keyCode = GetCGKeyCode(javaKeyCode);
|
||||
CGKeyCode keyCode;
|
||||
if (javaKeyCode == 0x1000000 + 0x0060) {
|
||||
// This is a dirty, dirty hack and is only used in tests.
|
||||
// When receiving this key code, Robot should switch the keyboard type to ISO
|
||||
// and then send the key code corresponding to VK_BACK_QUOTE.
|
||||
|
||||
// find an ISO keyboard type...
|
||||
// LMGetKbdType() returns Uint8, why don't we just iterate over all the possible values and find one
|
||||
// that works? It's really sad that macOS doesn't provide a decent API for this sort of thing.
|
||||
for (UInt32 keyboardType = 0; keyboardType < 0x100; ++keyboardType) {
|
||||
if (KBGetLayoutType(keyboardType) == kKeyboardISO) {
|
||||
CGEventSourceSetKeyboardType(source, keyboardType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
keyCode = OSX_kVK_ANSI_Grave;
|
||||
} else {
|
||||
keyCode = GetCGKeyCode(javaKeyCode);
|
||||
}
|
||||
CGEventRef event = CGEventCreateKeyboardEvent(source, keyCode, keyPressed);
|
||||
if (event != NULL) {
|
||||
// this assumes Robot isn't used to generate Fn key presses
|
||||
|
||||
@@ -160,6 +160,11 @@
|
||||
[NSNumber numberWithInt : OSX_F19], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F19],
|
||||
[NSNumber numberWithInt : OSX_F20], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F20],
|
||||
|
||||
// There's no VK_ key code for the section key (\u00a7), found on the Standard QWERTY (ABC) ISO layout.
|
||||
// For consistency, let's use the code returned by getExtendedKeyCodeForChar for this symbol.
|
||||
// Also see src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java
|
||||
[NSNumber numberWithInt : OSX_kVK_ISO_Section], [NSNumber numberWithInt : 0x1000000 + 0x00A7],
|
||||
|
||||
nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "MTLClip.h"
|
||||
#include "EncoderManager.h"
|
||||
#include "MTLSamplerManager.h"
|
||||
#import "MTLGlyphCache.h"
|
||||
|
||||
@class MTLStencilManager;
|
||||
@class MTLLayer;
|
||||
@@ -68,6 +69,16 @@
|
||||
@property (readonly) MTLTransform * transform;
|
||||
@property (readonly) MTLClip * clip;
|
||||
|
||||
/**
|
||||
* There are two separate glyph caches: for AA and for LCD.
|
||||
* Once one of them is initialized as either GRAY or LCD, it
|
||||
* stays in that mode for the duration of the MTLContext (it is not safe
|
||||
* to use this one glyph cache for all screens in a multi-monitor
|
||||
* environment)
|
||||
*/
|
||||
@property (readonly) MTLGlyphCache *glyphCacheLCD;
|
||||
@property (readonly) MTLGlyphCache *glyphCacheAA;
|
||||
|
||||
@property jint textureFunction;
|
||||
@property jboolean vertexCacheEnabled;
|
||||
@property jboolean aaEnabled;
|
||||
|
||||
@@ -181,6 +181,8 @@ extern void initSamplers(id<MTLDevice> device);
|
||||
CVDisplayLinkCreateWithCGDisplay(displayID, &_displayLink);
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, &mtlDisplayLinkCallback, (__bridge void *) self);
|
||||
}
|
||||
_glyphCacheLCD = [[MTLGlyphCache alloc] initWithContext:self];
|
||||
_glyphCacheAA = [[MTLGlyphCache alloc] initWithContext:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -191,6 +193,9 @@ extern void initSamplers(id<MTLDevice> device);
|
||||
// TODO : Check that texturePool is completely released.
|
||||
// texturePool content is released in MTLCommandBufferWrapper.onComplete()
|
||||
//self.texturePool = nil;
|
||||
[_glyphCacheLCD release];
|
||||
[_glyphCacheAA release];
|
||||
|
||||
self.vertexBuffer = nil;
|
||||
self.commandQueue = nil;
|
||||
self.pipelineStateStorage = nil;
|
||||
|
||||
@@ -35,12 +35,13 @@ extern "C" {
|
||||
#import <Metal/Metal.h>
|
||||
@class MTLContext;
|
||||
|
||||
typedef void (MTLFlushFunc)();
|
||||
typedef void (MTLFlushFunc)(MTLContext* mtlc);
|
||||
|
||||
typedef struct _MTLCacheCellInfo MTLCacheCellInfo;
|
||||
|
||||
typedef struct {
|
||||
MTLContext* mtlc;
|
||||
id<MTLRenderCommandEncoder> encoder;
|
||||
MTLCacheCellInfo *head;
|
||||
MTLCacheCellInfo *tail;
|
||||
id<MTLTexture> texture;
|
||||
@@ -72,26 +73,29 @@ struct _MTLCacheCellInfo {
|
||||
jfloat ty2;
|
||||
};
|
||||
|
||||
MTLGlyphCacheInfo *
|
||||
MTLGlyphCache_Init(MTLContext* mtlc, jint width, jint height,
|
||||
jint cellWidth, jint cellHeight, MTLFlushFunc *func);
|
||||
MTLCacheCellInfo *
|
||||
MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, struct GlyphInfo *glyph);
|
||||
bool
|
||||
MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph);
|
||||
void
|
||||
MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache);
|
||||
void
|
||||
MTLGlyphCache_AddCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo);
|
||||
void
|
||||
MTLGlyphCache_RemoveCellInfo(struct GlyphInfo *glyph, MTLCacheCellInfo *cellInfo);
|
||||
MTLCacheCellInfo *
|
||||
MTLGlyphCache_GetCellInfoForCache(struct GlyphInfo *glyph,
|
||||
MTLGlyphCacheInfo *cache);
|
||||
JNIEXPORT void
|
||||
MTLGlyphCache_RemoveAllCellInfos(struct GlyphInfo *glyph);
|
||||
void
|
||||
MTLGlyphCache_Free(MTLGlyphCacheInfo *cache);
|
||||
|
||||
@interface MTLGlyphCache : NSObject
|
||||
- (id)initWithContext:(MTLContext*)ctx;
|
||||
- (void) dealloc;
|
||||
- (BOOL) glyphCacheInitWidth:(jint)width
|
||||
height:(jint)height
|
||||
cellWidth:(jint)cellWidth
|
||||
cellHeight:(jint)cellHeight
|
||||
pixelFormat:(NSUInteger)pixelFormat
|
||||
func:(MTLFlushFunc*)func;
|
||||
- (MTLCacheCellInfo*) addGlyph:(GlyphInfo*)glyph;
|
||||
- (BOOL) isCacheFull:(GlyphInfo*)glyph;
|
||||
- (void) invalidate;
|
||||
- (void) free;
|
||||
|
||||
@property (readwrite) MTLGlyphCacheInfo *cacheInfo;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
*/
|
||||
#define TIMES_RENDERED_THRESHOLD 5
|
||||
|
||||
@implementation MTLGlyphCache {
|
||||
MTLContext* _ctx;
|
||||
}
|
||||
|
||||
- (id) initWithContext:(MTLContext*) ctx {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_ctx = ctx;
|
||||
_cacheInfo = NULL;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GlyphCacheInfo structure, fills in the initial values, and
|
||||
* then returns a pointer to the GlyphCacheInfo record.
|
||||
@@ -60,32 +73,40 @@
|
||||
* for retrieving cell info for the glyph, but instead just use the struct's
|
||||
* field directly.
|
||||
*/
|
||||
MTLGlyphCacheInfo *
|
||||
MTLGlyphCache_Init(MTLContext* mtlc, jint width, jint height,
|
||||
jint cellWidth, jint cellHeight,
|
||||
MTLFlushFunc *func)
|
||||
|
||||
- (BOOL) glyphCacheInitWidth:(jint)width
|
||||
height:(jint)height
|
||||
cellWidth:(jint)cellWidth
|
||||
cellHeight:(jint)cellHeight
|
||||
pixelFormat:(NSUInteger)pixelFormat
|
||||
func:(MTLFlushFunc *)func
|
||||
{
|
||||
MTLGlyphCacheInfo *gcinfo;
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.glyphCacheInitWidth");
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Init");
|
||||
|
||||
gcinfo = (MTLGlyphCacheInfo *)malloc(sizeof(MTLGlyphCacheInfo));
|
||||
if (gcinfo == NULL) {
|
||||
_cacheInfo = (MTLGlyphCacheInfo *)malloc(sizeof(MTLGlyphCacheInfo));
|
||||
if (_cacheInfo == NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
||||
"MTLGlyphCache_Init: could not allocate MTLGlyphCacheInfo");
|
||||
return NULL;
|
||||
"MTLGlyphCache.glyphCacheInitWidth: could not allocate MTLGlyphCacheInfo");
|
||||
return NO;
|
||||
}
|
||||
|
||||
gcinfo->head = NULL;
|
||||
gcinfo->tail = NULL;
|
||||
gcinfo->width = width;
|
||||
gcinfo->height = height;
|
||||
gcinfo->cellWidth = cellWidth;
|
||||
gcinfo->cellHeight = cellHeight;
|
||||
gcinfo->Flush = func;
|
||||
gcinfo->mtlc = mtlc;
|
||||
_cacheInfo->head = NULL;
|
||||
_cacheInfo->tail = NULL;
|
||||
_cacheInfo->width = width;
|
||||
_cacheInfo->height = height;
|
||||
_cacheInfo->cellWidth = cellWidth;
|
||||
_cacheInfo->cellHeight = cellHeight;
|
||||
_cacheInfo->Flush = func;
|
||||
_cacheInfo->mtlc = _ctx;
|
||||
_cacheInfo->encoder = nil;
|
||||
MTLTextureDescriptor *textureDescriptor =
|
||||
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat
|
||||
width:width
|
||||
height:height
|
||||
mipmapped:NO];
|
||||
_cacheInfo->texture = [_ctx.device newTextureWithDescriptor:textureDescriptor];
|
||||
|
||||
return gcinfo;
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,32 +125,31 @@ MTLGlyphCache_Init(MTLContext* mtlc, jint width, jint height,
|
||||
* Returns created cell info if it was successfully created and added to the
|
||||
* cache and glyph's cell lists, NULL otherwise.
|
||||
*/
|
||||
MTLCacheCellInfo *
|
||||
MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
|
||||
- (MTLCacheCellInfo*) addGlyph:(GlyphInfo*) glyph
|
||||
{
|
||||
MTLCacheCellInfo *cellinfo = NULL;
|
||||
jint w = glyph->width;
|
||||
jint h = glyph->height;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_AddGlyph");
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.addGlyph");
|
||||
|
||||
if ((glyph->width > cache->cellWidth) ||
|
||||
(glyph->height > cache->cellHeight))
|
||||
if ((glyph->width > _cacheInfo->cellWidth) ||
|
||||
(glyph->height > _cacheInfo->cellHeight))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jint x, y;
|
||||
|
||||
if (cache->head == NULL) {
|
||||
if (_cacheInfo->head == NULL) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
x = cache->tail->x + cache->cellWidth;
|
||||
y = cache->tail->y;
|
||||
if ((x + cache->cellWidth) > cache->width) {
|
||||
x = _cacheInfo->tail->x + _cacheInfo->cellWidth;
|
||||
y = _cacheInfo->tail->y;
|
||||
if ((x + _cacheInfo->cellWidth) > _cacheInfo->width) {
|
||||
x = 0;
|
||||
y += cache->cellHeight;
|
||||
y += _cacheInfo->cellHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,28 +160,28 @@ MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cellinfo->cacheInfo = cache;
|
||||
cellinfo->cacheInfo = _cacheInfo;
|
||||
cellinfo->glyphInfo = glyph;
|
||||
cellinfo->timesRendered = 0;
|
||||
cellinfo->x = x;
|
||||
cellinfo->y = y;
|
||||
cellinfo->leftOff = 0;
|
||||
cellinfo->rightOff = 0;
|
||||
cellinfo->tx1 = (jfloat)cellinfo->x / cache->width;
|
||||
cellinfo->ty1 = (jfloat)cellinfo->y / cache->height;
|
||||
cellinfo->tx2 = cellinfo->tx1 + ((jfloat)w / cache->width);
|
||||
cellinfo->ty2 = cellinfo->ty1 + ((jfloat)h / cache->height);
|
||||
cellinfo->tx1 = (jfloat)cellinfo->x / _cacheInfo->width;
|
||||
cellinfo->ty1 = (jfloat)cellinfo->y / _cacheInfo->height;
|
||||
cellinfo->tx2 = cellinfo->tx1 + ((jfloat)w / _cacheInfo->width);
|
||||
cellinfo->ty2 = cellinfo->ty1 + ((jfloat)h / _cacheInfo->height);
|
||||
|
||||
if (cache->head == NULL) {
|
||||
if (_cacheInfo->head == NULL) {
|
||||
// initialize the head cell
|
||||
cache->head = cellinfo;
|
||||
_cacheInfo->head = cellinfo;
|
||||
} else {
|
||||
// update existing tail cell
|
||||
cache->tail->next = cellinfo;
|
||||
_cacheInfo->tail->next = cellinfo;
|
||||
}
|
||||
|
||||
// add the new cell to the end of the list
|
||||
cache->tail = cellinfo;
|
||||
_cacheInfo->tail = cellinfo;
|
||||
cellinfo->next = NULL;
|
||||
cellinfo->nextGCI = NULL;
|
||||
|
||||
@@ -170,26 +190,24 @@ MTLGlyphCache_AddGlyph(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
|
||||
return cellinfo;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
|
||||
- (BOOL) isCacheFull:(GlyphInfo*) glyph
|
||||
{
|
||||
jint w = glyph->width;
|
||||
jint h = glyph->height;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_IsCacheFull");
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.isCacheFull");
|
||||
|
||||
jint x, y;
|
||||
|
||||
if (cache->head == NULL) {
|
||||
if (_cacheInfo->head == NULL) {
|
||||
return JNI_FALSE;
|
||||
} else {
|
||||
x = cache->tail->x + cache->cellWidth;
|
||||
y = cache->tail->y;
|
||||
if ((x + cache->cellWidth) > cache->width) {
|
||||
x = _cacheInfo->tail->x + _cacheInfo->cellWidth;
|
||||
y = _cacheInfo->tail->y;
|
||||
if ((x + _cacheInfo->cellWidth) > _cacheInfo->width) {
|
||||
x = 0;
|
||||
y += cache->cellHeight;
|
||||
if ((y + cache->cellHeight) > cache->height) {
|
||||
y += _cacheInfo->cellHeight;
|
||||
if ((y + _cacheInfo->cellHeight) > _cacheInfo->height) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
@@ -201,24 +219,23 @@ MTLGlyphCache_IsCacheFull(MTLGlyphCacheInfo *cache, GlyphInfo *glyph)
|
||||
* attempt to compact the cache in any way; it just invalidates any cells
|
||||
* that already exist.
|
||||
*/
|
||||
void
|
||||
MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache)
|
||||
- (void) invalidate
|
||||
{
|
||||
MTLCacheCellInfo *cellinfo;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Invalidate");
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.invalidate");
|
||||
|
||||
if (cache == NULL) {
|
||||
if (_cacheInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// flush any pending vertices that may be depending on the current
|
||||
// glyph cache layout
|
||||
if (cache->Flush != NULL) {
|
||||
cache->Flush();
|
||||
if (_cacheInfo->Flush != NULL) {
|
||||
_cacheInfo->Flush(_cacheInfo->mtlc);
|
||||
}
|
||||
|
||||
cellinfo = cache->head;
|
||||
cellinfo = _cacheInfo->head;
|
||||
while (cellinfo != NULL) {
|
||||
if (cellinfo->glyphInfo != NULL) {
|
||||
// if the cell is occupied, notify the base glyph that its
|
||||
@@ -233,36 +250,40 @@ MTLGlyphCache_Invalidate(MTLGlyphCacheInfo *cache)
|
||||
* Invalidates and frees all cells and the cache itself. The "cache" pointer
|
||||
* becomes invalid after this function returns.
|
||||
*/
|
||||
void
|
||||
MTLGlyphCache_Free(MTLGlyphCacheInfo *cache)
|
||||
- (void) free
|
||||
{
|
||||
MTLCacheCellInfo *cellinfo;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_Free");
|
||||
|
||||
if (cache == NULL) {
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.free");
|
||||
if (_cacheInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// flush any pending vertices that may be depending on the current
|
||||
// glyph cache
|
||||
if (cache->Flush != NULL) {
|
||||
cache->Flush();
|
||||
if (_cacheInfo->Flush != NULL) {
|
||||
_cacheInfo->Flush(_cacheInfo->mtlc);
|
||||
}
|
||||
[_cacheInfo->texture release];
|
||||
|
||||
while (cache->head != NULL) {
|
||||
cellinfo = cache->head;
|
||||
while (_cacheInfo->head != NULL) {
|
||||
MTLCacheCellInfo *cellinfo = _cacheInfo->head;
|
||||
if (cellinfo->glyphInfo != NULL) {
|
||||
// if the cell is occupied, notify the base glyph that its
|
||||
// cached version for this cache is about to be invalidated
|
||||
MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
|
||||
}
|
||||
cache->head = cellinfo->next;
|
||||
_cacheInfo->head = cellinfo->next;
|
||||
free(cellinfo);
|
||||
}
|
||||
free(cache);
|
||||
free(_cacheInfo);
|
||||
_cacheInfo = NULL;
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
[self free];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
/**
|
||||
* Add cell info to the head of the glyph's list of cached cells.
|
||||
*/
|
||||
@@ -310,57 +331,4 @@ MTLGlyphCache_RemoveCellInfo(GlyphInfo *glyph, MTLCacheCellInfo *cellInfo)
|
||||
J2dTraceLn2(J2D_TRACE_WARNING, "MTLGlyphCache_RemoveCellInfo: "\
|
||||
"no cell 0x%x in glyph 0x%x's cell list",
|
||||
cellInfo, glyph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes cell info from the glyph's list of cached cells.
|
||||
*/
|
||||
JNIEXPORT void
|
||||
MTLGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph)
|
||||
{
|
||||
MTLCacheCellInfo *currCell, *prevCell;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache_RemoveAllCellInfos");
|
||||
|
||||
if (glyph == NULL || glyph->cellInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// invalidate all of this glyph's accelerated cache cells
|
||||
currCell = glyph->cellInfo;
|
||||
do {
|
||||
currCell->glyphInfo = NULL;
|
||||
prevCell = currCell;
|
||||
currCell = currCell->nextGCI;
|
||||
prevCell->nextGCI = NULL;
|
||||
} while (currCell != NULL);
|
||||
|
||||
glyph->cellInfo = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cell info associated with particular cache from the glyph's list of
|
||||
* cached cells.
|
||||
*/
|
||||
MTLCacheCellInfo *
|
||||
MTLGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, MTLGlyphCacheInfo *cache)
|
||||
{
|
||||
// assert (glyph != NULL && cache != NULL)
|
||||
J2dTraceLn(J2D_TRACE_VERBOSE2, "MTLGlyphCache_GetCellInfoForCache");
|
||||
|
||||
if (glyph->cellInfo != NULL) {
|
||||
MTLCacheCellInfo *cellInfo = glyph->cellInfo;
|
||||
do {
|
||||
if (cellInfo->cacheInfo == cache) {
|
||||
J2dTraceLn3(J2D_TRACE_VERBOSE2,
|
||||
" glyph 0x%x: found cell 0x%x for cache 0x%x",
|
||||
glyph, cellInfo, cache);
|
||||
return cellInfo;
|
||||
}
|
||||
cellInfo = cellInfo->nextGCI;
|
||||
} while (cellInfo != NULL);
|
||||
}
|
||||
J2dTraceLn2(J2D_TRACE_VERBOSE2, " glyph 0x%x: no cell for cache 0x%x",
|
||||
glyph, cache);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -591,6 +591,8 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
jlong pDst = NEXT_LONG(b);
|
||||
|
||||
if (mtlc != NULL) {
|
||||
[mtlc.glyphCacheAA free];
|
||||
[mtlc.glyphCacheLCD free];
|
||||
[mtlc commitCommandBuffer:isSyncSurfacesEnabled() display:NO];
|
||||
}
|
||||
mtlc = [MTLContext setSurfacesEnv:env src:pSrc dst:pDst];
|
||||
@@ -604,16 +606,18 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
MTLGraphicsConfigInfo *mtlInfo =
|
||||
(MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
|
||||
|
||||
if (mtlInfo != NULL) {
|
||||
MTLContext *newMtlc = mtlInfo->context;
|
||||
if (newMtlc != NULL) {
|
||||
if (mtlc != NULL) {
|
||||
[mtlc commitCommandBuffer:NO display:NO];
|
||||
}
|
||||
mtlc = newMtlc;
|
||||
dstOps = NULL;
|
||||
}
|
||||
if (mtlc != NULL) {
|
||||
[mtlc.glyphCacheAA free];
|
||||
[mtlc.glyphCacheLCD free];
|
||||
[mtlc commitCommandBuffer:NO display:NO];
|
||||
}
|
||||
|
||||
if (mtlInfo != NULL) {
|
||||
mtlc = mtlInfo->context;
|
||||
} else {
|
||||
mtlc = NULL;
|
||||
}
|
||||
dstOps = NULL;
|
||||
break;
|
||||
}
|
||||
case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
|
||||
@@ -623,8 +627,8 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);
|
||||
if (mtlsdo != NULL) {
|
||||
CONTINUE_IF_NULL(mtlc);
|
||||
MTLTR_FreeGlyphCacheAA();
|
||||
MTLTR_FreeGlyphCacheLCD();
|
||||
[mtlc.glyphCacheAA free];
|
||||
[mtlc.glyphCacheLCD free];
|
||||
MTLSD_Delete(env, mtlsdo);
|
||||
}
|
||||
break;
|
||||
@@ -648,8 +652,8 @@ Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
|
||||
CHECK_PREVIOUS_OP(MTL_OP_OTHER);
|
||||
jlong pConfigInfo = NEXT_LONG(b);
|
||||
CONTINUE_IF_NULL(mtlc);
|
||||
MTLTR_FreeGlyphCacheAA();
|
||||
MTLTR_FreeGlyphCacheLCD();
|
||||
[mtlc.glyphCacheAA free];
|
||||
[mtlc.glyphCacheLCD free];
|
||||
[mtlc.encoderManager endEncoder];
|
||||
MTLGC_DestroyMTLGraphicsConfig(pConfigInfo);
|
||||
mtlc = NULL;
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
|
||||
void MTLTR_EnableGlyphVertexCache(MTLContext *mtlc, BMTLSDOps *dstOps);
|
||||
void MTLTR_DisableGlyphVertexCache(MTLContext *mtlc);
|
||||
id<MTLTexture> MTLTR_GetGlyphCacheTexture();
|
||||
id<MTLRenderCommandEncoder> MTLTR_GetGlyphCacheEncoder();
|
||||
void MTLTR_FreeGlyphCacheAA();
|
||||
void MTLTR_FreeGlyphCacheLCD();
|
||||
|
||||
void MTLTR_DrawGlyphList(JNIEnv *env, MTLContext *mtlc, BMTLSDOps *dstOps,
|
||||
jint totalGlyphs, jboolean usePositions,
|
||||
|
||||
@@ -66,19 +66,6 @@ typedef enum {
|
||||
} GlyphMode;
|
||||
static GlyphMode glyphMode = MODE_NOT_INITED;
|
||||
|
||||
/**
|
||||
* There are two separate glyph caches: for AA and for LCD.
|
||||
* Once one of them is initialized as either GRAY or LCD, it
|
||||
* stays in that mode for the duration of the application. It should
|
||||
* be safe to use this one glyph cache for all screens in a multimon
|
||||
* environment, since the glyph cache texture is shared between all contexts,
|
||||
* and (in theory) Metal drivers should be smart enough to manage that
|
||||
* texture across all screens.
|
||||
*/
|
||||
|
||||
static MTLGlyphCacheInfo *glyphCacheLCD = NULL;
|
||||
static MTLGlyphCacheInfo *glyphCacheAA = NULL;
|
||||
|
||||
/**
|
||||
* This value tracks the previous LCD rgbOrder setting, so if the rgbOrder
|
||||
* value has changed since the last time, it indicates that we need to
|
||||
@@ -98,8 +85,6 @@ static jboolean lastRGBOrder = JNI_TRUE;
|
||||
|
||||
static struct TxtVertex txtVertices[6];
|
||||
static jint vertexCacheIndex = 0;
|
||||
static id<MTLRenderCommandEncoder> aaCacheEncoder = nil;
|
||||
static id<MTLRenderCommandEncoder> lcdCacheEncoder = nil;
|
||||
|
||||
#define LCD_ADD_VERTEX(TX, TY, DX, DY, DZ) \
|
||||
do { \
|
||||
@@ -127,88 +112,28 @@ static id<MTLRenderCommandEncoder> lcdCacheEncoder = nil;
|
||||
* as intensity values.
|
||||
*/
|
||||
static jboolean
|
||||
MTLTR_InitGlyphCache(MTLContext *mtlc, BMTLSDOps *dstOps, jboolean lcdCache)
|
||||
MTLTR_ValidateGlyphCache(MTLContext *mtlc, BMTLSDOps *dstOps, jboolean lcdCache)
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_InitGlyphCache");
|
||||
// TODO : Need to verify RGB order in case of LCD
|
||||
MTLPixelFormat pixelFormat =
|
||||
lcdCache ? MTLPixelFormatBGRA8Unorm : MTLPixelFormatA8Unorm;
|
||||
|
||||
MTLGlyphCacheInfo *gcinfo;
|
||||
// init glyph cache data structure
|
||||
gcinfo = MTLGlyphCache_Init(mtlc, MTLTR_CACHE_WIDTH,
|
||||
MTLTR_CACHE_HEIGHT,
|
||||
MTLTR_CACHE_CELL_WIDTH,
|
||||
MTLTR_CACHE_CELL_HEIGHT,
|
||||
MTLVertexCache_FlushGlyphVertexCache);
|
||||
|
||||
if (gcinfo == NULL) {
|
||||
MTLGlyphCache* glyphCache = (lcdCache)?mtlc.glyphCacheLCD:mtlc.glyphCacheAA;
|
||||
if (glyphCache.cacheInfo == NULL && ![glyphCache glyphCacheInitWidth:MTLTR_CACHE_WIDTH
|
||||
height:MTLTR_CACHE_HEIGHT
|
||||
cellWidth:MTLTR_CACHE_CELL_WIDTH
|
||||
cellHeight:MTLTR_CACHE_CELL_HEIGHT
|
||||
pixelFormat:(lcdCache)?MTLPixelFormatBGRA8Unorm:MTLPixelFormatA8Unorm
|
||||
func:MTLVertexCache_FlushGlyphVertexCache])
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
||||
"MTLTR_InitGlyphCache: could not init MTL glyph cache");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
MTLTextureDescriptor *textureDescriptor =
|
||||
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat
|
||||
width:MTLTR_CACHE_WIDTH
|
||||
height:MTLTR_CACHE_HEIGHT
|
||||
mipmapped:NO];
|
||||
|
||||
gcinfo->texture = [mtlc.device newTextureWithDescriptor:textureDescriptor];
|
||||
|
||||
if (lcdCache) {
|
||||
glyphCacheLCD = gcinfo;
|
||||
} else {
|
||||
glyphCacheAA = gcinfo;
|
||||
}
|
||||
|
||||
glyphCache.cacheInfo->encoder = (lcdCache)?
|
||||
[mtlc.encoderManager getLCDEncoder:dstOps->pTexture isSrcOpaque:YES isDstOpaque:YES]:
|
||||
[mtlc.encoderManager getTextEncoder:dstOps isSrcOpaque:NO gammaCorrection:YES];
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static jboolean
|
||||
MTLTR_ValidateGlyphCache(MTLContext *mtlc, BMTLSDOps *dstOps, jboolean lcdCache)
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_ValidateGlyphCache");
|
||||
if (lcdCache) {
|
||||
if (glyphCacheLCD == NULL && !MTLTR_InitGlyphCache(mtlc, dstOps, JNI_TRUE)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
lcdCacheEncoder = [mtlc.encoderManager getLCDEncoder:dstOps->pTexture
|
||||
isSrcOpaque:YES
|
||||
isDstOpaque:YES];
|
||||
} else {
|
||||
if (glyphCacheAA == NULL && !MTLTR_InitGlyphCache(mtlc, dstOps, JNI_FALSE)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
aaCacheEncoder = [mtlc.encoderManager getTextEncoder:dstOps
|
||||
isSrcOpaque:NO
|
||||
gammaCorrection:YES];
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
id<MTLRenderCommandEncoder>
|
||||
MTLTR_GetGlyphCacheEncoder()
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_GetGlyphCacheEncoder");
|
||||
if (glyphCacheAA != NULL) {
|
||||
return aaCacheEncoder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id<MTLTexture>
|
||||
MTLTR_GetGlyphCacheTexture()
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_GetGlyphCacheTexture");
|
||||
if (glyphCacheAA != NULL) {
|
||||
return glyphCacheAA->texture;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given glyph to the glyph cache (texture and data structure)
|
||||
* associated with the given MTLContext.
|
||||
@@ -218,32 +143,30 @@ MTLTR_AddToGlyphCache(GlyphInfo *glyph, MTLContext *mtlc,
|
||||
BMTLSDOps *dstOps, jboolean lcdCache)
|
||||
{
|
||||
MTLCacheCellInfo *ccinfo;
|
||||
MTLGlyphCacheInfo *gcinfo;
|
||||
MTLGlyphCache* gc;
|
||||
jint w = glyph->width;
|
||||
jint h = glyph->height;
|
||||
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_AddToGlyphCache");
|
||||
if (!lcdCache) {
|
||||
gcinfo = glyphCacheAA;
|
||||
gc = mtlc.glyphCacheAA;
|
||||
} else {
|
||||
gcinfo = glyphCacheLCD;
|
||||
gc = mtlc.glyphCacheLCD;
|
||||
}
|
||||
|
||||
if ((gcinfo == NULL) || (glyph->image == NULL)) {
|
||||
if ((gc.cacheInfo == NULL) || (glyph->image == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isCacheFull = MTLGlyphCache_IsCacheFull(gcinfo, glyph);
|
||||
if (isCacheFull) {
|
||||
if ([gc isCacheFull:glyph]) {
|
||||
if (lcdCache) {
|
||||
MTLTR_FreeGlyphCacheLCD();
|
||||
[mtlc.glyphCacheLCD free];
|
||||
} else {
|
||||
MTLTR_FreeGlyphCacheAA();
|
||||
[mtlc.glyphCacheAA free];
|
||||
}
|
||||
MTLTR_ValidateGlyphCache(mtlc, dstOps, lcdCache);
|
||||
gcinfo = lcdCache ? glyphCacheLCD : glyphCacheAA;
|
||||
}
|
||||
MTLGlyphCache_AddGlyph(gcinfo, glyph);
|
||||
[gc addGlyph:glyph];
|
||||
ccinfo = (MTLCacheCellInfo *) glyph->cellInfo;
|
||||
|
||||
if (ccinfo != NULL) {
|
||||
@@ -254,7 +177,7 @@ MTLTR_AddToGlyphCache(GlyphInfo *glyph, MTLContext *mtlc,
|
||||
};
|
||||
if (!lcdCache) {
|
||||
NSUInteger bytesPerRow = 1 * w;
|
||||
[gcinfo->texture replaceRegion:region
|
||||
[gc.cacheInfo->texture replaceRegion:region
|
||||
mipmapLevel:0
|
||||
withBytes:glyph->image
|
||||
bytesPerRow:bytesPerRow];
|
||||
@@ -273,7 +196,7 @@ MTLTR_AddToGlyphCache(GlyphInfo *glyph, MTLContext *mtlc,
|
||||
}
|
||||
|
||||
NSUInteger bytesPerRow = 4 * w;
|
||||
[gcinfo->texture replaceRegion:region
|
||||
[gc.cacheInfo->texture replaceRegion:region
|
||||
mipmapLevel:0
|
||||
withBytes:imageData
|
||||
bytesPerRow:bytesPerRow];
|
||||
@@ -335,28 +258,10 @@ void
|
||||
MTLTR_DisableGlyphVertexCache(MTLContext *mtlc)
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DisableGlyphVertexCache");
|
||||
MTLVertexCache_FlushGlyphVertexCache();
|
||||
MTLVertexCache_FlushGlyphVertexCache(mtlc);
|
||||
MTLVertexCache_FreeVertexCache();
|
||||
}
|
||||
|
||||
void MTLTR_FreeGlyphCacheAA() {
|
||||
if (glyphCacheAA != NULL) {
|
||||
id<MTLTexture> txt = glyphCacheAA->texture;
|
||||
MTLGlyphCache_Free(glyphCacheAA);
|
||||
[txt release];
|
||||
glyphCacheAA = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MTLTR_FreeGlyphCacheLCD() {
|
||||
if (glyphCacheLCD != NULL) {
|
||||
id<MTLTexture> txt = glyphCacheLCD->texture;
|
||||
MTLGlyphCache_Free(glyphCacheLCD);
|
||||
[txt release];
|
||||
glyphCacheLCD = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static MTLPaint* storedPaint = nil;
|
||||
|
||||
static void EnableColorGlyphPainting(MTLContext *mtlc) {
|
||||
@@ -443,7 +348,7 @@ MTLTR_DrawLCDGlyphViaCache(MTLContext *mtlc, BMTLSDOps *dstOps,
|
||||
if (rgbOrder != lastRGBOrder) {
|
||||
// need to invalidate the cache in this case; see comments
|
||||
// for lastRGBOrder above
|
||||
MTLGlyphCache_Invalidate(glyphCacheLCD);
|
||||
[mtlc.glyphCacheLCD invalidate];
|
||||
lastRGBOrder = rgbOrder;
|
||||
}
|
||||
|
||||
@@ -463,7 +368,7 @@ MTLTR_DrawLCDGlyphViaCache(MTLContext *mtlc, BMTLSDOps *dstOps,
|
||||
cell = (MTLCacheCellInfo *) (ginfo->cellInfo);
|
||||
cell->timesRendered++;
|
||||
|
||||
MTLTR_SetLCDContrast(mtlc, contrast, lcdCacheEncoder);
|
||||
MTLTR_SetLCDContrast(mtlc, contrast, mtlc.glyphCacheLCD.cacheInfo->encoder);
|
||||
tx1 = cell->tx1;
|
||||
ty1 = cell->ty1;
|
||||
tx2 = cell->tx2;
|
||||
@@ -474,11 +379,11 @@ MTLTR_DrawLCDGlyphViaCache(MTLContext *mtlc, BMTLSDOps *dstOps,
|
||||
|
||||
LCD_ADD_TRIANGLES(tx1, ty1, tx2, ty2, x, y, x+w, y+h);
|
||||
|
||||
[lcdCacheEncoder setVertexBytes:txtVertices length:sizeof(txtVertices) atIndex:MeshVertexBuffer];
|
||||
[lcdCacheEncoder setFragmentTexture:glyphCacheLCD->texture atIndex:0];
|
||||
[lcdCacheEncoder setFragmentTexture:dstOps->pTexture atIndex:1];
|
||||
[mtlc.glyphCacheLCD.cacheInfo->encoder setVertexBytes:txtVertices length:sizeof(txtVertices) atIndex:MeshVertexBuffer];
|
||||
[mtlc.glyphCacheLCD.cacheInfo->encoder setFragmentTexture:mtlc.glyphCacheLCD.cacheInfo->texture atIndex:0];
|
||||
[mtlc.glyphCacheLCD.cacheInfo->encoder setFragmentTexture:dstOps->pTexture atIndex:1];
|
||||
|
||||
[lcdCacheEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
|
||||
[mtlc.glyphCacheLCD.cacheInfo->encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
|
||||
|
||||
vertexCacheIndex = 0;
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
*/
|
||||
jboolean MTLVertexCache_InitVertexCache();
|
||||
void MTLVertexCache_FlushVertexCache(MTLContext *mtlc);
|
||||
void MTLVertexCache_FlushGlyphVertexCache();
|
||||
void MTLVertexCache_FlushGlyphVertexCache(MTLContext *mtlc);
|
||||
void MTLVertexCache_FreeVertexCache();
|
||||
|
||||
void MTLVertexCache_EnableMaskCache(MTLContext *mtlc, BMTLSDOps *dstOps);
|
||||
|
||||
@@ -109,15 +109,15 @@ MTLVertexCache_FlushVertexCache(MTLContext *mtlc)
|
||||
}
|
||||
|
||||
void
|
||||
MTLVertexCache_FlushGlyphVertexCache()
|
||||
MTLVertexCache_FlushGlyphVertexCache(MTLContext *mtlc)
|
||||
{
|
||||
J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushGlyphVertexCache");
|
||||
|
||||
if (vertexCacheIndex > 0) {
|
||||
id<MTLRenderCommandEncoder> gcEncoder = MTLTR_GetGlyphCacheEncoder();
|
||||
if (vertexCacheIndex > 0 && mtlc.glyphCacheAA.cacheInfo != NULL) {
|
||||
id<MTLRenderCommandEncoder> gcEncoder = mtlc.glyphCacheAA.cacheInfo->encoder;
|
||||
[gcEncoder setVertexBytes: vertexCache length:vertexCacheIndex * sizeof(J2DVertex)
|
||||
atIndex:MeshVertexBuffer];
|
||||
id<MTLTexture> glyphCacheTex = MTLTR_GetGlyphCacheTexture();
|
||||
id<MTLTexture> glyphCacheTex = mtlc.glyphCacheAA.cacheInfo->texture;
|
||||
[gcEncoder setFragmentTexture:glyphCacheTex atIndex: 0];
|
||||
J2dTraceLn1(J2D_TRACE_INFO,
|
||||
"MTLVertexCache_FlushGlyphVertexCache : encode %d characters", (vertexCacheIndex / 6));
|
||||
@@ -319,7 +319,7 @@ MTLVertexCache_AddGlyphQuad(MTLContext *mtlc,
|
||||
if ((vertexCacheIndex + MTL_TRIS_IN_VERTEX) >= MTLVC_MAX_INDEX)
|
||||
{
|
||||
J2dTraceLn2(J2D_TRACE_INFO, "maskCacheIndex = %d, vertexCacheIndex = %d", maskCacheIndex, vertexCacheIndex);
|
||||
MTLVertexCache_FlushGlyphVertexCache();
|
||||
MTLVertexCache_FlushGlyphVertexCache(mtlc);
|
||||
}
|
||||
|
||||
MTLVC_ADD_TRIANGLES(tx1, ty1, tx2, ty2,
|
||||
|
||||
@@ -307,8 +307,8 @@ public class XBaseWindow {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected int scaleUp(int x) {
|
||||
return x;
|
||||
protected int scaleUp(int i) {
|
||||
return i;
|
||||
}
|
||||
protected int scaleUpX(int x) {
|
||||
return x;
|
||||
@@ -317,8 +317,8 @@ public class XBaseWindow {
|
||||
return y;
|
||||
}
|
||||
|
||||
protected int scaleDown(int x) {
|
||||
return x;
|
||||
protected int scaleDown(int i) {
|
||||
return i;
|
||||
}
|
||||
protected int scaleDownX(int x) {
|
||||
return x;
|
||||
|
||||
@@ -54,7 +54,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
XIconWindow iconWindow;
|
||||
volatile WindowDimensions dimensions;
|
||||
XContentWindow content;
|
||||
volatile Insets currentInsets;
|
||||
private volatile Insets currentInsets; // Device-space
|
||||
XFocusProxyWindow focusProxy;
|
||||
static final Map<Class<?>,Insets> lastKnownInsets =
|
||||
Collections.synchronizedMap(new HashMap<>());
|
||||
@@ -305,9 +305,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
insLog.finer("FRAME_EXTENTS: {0}", wm_set_insets);
|
||||
}
|
||||
|
||||
if (wm_set_insets != null) {
|
||||
wm_set_insets = copyAndScaleDown(wm_set_insets);
|
||||
}
|
||||
return wm_set_insets;
|
||||
}
|
||||
|
||||
@@ -344,7 +341,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
wm_set_insets = null;
|
||||
Insets in = getWMSetInsets(XAtom.get(ev.get_atom()));
|
||||
if (isReparented() && (!isMapped() || getMWMDecorTitleProperty().isPresent()) &&
|
||||
in != null && !in.equals(dimensions.getInsets())) {
|
||||
in != null && !copyAndScaleDown(in).equals(dimensions.getInsets())) {
|
||||
handleCorrectInsets(in);
|
||||
}
|
||||
} else {
|
||||
@@ -359,7 +356,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
if (!isEmbedded() && !isTargetUndecorated()) {
|
||||
lastKnownInsets.put(getClass(), in);
|
||||
}
|
||||
if (!in.equals(dimensions.getInsets())) {
|
||||
if (!copyAndScaleDown(in).equals(dimensions.getInsets())) {
|
||||
if (insets_corrected || isMaximized()) {
|
||||
currentInsets = in;
|
||||
insets_corrected = true;
|
||||
@@ -444,7 +441,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
// If these insets are equal to our current insets - no actions are necessary
|
||||
Insets dimInsets = dimensions.getInsets();
|
||||
if (correctWM.equals(dimInsets)) {
|
||||
if (copyAndScaleDown(correctWM).equals(dimInsets)) {
|
||||
insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
|
||||
no_reparent_artifacts = true;
|
||||
insets_corrected = true;
|
||||
@@ -453,9 +450,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
} else {
|
||||
correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
|
||||
if (correctWM != null) {
|
||||
correctWM = copyAndScaleDown(correctWM);
|
||||
}
|
||||
|
||||
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
if (correctWM != null) {
|
||||
@@ -528,14 +522,11 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
} else {
|
||||
if (!isNull(currentInsets)) {
|
||||
/* insets were set on wdata by System Properties */
|
||||
return copy(currentInsets);
|
||||
return currentInsets;
|
||||
} else {
|
||||
Insets res = getWMSetInsets(null);
|
||||
if (res == null) {
|
||||
res = XWM.getWM().guessInsets(this);
|
||||
if (res != null) {
|
||||
res = copyAndScaleDown(res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -547,15 +538,20 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
currentInsets = copy(guessed);
|
||||
}
|
||||
|
||||
private Insets getRealInsets() {
|
||||
@Override
|
||||
Insets getRealUnscaledInsets() {
|
||||
if (isNull(currentInsets)) {
|
||||
applyGuessedInsets();
|
||||
}
|
||||
return currentInsets;
|
||||
}
|
||||
|
||||
Insets getRealInsets() {
|
||||
return copyAndScaleDown(getRealUnscaledInsets());
|
||||
}
|
||||
|
||||
public Insets getInsets() {
|
||||
Insets in = copy(getRealInsets());
|
||||
Insets in = getRealInsets();
|
||||
in.top += getMenuBarHeight();
|
||||
if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
insLog.finest("Get insets returns {0}", in);
|
||||
@@ -696,7 +692,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
break;
|
||||
case SET_CLIENT_SIZE: {
|
||||
// Sets client rect size. Width and height contain insets.
|
||||
Insets in = currentInsets;
|
||||
Insets in = getRealInsets();
|
||||
width -= in.left+in.right;
|
||||
height -= in.top+in.bottom;
|
||||
dims.setClientSize(width, height);
|
||||
@@ -839,7 +835,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
}
|
||||
if (correctWM != null) {
|
||||
handleCorrectInsets(copyAndScaleDown(correctWM));
|
||||
handleCorrectInsets(correctWM);
|
||||
} else {
|
||||
//Only one attempt to correct insets is made (to lower risk)
|
||||
//if insets are still not available we simply set the flag
|
||||
@@ -849,23 +845,23 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
|
||||
updateChildrenSizes();
|
||||
|
||||
Point newLocation = getNewLocation(xe, currentInsets.left, currentInsets.top);
|
||||
WindowDimensions newDimensions =
|
||||
new WindowDimensions(newLocation,
|
||||
new Dimension(scaleDown(xe.get_width()),
|
||||
scaleDown(xe.get_height())),
|
||||
copy(currentInsets), true);
|
||||
WindowLocation newLocation = getNewLocation(xe);
|
||||
Dimension newDimension = new Dimension(xe.get_width(), xe.get_height());
|
||||
boolean xinerama = XToolkit.localEnv.runningXinerama();
|
||||
|
||||
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
insLog.finer("Insets are {0}, new dimensions {1}",
|
||||
currentInsets, newDimensions);
|
||||
}
|
||||
SunToolkit.executeOnEventHandlerThread(target, () -> {
|
||||
Point newUserLocation = newLocation.getUserLocation();
|
||||
WindowDimensions newDimensions = new WindowDimensions(newUserLocation,
|
||||
new Dimension(scaleDown(newDimension.width), scaleDown(newDimension.height)), getRealInsets(), true);
|
||||
|
||||
checkIfOnNewScreen(newDimensions.getBounds(), () -> {
|
||||
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
insLog.finer("Insets are {0}, new dimensions {1}",
|
||||
getRealInsets(), newDimensions);
|
||||
}
|
||||
|
||||
Point oldLocation = getLocation();
|
||||
dimensions = newDimensions;
|
||||
if (!newLocation.equals(oldLocation)) {
|
||||
if (!newUserLocation.equals(oldLocation)) {
|
||||
handleMoved(newDimensions);
|
||||
}
|
||||
reconfigureContentWindow(newDimensions);
|
||||
@@ -873,6 +869,9 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
|
||||
repositionSecurityWarning();
|
||||
|
||||
if (xinerama) {
|
||||
checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1401,13 +1400,28 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
return getMWMDecorTitleProperty().orElse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
void syncBounds() {
|
||||
Rectangle r = target.getBounds();
|
||||
if (syncSizeOnly && dimensions != null) {
|
||||
dimensions.setSize(r.width, r.height);
|
||||
dimensions.setInsets(getRealInsets());
|
||||
xSetSize(r.width, r.height);
|
||||
} else {
|
||||
dimensions = new WindowDimensions(r, getRealInsets(), false);
|
||||
xSetBounds(r.x, r.y, r.width, r.height);
|
||||
}
|
||||
reconfigureContentWindow(dimensions);
|
||||
doValidateSurface();
|
||||
layout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateGraphicsData(GraphicsConfiguration gc) {
|
||||
boolean ret = super.updateGraphicsData(gc);
|
||||
if (content != null) {
|
||||
content.initGraphicsConfiguration();
|
||||
content.syncBounds();
|
||||
}
|
||||
boolean ret = super.updateGraphicsData(gc);
|
||||
updateMinimumSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -143,22 +143,21 @@ public class XEmbeddedFramePeer extends XFramePeer {
|
||||
xembedLog.fine(xe.toString());
|
||||
}
|
||||
|
||||
WindowLocation newLocation = getNewLocation(xe);
|
||||
Dimension newDimension = new Dimension(xe.get_width(), xe.get_height());
|
||||
boolean xinerama = XToolkit.localEnv.runningXinerama();
|
||||
// fix for 5063031
|
||||
// if we use super.handleConfigureNotifyEvent() we would get wrong
|
||||
// size and position because embedded frame really is NOT a decorated one
|
||||
checkIfOnNewScreen(toGlobal(new Rectangle(
|
||||
scaleDown(xe.get_x()),
|
||||
scaleDown(xe.get_y()),
|
||||
scaleDown(xe.get_width()),
|
||||
scaleDown(xe.get_height()))), () -> {
|
||||
|
||||
SunToolkit.executeOnEventHandlerThread(target, () -> {
|
||||
Point newUserLocation = newLocation.getUserLocation();
|
||||
Rectangle oldBounds = getBounds();
|
||||
|
||||
synchronized (getStateLock()) {
|
||||
x = scaleDown(xe.get_x());
|
||||
y = scaleDown(xe.get_y());
|
||||
width = scaleDown(xe.get_width());
|
||||
height = scaleDown(xe.get_height());
|
||||
x = newUserLocation.x;
|
||||
y = newUserLocation.y;
|
||||
width = scaleDown(newDimension.width);
|
||||
height = scaleDown(newDimension.height);
|
||||
|
||||
dimensions.setClientSize(width, height);
|
||||
dimensions.setLocation(x, y);
|
||||
@@ -169,6 +168,9 @@ public class XEmbeddedFramePeer extends XFramePeer {
|
||||
}
|
||||
reconfigureContentWindow(dimensions);
|
||||
|
||||
if (xinerama) {
|
||||
checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1074,9 +1074,10 @@ final class XWM
|
||||
try {
|
||||
Rectangle shellBounds;
|
||||
if (getWMID() != UNITY_COMPIZ_WM) {
|
||||
Insets insets = window.getRealInsets();
|
||||
shellBounds = window.getShellBounds();
|
||||
shellBounds.translate(-window.currentInsets.left,
|
||||
-window.currentInsets.top);
|
||||
shellBounds.translate(-insets.left,
|
||||
-insets.top);
|
||||
} else {
|
||||
shellBounds = window.getDimensions().getScreenBounds();
|
||||
}
|
||||
|
||||
@@ -1745,8 +1745,8 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int scaleUp(int x) {
|
||||
return graphicsConfig.scaleUp(x);
|
||||
protected int scaleUp(int i) {
|
||||
return graphicsConfig.scaleUp(i);
|
||||
}
|
||||
@Override
|
||||
protected int scaleUpX(int x) {
|
||||
@@ -1758,8 +1758,8 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int scaleDown(int x) {
|
||||
return graphicsConfig.scaleDown(x);
|
||||
protected int scaleDown(int i) {
|
||||
return graphicsConfig.scaleDown(i);
|
||||
}
|
||||
@Override
|
||||
protected int scaleDownX(int x) {
|
||||
|
||||
@@ -40,7 +40,6 @@ import sun.awt.AWTAccessor.ComponentAccessor;
|
||||
import sun.awt.DisplayChangedListener;
|
||||
import sun.awt.IconInfo;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.X11GraphicsConfig;
|
||||
import sun.awt.X11GraphicsDevice;
|
||||
import sun.awt.X11GraphicsEnvironment;
|
||||
import sun.java2d.pipe.Region;
|
||||
@@ -99,6 +98,8 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
private Long desktopId; // guarded by AWT lock
|
||||
private boolean desktopIdInvalid; // guarded by AWT lock
|
||||
|
||||
transient boolean syncSizeOnly; // Force syncBounds() to sync only size, not location.
|
||||
|
||||
/*
|
||||
* Focus related flags
|
||||
*/
|
||||
@@ -528,6 +529,10 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
}
|
||||
|
||||
Insets getRealUnscaledInsets() {
|
||||
return new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public Insets getInsets() {
|
||||
return new Insets(0, 0, 0, 0);
|
||||
}
|
||||
@@ -652,83 +657,69 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
/* Xinerama
|
||||
* called to check if we've been moved onto a different screen
|
||||
* Based on checkNewXineramaScreen() in awt_GraphicsEnv.c
|
||||
* newBounds are specified in device space.
|
||||
*/
|
||||
public void checkIfOnNewScreen(Rectangle newBounds, Runnable next) {
|
||||
if (!XToolkit.localEnv.runningXinerama()) {
|
||||
if (next != null) next.run();
|
||||
return;
|
||||
}
|
||||
|
||||
public boolean checkIfOnNewScreen(Rectangle newBounds) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("XWindowPeer: Check if we've been moved to a new screen since we're running in Xinerama mode");
|
||||
}
|
||||
|
||||
// Remap new bounds to native unscaled coordinates
|
||||
newBounds.x = scaleUpX(newBounds.x);
|
||||
newBounds.y = scaleUpY(newBounds.y);
|
||||
newBounds.width = scaleUp(newBounds.width);
|
||||
newBounds.height = scaleUp(newBounds.height);
|
||||
|
||||
int largestIntersection = 0;
|
||||
int curScreenNum = ((X11GraphicsDevice)getGraphicsConfiguration().getDevice()).getScreen();
|
||||
int newScreenNum = curScreenNum;
|
||||
GraphicsDevice[] gds = XToolkit.localEnv.getScreenDevices();
|
||||
GraphicsConfiguration newGC = null;
|
||||
|
||||
XToolkit.awtUnlock();
|
||||
try {
|
||||
for (int i = 0; i < gds.length; i++) {
|
||||
X11GraphicsDevice device = (X11GraphicsDevice) gds[i];
|
||||
Rectangle screenBounds = gds[i].getDefaultConfiguration().getBounds();
|
||||
// Rescale screen size to native unscaled coordinates
|
||||
screenBounds.width = device.scaleUp(screenBounds.width);
|
||||
screenBounds.height = device.scaleUp(screenBounds.height);
|
||||
for (int i = 0; i < gds.length; i++) {
|
||||
X11GraphicsDevice device = (X11GraphicsDevice) gds[i];
|
||||
Rectangle screenBounds = gds[i].getDefaultConfiguration().getBounds();
|
||||
// Rescale screen size to native unscaled coordinates
|
||||
screenBounds.width = device.scaleUp(screenBounds.width);
|
||||
screenBounds.height = device.scaleUp(screenBounds.height);
|
||||
|
||||
Rectangle intersection = screenBounds.intersection(newBounds);
|
||||
if (!intersection.isEmpty()) {
|
||||
int area = intersection.width * intersection.height;
|
||||
if (area > largestIntersection) {
|
||||
largestIntersection = area;
|
||||
newScreenNum = i;
|
||||
newGC = gds[i].getDefaultConfiguration();
|
||||
if (intersection.equals(newBounds)) break;
|
||||
}
|
||||
Rectangle intersection = screenBounds.intersection(newBounds);
|
||||
if (!intersection.isEmpty()) {
|
||||
int area = intersection.width * intersection.height;
|
||||
if (area > largestIntersection) {
|
||||
largestIntersection = area;
|
||||
newScreenNum = i;
|
||||
newGC = gds[i].getDefaultConfiguration();
|
||||
if (intersection.equals(newBounds)) break;
|
||||
}
|
||||
}
|
||||
// Ensure that after window will be moved to another monitor and (probably)
|
||||
// resized as a result, majority of its area will stay on the new monitor
|
||||
if (newScreenNum != curScreenNum) {
|
||||
X11GraphicsDevice device = (X11GraphicsDevice) gds[newScreenNum];
|
||||
Rectangle screenBounds = newGC.getBounds();
|
||||
// Rescale screen size to native unscaled coordinates
|
||||
screenBounds.width = device.scaleUp(screenBounds.width);
|
||||
screenBounds.height = device.scaleUp(screenBounds.height);
|
||||
// Rescale window to new screen's scale
|
||||
newBounds.width = newBounds.width * device.getScaleFactor() / graphicsConfig.getScale();
|
||||
newBounds.height = newBounds.height * device.getScaleFactor() / graphicsConfig.getScale();
|
||||
}
|
||||
// Ensure that after window will be moved to another monitor and (probably)
|
||||
// resized as a result, majority of its area will stay on the new monitor
|
||||
if (newScreenNum != curScreenNum) {
|
||||
X11GraphicsDevice device = (X11GraphicsDevice) gds[newScreenNum];
|
||||
Rectangle screenBounds = newGC.getBounds();
|
||||
// Rescale screen size to native unscaled coordinates
|
||||
screenBounds.width = device.scaleUp(screenBounds.width);
|
||||
screenBounds.height = device.scaleUp(screenBounds.height);
|
||||
// Rescale window to new screen's scale
|
||||
newBounds.width = newBounds.width * device.getScaleFactor() / graphicsConfig.getScale();
|
||||
newBounds.height = newBounds.height * device.getScaleFactor() / graphicsConfig.getScale();
|
||||
|
||||
Rectangle intersection = screenBounds.intersection(newBounds);
|
||||
if (intersection.isEmpty() ||
|
||||
intersection.width * intersection.height < newBounds.width * newBounds.height / 2) {
|
||||
newScreenNum = curScreenNum; // Don't move to new screen
|
||||
}
|
||||
Rectangle intersection = screenBounds.intersection(newBounds);
|
||||
if (intersection.isEmpty() ||
|
||||
intersection.width * intersection.height <= newBounds.width * newBounds.height / 2) {
|
||||
newScreenNum = curScreenNum; // Don't move to new screen
|
||||
}
|
||||
} finally {
|
||||
XToolkit.awtLock();
|
||||
}
|
||||
if (newScreenNum != curScreenNum) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("XWindowPeer: Moved to a new screen");
|
||||
}
|
||||
graphicsConfig = (X11GraphicsConfig) newGC;
|
||||
final GraphicsConfiguration ngc = newGC;
|
||||
SunToolkit.executeOnEventHandlerThread(target, () -> {
|
||||
AWTAccessor.getComponentAccessor().setGraphicsConfiguration(target, ngc);
|
||||
if (next != null) next.run();
|
||||
});
|
||||
} else {
|
||||
if (next != null) next.run();
|
||||
var gc = newGC;
|
||||
var device = (X11GraphicsDevice) gc.getDevice();
|
||||
var acc = AWTAccessor.getComponentAccessor();
|
||||
syncSizeOnly = true;
|
||||
acc.setSize(target, device.scaleDown(newBounds.width), device.scaleDown(newBounds.height));
|
||||
acc.setGraphicsConfiguration(target, gc);
|
||||
syncSizeOnly = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -751,17 +742,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
* X11GraphicsDevice when the display mode has been changed.
|
||||
*/
|
||||
public void displayChanged() {
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
final GraphicsConfiguration oldGC = getGraphicsConfiguration();
|
||||
checkIfOnNewScreen(getBounds(), () -> {
|
||||
if (getGraphicsConfiguration() == oldGC) {
|
||||
executeDisplayChangedOnEDT(oldGC);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
executeDisplayChangedOnEDT(getGraphicsConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -771,28 +752,63 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
public void paletteChanged() {
|
||||
}
|
||||
|
||||
private Point queryXLocation()
|
||||
{
|
||||
Point p = XlibUtil.translateCoordinates(getContentWindow(), XlibWrapper
|
||||
.RootWindow(XToolkit.getDisplay(),
|
||||
getScreenNumber()),
|
||||
0, 0);
|
||||
p.x = scaleDownX(p.x);
|
||||
p.y = scaleDownY(p.y);
|
||||
return p;
|
||||
void xSetSize(int width, int height) {
|
||||
if (getWindow() == 0) {
|
||||
insLog.warning("Attempt to resize uncreated window");
|
||||
throw new IllegalStateException("Attempt to resize uncreated window");
|
||||
}
|
||||
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
insLog.fine("Setting size on " + this + " to " + width + "x" + height);
|
||||
}
|
||||
width = Math.max(MIN_SIZE, width);
|
||||
height = Math.max(MIN_SIZE, height);
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getWindow(),
|
||||
scaleUp(width), scaleUp(height));
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) {
|
||||
// Bounds of the window
|
||||
Rectangle targetBounds = AWTAccessor.getComponentAccessor().getBounds(target);
|
||||
class WindowLocation {
|
||||
private final Point location; // Device space
|
||||
private final boolean client;
|
||||
private WindowLocation(Point location, boolean client) {
|
||||
this.location = location;
|
||||
this.client = client;
|
||||
}
|
||||
Point getDeviceLocation() {
|
||||
if (location == null) {
|
||||
Point l = AWTAccessor.getComponentAccessor().getLocation(target);
|
||||
l.x = scaleUpX(l.x);
|
||||
l.y = scaleUpY(l.y);
|
||||
return l;
|
||||
} else if (client) {
|
||||
Insets insets = getRealUnscaledInsets();
|
||||
return new Point(location.x - insets.left, location.y - insets.top);
|
||||
} else {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
Point getUserLocation() {
|
||||
if (location == null) {
|
||||
return AWTAccessor.getComponentAccessor().getLocation(target);
|
||||
} else if (client) {
|
||||
Insets insets = getRealUnscaledInsets();
|
||||
return new Point(scaleDownX(location.x - insets.left), scaleDownY(location.y - insets.top));
|
||||
} else {
|
||||
return new Point(scaleDownX(location.x), scaleDownY(location.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WindowLocation getNewLocation(XConfigureEvent xe) {
|
||||
int runningWM = XWM.getWMID();
|
||||
Point newLocation = targetBounds.getLocation();
|
||||
if (xe.get_send_event() ||
|
||||
(ENABLE_REPARENTING_CHECK ? (runningWM == XWM.NO_WM || XWM.isNonReparentingWM()) : !isReparented())) {
|
||||
// Location, Client size + insets
|
||||
newLocation = new Point(scaleDownX(xe.get_x()) - leftInset,
|
||||
scaleDownY(xe.get_y()) - topInset);
|
||||
return new WindowLocation(new Point(xe.get_x(), xe.get_y()), true);
|
||||
} else {
|
||||
// ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
|
||||
// a window is resized but the client can not tell if the window was
|
||||
@@ -809,20 +825,17 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
case XWM.UNITY_COMPIZ_WM:
|
||||
case XWM.AWESOME_WM:
|
||||
{
|
||||
Point xlocation = queryXLocation();
|
||||
Point xlocation = XlibUtil.translateCoordinates(getContentWindow(), XlibWrapper
|
||||
.RootWindow(XToolkit.getDisplay(),
|
||||
getScreenNumber()), 0, 0);
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine("New X location: {0}", xlocation);
|
||||
}
|
||||
if (xlocation != null) {
|
||||
newLocation = xlocation;
|
||||
}
|
||||
break;
|
||||
return new WindowLocation(xlocation, false);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newLocation;
|
||||
return new WindowLocation(null, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -837,18 +850,18 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
insLog.fine(xe.toString());
|
||||
}
|
||||
|
||||
Rectangle oldBounds = getBounds();
|
||||
WindowLocation newLocation = getNewLocation(xe);
|
||||
Dimension newDimension = new Dimension(xe.get_width(), xe.get_height());
|
||||
boolean xinerama = XToolkit.localEnv.runningXinerama();
|
||||
|
||||
x = scaleDownX(xe.get_x());
|
||||
y = scaleDownY(xe.get_y());
|
||||
width = scaleDown(xe.get_width());
|
||||
height = scaleDown(xe.get_height());
|
||||
SunToolkit.executeOnEventHandlerThread(target, () -> {
|
||||
Point newUserLocation = newLocation.getUserLocation();
|
||||
Rectangle oldBounds = getBounds();
|
||||
|
||||
checkIfOnNewScreen(new Rectangle(
|
||||
scaleDownX(xe.get_x()),
|
||||
scaleDownY(xe.get_y()),
|
||||
scaleDown(xe.get_width()),
|
||||
scaleDown(xe.get_height())), () -> {
|
||||
x = newUserLocation.x;
|
||||
y = newUserLocation.y;
|
||||
width = scaleDown(newDimension.width);
|
||||
height = scaleDown(newDimension.height);
|
||||
|
||||
if (!getBounds().getSize().equals(oldBounds.getSize())) {
|
||||
AWTAccessor.getComponentAccessor().setSize(target, width, height);
|
||||
@@ -860,6 +873,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
repositionSecurityWarning();
|
||||
|
||||
if (xinerama) {
|
||||
checkIfOnNewScreen(new Rectangle(newLocation.getDeviceLocation(), newDimension));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2597,6 +2613,29 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
void syncBounds() {
|
||||
Rectangle r = target.getBounds();
|
||||
width = r.width;
|
||||
height = r.height;
|
||||
if (syncSizeOnly) {
|
||||
xSetSize(width, height);
|
||||
} else {
|
||||
x = r.x;
|
||||
y = r.y;
|
||||
xSetBounds(x, y, width, height);
|
||||
}
|
||||
doValidateSurface();
|
||||
layout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateGraphicsData(GraphicsConfiguration gc) {
|
||||
if (super.updateGraphicsData(gc)) return true;
|
||||
repositionSecurityWarning();
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean haveCommonAncestor(Component c1, Component c2) {
|
||||
return getRootOwner(c1) == getRootOwner(c2);
|
||||
}
|
||||
|
||||
@@ -271,8 +271,8 @@ public class X11GraphicsConfig extends GraphicsConfiguration
|
||||
return getDevice().getScaleFactor();
|
||||
}
|
||||
|
||||
public int scaleUp(int x) {
|
||||
return getDevice().scaleUp(x);
|
||||
public int scaleUp(int i) {
|
||||
return getDevice().scaleUp(i);
|
||||
}
|
||||
public int scaleUpX(int x) {
|
||||
return getDevice().scaleUpX(x);
|
||||
@@ -281,8 +281,8 @@ public class X11GraphicsConfig extends GraphicsConfiguration
|
||||
return getDevice().scaleUpY(y);
|
||||
}
|
||||
|
||||
public int scaleDown(int x) {
|
||||
return getDevice().scaleDown(x);
|
||||
public int scaleDown(int i) {
|
||||
return getDevice().scaleDown(i);
|
||||
}
|
||||
public int scaleDownX(int x) {
|
||||
return getDevice().scaleDownX(x);
|
||||
|
||||
@@ -130,8 +130,8 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
return TYPE_RASTER_SCREEN;
|
||||
}
|
||||
|
||||
public int scaleUp(int x) {
|
||||
return Region.clipRound(x * (double)getScaleFactor());
|
||||
public int scaleUp(int i) {
|
||||
return Region.clipRound(i * (double)getScaleFactor());
|
||||
}
|
||||
public int scaleUpX(int x) {
|
||||
int s = getBoundsCached().x;
|
||||
@@ -142,8 +142,8 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
return Region.clipRound(s + (y - s) * (double)getScaleFactor());
|
||||
}
|
||||
|
||||
public int scaleDown(int x) {
|
||||
return Region.clipRound(x / (double)getScaleFactor());
|
||||
public int scaleDown(int i) {
|
||||
return Region.clipRound(i / (double)getScaleFactor());
|
||||
}
|
||||
public int scaleDownX(int x) {
|
||||
int s = getBoundsCached().x;
|
||||
|
||||
@@ -266,17 +266,20 @@ class WFramePeer extends WWindowPeer implements FramePeer {
|
||||
}
|
||||
private static native void updateCustomTitleBar(WWindowPeer peer);
|
||||
|
||||
// Used from native
|
||||
private static final boolean WIN11_OR_NEWER;
|
||||
static {
|
||||
if ("Windows 10".equals(System.getProperty("os.name"))) {
|
||||
WIN11_OR_NEWER = false;
|
||||
@SuppressWarnings("removal")
|
||||
private static boolean isWin11OrNewer() {
|
||||
String osName = AccessController.doPrivileged(new GetPropertyAction("os.name"));
|
||||
String osVersion = AccessController.doPrivileged(new GetPropertyAction("os.version"));
|
||||
if ("Windows 10".equals(osName)) {
|
||||
return false;
|
||||
} else {
|
||||
int version = 10;
|
||||
try {
|
||||
version = (int) Double.parseDouble(System.getProperty("os.version"));
|
||||
version = (int) Double.parseDouble(osVersion);
|
||||
} catch (NullPointerException | NumberFormatException ignored) {}
|
||||
WIN11_OR_NEWER = version >= 10;
|
||||
return version >= 10;
|
||||
}
|
||||
}
|
||||
// Used from native
|
||||
private static final boolean WIN11_OR_NEWER = isWin11OrNewer();
|
||||
}
|
||||
|
||||
@@ -552,7 +552,6 @@ MsgRouting AwtFrame::WmMouseUp(UINT flags, int x, int y, int button) {
|
||||
}
|
||||
|
||||
MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) {
|
||||
if (customTitleBarControls) customTitleBarControls->Hit(CustomTitleBarControls::HitType::RESET, 0, 0);
|
||||
/**
|
||||
* If this Frame is non-focusable then we should implement move and size operation for it by
|
||||
* ourselfves because we don't dispatch appropriate mouse messages to default window procedure.
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Button;
|
||||
import java.awt.Robot;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@@ -48,14 +50,18 @@ import java.awt.event.InputEvent;
|
||||
public class ActionListenerTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), actionListener);
|
||||
TaskResult awtResult = CommonAPISuite.runTestSuite(List.of(TestUtils::createFrameWithCustomTitleBar, TestUtils::createDialogWithCustomTitleBar), actionListenerAWT);
|
||||
TaskResult swingResult = CommonAPISuite.runTestSuite(List.of(TestUtils::createJFrameWithCustomTitleBar, TestUtils::createJFrameWithCustomTitleBar), actionListenerSwing);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("ActionListenerTest FAILED");
|
||||
TaskResult result = awtResult.merge(swingResult);
|
||||
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Task actionListener = new Task("Using of action listener") {
|
||||
private static final Task actionListenerAWT = new Task("Using of action listener in AWT") {
|
||||
|
||||
private Button button;
|
||||
private boolean actionListenerGotEvent = false;
|
||||
@@ -74,7 +80,7 @@ public class ActionListenerTest {
|
||||
@Override
|
||||
public void customizeWindow() {
|
||||
button = new Button();
|
||||
button.setBounds(200, 20, 50, 50);
|
||||
button.setLocation(window.getWidth() / 2, 0);
|
||||
button.addActionListener(a -> {
|
||||
actionListenerGotEvent = true;
|
||||
});
|
||||
@@ -83,21 +89,67 @@ public class ActionListenerTest {
|
||||
|
||||
@Override
|
||||
public void test() throws AWTException {
|
||||
Robot robot = new Robot();
|
||||
robot.waitForIdle();
|
||||
int x = button.getLocationOnScreen().x + button.getWidth() / 2;
|
||||
int y = button.getLocationOnScreen().y + button.getHeight() / 2;
|
||||
System.out.println("Click at (" + x + ", " + y + ")");
|
||||
robot.mouseMove(x, y);
|
||||
robot.waitForIdle();
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
doClick(button.getLocationOnScreen(), button.getWidth(), button.getHeight());
|
||||
|
||||
if (!actionListenerGotEvent) {
|
||||
System.out.println("Error: button didn't get event by action listener");
|
||||
err("button didn't get event by action listener");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static final Task actionListenerSwing = new Task("Using of action listener in Swing") {
|
||||
|
||||
private JButton button;
|
||||
private boolean actionListenerGotEvent = false;
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
actionListenerGotEvent = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareTitleBar() {
|
||||
titleBar = JBR.getWindowDecorations().createCustomTitleBar();
|
||||
titleBar.setHeight(TestUtils.TITLE_BAR_HEIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeWindow() {
|
||||
button = new JButton();
|
||||
button.setLocation(window.getWidth() / 2, 0);
|
||||
button.addActionListener(a -> {
|
||||
actionListenerGotEvent = true;
|
||||
});
|
||||
window.add(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void test() throws AWTException {
|
||||
doClick(button.getLocationOnScreen(), button.getWidth(), button.getHeight());
|
||||
|
||||
if (!actionListenerGotEvent) {
|
||||
err("button didn't get event by action listener");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static void doClick(Point location, int w, int h) throws AWTException {
|
||||
Robot robot = new Robot();
|
||||
robot.waitForIdle();
|
||||
int x = location.x + w / 2;
|
||||
int y = location.y + h / 2;
|
||||
System.out.println("Click at (" + x + ", " + y + ")");
|
||||
robot.mouseMove(x, y);
|
||||
robot.waitForIdle();
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,8 +24,11 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Verify modifying of title bar height
|
||||
@@ -43,11 +46,13 @@ import util.TestUtils;
|
||||
public class ChangeTitleBarHeightTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), changeTitleBarHeight);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), changeTitleBarHeight);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("ChangeTitleBarHeightTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Task changeTitleBarHeight = new Task("Changing of title bar height") {
|
||||
|
||||
@@ -24,8 +24,11 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Verify creating to a custom title bar
|
||||
@@ -43,11 +46,13 @@ import util.TestUtils;
|
||||
public class CreateTitleBarTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), createTitleBar);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), createTitleBar);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("CreateTitleBarTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Task createTitleBar = new Task("Create title bar with default settings") {
|
||||
@@ -64,8 +69,7 @@ public class CreateTitleBarTest {
|
||||
passed = passed && TestUtils.checkFrameInsets(window);
|
||||
|
||||
if (titleBar.getLeftInset() == 0 && titleBar.getRightInset() == 0) {
|
||||
passed = false;
|
||||
System.out.println("Left or right space must be occupied by system controls");
|
||||
err("Left or right space must be occupied by system controls");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
* questions.
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
@@ -32,6 +29,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -51,11 +49,13 @@ import java.util.List;
|
||||
public class DialogNativeControlsTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = nativeControlClicks.run(TestUtils::createDialogWithCustomTitleBar);
|
||||
TaskResult result = nativeControlClicks.run(TestUtils::createDialogWithCustomTitleBar);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("DialogNativeControlsTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Task nativeControlClicks = new Task("Native controls clicks") {
|
||||
@@ -111,7 +111,7 @@ public class DialogNativeControlsTest {
|
||||
robot.waitForIdle();
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
passed = false;
|
||||
@@ -140,13 +140,11 @@ public class DialogNativeControlsTest {
|
||||
});
|
||||
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("mac") && !maximizingActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: maximizing action was not detected");
|
||||
err("maximizing action was not detected");
|
||||
}
|
||||
|
||||
if (!closingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: closing action was not detected");
|
||||
err("closing action was not detected");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,11 +22,7 @@
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import com.jetbrains.WindowDecorations;
|
||||
import util.CommonAPISuite;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import java.awt.Frame;
|
||||
@@ -37,6 +33,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -61,11 +58,13 @@ public class FrameNativeControlsMacOSTest {
|
||||
public static void main(String... args) {
|
||||
List<Function<WindowDecorations.CustomTitleBar, Window>> functions =
|
||||
List.of(TestUtils::createFrameWithCustomTitleBar, TestUtils::createJFrameWithCustomTitleBar);
|
||||
boolean status = CommonAPISuite.runTestSuite(functions, frameNativeControlsClicks);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(functions, frameNativeControlsClicks);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("FrameNativeControlsMacOSTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Task frameNativeControlsClicks = new Task("Frame native controls clicks") {
|
||||
@@ -164,7 +163,7 @@ public class FrameNativeControlsMacOSTest {
|
||||
robot.delay(500);
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
passed = false;
|
||||
@@ -193,22 +192,18 @@ public class FrameNativeControlsMacOSTest {
|
||||
});
|
||||
|
||||
if (!maximizingActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: maximizing action was not detected");
|
||||
err("maximizing action was not detected");
|
||||
}
|
||||
|
||||
if (!closingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: closing action was not detected");
|
||||
err("closing action was not detected");
|
||||
}
|
||||
|
||||
if (!iconifyingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: iconifying action was not detected");
|
||||
err("iconifying action was not detected");
|
||||
}
|
||||
if (!deiconifyindActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: deiconifying action was not detected");
|
||||
err("deiconifying action was not detected");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,11 +22,7 @@
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import com.jetbrains.WindowDecorations;
|
||||
import util.CommonAPISuite;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import java.awt.Frame;
|
||||
@@ -37,6 +33,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -59,10 +56,11 @@ public class FrameNativeControlsTest {
|
||||
public static void main(String... args) {
|
||||
List<Function<WindowDecorations.CustomTitleBar, Window>> functions =
|
||||
List.of(TestUtils::createFrameWithCustomTitleBar, TestUtils::createJFrameWithCustomTitleBar);
|
||||
boolean status = CommonAPISuite.runTestSuite(functions, frameNativeControlsClicks);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(functions, frameNativeControlsClicks);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("FrameNativeControlsTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +138,7 @@ public class FrameNativeControlsTest {
|
||||
robot.delay(500);
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
passed = false;
|
||||
@@ -169,22 +167,18 @@ public class FrameNativeControlsTest {
|
||||
});
|
||||
|
||||
if (!maximizingActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: maximizing action was not detected");
|
||||
err("maximizing action was not detected");
|
||||
}
|
||||
|
||||
if (!closingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: closing action was not detected");
|
||||
err("closing action was not detected");
|
||||
}
|
||||
|
||||
if (!iconifyingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: iconifying action was not detected");
|
||||
err("iconifying action was not detected");
|
||||
}
|
||||
if (!deiconifyindActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: deiconifying action was not detected");
|
||||
err("deiconifying action was not detected");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,14 +21,11 @@
|
||||
* questions.
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Robot;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -48,10 +45,11 @@ import java.util.List;
|
||||
public class HiddenNativeControlsTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), hiddenControls);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), hiddenControls);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("HiddenNativeControlsTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,25 +75,22 @@ public class HiddenNativeControlsTest {
|
||||
passed = passed && TestUtils.checkFrameInsets(window);
|
||||
|
||||
if (!"false".equals(titleBar.getProperties().get(PROPERTY_NAME).toString())) {
|
||||
passed = false;
|
||||
System.out.println("controls.visible isn't false");
|
||||
err("controls.visible isn't false");
|
||||
}
|
||||
if (titleBar.getLeftInset() != 0 || titleBar.getRightInset() != 0) {
|
||||
passed = false;
|
||||
System.out.println("System controls are hidden so insets must be zero");
|
||||
err("System controls are hidden so insets must be zero");
|
||||
}
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
|
||||
System.out.println("image w = " + image.getWidth() + " h = " + image.getHeight());
|
||||
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar, true);
|
||||
System.out.println("Found controls at the title bar:");
|
||||
foundControls.forEach(System.out::println);
|
||||
|
||||
if (foundControls.size() != 0) {
|
||||
passed = false;
|
||||
System.out.println("Error: there are must be 0 controls");
|
||||
err("controls are disabled, but found in the screenshot");
|
||||
}
|
||||
|
||||
if (!passed) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
@@ -39,6 +40,7 @@ import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -59,13 +61,13 @@ import java.util.List;
|
||||
public class HitTestClientArea {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean awtStatus = CommonAPISuite.runTestSuite(List.of(TestUtils::createFrameWithCustomTitleBar, TestUtils::createDialogWithCustomTitleBar), hitTestClientAreaAWT);
|
||||
boolean swingStatus = CommonAPISuite.runTestSuite(List.of(TestUtils::createJFrameWithCustomTitleBar, TestUtils::createJFrameWithCustomTitleBar), hitTestClientAreaSwing);
|
||||
TaskResult awtResult = CommonAPISuite.runTestSuite(List.of(TestUtils::createFrameWithCustomTitleBar, TestUtils::createDialogWithCustomTitleBar), hitTestClientAreaAWT);
|
||||
TaskResult swingResult = CommonAPISuite.runTestSuite(List.of(TestUtils::createJFrameWithCustomTitleBar, TestUtils::createJFrameWithCustomTitleBar), hitTestClientAreaSwing);
|
||||
|
||||
boolean status = awtStatus && swingStatus;
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("HitTestClientArea FAILED");
|
||||
TaskResult result = awtResult.merge(swingResult);
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +149,7 @@ public class HitTestClientArea {
|
||||
int initialX = window.getLocationOnScreen().x + PANEL_WIDTH / 2;
|
||||
int initialY = window.getLocationOnScreen().y + PANEL_HEIGHT / 2;
|
||||
|
||||
window.requestFocus();
|
||||
for (Integer mask: BUTTON_MASKS) {
|
||||
robot.waitForIdle();
|
||||
|
||||
@@ -174,24 +177,20 @@ public class HitTestClientArea {
|
||||
for (int i = 0; i < BUTTON_MASKS.size(); i++) {
|
||||
System.out.println("Button no " + (i+1) + " clicks count = " + gotClicks[i]);
|
||||
if (gotClicks[i] == 0) {
|
||||
System.out.println("Mouse click to button no " + (i+1) + " was not registered");
|
||||
passed = false;
|
||||
err("Mouse click to button no " + (i+1) + " was not registered");
|
||||
}
|
||||
}
|
||||
|
||||
boolean moved = initialLocation.x < newLocation.x && initialLocation.y < newLocation.y;
|
||||
if (moved) {
|
||||
System.out.println("Window was moved, but drag'n drop action must be disabled in the client area");
|
||||
passed = false;
|
||||
err("Window was moved, but drag'n drop action must be disabled in the client area");
|
||||
}
|
||||
|
||||
if (!mousePressed) {
|
||||
System.out.println("Mouse press to the client area wasn't detected");
|
||||
passed = false;
|
||||
err("Mouse press to the client area wasn't detected");
|
||||
}
|
||||
if (!mouseReleased) {
|
||||
System.out.println("Mouse release to the client area wasn't detected");
|
||||
passed = false;
|
||||
err("Mouse release to the client area wasn't detected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,24 +307,20 @@ public class HitTestClientArea {
|
||||
for (int i = 0; i < BUTTON_MASKS.size(); i++) {
|
||||
System.out.println("Button no " + (i+1) + " clicks count = " + gotClicks[i]);
|
||||
if (gotClicks[i] == 0) {
|
||||
System.out.println("Mouse click to button no " + (i+1) + " was not registered");
|
||||
passed = false;
|
||||
err("Mouse click to button no " + (i+1) + " was not registered");
|
||||
}
|
||||
}
|
||||
|
||||
boolean moved = initialLocation.x < newLocation.x && initialLocation.y < newLocation.y;
|
||||
if (moved) {
|
||||
System.out.println("Window was moved, but drag'n drop action must be disabled in the client area");
|
||||
passed = false;
|
||||
err("Window was moved, but drag'n drop action must be disabled in the client area");
|
||||
}
|
||||
|
||||
if (!mousePressed) {
|
||||
System.out.println("Mouse press to the client area wasn't detected");
|
||||
passed = false;
|
||||
err("Mouse press to the client area wasn't detected");
|
||||
}
|
||||
if (!mouseReleased) {
|
||||
System.out.println("Mouse release to the client area wasn't detected");
|
||||
passed = false;
|
||||
err("Mouse release to the client area wasn't detected");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.awt.AWTException;
|
||||
@@ -35,6 +36,7 @@ import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -55,10 +57,11 @@ import java.util.List;
|
||||
public class HitTestNonClientArea {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), hitTestNonClientArea);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), hitTestNonClientArea);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("HitTestNonClientArea FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,8 +165,7 @@ public class HitTestNonClientArea {
|
||||
}
|
||||
for (int i = 0; i < BUTTON_MASKS.size(); i++) {
|
||||
if (!gotClicks[i]) {
|
||||
System.out.println("Mouse click to button no " + (i+1) + " was not registered");
|
||||
passed = false;
|
||||
err("Mouse click to button no " + (i+1) + " was not registered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
* questions.
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
@@ -33,6 +30,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -52,10 +50,11 @@ import java.util.List;
|
||||
public class JDialogNativeControlsTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = nativeControlClicks.run(TestUtils::createJDialogWithCustomTitleBar);
|
||||
TaskResult result = nativeControlClicks.run(TestUtils::createJDialogWithCustomTitleBar);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("JDialogNativeControlsTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ public class JDialogNativeControlsTest {
|
||||
robot.delay(500);
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
passed = false;
|
||||
@@ -143,14 +142,12 @@ public class JDialogNativeControlsTest {
|
||||
final String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.startsWith("mac os")) {
|
||||
if (!maximizingActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: maximizing action was not detected");
|
||||
err("maximizing action was not detected");
|
||||
}
|
||||
}
|
||||
|
||||
if (!closingActionCalled) {
|
||||
passed = false;
|
||||
System.out.println("Error: closing action was not detected");
|
||||
err("closing action was not detected");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jetbrains.JBR;
|
||||
import com.jetbrains.WindowDecorations;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.awt.AWTException;
|
||||
@@ -35,6 +36,7 @@ import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
@@ -64,14 +66,15 @@ public class MaximizeWindowTest {
|
||||
functions = TestUtils.getWindowCreationFunctions();
|
||||
}
|
||||
|
||||
boolean status = CommonAPISuite.runTestSuite(functions, maximizeWindow);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(functions, maximizeWindow);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("MaximizeWindowTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Task maximizeWindow = new Task("Maximize frame") {
|
||||
private static final Task maximizeWindow = new Task("Maximize window") {
|
||||
|
||||
@Override
|
||||
public void prepareTitleBar() {
|
||||
@@ -90,8 +93,7 @@ public class MaximizeWindowTest {
|
||||
System.out.printf(String.format("Initial size (w = %d, h = %d)%n", window.getWidth(), window.getHeight()));
|
||||
System.out.printf(String.format("New size (w = %d, h = %d)%n", window.getWidth(), window.getHeight()));
|
||||
if (initialHeight == window.getHeight() && initialWidth == window.getWidth()) {
|
||||
passed = false;
|
||||
System.out.println("Frame size wasn't changed");
|
||||
err("Frame size wasn't changed after double click to title bar");
|
||||
}
|
||||
|
||||
setResizable(false);
|
||||
@@ -102,8 +104,7 @@ public class MaximizeWindowTest {
|
||||
System.out.printf(String.format("Initial size (w = %d, h = %d)%n", window.getWidth(), window.getHeight()));
|
||||
System.out.printf(String.format("New size (w = %d, h = %d)%n", window.getWidth(), window.getHeight()));
|
||||
if (initialHeight != window.getHeight() || initialWidth != window.getWidth()) {
|
||||
passed = false;
|
||||
System.out.println("Frame size was changed");
|
||||
err("Frame size was changed after double click to title bar, but resize is disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ public class MaximizeWindowTest {
|
||||
System.out.println("Window was created with bounds: " + window.getBounds());
|
||||
|
||||
int w = window.getBounds().width / 2;
|
||||
int h = window.getBounds().height / 2;
|
||||
int h = Math.max(window.getBounds().height / 2, 20 + (int) titleBar.getHeight());
|
||||
window.setBounds(window.getBounds().x, window.getBounds().y, w, h);
|
||||
|
||||
System.out.println("New window bounds: " + window.getBounds());
|
||||
@@ -154,4 +155,4 @@ public class MaximizeWindowTest {
|
||||
robot.delay(1000);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBR;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.InputEvent;
|
||||
@@ -34,6 +31,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -53,10 +51,11 @@ import java.util.List;
|
||||
public class MinimizingWindowTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = minimizingWindowTest.run(TestUtils::createFrameWithCustomTitleBar);
|
||||
TaskResult result = minimizingWindowTest.run(TestUtils::createFrameWithCustomTitleBar);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("MinimizingWindowTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,11 +115,10 @@ public class MinimizingWindowTest {
|
||||
robot.waitForIdle();
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
passed = false;
|
||||
System.out.println("Error: no controls found");
|
||||
err("no controls found");
|
||||
}
|
||||
|
||||
foundControls.forEach(control -> {
|
||||
@@ -145,8 +143,7 @@ public class MinimizingWindowTest {
|
||||
});
|
||||
|
||||
if (!iconifyingActionCalled || !iconifyingActionDetected) {
|
||||
passed = false;
|
||||
System.out.println("Error: iconifying action was not detected");
|
||||
err("iconifying action was not detected");
|
||||
}
|
||||
|
||||
if (!passed) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.awt.AWTException;
|
||||
@@ -34,6 +35,7 @@ import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -54,10 +56,11 @@ import java.util.List;
|
||||
public class MouseEventsOnClientArea {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), mouseClicks);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), mouseClicks);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("MouseEventsOnClientArea FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,31 +136,29 @@ public class MouseEventsOnClientArea {
|
||||
public void test() throws AWTException {
|
||||
Robot robot = new Robot();
|
||||
|
||||
int x = panel.getLocationOnScreen().x + panel.getWidth() / 2;
|
||||
int y = panel.getLocationOnScreen().y + panel.getHeight() / 2;
|
||||
|
||||
BUTTON_MASKS.forEach(mask -> {
|
||||
robot.delay(500);
|
||||
|
||||
robot.mouseMove(panel.getLocationOnScreen().x + panel.getWidth() / 2,
|
||||
panel.getLocationOnScreen().y + panel.getHeight() / 2);
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(mask);
|
||||
robot.mouseRelease(mask);
|
||||
|
||||
robot.delay(500);
|
||||
});
|
||||
|
||||
robot.delay(500);
|
||||
robot.mouseMove(panel.getLocationOnScreen().x + panel.getWidth() / 2,
|
||||
panel.getLocationOnScreen().y + panel.getHeight() / 2);
|
||||
robot.delay(500);
|
||||
robot.mouseMove(panel.getLocationOnScreen().x + panel.getWidth() + 10,
|
||||
panel.getLocationOnScreen().y + panel.getWidth() + 10);
|
||||
robot.delay(500);
|
||||
|
||||
boolean status = true;
|
||||
for (int i = 0; i < BUTTON_MASKS.size(); i++) {
|
||||
System.out.println("Button mask: " + BUTTON_MASKS.get(i));
|
||||
System.out.println("pressed = " + buttonsPressed[i]);
|
||||
System.out.println("released = " + buttonsReleased[i]);
|
||||
System.out.println("clicked = " + buttonsClicked[i]);
|
||||
passed = buttonsPressed[i] && buttonsReleased[i] && buttonsClicked[i];
|
||||
status = status && buttonsPressed[i] && buttonsReleased[i] && buttonsClicked[i];
|
||||
}
|
||||
if (!status) {
|
||||
err("some of mouse events weren't registered");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,14 +22,11 @@
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Rect;
|
||||
import util.Task;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Robot;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -49,15 +46,15 @@ import java.util.List;
|
||||
public class NativeControlsVisibilityTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), visibleControls);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), visibleControls);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("NativeControlsVisibilityTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Task visibleControls = new Task("Visible native controls") {
|
||||
private static final String PROPERTY_NAME = "controls.visible";
|
||||
@Override
|
||||
public void prepareTitleBar() {
|
||||
titleBar = JBR.getWindowDecorations().createCustomTitleBar();
|
||||
@@ -82,7 +79,7 @@ public class NativeControlsVisibilityTest {
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar, false);
|
||||
System.out.println("Found controls at the title bar:");
|
||||
foundControls.forEach(System.out::println);
|
||||
|
||||
|
||||
@@ -21,16 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.RectCoordinates;
|
||||
import util.Task;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@@ -49,10 +46,11 @@ import java.awt.image.BufferedImage;
|
||||
public class WindowResizeTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), windowResizeTest);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), windowResizeTest);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("WindowResizeTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,8 +76,7 @@ public class WindowResizeTest {
|
||||
robot.delay(1000);
|
||||
|
||||
if (titleBar.getHeight() != initialTitleBarHeight) {
|
||||
passed = false;
|
||||
System.out.println("Error: title bar height has been changed");
|
||||
err("title bar height has been changed");
|
||||
}
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Task;
|
||||
import util.TaskResult;
|
||||
import util.TestUtils;
|
||||
|
||||
import java.awt.Robot;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@@ -44,10 +46,11 @@ import java.awt.Robot;
|
||||
public class WindowVisibilityTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), visibilityTest);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), visibilityTest);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("WindowVisibilityTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,12 +75,10 @@ public class WindowVisibilityTest {
|
||||
robot.delay(1000);
|
||||
|
||||
if (titleBarHeight != titleBar.getHeight()) {
|
||||
passed = false;
|
||||
System.out.println("Error: title bar height has been changed");
|
||||
err("Error: title bar height has been changed");
|
||||
}
|
||||
if (!titleBar.getContainingWindow().equals(window)) {
|
||||
passed = false;
|
||||
System.out.println("Error: wrong containing window");
|
||||
err("wrong containing window");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,15 +22,12 @@
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBR;
|
||||
import util.CommonAPISuite;
|
||||
import util.Rect;
|
||||
import util.ScreenShotHelpers;
|
||||
import util.Task;
|
||||
import util.TestUtils;
|
||||
import util.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Robot;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
@@ -38,30 +35,23 @@ import java.util.List;
|
||||
* @summary Verify a property to change visibility of native controls
|
||||
* @requires os.family == "windows"
|
||||
* @run main/othervm WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 10" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=4.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dos.version=10 -Dos.name="Windows 11" -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=4.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.25 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=1.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=2.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.0 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=3.5 WindowsControlWidthTest
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true -Dsun.java2d.uiScale=4.0 WindowsControlWidthTest
|
||||
*/
|
||||
public class WindowsControlWidthTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
boolean status = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), nativeControlsWidth);
|
||||
TaskResult result = CommonAPISuite.runTestSuite(TestUtils.getWindowCreationFunctions(), nativeControlsWidth);
|
||||
|
||||
if (!status) {
|
||||
throw new RuntimeException("WindowsControlWidthTest FAILED");
|
||||
if (!result.isPassed()) {
|
||||
final String message = String.format("%s FAILED. %s", MethodHandles.lookup().lookupClass().getName(), result.getError());
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,38 +73,36 @@ public class WindowsControlWidthTest {
|
||||
passed = passed && TestUtils.checkFrameInsets(window);
|
||||
|
||||
if (titleBar.getLeftInset() == 0 && titleBar.getRightInset() == 0) {
|
||||
passed = false;
|
||||
System.out.println("Left or right inset must be non-zero");
|
||||
err("Left or right inset must be non-zero");
|
||||
}
|
||||
|
||||
BufferedImage image = ScreenShotHelpers.takeScreenshot(window);
|
||||
|
||||
List<Rect> foundControls = ScreenShotHelpers.detectControlsByBackground(image, (int) titleBar.getHeight(), TestUtils.TITLE_BAR_COLOR);
|
||||
List<Rect> foundControls = ScreenShotHelpers.findControls(image, window, titleBar);
|
||||
|
||||
double uiScale = TestUtils.getUIScale();
|
||||
double adjustedControlsWidth = CONTROLS_WIDTH / uiScale;
|
||||
|
||||
if (foundControls.size() == 0) {
|
||||
System.out.println("Error: controls not found");
|
||||
passed = false;
|
||||
err("controls not found");
|
||||
} else if (foundControls.size() == 3) {
|
||||
System.out.println("3 controls found");
|
||||
int minX = foundControls.get(0).getX1();
|
||||
int maxX = foundControls.get(2).getX2();
|
||||
int dist = (foundControls.get(1).getX1() - foundControls.get(0).getX2() + foundControls.get(2).getX1() - foundControls.get(1).getX2()) / 2;
|
||||
int calculatedWidth = maxX - minX + dist;
|
||||
float diff = (float) calculatedWidth / CONTROLS_WIDTH;
|
||||
double diff = calculatedWidth / adjustedControlsWidth;
|
||||
if (diff < 0.95 || diff > 1.05) {
|
||||
System.out.println("Error: control's width is much differ than the expected value");
|
||||
passed = false;
|
||||
err("control's width is much differ than the expected value");
|
||||
}
|
||||
} else if (foundControls.size() == 1){
|
||||
System.out.println("1 control found");
|
||||
int calculatedWidth = foundControls.get(0).getX2() - foundControls.get(0).getX1();
|
||||
if (calculatedWidth < 0.5) {
|
||||
System.out.println("Error: control's width is much differ than the expected value");
|
||||
passed = false;
|
||||
err("control's width is much differ than the expected value");
|
||||
}
|
||||
} else {
|
||||
System.out.println("Error: unexpected controls count = " + foundControls.size());
|
||||
passed = false;
|
||||
err("unexpected controls count = " + foundControls.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,24 @@ package util;
|
||||
import com.jetbrains.WindowDecorations;
|
||||
|
||||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommonAPISuite {
|
||||
|
||||
public static boolean runTestSuite(List<Function<WindowDecorations.CustomTitleBar, Window>> functions, Task task) {
|
||||
public static TaskResult runTestSuite(List<Function<WindowDecorations.CustomTitleBar, Window>> functions, Task task) {
|
||||
AtomicBoolean testPassed = new AtomicBoolean(true);
|
||||
functions.forEach(function -> testPassed.set(testPassed.get() && task.run(function)));
|
||||
List<String> errors = new ArrayList<>();
|
||||
functions.forEach(function -> {
|
||||
TaskResult result = task.run(function);
|
||||
testPassed.set(testPassed.get() && result.isPassed());
|
||||
errors.add(result.getError());
|
||||
});
|
||||
|
||||
return testPassed.get();
|
||||
return new TaskResult(testPassed.get(), errors.stream().collect(Collectors.joining("\n")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
*/
|
||||
package util;
|
||||
|
||||
import com.jetbrains.WindowDecorations;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Color;
|
||||
@@ -57,6 +59,88 @@ public class ScreenShotHelpers {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static List<Rect> findControls(BufferedImage image, Window window, WindowDecorations.CustomTitleBar titleBar) {
|
||||
return findControls(image, window, titleBar, false);
|
||||
}
|
||||
|
||||
public static List<Rect> findControls(BufferedImage image, Window window, WindowDecorations.CustomTitleBar titleBar, boolean disabledControls) {
|
||||
final int windowWidth = window.getWidth();
|
||||
final int windowHeight = window.getHeight();
|
||||
final int titleBarHeight = (int) titleBar.getHeight();
|
||||
final int leftInset = Math.round(titleBar.getLeftInset());
|
||||
final int rightInset = Math.round(titleBar.getRightInset());
|
||||
|
||||
System.out.println("Image w = " + image.getWidth() + " height = " + image.getHeight());
|
||||
System.out.println("Window w = " + windowWidth + " height = " + window.getHeight());
|
||||
|
||||
// option 1
|
||||
List<Rect> controls1 = detectControlsByBackground(image, titleBarHeight, TestUtils.TITLE_BAR_COLOR);
|
||||
System.out.println("Option1 for " + window.getName());
|
||||
controls1.forEach(System.out::println);
|
||||
|
||||
if (isMatchCondition(window, controls1.size(), disabledControls)) {
|
||||
return controls1;
|
||||
}
|
||||
|
||||
// option2
|
||||
List<Rect> controls2 = detectControlsByBackground2(image, windowWidth, windowHeight, titleBarHeight, leftInset, rightInset, TestUtils.TITLE_BAR_COLOR);
|
||||
System.out.println("Option2 for " + window.getName());
|
||||
controls2.forEach(System.out::println);
|
||||
|
||||
if (isMatchCondition(window, controls2.size(), disabledControls)) {
|
||||
return controls2;
|
||||
}
|
||||
|
||||
// option3
|
||||
List<Rect> controls3 = detectControls(image, titleBarHeight, leftInset, rightInset);
|
||||
System.out.println("Option3 for " + window.getName());
|
||||
controls3.forEach(System.out::println);
|
||||
|
||||
if (isMatchCondition(window, controls3.size(), disabledControls)) {
|
||||
return controls3;
|
||||
}
|
||||
|
||||
// option4
|
||||
List<Rect> controls4 = detectControls2(image, windowWidth, windowHeight, titleBarHeight, leftInset, rightInset);
|
||||
System.out.println("Option4 for " + window.getName());
|
||||
controls4.forEach(System.out::println);
|
||||
|
||||
return controls4;
|
||||
}
|
||||
|
||||
private static boolean isMatchCondition(Window window, int size, boolean disabledControls) {
|
||||
if (!disabledControls) {
|
||||
if (window.getName().equals("Frame") || window.getName().equals("JFrame")) {
|
||||
return size == 3;
|
||||
}
|
||||
if (window.getName().equals("Dialog") || window.getName().equals("JDialog")) {
|
||||
final String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.startsWith("windows")) {
|
||||
return size == 1;
|
||||
}
|
||||
return size == 3;
|
||||
}
|
||||
}
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
public static RectCoordinates calculateControlsRect(BufferedImage image, int windowWidth, int windowHeight, int titleBarHeight, int leftInset, int rightInset) {
|
||||
final int shiftW = (image.getWidth() - windowWidth) / 2;
|
||||
final int shiftH = (image.getHeight() - windowHeight) / 2;
|
||||
int x1;
|
||||
int y1 = shiftH;
|
||||
int x2;
|
||||
int y2 = shiftH + titleBarHeight;
|
||||
if (leftInset > rightInset) {
|
||||
x1 = shiftW;
|
||||
x2 = shiftW + leftInset;
|
||||
} else {
|
||||
x1 = shiftW + windowWidth - rightInset;
|
||||
x2 = windowWidth - shiftW;
|
||||
}
|
||||
return new RectCoordinates(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public static RectCoordinates findRectangleTitleBar(BufferedImage image, int titleBarHeight) {
|
||||
int centerX = image.getWidth() / 2;
|
||||
int centerY = titleBarHeight / 2;
|
||||
@@ -106,6 +190,7 @@ public class ScreenShotHelpers {
|
||||
RectCoordinates coords = findRectangleTitleBar(image, titleBarHeight);
|
||||
List<Rect> result = new ArrayList<>();
|
||||
|
||||
System.out.println("Detect controls by background");
|
||||
System.out.println(coords);
|
||||
|
||||
List<Integer> lefts = new ArrayList<>();
|
||||
@@ -114,9 +199,54 @@ public class ScreenShotHelpers {
|
||||
int leftX = -1;
|
||||
int rightX = -1;
|
||||
|
||||
for (int x = coords.x1(); x <= coords.x2(); x++) {
|
||||
for (int x = coords.x1(); x < coords.x2(); x++) {
|
||||
boolean isBackground = true;
|
||||
for (int y = coords.y1(); y <= coords.y2(); y++) {
|
||||
for (int y = coords.y1(); y < coords.y2(); y++) {
|
||||
Color color = adjustColor(new Color(image.getRGB(x, y)));
|
||||
if (!color.equals(backgroundColor)) {
|
||||
isBackground = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isBackground) {
|
||||
if (leftX == -1) {
|
||||
leftX = x;
|
||||
}
|
||||
rightX = x;
|
||||
} else if (leftX != -1) {
|
||||
lefts.add(leftX);
|
||||
rights.add(rightX);
|
||||
leftX = -1;
|
||||
rightX = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < lefts.size(); i++) {
|
||||
int lx = lefts.get(i);
|
||||
int rx = rights.get(i);
|
||||
|
||||
System.out.println("lx = " + lx + " rx = " + rx);
|
||||
result.add(new Rect(lx, coords.y1(), rx, coords.y2(), 0, Color.BLACK));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Rect> detectControlsByBackground2(BufferedImage image, int windowWidth, int windowHeight, int titleBarHeight, int leftInset, int rightInset, Color backgroundColor) {
|
||||
RectCoordinates coords = calculateControlsRect(image, windowWidth, windowHeight, titleBarHeight, leftInset, rightInset);
|
||||
List<Rect> result = new ArrayList<>();
|
||||
|
||||
System.out.println("Detect controls by background2");
|
||||
System.out.println(coords);
|
||||
|
||||
List<Integer> lefts = new ArrayList<>();
|
||||
List<Integer> rights = new ArrayList<>();
|
||||
|
||||
int leftX = -1;
|
||||
int rightX = -1;
|
||||
|
||||
for (int x = coords.x1(); x < coords.x2(); x++) {
|
||||
boolean isBackground = true;
|
||||
for (int y = coords.y1(); y < coords.y2(); y++) {
|
||||
Color color = adjustColor(new Color(image.getRGB(x, y)));
|
||||
if (!color.equals(backgroundColor)) {
|
||||
isBackground = false;
|
||||
@@ -148,11 +278,41 @@ public class ScreenShotHelpers {
|
||||
|
||||
public static List<Rect> detectControls(BufferedImage image, int titleBarHeight, int leftInset, int rightInset) {
|
||||
RectCoordinates coords = ScreenShotHelpers.findRectangleTitleBar(image, titleBarHeight);
|
||||
System.out.println("Detect controls");
|
||||
System.out.println(coords);
|
||||
|
||||
Map<Color, Rect> map = new HashMap<>();
|
||||
|
||||
for (int x = coords.x1(); x <= coords.x2(); x++) {
|
||||
for (int y = coords.y1(); y <= coords.y2(); y++) {
|
||||
for (int x = coords.x1(); x < coords.x2(); x++) {
|
||||
for (int y = coords.y1(); y < coords.y2(); y++) {
|
||||
Color color = new Color(image.getRGB(x, y));
|
||||
Color adjustedColor = adjustColor(color);
|
||||
Rect rect = map.getOrDefault(adjustedColor, new Rect(adjustedColor));
|
||||
rect.addPoint(x, y);
|
||||
map.put(adjustedColor, rect);
|
||||
}
|
||||
}
|
||||
|
||||
int checkedHeight = coords.y2() - coords.y1() + 1;
|
||||
int checkedWidth = coords.x2() - coords.x1() + 1;
|
||||
int pixels = checkedWidth * checkedHeight;
|
||||
|
||||
int nonCoveredAreaApprox = pixels - (leftInset * checkedHeight + rightInset * checkedHeight);
|
||||
|
||||
List<Rect> rects = map.values().stream().filter(v -> v.getPixelCount() < nonCoveredAreaApprox).toList();
|
||||
|
||||
return groupRects(rects);
|
||||
}
|
||||
|
||||
public static List<Rect> detectControls2(BufferedImage image, int windowWidth, int windowHeight, int titleBarHeight, int leftInset, int rightInset) {
|
||||
RectCoordinates coords = calculateControlsRect(image, windowWidth, windowHeight, titleBarHeight, leftInset, rightInset);
|
||||
System.out.println("Detect controls 2");
|
||||
System.out.println(coords);
|
||||
|
||||
Map<Color, Rect> map = new HashMap<>();
|
||||
|
||||
for (int x = coords.x1(); x < coords.x2(); x++) {
|
||||
for (int y = coords.y1(); y < coords.y2(); y++) {
|
||||
Color color = new Color(image.getRGB(x, y));
|
||||
Color adjustedColor = adjustColor(color);
|
||||
Rect rect = map.getOrDefault(adjustedColor, new Rect(adjustedColor));
|
||||
|
||||
@@ -36,23 +36,25 @@ abstract public class Task {
|
||||
protected Window window;
|
||||
protected boolean passed = true;
|
||||
protected Robot robot;
|
||||
protected String error;
|
||||
|
||||
|
||||
public Task(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public final boolean run(Function<WindowDecorations.CustomTitleBar, Window> windowCreator) {
|
||||
public final TaskResult run(Function<WindowDecorations.CustomTitleBar, Window> windowCreator) {
|
||||
try {
|
||||
robot = new Robot();
|
||||
} catch (AWTException e) {
|
||||
System.out.println("ERROR: unable to initialize robot");
|
||||
final String message = "ERROR: unable to initialize robot";
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
return new TaskResult(false, message);
|
||||
}
|
||||
init();
|
||||
System.out.printf("RUN TEST CASE: %s%n", name);
|
||||
passed = true;
|
||||
error = "";
|
||||
prepareTitleBar();
|
||||
window = windowCreator.apply(titleBar);
|
||||
System.out.println("Created a window with the custom title bar. Window name: " + window.getName());
|
||||
@@ -71,12 +73,21 @@ abstract public class Task {
|
||||
titleBar = null;
|
||||
window.dispose();
|
||||
|
||||
if (passed) {
|
||||
System.out.println("State: PASSED");
|
||||
} else {
|
||||
System.out.println("State: FAILED");
|
||||
if (!TestUtils.isBasicTestCase()) {
|
||||
boolean isMetConditions = TestUtils.checkScreenSizeConditions(window);
|
||||
if (!isMetConditions) {
|
||||
error += "SKIPPED: environment don't match screen size conditions";
|
||||
return new TaskResult(false, true, error);
|
||||
}
|
||||
}
|
||||
return passed;
|
||||
|
||||
return new TaskResult(passed, error);
|
||||
}
|
||||
|
||||
protected void err(String message) {
|
||||
this.error = error + message + "\n";
|
||||
passed = false;
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
|
||||
35
test/jdk/jb/java/awt/CustomTitleBar/util/TaskResult.java
Normal file
35
test/jdk/jb/java/awt/CustomTitleBar/util/TaskResult.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package util;
|
||||
|
||||
public class TaskResult {
|
||||
|
||||
private final boolean passed;
|
||||
private final boolean metConditions;
|
||||
private final String error;
|
||||
|
||||
public TaskResult(boolean passed, String error) {
|
||||
this.passed = passed;
|
||||
this.metConditions = true;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public TaskResult(boolean metConditions, boolean passed, String error) {
|
||||
this.metConditions = metConditions;
|
||||
this.passed = passed;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public boolean isPassed() {
|
||||
return passed;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public TaskResult merge(TaskResult another) {
|
||||
final String error = this.error + "\n" + another.error;
|
||||
final boolean status = this.passed && another.passed;
|
||||
return new TaskResult(status, error);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -160,14 +160,56 @@ public class TestUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private static Rectangle calculateWindowBounds(Window window) {
|
||||
public static boolean isBasicTestCase() {
|
||||
return getUIScale() == 1.0;
|
||||
}
|
||||
|
||||
public static boolean checkScreenSizeConditions(Window window) {
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Insets scnMax = Toolkit.getDefaultToolkit().
|
||||
getScreenInsets(window.getGraphicsConfiguration());
|
||||
int maxHeight = screenSize.height - scnMax.top - scnMax.bottom;
|
||||
int maxWidth = screenSize.width - scnMax.left - scnMax.right;
|
||||
System.out.println("Screen size: " + screenSize);
|
||||
System.out.println("Screen insets: " + scnMax);
|
||||
final int width = screenSize.width - scnMax.left - scnMax.right;
|
||||
final int height = screenSize.height - scnMax.top - scnMax.bottom;
|
||||
System.out.println("Max width = " + width + " max height = " + height);
|
||||
|
||||
return new Rectangle(scnMax.left + 2, scnMax.top + 2, (int) (maxWidth * 0.8), (int) (maxHeight * 0.8));
|
||||
double uiScale = getUIScale();
|
||||
|
||||
final int effectiveWidth = (int) (width / uiScale);
|
||||
final int effectiveHeight = (int) (height / uiScale);
|
||||
|
||||
if (effectiveWidth < 200 || effectiveHeight < 200) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Rectangle calculateWindowBounds(Window window) {
|
||||
double uiScale = getUIScale();
|
||||
System.out.println("UI Scale: " + uiScale);
|
||||
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
System.out.println("Screen size: " + screenSize);
|
||||
|
||||
Insets scnMax = Toolkit.getDefaultToolkit().
|
||||
getScreenInsets(window.getGraphicsConfiguration());
|
||||
int maxHeight = (int) ((screenSize.height - scnMax.top - scnMax.bottom) / uiScale);
|
||||
int maxWidth = (int) ((screenSize.width - scnMax.left - scnMax.right) / uiScale);
|
||||
|
||||
Rectangle bounds = new Rectangle(scnMax.left + 2, scnMax.top + 2, (int) (maxWidth * 0.95), (int) (maxHeight * 0.95));
|
||||
System.out.println("Window bounds: " + bounds);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public static double getUIScale() {
|
||||
boolean scaleEnabled = "true".equals(System.getProperty("sun.java2d.uiScale.enabled"));
|
||||
double uiScale = 1.0;
|
||||
if (scaleEnabled) {
|
||||
uiScale = Float.parseFloat(System.getProperty("sun.java2d.uiScale"));
|
||||
}
|
||||
return uiScale;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
481
test/jdk/jb/java/nio/file/spi/TestProvider.java
Normal file
481
test/jdk/jb/java/nio/file/spi/TestProvider.java
Normal file
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, 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.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.FileAttributeView;
|
||||
import java.nio.file.attribute.UserPrincipalLookupService;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.net.URI;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TestProvider extends FileSystemProvider {
|
||||
|
||||
private final FileSystemProvider defaultProvider;
|
||||
private final TestFileSystem theFileSystem;
|
||||
|
||||
public TestProvider(FileSystemProvider defaultProvider) {
|
||||
this.defaultProvider = defaultProvider;
|
||||
FileSystem fs = defaultProvider.getFileSystem(URI.create("file:/"));
|
||||
this.theFileSystem = new TestFileSystem(fs, this);
|
||||
}
|
||||
|
||||
FileSystemProvider defaultProvider() {
|
||||
return defaultProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
return "file";
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystem newFileSystem(URI uri, Map<String,?> env) throws IOException {
|
||||
return defaultProvider.newFileSystem(uri, env);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystem getFileSystem(URI uri) {
|
||||
return theFileSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(URI uri) {
|
||||
Path path = defaultProvider.getPath(uri);
|
||||
return theFileSystem.wrap(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(Path file, String attribute, Object value,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,Object> readAttributes(Path file, String attributes,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
return defaultProvider.readAttributes(delegate, attributes, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends BasicFileAttributes> A readAttributes(Path file,
|
||||
Class<A> type,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
return defaultProvider.readAttributes(delegate, type, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V extends FileAttributeView> V getFileAttributeView(Path file,
|
||||
Class<V> type,
|
||||
LinkOption... options)
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
return defaultProvider.getFileAttributeView(delegate, type, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Path file) throws IOException {
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
defaultProvider.delete(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLink(Path link, Path existing) throws IOException {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path readSymbolicLink(Path link) throws IOException {
|
||||
Path delegate = theFileSystem.unwrap(link);
|
||||
Path target = defaultProvider.readSymbolicLink(delegate);
|
||||
return theFileSystem.wrap(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(Path source, Path target, CopyOption... options)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(Path source, Path target, CopyOption... options)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectoryStream<Path> newDirectoryStream(Path dir,
|
||||
DirectoryStream.Filter<? super Path> filter)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createDirectory(Path dir, FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(dir);
|
||||
defaultProvider.createDirectory(delegate, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekableByteChannel newByteChannel(Path file,
|
||||
Set<? extends OpenOption> options,
|
||||
FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
return defaultProvider.newByteChannel(delegate, options, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileChannel newFileChannel(Path file,
|
||||
Set<? extends OpenOption> options,
|
||||
FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
Path delegate = theFileSystem.unwrap(file);
|
||||
return defaultProvider.newFileChannel(delegate, options, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(Path file) throws IOException {
|
||||
throw new ReadOnlyFileSystemException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileStore getFileStore(Path file) throws IOException {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(Path file, Path other) throws IOException {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAccess(Path file, AccessMode... modes)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
static class TestFileSystem extends FileSystem {
|
||||
private final FileSystem delegate;
|
||||
private final TestProvider provider;
|
||||
|
||||
TestFileSystem(FileSystem delegate, TestProvider provider) {
|
||||
this.delegate = delegate;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
Path wrap(Path path) {
|
||||
return (path != null) ? new TestPath(this, path) : null;
|
||||
}
|
||||
|
||||
Path unwrap(Path wrapper) {
|
||||
if (wrapper == null)
|
||||
throw new NullPointerException();
|
||||
if (!(wrapper instanceof TestPath))
|
||||
throw new ProviderMismatchException();
|
||||
return ((TestPath)wrapper).unwrap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystemProvider provider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSeparator() {
|
||||
return delegate.getSeparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Path> getRootDirectories() {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<FileStore> getFileStores() {
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> supportedFileAttributeViews() {
|
||||
return delegate.supportedFileAttributeViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(String first, String... more) {
|
||||
Path path = delegate.getPath(first, more);
|
||||
return wrap(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathMatcher getPathMatcher(String syntaxAndPattern) {
|
||||
return delegate.getPathMatcher(syntaxAndPattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserPrincipalLookupService getUserPrincipalLookupService() {
|
||||
return delegate.getUserPrincipalLookupService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchService newWatchService() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
static class TestPath implements Path {
|
||||
private final TestFileSystem fs;
|
||||
private final Path delegate;
|
||||
|
||||
TestPath(TestFileSystem fs, Path delegate) {
|
||||
this.fs = fs;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
Path unwrap() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystem getFileSystem() {
|
||||
return fs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbsolute() {
|
||||
return delegate.isAbsolute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getRoot() {
|
||||
return fs.wrap(delegate.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getParent() {
|
||||
return fs.wrap(delegate.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNameCount() {
|
||||
return delegate.getNameCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFileName() {
|
||||
return fs.wrap(delegate.getFileName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getName(int index) {
|
||||
return fs.wrap(delegate.getName(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path subpath(int beginIndex, int endIndex) {
|
||||
return fs.wrap(delegate.subpath(beginIndex, endIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startsWith(Path other) {
|
||||
return delegate.startsWith(fs.unwrap(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startsWith(String other) {
|
||||
return delegate.startsWith(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endsWith(Path other) {
|
||||
return delegate.endsWith(fs.unwrap(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endsWith(String other) {
|
||||
return delegate.endsWith(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path normalize() {
|
||||
return fs.wrap(delegate.normalize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolve(Path other) {
|
||||
return fs.wrap(delegate.resolve(fs.unwrap(other)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolve(String other) {
|
||||
return fs.wrap(delegate.resolve(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolveSibling(Path other) {
|
||||
return fs.wrap(delegate.resolveSibling(fs.unwrap(other)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolveSibling(String other) {
|
||||
return fs.wrap(delegate.resolveSibling(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path relativize(Path other) {
|
||||
return fs.wrap(delegate.relativize(fs.unwrap(other)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof TestPath))
|
||||
return false;
|
||||
return delegate.equals(fs.unwrap((TestPath) other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI toUri() {
|
||||
String ssp = delegate.toUri().getSchemeSpecificPart();
|
||||
return URI.create(fs.provider().getScheme() + ":" + ssp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path toAbsolutePath() {
|
||||
return fs.wrap(delegate.toAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path toRealPath(LinkOption... options) throws IOException {
|
||||
return fs.wrap(delegate.toRealPath(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File toFile() {
|
||||
return new File(toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Path> iterator() {
|
||||
final Iterator<Path> itr = delegate.iterator();
|
||||
return new Iterator<Path>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return itr.hasNext();
|
||||
}
|
||||
@Override
|
||||
public Path next() {
|
||||
return fs.wrap(itr.next());
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
itr.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Path other) {
|
||||
return delegate.compareTo(fs.unwrap(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchKey register(WatchService watcher,
|
||||
WatchEvent.Kind<?>[] events,
|
||||
WatchEvent.Modifier... modifiers)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchKey register(WatchService watcher,
|
||||
WatchEvent.Kind<?>... events)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static final byte[] EMPTY_PATH = new byte[0];
|
||||
|
||||
public byte[] getSunPathForSocketFile(Path path) {
|
||||
if (path.getNameCount() == 0) {
|
||||
return EMPTY_PATH;
|
||||
}
|
||||
return path.toString().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Verifies that Unix domain sockets work with a non-default
|
||||
* file system provider that implements
|
||||
* @library /test/lib
|
||||
* @build TestProvider
|
||||
* @run main/othervm -Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider UnixSocketWithCustomProvider
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.net.UnixDomainSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
|
||||
public class UnixSocketWithCustomProvider {
|
||||
public static void main(String[] args) {
|
||||
FileSystemProvider provider = FileSystems.getDefault().provider();
|
||||
if (!provider.getClass().getName().equals("TestProvider")) {
|
||||
throw new Error("Test must be run with non-default file system");
|
||||
}
|
||||
|
||||
Path socketPath = Path.of("socket");
|
||||
UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress.of(socketPath);
|
||||
try (ServerSocketChannel serverCh = ServerSocketChannel.open(StandardProtocolFamily.UNIX)) {
|
||||
serverCh.bind(socketAddress);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
Files.deleteIfExists(socketPath);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import com.jetbrains.JBR;
|
||||
import com.jetbrains.WindowDecorations;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key headful
|
||||
* @requires (os.family == "windows" | os.family == "mac")
|
||||
* @summary JBR-4875 The test drag&drops a frame which contains an instance of JComboBox and checks that ComboBoxPopup
|
||||
* does not become detached from its' control. The test performs checking for both cases when
|
||||
* <code>apple.awt.transparentTitleBar</code> is not set and it is set to <code>true</code>.
|
||||
* It is expected that <code>x</code>-coordinates for <code>JFrame</code>, <code>JComboBox</code> and ComboBoxPopup
|
||||
* have the same values after dragging&dropping <code>JFrame</code>.
|
||||
* @run main/timeout=600 ComboBoxTransparentTittleBarTest
|
||||
*/
|
||||
public final class ComboBoxTransparentTittleBarTest {
|
||||
|
||||
private static final int SIZE = 300;
|
||||
private static volatile Robot robot;
|
||||
private static volatile JComboBox<String> comboBox;
|
||||
private static volatile JFrame frame;
|
||||
private static final boolean[] titleBarTransparencies = {false, true};
|
||||
private static final int DRAG_X = 200;
|
||||
private static final StringBuilder errMessages= new StringBuilder();
|
||||
private static int errCount = 0;
|
||||
|
||||
private static final float TITLE_BAR_HEIGHT = 54f;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
robot.setAutoDelay(100);
|
||||
robot.setAutoWaitForIdle(true);
|
||||
|
||||
for (boolean doTitleBarTransparent : titleBarTransparencies) {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
setup(doTitleBarTransparent);
|
||||
});
|
||||
robot.waitForIdle();
|
||||
test();
|
||||
robot.waitForIdle();
|
||||
dispose();
|
||||
}
|
||||
if (errCount > 0)
|
||||
throw new RuntimeException(String.valueOf(errMessages));
|
||||
}
|
||||
|
||||
private static void test() {
|
||||
getLocationOnScreen(frame);
|
||||
getLocationOnScreen(comboBox);
|
||||
|
||||
BasicComboPopup popup = (BasicComboPopup) comboBox.getUI().getAccessibleChild(comboBox, 0);
|
||||
popup.show();
|
||||
getLocationOnScreen(popup);
|
||||
popup.hide();
|
||||
|
||||
int x_init = frame.getLocationOnScreen().x + frame.getWidth() / 2;;
|
||||
int y_init = frame.getLocationOnScreen().y + 5;
|
||||
System.out.print("Drag " + frame.getName() + " from: (" + x_init + ", " + y_init + ")");
|
||||
robot.mouseMove(x_init, y_init);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
|
||||
int x = x_init + DRAG_X;
|
||||
for (int j = x_init; j < x; j += 5) {
|
||||
robot.mouseMove(j, y_init);
|
||||
robot.waitForIdle();
|
||||
}
|
||||
|
||||
System.out.println(" and drop to: (" + x + ", " + y_init + ")");
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
|
||||
Point frameLocation = getLocationOnScreen(frame);
|
||||
Point comboBoxLocation = getLocationOnScreen(comboBox);
|
||||
|
||||
int errCount_before = errCount;
|
||||
if (popup.isVisible()) {
|
||||
System.out.println("ComboPopup is visible");
|
||||
Point popupLocation = popup.getLocationOnScreen();
|
||||
if (frameLocation.x - comboBoxLocation.x != 0)
|
||||
appendErrMsg("***ComboBox location was not changed. Expected point: (" + frameLocation.x + ", " + comboBoxLocation.y + ")");
|
||||
if (frameLocation.x - popupLocation.x != 0)
|
||||
appendErrMsg("***ComboPopup location was not changed. Expected point: (" + frameLocation.x + ", " + popupLocation.y + ")");
|
||||
}
|
||||
if (errCount_before < errCount)
|
||||
System.out.println("***FAILED***");
|
||||
if (errCount_before == errCount)
|
||||
System.out.println("***PASSED***");
|
||||
}
|
||||
|
||||
private static void appendErrMsg(String msg) {
|
||||
errMessages.append(msg);
|
||||
errCount += 1;
|
||||
}
|
||||
|
||||
private static void dispose() throws Exception {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Point getLocationOnScreen(Component component) {
|
||||
Point point = component.getLocationOnScreen();
|
||||
System.out.println(component.getName() + " location: (" + point.x + ", " + point.y + ")");
|
||||
return point;
|
||||
}
|
||||
private static void setup(boolean doTitleBarTransparent) {
|
||||
comboBox = new JComboBox<>();
|
||||
comboBox.setName("ComboBox" + comboBox.hashCode());
|
||||
for (int i = 1; i < 7; i++) {
|
||||
comboBox.addItem("some text in the item-" + i);
|
||||
}
|
||||
|
||||
frame = new JFrame();
|
||||
frame.setAlwaysOnTop(true);
|
||||
frame.add(comboBox);
|
||||
frame.pack();
|
||||
frame.setSize(frame.getWidth(), SIZE);
|
||||
frame.setVisible(true);
|
||||
System.out.println("------------------------------------");
|
||||
System.out.println("The case transparentTitleBar = " + doTitleBarTransparent);
|
||||
if (doTitleBarTransparent) {
|
||||
WindowDecorations.CustomTitleBar titleBar = JBR.getWindowDecorations().createCustomTitleBar();
|
||||
titleBar.setHeight(TITLE_BAR_HEIGHT);
|
||||
JBR.getWindowDecorations().setCustomTitleBar(frame, titleBar);
|
||||
|
||||
MouseListener mouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
titleBar.forceHitTest(false);
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < comboBox.getComponents().length; i++) {
|
||||
comboBox.getComponent(i).addMouseListener(mouseListener);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@
|
||||
import static java.awt.event.KeyEvent.*;
|
||||
|
||||
public class KeyCodesTest implements Runnable {
|
||||
static private final int VK_BACK_QUOTE_ISO = 0x01000000+0x0060;
|
||||
static private final int VK_SECTION = 0x01000000+0x00A7;
|
||||
@Override
|
||||
public void run() {
|
||||
verify('!', VK_EXCLAMATION_MARK, "com.apple.keylayout.French-PC", VK_SLASH);
|
||||
@@ -63,7 +65,28 @@ public class KeyCodesTest implements Runnable {
|
||||
verify('}', VK_BRACERIGHT, "com.apple.keylayout.LatinAmerican", VK_BACK_SLASH);
|
||||
verify('\u00a1', VK_INVERTED_EXCLAMATION_MARK, "com.apple.keylayout.Spanish-ISO", VK_EQUALS);
|
||||
// TODO: figure out which keyboard layout has VK_EURO_SIGN as a key on the primary layer
|
||||
verify('/', VK_DIVIDE, "com.apple.keylayout.ABC", VK_DIVIDE, VK_SLASH);
|
||||
verify('*', VK_MULTIPLY, "com.apple.keylayout.ABC", VK_MULTIPLY, VK_ASTERISK);
|
||||
verify('+', VK_ADD, "com.apple.keylayout.ABC", VK_ADD, VK_PLUS);
|
||||
verify('-', VK_SUBTRACT, "com.apple.keylayout.ABC", VK_SUBTRACT, VK_MINUS);
|
||||
verify('\t', VK_TAB, "com.apple.keylayout.ABC", VK_TAB);
|
||||
verify(' ', VK_SPACE, "com.apple.keylayout.ABC", VK_SPACE);
|
||||
|
||||
// Test numpad numbers
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
verify((char)('0' + i), VK_NUMPAD0 + i, "com.apple.keylayout.ABC", VK_NUMPAD0 + i, VK_0 + i);
|
||||
}
|
||||
verify('\0', VK_F1, "com.apple.keylayout.ABC", VK_F1);
|
||||
verify('\0', VK_F19, "com.apple.keylayout.ABC", VK_F19);
|
||||
|
||||
// Test ANSI/ISO keyboard weirdness
|
||||
verify('\u00a7', 0x01000000+0x00A7, "com.apple.keylayout.ABC", VK_SECTION);
|
||||
verify('\u00b2', 0x01000000+0x00B2, "com.apple.keylayout.French-PC", VK_SECTION);
|
||||
verify('#', VK_NUMBER_SIGN, "com.apple.keylayout.CanadianFrench-PC", VK_SECTION);
|
||||
verify('\u00ab', 0x01000000+0x00AB, "com.apple.keylayout.CanadianFrench-PC", VK_BACK_QUOTE_ISO);
|
||||
verify('#', VK_NUMBER_SIGN, "com.apple.keylayout.CanadianFrench-PC", VK_BACK_QUOTE);
|
||||
|
||||
// Test extended key codes that don't match the unicode char
|
||||
verify('\u00e4', 0x01000000+0x00C4, "com.apple.keylayout.German", VK_QUOTE);
|
||||
verify('\u00e5', 0x01000000+0x00C5, "com.apple.keylayout.Norwegian", VK_OPEN_BRACKET);
|
||||
verify('\u00e6', 0x01000000+0x00C6, "com.apple.keylayout.Norwegian", VK_QUOTE);
|
||||
@@ -73,12 +96,18 @@ public class KeyCodesTest implements Runnable {
|
||||
verify('\u00f8', 0x01000000+0x00D8, "com.apple.keylayout.Norwegian", VK_SEMICOLON);
|
||||
}
|
||||
|
||||
private void verify(char ch, int vk, String layout, int key) {
|
||||
private void verify(char ch, int vk, String layout, int key, int correctKeyCode) {
|
||||
InputMethodTest.section("Key code test: " + vk + ", char: " + ch);
|
||||
InputMethodTest.layout(layout);
|
||||
InputMethodTest.type(key, 0);
|
||||
InputMethodTest.expect(String.valueOf(ch));
|
||||
InputMethodTest.expectKeyCode(vk);
|
||||
InputMethodTest.expectTrue(getExtendedKeyCodeForChar(ch) == vk, "getExtendedKeyCodeForChar(ch) == vk");
|
||||
if (ch != 0) {
|
||||
InputMethodTest.expect(String.valueOf(ch));
|
||||
InputMethodTest.expectTrue(getExtendedKeyCodeForChar(ch) == correctKeyCode, "getExtendedKeyCodeForChar");
|
||||
}
|
||||
}
|
||||
|
||||
private void verify(char ch, int vk, String layout, int key) {
|
||||
verify(ch, vk, layout, key, vk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ public class Key {
|
||||
// So to press some key on the current layout, one needs to pass corresponding US layout key code to Robot.
|
||||
// So every key stores corresponding KeyEvent.VK_ constant name to provide mapping to US layout.
|
||||
int getKeyCode_US() {
|
||||
if (vkName.equals("VK_SECTION")) {
|
||||
return 0x01000000 + 0x00A7;
|
||||
}
|
||||
try {
|
||||
return KeyEvent.class.getField(vkName).getInt(null);
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
|
||||
@@ -38,10 +38,7 @@ public enum Layout_ABC implements LayoutKey {
|
||||
// Enum name must be the same as KeyEvent.VK_ constant name corresponding to the key on US keyboard layout
|
||||
// Note that '\u0000' may be used if no char is mapped to a key + modifier or if one wants to skip its testing
|
||||
|
||||
// TODO Robot cannot press section sign key (16777383),
|
||||
// located on the left side of the key 1 on the Apple International English keyboard
|
||||
// SECTION ('§', '§', '±', '±'),
|
||||
|
||||
VK_SECTION ('§', '§', '±', '±', '0'),
|
||||
VK_MINUS ('-', '–', '_', '—', '\u001F'),
|
||||
VK_EQUALS ('=', '≠', '+', '±', '='),
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public enum Layout_FRENCH_PC implements LayoutKey {
|
||||
|
||||
// Enum name must be the same as KeyEvent.VK_ constant name corresponding to the key on US keyboard layout
|
||||
// Note that '\u0000' may be used if no char is mapped to a key + modifier or if one wants to skip its testing
|
||||
|
||||
VK_SECTION ('²', '≤', '>', '≥', '0'),
|
||||
VK_MINUS (')', ']', '°', ']', '\u001B'),
|
||||
VK_EQUALS ('=', '}', '+', '≠', '\u001F'),
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public enum Layout_GERMAN implements LayoutKey {
|
||||
// Enum name must be the same as KeyEvent.VK_ constant name corresponding to the key on US keyboard layout
|
||||
// Note that '\u0000' may be used if no char is mapped to a key + modifier or if one wants to skip its testing
|
||||
|
||||
VK_SECTION (KeyChar.dead('^'), KeyChar.ch('„'), KeyChar.ch('°'), KeyChar.ch('“'), KeyChar.ch('\u001E')),
|
||||
// Eszett
|
||||
VK_MINUS ('ß', '¿', '?', '˙', 'ß'),
|
||||
VK_EQUALS (KeyChar.dead('´'), KeyChar.ch('\''), KeyChar.dead('`'), KeyChar.ch('˚'), KeyChar.ch('´')),
|
||||
|
||||
@@ -37,6 +37,7 @@ public enum Layout_SPANISH_ISO implements LayoutKey {
|
||||
// Enum name must be the same as KeyEvent.VK_ constant name corresponding to the key on US keyboard layout
|
||||
// Note that '\u0000' may be used if no char is mapped to a key + modifier or if one wants to skip its testing
|
||||
|
||||
VK_SECTION ('º', '\\', 'ª', '°', '0'),
|
||||
VK_MINUS ('\'', '´', '?', '¸', '\u001F'),
|
||||
VK_EQUALS ('¡', '‚', '¿', '˛', '='),
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ public enum Layout_US_INTERNATIONAL_PC implements LayoutKey {
|
||||
// Enum name must be the same as KeyEvent.VK_ constant name corresponding to the key on US keyboard layout
|
||||
// Note that '\u0000' may be used if no char is mapped to a key + modifier or if one wants to skip its testing
|
||||
|
||||
VK_SECTION ('§', '§', '±', '±', '0'),
|
||||
VK_MINUS ('-', '–', '_', '—', '\u001F'),
|
||||
VK_EQUALS ('=', '≠', '+', '±', '='),
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java 8202931,JBR-5398 macosx-all,linux-all,windows-all
|
||||
java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java 8292588 macosx-all
|
||||
java/awt/Frame/MaximizedToOppositeScreen/MaximizedToOppositeScreenSmall.java JBR-4379 windows-all
|
||||
java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java JBR-4379 windows-all
|
||||
|
||||
@@ -114,9 +114,9 @@
|
||||
# jdk_awt
|
||||
|
||||
java/awt/event/MouseEvent/MouseClickTest/MouseClickTest.java 8168389 windows-all,macosx-all
|
||||
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java 8224055 macosx-all
|
||||
java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java 8081489 generic-all
|
||||
java/awt/Focus/FocusSubRequestTest/FocusSubRequestTest.java JBR-5178 windows-all
|
||||
java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java JBR-5210 windows-all
|
||||
java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-all
|
||||
java/awt/Focus/IconifiedFrameFocusChangeTest/IconifiedFrameFocusChangeTest.java 6849364 generic-all
|
||||
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 generic-all
|
||||
@@ -136,13 +136,13 @@ java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java 8164
|
||||
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java 8171510,JBR-881 macosx-all,linux-all
|
||||
javax/swing/dnd/7171812/bug7171812.java 8041447,8253184 macosx-all,windows-all
|
||||
java/awt/Focus/ChoiceFocus/ChoiceFocus.java 8169103 windows-all,macosx-all
|
||||
java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618 macosx-all
|
||||
java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252,JBR-5178 macosx-all,windows-all
|
||||
java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618,JBR-814 macosx-all,linux-all
|
||||
java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252,JBR-5178 windows-all
|
||||
java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java 8194753 linux-all,macosx-all
|
||||
java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest.java 7152980 macosx-all
|
||||
java/awt/Focus/TypeAhead/TestFocusFreeze.java 8198622,6447537 macosx-all,windows-all,linux-all
|
||||
java/awt/Focus/ToFrontFocusTest/ToFrontFocus.java 7156130 linux-all
|
||||
java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096,JBR-4880 macosx-all,windows-all
|
||||
java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096,JBR-4880,JBR-5387 windows-all,linux-all
|
||||
java/awt/event/KeyEvent/CorrectTime/CorrectTime.java 6626492 generic-all
|
||||
java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all
|
||||
java/awt/Frame/ExceptionOnSetExtendedStateTest/ExceptionOnSetExtendedStateTest.java 8198237 macosx-all
|
||||
@@ -217,14 +217,14 @@ java/awt/Focus/8000326/SetFocusTraversalKeysEnabledTest.java JBR-4997 windows-al
|
||||
java/awt/Focus/8073453/AWTFocusTransitionTest.java JBR-5210,8298247 windows-all,linux-all
|
||||
java/awt/Focus/8073453/SwingFocusTransitionTest.java JBR-5210 windows-all
|
||||
java/awt/event/KeyEvent/AltCharAcceleratorTest/AltCharAcceleratorTest.java JBR-5210 windows-all
|
||||
java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java 8169476 windows-all,macosx-all
|
||||
java/awt/event/KeyEvent/KeyChar/KeyCharTest.java 8169474,8224055 macosx-all,windows-all
|
||||
java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java 8169476 windows-all
|
||||
java/awt/event/KeyEvent/KeyChar/KeyCharTest.java 8169474,8224055 windows-all
|
||||
java/awt/event/KeyEvent/ExtendedModifiersTest/ExtendedModifiersTest.java 8129778 generic-all
|
||||
java/awt/event/KeyEvent/KeyMaskTest/KeyMaskTest.java 8129778 generic-all
|
||||
|
||||
java/awt/event/KeyEvent/KeyTyped/CtrlASCII.java JBR-3636,JBR-4880 macosx-all,windows-all
|
||||
java/awt/event/KeyEvent/KeyTyped/CtrlASCII.java JBR-3636,JBR-4880 windows-all
|
||||
|
||||
java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java JBR-3817 windows-all,macosx-all
|
||||
java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java JBR-3817 windows-all
|
||||
java/awt/event/MouseEvent/MouseButtonsAndKeyMasksTest/MouseButtonsAndKeyMasksTest.java 8129778 generic-all
|
||||
|
||||
java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java 8194947 generic-all
|
||||
@@ -278,9 +278,10 @@ java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8253184 w
|
||||
java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all
|
||||
sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all
|
||||
sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all
|
||||
sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java JBR-5393 windows-aarch64
|
||||
sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all
|
||||
sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java 8196180,8252812 windows-all,macosx-all,linux-all
|
||||
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354 macosx-all,windows-aarch64
|
||||
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354 macosx-all,windows-all
|
||||
java/awt/Graphics2D/DrawString/DisposerTest.java JBR-5010 linux-aarch64
|
||||
java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 linux-all
|
||||
java/awt/Graphics2D/DrawString/TextRenderingTest.java JBR-4260,JBR-5359 macosx-11.7.1,windows-aarch64
|
||||
@@ -583,7 +584,7 @@ java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528,8253
|
||||
java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java 8282232 windows-all
|
||||
java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java 8253184 windows-all
|
||||
java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676,8253184 linux-all,windows-all
|
||||
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java 8157147 linux-all,windows-all,macosx-all
|
||||
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java 8157147 linux-all,windows-all
|
||||
java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java 8253184 windows-all
|
||||
java/awt/Mouse/TitleBarDoubleClick/TitleBarDoubleClick.java 8148041 linux-all
|
||||
java/awt/Toolkit/DesktopProperties/rfe4758438.java 8193547 linux-all
|
||||
@@ -596,7 +597,6 @@ java/awt/Frame/DisposeParentGC/DisposeParentGC.java 8079786 macosx-all
|
||||
java/awt/GraphicsDevice/CheckDisplayModes.java 8266242 macosx-aarch64
|
||||
java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223 linux-all,windows-all,macosx-all
|
||||
java/awt/keyboard/8218917/AltKeyBug.java JBR-3636,JBR-5312 macosx-all,windows-all
|
||||
java/awt/keyboard/AllKeyCode/AllKeyCode.java 8242930 macosx-all
|
||||
java/awt/keyboard/AltPlusNumberKeyCombinationsTest/AltPlusNumberKeyCombinationsTest.java JBR-5210 windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogButtonTest/EnqueueWithDialogButtonTest.java JBR-5210 windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-5210 windows-all
|
||||
@@ -604,7 +604,6 @@ java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java JBR
|
||||
java/awt/FullScreen/8013581/bug8013581.java 8169471,JBR-80 macosx-all,windows-all
|
||||
java/awt/event/MouseEvent/RobotLWTest/RobotLWTest.java 8233568 macosx-all
|
||||
java/awt/event/MouseEvent/MultipleMouseButtonsTest/MultipleMouseButtonsTest.java 8233568 macosx-all
|
||||
java/awt/event/MouseEvent/ClickDuringKeypress/ClickDuringKeypress.java 8233568 macosx-all
|
||||
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java 8233568 macosx-all
|
||||
java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java 8233568 macosx-all
|
||||
java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 8271519 linux-all
|
||||
@@ -890,7 +889,9 @@ javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all
|
||||
javax/swing/JComboBox/4523758/bug4523758.java 8253184 windows-all
|
||||
javax/swing/JComboBox/8182031/ComboPopupTest.java 8196465,8253184 linux-all,macosx-all,windows-all
|
||||
javax/swing/JFileChooser/6738668/bug6738668.java 8194946 generic-all
|
||||
javax/swing/JInternalFrame/6288609/TestJInternalFrameDispose.java JBR-788 windows-all,linux-all
|
||||
javax/swing/JInternalFrame/6647340/bug6647340.java 8253184 windows-all
|
||||
javax/swing/JInternalFrame/8145060/TestJInternalFrameMinimize.java JBR-788 windows-all,linux-all
|
||||
javax/swing/JInternalFrame/Test6325652.java 8224977 macosx-all,windows-all
|
||||
javax/swing/JInternalFrame/Test6802868.java 8253184 windows-all
|
||||
javax/swing/JPopupMenu/4634626/bug4634626.java 8253184 windows-all
|
||||
@@ -914,12 +915,12 @@ javax/swing/plaf/synth/SynthScrollbarThumbPainter/SynthScrollbarThumbPainterTest
|
||||
javax/swing/JInternalFrame/5066752/bug5066752.java 8253184 windows-all
|
||||
javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java 8277816,JBR-5359 macosx-aarch64,windows-aarch64
|
||||
javax/swing/JInternalFrame/8020708/bug8020708.java JBR-4879 windows-all
|
||||
javax/swing/JInternalFrame/8069348/bug8069348.java 8277816,8253184 macosx-aarch64,windows-all
|
||||
javax/swing/JInternalFrame/8069348/bug8069348.java 8277816,8253184,JBR-900 macosx-aarch64,windows-all,linux-all
|
||||
javax/swing/SwingUtilities/7088744/bug7088744.java 8197552 windows-all
|
||||
javax/swing/ToolTipManager/Test6256140.java 8197552 windows-all
|
||||
javax/swing/text/DefaultEditorKit/4278839/bug4278839.java CODETOOLS-7901623 windows-all
|
||||
javax/swing/text/GlyphPainter2/6427244/bug6427244.java JBR-896 windows-all
|
||||
javax/swing/text/JTextComponent/5074573/bug5074573.java CODETOOLS-7901623 windows-all
|
||||
javax/swing/text/JTextComponent/5074573/bug5074573.java CODETOOLS-7901623,JBR-5386 windows-all,linux-all
|
||||
javax/swing/text/StyledEditorKit/4506788/bug4506788.java JBR-180 windows-all
|
||||
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184 windows-all
|
||||
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8277816,8253184 macosx-aarch64,windows-all
|
||||
@@ -1056,7 +1057,7 @@ java/awt/font/EmojiVariation.java JBR-5009 linux-aarch64
|
||||
java/awt/font/TextLayout/TestJustification.html 8250791 macosx-all
|
||||
java/awt/font/TextLayout/TestSinhalaChar.java JBR-5103 generic-all
|
||||
javax/swing/JTabbedPane/4209065/bug4209065.java 8251177 macosx-all
|
||||
javax/swing/JTableHeader/6889007/bug6889007.java 8253184,8197552 windows-all
|
||||
javax/swing/JTableHeader/6889007/bug6889007.java 8253184,8197552,JBR-5387 windows-all,linux-all
|
||||
javax/swing/JTextField/8036819/bug8036819.java 8197552 windows-all
|
||||
javax/swing/JTree/4908142/bug4908142.java 8197552 windows-all
|
||||
javax/swing/JTree/4927934/bug4927934.java 8197552 windows-all
|
||||
@@ -1123,6 +1124,7 @@ com/sun/java/swing/plaf/windows/Test8173145.java
|
||||
com/sun/java/swing/plaf/windows/AltFocusIssueTest.java JBR-4197 windows-all
|
||||
|
||||
java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java JBR-4207 windows-all
|
||||
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-5392 windows-aarch64
|
||||
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTestLinux.sh JBR-4078 linux-all
|
||||
jb/java/awt/keyboard/AltGrMustGenerateAltGrModifierTest4207.java JBR-4207 windows-all
|
||||
jb/java/awt/Toolkit/AWTThreadingTest.java JBR-4350 macosx-all
|
||||
@@ -1147,7 +1149,7 @@ java/awt/image/multiresolution/MenuMultiresolutionIconTest.java JBR-4880,8253184
|
||||
java/awt/MenuBar/SeparatorsNavigation/SeparatorsNavigation.java JBR-4880 windows-all
|
||||
javax/swing/JFileChooser/8002077/bug8002077.java JBR-4880 windows-all
|
||||
javax/swing/JFileChooser/JFileChooserSetLocationTest.java 8295804 linux-all,macosx-all,windows-all
|
||||
javax/swing/JSlider/6348946/bug6348946.java 8197552 windows-all
|
||||
javax/swing/JSlider/6348946/bug6348946.java 8197552,JBR-5387 windows-all,linux-all
|
||||
javax/swing/JSpinner/4973721/bug4973721.java 8197552 windows-all
|
||||
javax/swing/JSpinner/5012888/bug5012888.java JBR-4880 windows-all
|
||||
javax/swing/JSpinner/JSpinnerFocusTest.java JBR-5288 windows-all
|
||||
|
||||
@@ -10,14 +10,12 @@ java/awt/event/KeyEvent/AltCharAcceleratorTest/AltCharAcceleratorTest.java nobug
|
||||
java/awt/hidpi/SetMaximizedBoundsTest.java nobug windows-all
|
||||
java/awt/Focus/8000326/SetFocusTraversalKeysEnabledTest.java nobug windows-all
|
||||
java/awt/Focus/FocusSubRequestTest/FocusSubRequestTest.java nobug windows-all
|
||||
java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayoutTraversalTest.java nobug windows-all
|
||||
java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java nobug windows-all
|
||||
java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest.java nobug windows-all
|
||||
java/awt/Focus/ShowFrameCheckForegroundTest/ShowFrameCheckForegroundTest.java nobug windows-all
|
||||
java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java nobug windows-all,macosx-all,linux-all
|
||||
java/awt/Focus/UnaccessibleChoice/AccessibleChoiceTest.java nobug windows-all
|
||||
java/awt/Focus/WindowInitialFocusTest/WindowInitialFocusTest.java nobug windows-all
|
||||
java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java nobug windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/FreezeTest/FreezeTest.java nobug windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java nobug windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java nobug windows-all
|
||||
@@ -53,9 +51,6 @@ javax/swing/JEditorPane/8195095/ImageViewTest.java nobug windows-all
|
||||
javax/swing/JFrame/8016356/bug8016356.java nobug windows-all
|
||||
javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java nobug windows-all
|
||||
javax/swing/JInternalFrame/5066752/bug5066752.java nobug windows-all
|
||||
javax/swing/JInternalFrame/6288609/TestJInternalFrameDispose.java nobug windows-all
|
||||
javax/swing/JInternalFrame/8069348/bug8069348.java nobug windows-all
|
||||
javax/swing/JInternalFrame/8145060/TestJInternalFrameMinimize.java nobug windows-all,linux-all
|
||||
javax/swing/JInternalFrame/Test6505027.java nobug windows-all
|
||||
javax/swing/JLabel/7004134/bug7004134.java nobug linux-all
|
||||
javax/swing/JMenu/6538132/6538132.java 8197552 windows-all
|
||||
|
||||
Reference in New Issue
Block a user