Compare commits

..

19 Commits
1665 ... 1692

Author SHA1 Message Date
Vitaly Provodin
f950ff463c a11y: exclude tests crashing JBR in the runs with enabled Voice Over 2021-10-01 10:40:34 +07:00
Mikhail Grishchenko
cf2f09827c Revert "JBR-3688 PyCharm incredibly slow with fakexrandr"
This reverts commit accef6f21e.
2021-09-27 05:53:55 +07:00
Maxim Kartashev
152a4e886d JBR-3680 Cherry-pick Google's NIO patches to get faster file listing
Fix regression introduced by Google's NIO patches:
- do not attempt to get the next entry after the directory stream has
been closed already,
- fix FaultyFileSystem that is used in StreamTest.java to throw
the right exception even when getFileAttributeView() is used instead of
readAttributes(),
- added a test for walking a directory with a non-latin name.
2021-09-24 14:16:22 +03:00
Brian Burkhalter
ef6db5cad0 8264400: (fs) WindowsFileStore equality depends on how the FileStore was constructed
Reviewed-by: alanb

(AKA JBR-3680 Cherry-pick Google's NIO patches to get faster file listing)
2021-09-24 10:38:30 +03:00
Renaud Paquay
6d1c3f06c4 Add BasicWithKeyFileAttributeView interface
This new interface is similar to `BasicFileAttributeView` except it
gives implementations a hint that the fileKey() should be acquired
even at some performance cost.

`FileTreeWalker` uses this new interface to request a file key
in addition to regular file attributes so that file equality can
be efficiently performed when checking for loops during file
tree traversal.

This makes `FileTreeWalker` about 2x faster when traversing non
trivial file system trees with the FOLLOW_LINKS option.

Change-Id: I8de047c8fc241dbab9ad57c5e361118a3a94893d

(AKA JBR-3680 Cherry-pick Google's NIO patches to get faster file listing)
2021-09-24 10:38:19 +03:00
Renaud Paquay
7c2d7541ba Improve performance of WindowsDirectoryStream
Use `NtQueryDirectoryInformation` instead of `FindFirst/FindNext` to
retrieve the list of entries of a directory.

`NtQueryDirectionInformation` has 2 main benefits over
`FindFist`/`FindNext`:

* Performance is about 40% faster

* Each retrieved entry retrieved contains a 64-bit `FileId` in addition
  to the usual attributes, ensuring that returned `java.nio.Path`
  instances hold onto a `BasicFileAttributes` instance that exposes a
  non-null `java.nio.file.attribute.BasicFileAttributes.fileKey()`.

This change also requires creating a new WindowsFileKey class, similar
to UnixFileKey class, so that
`java.nio.file.attribute.BasicFileAttributes.fileKey()` can return an
Object instance that can be used to compare files for equality.

With this change, the Windows implementation of Files.walkFileTree is
about 40% faster when the FOLLOW_LINKS option is not used, and about
2.5x faster when the FOLLOW_LINKS option is used.

When the FOLLOW_LINKS option is used, most calls to
`Files.isSameFile`, which is expensive as it requires 2 file I/O
operations, are avoided because the Path entries returned by the
new WindowsDirectoryStream implementation now contain a non-null
BasicFileAttributes.fileKey(). The remaining calls to
`Files.isSameFile` are performed when Files.walkFileTree need
to compare the initial directory with other entries.

Change-Id: Id79d89d477a6d5dcf151c63a9d6072c6f7ef43b2

(AKA JBR-3680 Cherry-pick Google's NIO patches to get faster file listing)
2021-09-24 10:37:53 +03:00
Roger Riggs
4d01bcc46e 8269850: Most JDK releases report macOS version 12 as 10.16 instead of 12.0
Reviewed-by: naoto, clanger
(cherry picked from commit 3b1b8fc646)
(AKA JBR-3804 Cherry-pick 8269850 from OpenJDK11)
2021-09-24 09:12:04 +03:00
Dmitry Batrak
7d915be754 JBR-3799 Broken input of supplementary plane Unicode characters on macOS
apply upstream fix (JDK-8272602)
2021-09-22 15:10:09 +03:00
Dmitry Batrak
f2bcb756f8 JBR-3799 Broken input of supplementary plane Unicode characters on macOS
revert initial fix, to be replaced with upstream one
2021-09-22 15:10:09 +03:00
Anton Tarasov
a38b7a22fe JBR-3722 macOS: SIGSEGV at [libjvm] _ZN14AccessInternal19PostRuntimeDispatchIN12G1BarrierSet13AccessBarrierILy1097844ES1_EELNS_11BarrierTypeE2ELy1097844EE18oop_access_barrierEPv 2021-09-22 13:22:23 +03:00
Dmitry Batrak
8e58801c9a JBR-3799 Broken input of supplementary plane Unicode characters on macOS
free memory in 'finally' clause, just in case
2021-09-22 13:13:29 +03:00
Dmitry Batrak
7864d59d6f JBR-3799 Broken input of supplementary plane Unicode characters on macOS 2021-09-22 13:08:53 +03:00
Artem Semenov
aad640dcc9 JBR-3792 JavaAccessibilityUtilities leaks JNI objects 2021-09-22 10:23:56 +03:00
Dmitry Batrak
37901295e1 improve the stability of TypeaheadRequestFocusTest
it failed sometimes under MATE desktop environment on Linux
2021-09-21 13:01:07 +03:00
Dmitry Batrak
ad1595b5c2 make NestedDialogHideTest more reliable
currently, if fails on KDE, if multiple workspaces are configured, because mouse cursor happens to be located over 'pin' button in window title bar,
and that hover causes a tooltip to be shown, which blocks mouse clicks
2021-09-20 18:09:38 +03:00
Dmitry Batrak
f5c5388fb5 JBR-3786 javax/swing/plaf/aqua/CustomComboBoxFocusTest.java fails on MacOS by timeout 2021-09-20 17:13:28 +03:00
Dmitry Batrak
0bf13985d5 JBR-3779 Unexpected Alt+Tab behaviour for Java frames on Cinnamon DE 2021-09-20 12:03:39 +03:00
Ivan Migalev
2f772fd1a2 JBR-3785: don't touch the active keyboard layout on input method activation / deactivation.
origin PR: github.com/JetBrains/JetBrainsRuntime/pull/78.
2021-09-20 14:52:49 +07:00
Maxim Kartashev
accef6f21e JBR-3688 PyCharm incredibly slow with fakexrandr
Cache screen bounds and insets and (conservatively) reset those caches
upon any possibility of a change.
This feature can be disabled with -Dx11.cache.screen.insets=false and
-Dx11.cache.screen.bounds=false.
2021-09-20 10:07:27 +03:00
29 changed files with 953 additions and 175 deletions

View File

@@ -254,6 +254,7 @@ void setOSNameAndVersion(java_props_t *sprops) {
// Hardcode os_name, and fill in os_version
sprops->os_name = strdup("Mac OS X");
NSString *nsVerStr = NULL;
char* osVersionCStr = NULL;
// Mac OS 10.9 includes the [NSProcessInfo operatingSystemVersion] function,
// but it's not in the 10.9 SDK. So, call it via NSInvocation.
@@ -266,7 +267,6 @@ void setOSNameAndVersion(java_props_t *sprops) {
[invoke invokeWithTarget:[NSProcessInfo processInfo]];
[invoke getReturnValue:&osVer];
NSString *nsVerStr;
// Copy out the char* if running on version other than 10.16 Mac OS (10.16 == 11.x)
// or explicitly requesting version compatibility
if (!((long)osVer.majorVersion == 10 && (long)osVer.minorVersion >= 16) ||
@@ -278,36 +278,30 @@ void setOSNameAndVersion(java_props_t *sprops) {
nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld",
(long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion];
}
// Copy out the char*
osVersionCStr = strdup([nsVerStr UTF8String]);
} else {
// Version 10.16, without explicit env setting of SYSTEM_VERSION_COMPAT
// AKA 11.x; compute the version number from the letter in the ProductBuildVersion
// AKA 11+ Read the *real* ProductVersion from the hidden link to avoid SYSTEM_VERSION_COMPAT
// If not found, fallback below to the SystemVersion.plist
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
@"/System/Library/CoreServices/SystemVersion.plist"];
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
if (version != NULL) {
NSString *nsBuildVerStr = [version objectForKey : @"ProductBuildVersion"];
if (nsBuildVerStr != NULL && nsBuildVerStr.length >= 3) {
int letter = [nsBuildVerStr characterAtIndex:2];
if (letter >= 'B' && letter <= 'Z') {
int vers = letter - 'A' - 1;
asprintf(&osVersionCStr, "11.%d", vers);
}
}
nsVerStr = [version objectForKey : @"ProductVersion"];
}
}
}
// Fallback if running on pre-10.9 Mac OS
if (osVersionCStr == NULL) {
if (nsVerStr == NULL) {
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
@"/System/Library/CoreServices/SystemVersion.plist"];
if (version != NULL) {
NSString *nsVerStr = [version objectForKey : @"ProductVersion"];
if (nsVerStr != NULL) {
osVersionCStr = strdup([nsVerStr UTF8String]);
}
nsVerStr = [version objectForKey : @"ProductVersion"];
}
}
if (nsVerStr != NULL) {
// Copy out the char*
osVersionCStr = strdup([nsVerStr UTF8String]);
}
if (osVersionCStr == NULL) {
osVersionCStr = strdup("Unknown");
}

View File

@@ -25,6 +25,8 @@
package java.nio.file;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicWithKeyFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.io.Closeable;
import java.io.IOException;
@@ -216,7 +218,11 @@ class FileTreeWalker implements Closeable {
// links then a link target might not exist so get attributes of link
BasicFileAttributes attrs;
try {
attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
BasicFileAttributeView view = Files.getFileAttributeView(file, BasicWithKeyFileAttributeView.class, linkOptions);
if (view == null) {
view = Files.getFileAttributeView(file, BasicFileAttributeView.class, linkOptions);
}
attrs = view.readAttributes();
} catch (IOException ioe) {
if (!followLinks)
throw ioe;

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2007, 2011, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package java.nio.file.attribute;
import java.io.IOException;
/**
* Similar to {@link BasicFileAttributeView} with a hint to implementors
* to retrieve a valid {@link BasicFileAttributes#fileKey()} if possible, even
* at a performance cost.
*/
public interface BasicWithKeyFileAttributeView
extends BasicFileAttributeView {
}

View File

@@ -41,16 +41,16 @@ import static sun.nio.fs.WindowsConstants.*;
class WindowsDirectoryStream
implements DirectoryStream<Path>
{
private static final int NATIVE_BUFFER_SIZE = 8192;
private final WindowsPath dir;
private final DirectoryStream.Filter<? super Path> filter;
// handle to directory
private final long handle;
// first entry in the directory
private final String firstName;
// Query directory information data structure
private final QueryDirectoryInformation queryDirectoryInformation;
// buffer for WIN32_FIND_DATA structure that receives information about file
private final NativeBuffer findDataBuffer;
// Buffer used to receive file entries from NtQueryDirectoryInformation calls
private final NativeBuffer queryDirectoryInformationBuffer;
private final Object closeLock = new Object();
@@ -65,21 +65,15 @@ class WindowsDirectoryStream
this.dir = dir;
this.filter = filter;
this.queryDirectoryInformationBuffer = NativeBuffers.getNativeBuffer(NATIVE_BUFFER_SIZE);
try {
// Need to append * or \* to match entries in directory.
// Open the directory for reading and read the first set of entries in the native buffer
String search = dir.getPathForWin32Calls();
char last = search.charAt(search.length() -1);
if (last == ':' || last == '\\') {
search += "*";
} else {
search += "\\*";
}
FirstFile first = FindFirstFile(search);
this.handle = first.handle();
this.firstName = first.name();
this.findDataBuffer = WindowsFileAttributes.getBufferForFindData();
this.queryDirectoryInformation = OpenNtQueryDirectoryInformation(search, this.queryDirectoryInformationBuffer);
} catch (WindowsException x) {
// Release the buffer, as this instance is not fully constructed
this.queryDirectoryInformationBuffer.release();
if (x.lastError() == ERROR_DIRECTORY) {
throw new NotDirectoryException(dir.getPathForExceptionMessage());
}
@@ -99,9 +93,9 @@ class WindowsDirectoryStream
return;
isOpen = false;
}
findDataBuffer.release();
queryDirectoryInformationBuffer.release();
try {
FindClose(handle);
CloseNtQueryDirectoryInformation(queryDirectoryInformation);
} catch (WindowsException x) {
x.rethrowAsIOException(dir);
}
@@ -115,20 +109,20 @@ class WindowsDirectoryStream
synchronized (this) {
if (iterator != null)
throw new IllegalStateException("Iterator already obtained");
iterator = new WindowsDirectoryIterator(firstName);
iterator = new WindowsDirectoryIterator();
return iterator;
}
}
private class WindowsDirectoryIterator implements Iterator<Path> {
private boolean atEof;
private String first;
private Path nextEntry;
private String prefix;
private int nextOffset;
WindowsDirectoryIterator(String first) {
WindowsDirectoryIterator() {
atEof = false;
this.first = first;
nextOffset = 0;
if (dir.needsSlashWhenResolving()) {
prefix = dir.toString() + "\\";
} else {
@@ -156,44 +150,40 @@ class WindowsDirectoryStream
// reads next directory entry
private Path readNextEntry() {
// handle first element returned by search
if (first != null) {
nextEntry = isSelfOrParent(first) ? null : acceptEntry(first, null);
first = null;
if (nextEntry != null)
return nextEntry;
}
for (;;) {
String name = null;
String name;
WindowsFileAttributes attrs;
// synchronize on closeLock to prevent close while reading
synchronized (closeLock) {
try {
if (isOpen) {
name = FindNextFile(handle, findDataBuffer.address());
}
} catch (WindowsException x) {
IOException ioe = x.asIOException(dir);
throw new DirectoryIteratorException(ioe);
}
// NO_MORE_FILES or stream closed
if (name == null) {
// Fetch next set of entries if we don't have anything available in buffer
if (!isOpen) {
atEof = true;
return null;
}
// ignore link to self and parent directories
if (isSelfOrParent(name))
continue;
if (nextOffset < 0) {
try {
atEof = !NextNtQueryDirectoryInformation(queryDirectoryInformation, queryDirectoryInformationBuffer);
} catch (WindowsException x) {
IOException ioe = x.asIOException(dir);
throw new DirectoryIteratorException(ioe);
}
if (atEof) {
return null;
}
nextOffset = 0;
}
// grab the attributes from the WIN32_FIND_DATA structure
// (needs to be done while holding closeLock because close
// will release the buffer)
attrs = WindowsFileAttributes
.fromFindData(findDataBuffer.address());
long fullDirInformationAddress = queryDirectoryInformationBuffer.address() + nextOffset;
int nextEntryOffset = WindowsFileAttributes.getNextOffsetFromFileIdFullDirInformation(fullDirInformationAddress);
nextOffset = nextEntryOffset == 0 ? -1 : nextOffset + nextEntryOffset;
name = WindowsFileAttributes.getFileNameFromFileIdFullDirInformation(fullDirInformationAddress);
if (isSelfOrParent(name)) {
// Skip "." and ".."
continue;
}
attrs = WindowsFileAttributes.fromFileIdFullDirInformation(fullDirInformationAddress, queryDirectoryInformation.volSerialNumber());
}
// return entry if accepted by filter

View File

@@ -150,6 +150,23 @@ class WindowsFileAttributeViews {
}
}
private static class BasicWithKey extends Basic {
BasicWithKey(WindowsPath file, boolean followLinks) {
super(file, followLinks);
}
@Override
public WindowsFileAttributes readAttributes() throws IOException {
file.checkRead();
try {
return WindowsFileAttributes.getWithFileKey(file, followLinks);
} catch (WindowsException x) {
x.rethrowAsIOException(file);
return null; // keep compiler happy
}
}
}
static class Dos extends Basic implements DosFileAttributeView {
private static final String READONLY_NAME = "readonly";
private static final String ARCHIVE_NAME = "archive";
@@ -289,6 +306,10 @@ class WindowsFileAttributeViews {
return new Basic(file, followLinks);
}
static Basic createBasicWithKeyView(WindowsPath file, boolean followLinks) {
return new BasicWithKey(file, followLinks);
}
static Dos createDosView(WindowsPath file, boolean followLinks) {
return new Dos(file, followLinks);
}

View File

@@ -108,6 +108,34 @@ class WindowsFileAttributes
private static final short OFFSETOF_FIND_DATA_SIZELOW = 32;
private static final short OFFSETOF_FIND_DATA_RESERVED0 = 36;
/**
* typedef struct _FILE_ID_FULL_DIR_INFORMATION {
* ULONG NextEntryOffset; // offset = 0
* ULONG FileIndex; // offset = 4
* LARGE_INTEGER CreationTime; // offset = 8
* LARGE_INTEGER LastAccessTime; // offset = 16
* LARGE_INTEGER LastWriteTime; // offset = 24
* LARGE_INTEGER ChangeTime; // offset = 32
* LARGE_INTEGER EndOfFile; // offset = 40
* LARGE_INTEGER AllocationSize; // offset = 48
* ULONG FileAttributes; // offset = 56
* ULONG FileNameLength; // offset = 60
* ULONG EaSize; // offset = 64
* LARGE_INTEGER FileId; // offset = 72
* WCHAR FileName[1]; // offset = 80
* } FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
*/
private static final int OFFSETOF_FULL_DIR_INFO_NEXT_ENTRY_OFFSET = 0;
private static final int OFFSETOF_FULL_DIR_INFO_CREATION_TIME = 8;
private static final int OFFSETOF_FULL_DIR_INFO_LAST_ACCESS_TIME = 16;
private static final int OFFSETOF_FULL_DIR_INFO_LAST_WRITE_TIME = 24;
private static final int OFFSETOF_FULL_DIR_INFO_END_OF_FILE = 40;
private static final int OFFSETOF_FULL_DIR_INFO_FILE_ATTRIBUTES = 56;
private static final int OFFSETOF_FULL_DIR_INFO_FILENAME_LENGTH = 60;
private static final int OFFSETOF_FULL_DIR_INFO_EA_SIZE = 64;
private static final int OFFSETOF_FULL_DIR_INFO_FILE_ID = 72;
private static final int OFFSETOF_FULL_DIR_INFO_FILENAME = 80;
// used to adjust values between Windows and java epoch
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
@@ -132,6 +160,9 @@ class WindowsFileAttributes
private final int fileIndexHigh;
private final int fileIndexLow;
// created lazily
private volatile WindowsFileKey key;
/**
* Convert 64-bit value representing the number of 100-nanosecond intervals
* since January 1, 1601 to a FileTime.
@@ -257,6 +288,47 @@ class WindowsFileAttributes
0); // fileIndexLow
}
/**
* Create a WindowsFileAttributes from a FILE_ID_FULL_DIR_INFORMATION structure
*/
static WindowsFileAttributes fromFileIdFullDirInformation(long address, int volSerialNumber) {
int fileAttrs = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ATTRIBUTES);
long creationTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_CREATION_TIME);
long lastAccessTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_LAST_ACCESS_TIME);
long lastWriteTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_LAST_WRITE_TIME);
long size = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_END_OF_FILE);
int reparseTag = isReparsePoint(fileAttrs) ?
unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_EA_SIZE) : 0;
int fileIndexLow = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ID);
int fileIndexHigh = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ID + 4);
return new WindowsFileAttributes(fileAttrs,
creationTime,
lastAccessTime,
lastWriteTime,
size,
reparseTag,
volSerialNumber,
fileIndexHigh, // fileIndexHigh
fileIndexLow); // fileIndexLow
}
static int getNextOffsetFromFileIdFullDirInformation(long address) {
return unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_NEXT_ENTRY_OFFSET);
}
static String getFileNameFromFileIdFullDirInformation(long address) {
// copy the name
int nameLengthInBytes = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILENAME_LENGTH);
if ((nameLengthInBytes % 2) != 0) {
throw new AssertionError("FileNameLength is not a multiple of 2");
}
char[] nameAsArray = new char[nameLengthInBytes/2];
unsafe.copyMemory(null, address + OFFSETOF_FULL_DIR_INFO_FILENAME, nameAsArray,
Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes);
return new String(nameAsArray);
}
/**
* Reads the attributes of an open file
*/
@@ -347,6 +419,15 @@ class WindowsFileAttributes
}
// file is reparse point so need to open file to get attributes
return getWithFileKey(path, followLinks);
}
/**
* Returns attributes of given file.
*/
static WindowsFileAttributes getWithFileKey(WindowsPath path, boolean followLinks)
throws WindowsException
{
long handle = path.openForReadAttributeAccess(followLinks);
try {
return readAttributes(handle);
@@ -414,7 +495,17 @@ class WindowsFileAttributes
@Override
public Object fileKey() {
return null;
if (volSerialNumber == 0) {
return null;
}
if (key == null) {
synchronized (this) {
if (key == null) {
key = new WindowsFileKey(volSerialNumber, ((long)fileIndexHigh << 32) + fileIndexLow);
}
}
}
return key;
}
// package private

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2008, 2009, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package sun.nio.fs;
/**
* Container for volume/file id to uniquely identify file.
*/
class WindowsFileKey {
private final int volSerialNumber;
private final long fileId;
WindowsFileKey(int volSerialNumber, long fileId) {
this.volSerialNumber = volSerialNumber;
this.fileId = fileId;
}
@Override
public int hashCode() {
return (int)(volSerialNumber ^ (volSerialNumber >>> 16)) +
(int)(fileId ^ (fileId >>> 32));
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof WindowsFileKey))
return false;
WindowsFileKey other = (WindowsFileKey)obj;
return (this.volSerialNumber == other.volSerialNumber) && (this.fileId == other.fileId);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(volId=")
.append(Integer.toHexString(volSerialNumber))
.append(",fileId=")
.append(Long.toHexString(fileId))
.append(')');
return sb.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,17 @@
package sun.nio.fs;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.FileStore;
import java.nio.file.FileSystemException;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.FileStoreAttributeView;
import java.nio.file.attribute.UserDefinedFileAttributeView;
import java.io.IOException;
import java.util.Locale;
import static sun.nio.fs.WindowsConstants.*;
import static sun.nio.fs.WindowsNativeDispatcher.*;
@@ -44,6 +52,8 @@ class WindowsFileStore
private final int volType;
private final String displayName; // returned by toString
private int hashCode;
private WindowsFileStore(String root) throws WindowsException {
assert root.charAt(root.length()-1) == '\\';
this.root = root;
@@ -223,12 +233,20 @@ class WindowsFileStore
if (!(ob instanceof WindowsFileStore))
return false;
WindowsFileStore other = (WindowsFileStore)ob;
return root.equals(other.root);
if (root.equals(other.root))
return true;
if (volType == DRIVE_FIXED && other.volumeType() == DRIVE_FIXED)
return root.equalsIgnoreCase(other.root);
return false;
}
@Override
public int hashCode() {
return root.hashCode();
if (hashCode == 0) { // Don't care about race
hashCode = (volType == DRIVE_FIXED) ?
root.toLowerCase(Locale.ROOT).hashCode() : root.hashCode();
}
return hashCode;
}
@Override
@@ -242,4 +260,4 @@ class WindowsFileStore
sb.append(")");
return sb.toString();
}
}
}

View File

@@ -167,6 +167,8 @@ class WindowsFileSystemProvider
boolean followLinks = Util.followLinks(options);
if (view == BasicFileAttributeView.class)
return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
if (view == BasicWithKeyFileAttributeView.class)
return (V) WindowsFileAttributeViews.createBasicWithKeyView(file, followLinks);
if (view == DosFileAttributeView.class)
return (V) WindowsFileAttributeViews.createDosView(file, followLinks);
if (view == AclFileAttributeView.class)
@@ -204,6 +206,8 @@ class WindowsFileSystemProvider
boolean followLinks = Util.followLinks(options);
if (name.equals("basic"))
return WindowsFileAttributeViews.createBasicView(file, followLinks);
if (name.equals("basicwithkey"))
return WindowsFileAttributeViews.createBasicWithKeyView(file, followLinks);
if (name.equals("dos"))
return WindowsFileAttributeViews.createDosView(file, followLinks);
if (name.equals("acl"))

View File

@@ -277,6 +277,38 @@ class WindowsNativeDispatcher {
*/
static native void FindClose(long handle) throws WindowsException;
static QueryDirectoryInformation OpenNtQueryDirectoryInformation(String path, NativeBuffer buffer) throws WindowsException {
NativeBuffer pathBuffer = asNativeBuffer(path);
try {
QueryDirectoryInformation data = new QueryDirectoryInformation();
OpenNtQueryDirectoryInformation0(pathBuffer.address(), buffer.address(), buffer.size(), data);
return data;
} finally {
pathBuffer.release();
}
}
static class QueryDirectoryInformation {
private long handle;
private int volSerialNumber;
private QueryDirectoryInformation() { }
public long handle() { return handle; }
public int volSerialNumber() { return volSerialNumber; }
}
private static native void OpenNtQueryDirectoryInformation0(long lpFileName, long buffer, int bufferSize, QueryDirectoryInformation obj)
throws WindowsException;
static boolean NextNtQueryDirectoryInformation(QueryDirectoryInformation data, NativeBuffer buffer) throws WindowsException {
return NextNtQueryDirectoryInformation0(data.handle(), buffer.address(), buffer.size());
}
private static native boolean NextNtQueryDirectoryInformation0(long handle, long buffer, int bufferSize)
throws WindowsException;
static void CloseNtQueryDirectoryInformation(QueryDirectoryInformation data) throws WindowsException {
CloseHandle(data.handle);
}
/**
* GetFileInformationByHandle(
* HANDLE hFile,

View File

@@ -38,6 +38,8 @@
#include "jni_util.h"
#include "jlong.h"
#include "ntifs_min.h"
#include "sun_nio_fs_WindowsNativeDispatcher.h"
/**
@@ -50,6 +52,9 @@ static jfieldID findFirst_attributes;
static jfieldID findStream_handle;
static jfieldID findStream_name;
static jfieldID queryDirectoryInformation_handle;
static jfieldID queryDirectoryInformation_volSerialNumber;
static jfieldID volumeInfo_fsName;
static jfieldID volumeInfo_volName;
static jfieldID volumeInfo_volSN;
@@ -71,6 +76,13 @@ static jfieldID completionStatus_error;
static jfieldID completionStatus_bytesTransferred;
static jfieldID completionStatus_completionKey;
typedef NTSYSCALLAPI NTSTATUS(NTAPI* NtQueryDirectoryFile_Proc) (HANDLE, HANDLE, PIO_APC_ROUTINE,
PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
typedef ULONG(NTAPI* RtlNtStatusToDosError_Proc) (NTSTATUS);
static NtQueryDirectoryFile_Proc NtQueryDirectoryFile_func;
static RtlNtStatusToDosError_Proc RtlNtStatusToDosError_func;
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
"(I)V", lastError);
@@ -87,6 +99,7 @@ JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
{
jclass clazz;
HMODULE h;
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
CHECK_NULL(clazz);
@@ -104,6 +117,13 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
CHECK_NULL(findStream_name);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$QueryDirectoryInformation");
CHECK_NULL(clazz);
queryDirectoryInformation_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
CHECK_NULL(queryDirectoryInformation_handle);
queryDirectoryInformation_volSerialNumber = (*env)->GetFieldID(env, clazz, "volSerialNumber", "I");;
CHECK_NULL(queryDirectoryInformation_volSerialNumber);
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
CHECK_NULL(clazz);
volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
@@ -148,6 +168,16 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
CHECK_NULL(completionStatus_bytesTransferred);
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
CHECK_NULL(completionStatus_completionKey);
// get handle to ntdll
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
L"ntdll.dll", &h) != 0)
{
NtQueryDirectoryFile_func =
(NtQueryDirectoryFile_Proc)GetProcAddress(h, "NtQueryDirectoryFile");
RtlNtStatusToDosError_func =
(RtlNtStatusToDosError_Proc)GetProcAddress(h, "RtlNtStatusToDosError");
}
}
JNIEXPORT jlong JNICALL
@@ -404,6 +434,118 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv* env, jclass this,
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_OpenNtQueryDirectoryInformation0(JNIEnv* env, jclass this,
jlong address, jlong bufferAddress, jint bufferSize, jobject obj)
{
LPCWSTR lpFileName = jlong_to_ptr(address);
BOOL ok;
BY_HANDLE_FILE_INFORMATION info;
HANDLE handle;
NTSTATUS status;
ULONG win32ErrorCode;
IO_STATUS_BLOCK ioStatusBlock;
if ((NtQueryDirectoryFile_func == NULL) || (RtlNtStatusToDosError_func == NULL)) {
JNU_ThrowInternalError(env, "Should not get here");
return;
}
handle = CreateFileW(lpFileName, FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (handle == INVALID_HANDLE_VALUE) {
throwWindowsException(env, GetLastError());
return;
}
status = NtQueryDirectoryFile_func(
handle, // FileHandle
NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&ioStatusBlock, // IoStatusBlock
jlong_to_ptr(bufferAddress), // FileInformation
bufferSize, // Length
FileIdFullDirectoryInformation, // FileInformationClass
FALSE, // ReturnSingleEntry
NULL, // FileName
FALSE); // RestartScan
if (!NT_SUCCESS(status)) {
/*
* NtQueryDirectoryFile returns STATUS_INVALID_PARAMETER when
* asked to enumerate an invalid directory (ie it is a file
* instead of a directory). Verify that is the actual cause
* of the error.
*/
if (status == STATUS_INVALID_PARAMETER) {
DWORD attributes = GetFileAttributesW(lpFileName);
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
status = STATUS_NOT_A_DIRECTORY;
}
}
win32ErrorCode = RtlNtStatusToDosError_func(status);
throwWindowsException(env, win32ErrorCode);
CloseHandle(handle);
return;
}
// This call allows retrieving the volume ID of this directory (and all its entries)
ok = GetFileInformationByHandle(handle, &info);
if (!ok) {
throwWindowsException(env, GetLastError());
CloseHandle(handle);
return;
}
(*env)->SetLongField(env, obj, queryDirectoryInformation_handle, ptr_to_jlong(handle));
(*env)->SetIntField(env, obj, queryDirectoryInformation_volSerialNumber, info.dwVolumeSerialNumber);
}
JNIEXPORT jboolean JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_NextNtQueryDirectoryInformation0(JNIEnv* env, jclass this,
jlong handle, jlong address, jint size)
{
HANDLE h = (HANDLE)jlong_to_ptr(handle);
ULONG win32ErrorCode;
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS status;
if ((NtQueryDirectoryFile_func == NULL) || (RtlNtStatusToDosError_func == NULL)) {
JNU_ThrowInternalError(env, "Should not get here");
return JNI_FALSE;
}
status = NtQueryDirectoryFile_func(
h, // FileHandle
NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&ioStatusBlock, // IoStatusBlock
jlong_to_ptr(address), // FileInformation
size, // Length
FileIdFullDirectoryInformation, // FileInformationClass
FALSE, // ReturnSingleEntry
NULL, // FileName
FALSE); // RestartScan
if (NT_SUCCESS(status)) {
return JNI_TRUE;
}
// Normal completion: no more files in directory
if (status == STATUS_NO_MORE_FILES) {
return JNI_FALSE;
}
win32ErrorCode = RtlNtStatusToDosError_func(status);
throwWindowsException(env, win32ErrorCode);
return JNI_FALSE;
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv* env, jclass this,
jlong handle, jlong address)

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2008, 2018, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
#ifndef _NTIFS_MIN_
#define _NTIFS_MIN_
/*
* Copy necessary structures and definitions out of the Windows DDK
* to enable calling NtQueryDirectoryFile()
*/
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWCH Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileIoCompletionNotificationInformation,
FileIoStatusBlockRangeInformation,
FileIoPriorityHintInformation,
FileSfioReserveInformation,
FileSfioVolumeInformation,
FileHardLinkInformation,
FileProcessIdsUsingFileInformation,
FileNormalizedNameInformation,
FileNetworkPhysicalNameInformation,
FileIdGlobalTxDirectoryInformation,
FileIsRemoteDeviceInformation,
FileAttributeCacheInformation,
FileNumaNodeInformation,
FileStandardLinkInformation,
FileRemoteProtocolInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _FILE_ID_FULL_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
} u;
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef VOID
(NTAPI *PIO_APC_ROUTINE)(
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved);
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryDirectoryFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID FileInformation,
_In_ ULONG Length,
_In_ FILE_INFORMATION_CLASS FileInformationClass,
_In_ BOOLEAN ReturnSingleEntry,
_In_opt_ PUNICODE_STRING FileName,
_In_ BOOLEAN RestartScan
);
ULONG
NTAPI
RtlNtStatusToDosError(
NTSTATUS Status
);
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xC0000103L)
#endif // _NTIFS_MIN_

View File

@@ -50,6 +50,7 @@ static jclass sjc_CAccessibility = NULL;
NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
{
GET_CACCESSIBILITY_CLASS_RETURN(NSZeroSize);
DECLARE_CLASS_RETURN(jc_Dimension, "java/awt/Dimension", NSZeroSize);
DECLARE_FIELD_RETURN(jf_width, jc_Dimension, "width", "I", NSZeroSize);
DECLARE_FIELD_RETURN(jf_height, jc_Dimension, "height", "I", NSZeroSize);
@@ -60,7 +61,10 @@ NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
CHECK_EXCEPTION();
if (dimension == NULL) return NSZeroSize;
return NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height));
NSSize size = NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height));
(*env)->DeleteLocalRef(env, dimension);
return size;
}
NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
@@ -253,7 +257,10 @@ NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject
axComponent, component);
CHECK_EXCEPTION();
if (jpoint == NULL) return NSZeroPoint;
return NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y));
NSPoint p = NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y));
(*env)->DeleteLocalRef(env, jpoint);
return p;
}
jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)

View File

@@ -40,11 +40,18 @@ NSString* JavaStringToNSString(JNIEnv *env, jstring jstr) {
}
jstring NSStringToJavaString(JNIEnv* env, NSString *str) {
if (str == NULL) {
return NULL;
}
jstring jStr = (*env)->NewStringUTF(env, [str UTF8String]);
jsize len = [str length];
unichar *buffer = (unichar*)calloc(len, sizeof(unichar));
if (buffer == NULL) {
return NULL;
}
NSRange crange = NSMakeRange(0, len);
[str getCharacters:buffer range:crange];
jstring jStr = (*env)->NewString(env, buffer, len);
free(buffer);
CHECK_EXCEPTION();
return jStr;
}

View File

@@ -168,8 +168,6 @@ public class XBaseWindow {
// Set WM_CLIENT_LEADER property
initClientLeader();
initUserTimeWindow();
}
/**
@@ -441,13 +439,6 @@ public class XBaseWindow {
}
}
private void initUserTimeWindow() {
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
if (netProtocol != null ) {
netProtocol.setupUserTimeWindow(this);
}
}
static XRootWindow getXAWTRootWindow() {
return XRootWindow.getInstance();
}
@@ -1314,12 +1305,18 @@ public class XBaseWindow {
}
protected void setUserTime(long time, boolean updateGlobalTime) {
setUserTime(time, updateGlobalTime, true);
}
protected void setUserTime(long time, boolean updateGlobalTime, boolean updateWindowProperty) {
if (updateGlobalTime && (int)time - (int)globalUserTime > 0 /* accounting for wrap-around */) {
globalUserTime = time;
}
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
if (netProtocol != null) {
netProtocol.setUserTime(this, time);
if (updateWindowProperty) {
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
if (netProtocol != null) {
netProtocol.setUserTime(this, time);
}
}
}

View File

@@ -1072,10 +1072,13 @@ abstract class XDecoratedPeer extends XWindowPeer {
XClientMessageEvent cl = xev.get_xclient();
if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
long timestamp = getTimeStampFromClientMessage(cl);
// we should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
// We should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
// e.g. from user clicking on window title bar and window close button correspondingly
// (there will be no ButtonPress/ButtonRelease events in those cases)
setUserTime(timestamp, true);
// (there will be no ButtonPress/ButtonRelease events in those cases).
// The received timestamp will be used to set _NET_WM_USER_TIME on newly opened windows to ensure their
// correct focusing/positioning, but we don't set it on current window to avoid race conditions (when e.g.
// WM_TAKE_FOCUS arrives around the time of new window opening).
setUserTime(timestamp, true, false);
if (cl.get_data(0) == wm_delete_window.getAtom()) {
handleQuit();

View File

@@ -287,7 +287,6 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
XAtom XA_NET_WM_USER_TIME = XAtom.get("_NET_WM_USER_TIME");
XAtom XA_NET_WM_USER_TIME_WINDOW = XAtom.get("_NET_WM_USER_TIME_WINDOW");
/* For _NET_WM_STATE ClientMessage requests */
static final int _NET_WM_STATE_REMOVE =0; /* remove/unset property */
@@ -460,20 +459,9 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
return (state != null && state.size() != 0 && state.contains(XA_NET_WM_STATE_HIDDEN));
}
private boolean isUserTimeWindowSupported() {
return checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_USER_TIME_WINDOW);
}
void setupUserTimeWindow(XBaseWindow window) {
if (active() && isUserTimeWindowSupported()) {
XA_NET_WM_USER_TIME_WINDOW.setWindowProperty(window, XRootWindow.getInstance());
}
}
void setUserTime(XBaseWindow window, long time) {
if (active()) {
XBaseWindow target = isUserTimeWindowSupported() ? XRootWindow.getInstance() : window;
XA_NET_WM_USER_TIME.setCard32Property(target, time);
XA_NET_WM_USER_TIME.setCard32Property(window, time);
}
}
}

View File

@@ -168,10 +168,6 @@ final class WInputMethod extends InputMethodAdapter
@Override
public boolean setLocale(Locale lang) {
return setLocale(lang, false);
}
private boolean setLocale(Locale lang, boolean onActivate) {
Locale[] available = WInputMethodDescriptor.getAvailableLocalesInternal();
for (int i = 0; i < available.length; i++) {
Locale locale = available[i];
@@ -180,7 +176,7 @@ final class WInputMethod extends InputMethodAdapter
locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
if (isActive) {
setNativeLocale(locale.toLanguageTag(), onActivate);
setNativeLocale(locale.toLanguageTag());
}
currentLocale = locale;
return true;
@@ -319,9 +315,6 @@ final class WInputMethod extends InputMethodAdapter
isLastFocussedActiveClient = isAc;
}
isActive = true;
if (currentLocale != null) {
setLocale(currentLocale, true);
}
// Compare IM's composition string with Java's composition string
if (hasCompositionString && !isCompositionStringAvailable(context)) {
@@ -348,10 +341,6 @@ final class WInputMethod extends InputMethodAdapter
@Override
public void deactivate(boolean isTemporary)
{
// Sync currentLocale with the Windows keyboard layout which might be changed
// by hot key
getLocale();
// Delay calling disableNativeIME until activate is called and the newly
// focussed component has a different peer as the last focussed component.
if (awtFocussedComponentPeer != null) {
@@ -667,7 +656,7 @@ final class WInputMethod extends InputMethodAdapter
private native void setStatusWindowVisible(WComponentPeer peer, boolean visible);
private native String getNativeIMMDescription();
static native Locale getNativeLocale();
static native boolean setNativeLocale(String localeName, boolean onActivate);
static native boolean setNativeLocale(String localeName);
private native void openCandidateWindow(WComponentPeer peer, int x, int y);
private native boolean isCompositionStringAvailable(int context);
}

View File

@@ -88,15 +88,6 @@ static DCList passiveDCList;
extern void CheckFontSmoothingSettings(HWND);
extern "C" {
// Remember the input language has changed by some user's action
// (Alt+Shift or through the language icon on the Taskbar) to control the
// race condition between the toolkit thread and the AWT event thread.
// This flag remains TRUE until the next WInputMethod.getNativeLocale() is
// issued.
BOOL g_bUserHasChangedInputLang = FALSE;
}
BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;
BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;
HWND AwtComponent::sm_focusOwner = NULL;
@@ -1900,9 +1891,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
keyboardState, &ignored, 0, GetKeyboardLayout());
// Set this flag to block ActivateKeyboardLayout from
// WInputMethod.activate()
g_bUserHasChangedInputLang = TRUE;
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
break;
}
@@ -1911,7 +1899,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
"new = 0x%08X",
GetHWnd(), GetClassName(), (UINT)lParam);
mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));
g_bUserHasChangedInputLang = TRUE;
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
// should return non-zero if we process this message
retValue = 1;

View File

@@ -44,8 +44,6 @@ extern "C" {
jobject CreateLocaleObject(JNIEnv *env, const char * name);
HKL getDefaultKeyboardLayout();
extern BOOL g_bUserHasChangedInputLang;
/*
* Class: sun_awt_windows_WInputMethod
* Method: createNativeContext
@@ -292,10 +290,6 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
const char * javaLocaleName = getJavaIDFromLangID(AwtComponent::GetInputLanguage());
if (javaLocaleName != NULL) {
// Now WInputMethod.currentLocale and AwtComponent::m_idLang are get sync'ed,
// so we can reset this flag.
g_bUserHasChangedInputLang = FALSE;
jobject ret = CreateLocaleObject(env, javaLocaleName);
free((void *)javaLocaleName);
return ret;
@@ -309,10 +303,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
/*
* Class: sun_awt_windows_WInputMethod
* Method: setNativeLocale
* Signature: (Ljava/lang/String;Z)Z
* Signature: (Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
(JNIEnv *env, jclass cls, jstring localeString, jboolean onActivate)
(JNIEnv *env, jclass cls, jstring localeString)
{
TRY;
@@ -353,7 +347,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
if (supported != NULL) {
if (strcmp(supported, requested) == 0) {
// use special message to call ActivateKeyboardLayout() in main thread.
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) {
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, 0, (LPARAM)hKLList[i])) {
//also need to change the same keyboard layout for the Java AWT-EventQueue thread
AwtToolkit::activateKeyboardLayout(hKLList[i]);
retValue = JNI_TRUE;

View File

@@ -71,7 +71,6 @@ extern void initScreens(JNIEnv *env);
extern "C" void awt_dnd_initialize();
extern "C" void awt_dnd_uninitialize();
extern "C" void awt_clipboard_uninitialize(JNIEnv *env);
extern "C" BOOL g_bUserHasChangedInputLang;
extern CriticalSection windowMoveLock;
extern BOOL windowMoveLockHeld;
@@ -1235,14 +1234,6 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
return cmode;
}
case WM_AWT_ACTIVATEKEYBOARDLAYOUT: {
if (wParam && g_bUserHasChangedInputLang) {
// Input language has been changed since the last WInputMethod.getNativeLocale()
// call. So let's honor the user's selection.
// Note: we need to check this flag inside the toolkit thread to synchronize access
// to the flag.
return FALSE;
}
if (lParam == (LPARAM)::GetKeyboardLayout(0)) {
// already active
return FALSE;

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@key headful
@bug 8272602
@summary Ctrl+Space should generate a KeyTyped event on macOS
@run main CtrlSpace
*/
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class CtrlSpace extends Frame implements KeyListener {
static volatile boolean testPassed = false;
static volatile Robot robot;
public static void main(String[] args) throws Exception {
robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(100);
Frame frame = createAndShowGUI(robot);
test(robot);
robot.waitForIdle();
Thread.sleep(2000);
frame.setVisible(false);
frame.dispose();
if (!testPassed) {
throw new RuntimeException("No KeyTyped event");
}
}
static Frame createAndShowGUI(Robot robot) {
CtrlSpace win = new CtrlSpace();
win.setSize(300, 300);
Panel panel = new Panel(new BorderLayout());
TextField textField = new TextField("abcdefghijk");
textField.addKeyListener(win);
panel.add(textField, BorderLayout.CENTER);
win.add(panel);
win.setVisible(true);
robot.waitForIdle();
textField.requestFocusInWindow();
robot.waitForIdle();
return win;
}
public static void test(Robot robot) {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.delay(200);
}
public void keyPressed(KeyEvent evt) {
System.out.println("Pressed " + evt);
}
public void keyReleased(KeyEvent evt) {
System.out.println("Released " + evt);
}
public void keyTyped(KeyEvent evt) {
System.out.println("Typed " + evt);
testPassed = true;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887 6873621 6979526 7006126 7020517
* @bug 4313887 6873621 6979526 7006126 7020517 8264400
* @summary Unit test for java.nio.file.FileStore
* @key intermittent
* @library .. /test/lib
@@ -36,9 +36,9 @@ import java.nio.file.attribute.*;
import java.io.File;
import java.io.IOException;
import jdk.test.lib.Platform;
import jdk.test.lib.util.FileUtils;
public class Basic {
static final long G = 1024L * 1024L * 1024L;
@@ -80,6 +80,15 @@ public class Basic {
assertTrue(store2.equals(store1));
assertTrue(store1.hashCode() == store2.hashCode());
if (Platform.isWindows()) {
/**
* Test: FileStore.equals() should not be case sensitive
*/
FileStore upper = Files.getFileStore(Path.of("C:\\"));
FileStore lower = Files.getFileStore(Path.of("c:\\"));
assertTrue(lower.equals(upper));
}
/**
* Test: File and FileStore attributes
*/

View File

@@ -42,6 +42,8 @@ import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Iterator;
@@ -323,12 +325,44 @@ class FaultyFileSystem extends FileSystem {
return Files.readAttributes(unwrap(file), attributes, options);
}
private class FaultyBasicFileAttributeView implements BasicFileAttributeView {
private final Path file;
private final LinkOption[] options;
public FaultyBasicFileAttributeView(final Path file, final LinkOption... options) {
this.file = file;
this.options = options;
}
@Override
public String name() {
return "faulty";
}
@Override
public BasicFileAttributes readAttributes() throws IOException {
triggerEx(file, "readAttributes");
return Files.readAttributes(file, BasicFileAttributes.class, options);
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime) throws IOException {
triggerEx(file, "setTimes");
}
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path file,
Class<V> type,
LinkOption... options)
{
return Files.getFileAttributeView(unwrap(file), type, options);
if (type != BasicFileAttributeView.class) {
return null;
}
return (V)new FaultyBasicFileAttributeView(unwrap(file), options);
}
@Override

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Tests that walkFileTree can find files in a directory with
* non-latin characters in the name (including ones from
* the supplementary plane)
* @library /test/lib
*/
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.FileVisitOption;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.FileVisitResult;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Vector;
import java.util.HashSet;
import jdk.test.lib.Asserts;
public class NonLatin {
// Use non-Latin characters from basic (\u1889) and supplementary (\uD844\uDDD9) Unicode planes
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-supp-\uD844\uDDD9";
public static void main(String args[]) throws Exception {
final Path currentDirPath = Paths.get(".").toAbsolutePath();
Path nonLatinPath = null;
try {
nonLatinPath = currentDirPath.resolve(NON_LATIN_PATH_NAME);
Files.createDirectory(nonLatinPath);
final Path underNonLatinPath = nonLatinPath.resolve("dir");
Files.createDirectory(underNonLatinPath);
} catch (java.nio.file.InvalidPathException e) {
System.out.println("Cannot create the directory with the right name. Test is considered passed");
return;
}
final Vector<String> visitedDirs = new Vector<String>();
Files.walkFileTree(nonLatinPath, new HashSet<FileVisitOption>(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
visitedDirs.add(dir.toString());
return FileVisitResult.CONTINUE;
}
});
boolean found = false;
for (final String dirName : visitedDirs) {
System.out.println("Found: " + dirName);
found |= dirName.contains(NON_LATIN_PATH_NAME);
}
Asserts.assertTrue(found);
}
}

View File

@@ -244,20 +244,23 @@ public class CustomComboBoxFocusTest {
System.out.println("Request focus on " + target);
final Component c = target.getEditor().getEditorComponent();
c.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
SwingUtilities.invokeLater(focusHandler);
}
if (c.isFocusOwner()) {
SwingUtilities.invokeLater(focusHandler);
} else {
c.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
SwingUtilities.invokeLater(focusHandler);
}
@Override
public void focusLost(FocusEvent e) {
@Override
public void focusLost(FocusEvent e) {
}
});
c.requestFocus();
}
});
c.requestFocus();
}
}
public Step nextStep() {

View File

@@ -45,6 +45,7 @@ public class TypeaheadRequestFocusTest {
initFinished.get(10, TimeUnit.SECONDS);
clickOn(frameField);
SwingUtilities.invokeAndWait(TypeaheadRequestFocusTest::showPopup);
robot.delay(1000);
pressAndRelease(KeyEvent.VK_ENTER);
pressAndRelease(KeyEvent.VK_A);
typedInPopup.get(10, TimeUnit.SECONDS);

View File

@@ -61,13 +61,11 @@ public class NestedDialogHideTest {
button3 = new JButton("Hide");
button3.addActionListener(eee -> d.setVisible(false));
d2.add(button3);
d2.pack();
d2.setLocation(240, 240);
d2.setBounds(240, 240, 200, 200);
d2.setVisible(true);
});
d.add(button2);
d.pack();
d.setLocation(220, 220);
d.setBounds(220, 220, 200, 200);
d.setVisible(true);
d.addComponentListener(new ComponentAdapter() {
@Override
@@ -77,8 +75,7 @@ public class NestedDialogHideTest {
});
});
frame.add(button1);
frame.pack();
frame.setLocation(200, 200);
frame.setBounds(200, 200, 200, 200);
frame.setVisible(true);
}

View File

@@ -0,0 +1,28 @@
java/awt/Focus/ModalDialogInitialFocusTest/ModalDialogInitialFocusTest.java JBR-3730 macosx-all
java/awt/Choice/UnfocusableCB_ERR/UnfocusableCB_ERR.java JBR-3730 macosx-all
java/awt/Component/7097771/bug7097771.java JBR-3730 macosx-all
java/awt/Component/NoUpdateUponShow/NoUpdateUponShow.java JBR-3730 macosx-all
java/awt/Component/PaintAll/PaintAll.java JBR-3730 macosx-all
java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.java JBR-3730 macosx-all
java/awt/Focus/ModalDialogInitialFocusTest/ModalDialogInitialFocusTest.html JBR-3730 macosx-all
java/awt/Focus/NonFocusableWindowTest/NoEventsTest.java JBR-3730 macosx-all
java/awt/Focus/RemoveAfterRequest/RemoveAfterRequest.java JBR-3730 macosx-all
java/awt/Focus/RequestFocusAndHideTest/RequestFocusAndHideTest.java JBR-3730 macosx-all
java/awt/Focus/RequestOnCompWithNullParent/RequestOnCompWithNullParent1.java JBR-3730 macosx-all
java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java JBR-3730 macosx-all
java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java JBR-3730 macosx-all
java/awt/Focus/WindowIsFocusableAccessByThreadsTest/WindowIsFocusableAccessByThreadsTest.java JBR-3730 macosx-all
java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java JBR-3730 macosx-all
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-3733 macosx-all
java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java JBR-3730 macosx-all
java/awt/Frame/ResizeAfterSetFont/ResizeAfterSetFont.java JBR-3730 macosx-all
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-3730 macosx-all
java/awt/Mixing/Validating.java JBR-3730 macosx-all
java/awt/Mixing/ValidBounds.java JBR-3730 macosx-all
java/awt/MouseAdapter/MouseAdapterUnitTest/MouseAdapterUnitTest.java JBR-3730 macosx-all
java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java JBR-3730 macosx-all
java/awt/event/ComponentEvent/MovedResizedTwiceTest/MovedResizedTwiceTest.java JBR-3730 macosx-all
java/awt/event/MouseEvent/EnterAsGrabbedEvent/EnterAsGrabbedEvent.java JBR-3730 macosx-all
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.html JBR-3730 macosx-all
java/awt/event/MouseEvent/MouseButtonsTest/MouseButtonsTest.java JBR-3730 macosx-all
java/awt/event/MouseEvent/MultipleMouseButtonsTest/MultipleMouseButtonsTest.java JBR-3730 macosx-all