Shortly said, we don't need to handle recursive invocations of the `java.io` to nio adapters, while this recursion leads to problems.
# Problem
Since we're not allowed to modify public API of Java classes, an unreliable workaround `IoOverNio.PARENT_FOR_FILE_CHANNEL_IMPL` had been introduced. This trick lets us pass some object into a called function without adding a new function argument.
The trick backfired at the following code:
```java
// at java.base/java.io.IoOverNioFileSystem.initializeStreamUsingNio (simplified code)
IoOverNio.PARENT_FOR_FILE_CHANNEL_IMPL.set(owner);
return initializeStreamsUsingNio0(owner, nioFs, file, nioPath, optionsForChannel, channelCleanable);
// at java.base/java.io.IoOverNioFileSystem.initializeStreamsUsingNio0
channel = nioFs.provider().newFileChannel(nioPath, optionsForChannel);
```
The intention of setting `PARENT_FOR_FILE_CHANNEL_IMPL` is to path `owner` inside a constructor of `sun.nio.ch.FileChannelImpl` which may be called by `newFileChannel(nioPath, optionsForChannel)`.
The implementation of `newFileChannel` in IntelliJ triggered class loading. The classloader of IntelliJ triggered the call `java.nio.file.Files.readAllBytes`. The latter code also invoked the constructor of `FileChannelImpl`, and the constructor got from the thread-local variable the value for the field `parent`. That value was supposed to be passed to a different invocation of the constructor.
The observable result of this bug was a `NullPointerExceptions` from `java.io.FileOutputStream.close`. Hypothetically, this bug could also lead to closing file descriptors earlier as expected in other unpredictable places.
# Rejected approaches
* The cleanest solution could be passing specific function arguments through function arguments.
However, we may neither create a new public function in the module `java.base`, nor add an argument to an existing one. Thus, we have to keep dealing with thread-local variables.
* To hold several values in the thread-local variable.
In this case, the constructor of `FileChannelImpl` should somehow choose the right value from the list. The only possible way for filtering values is by the provided path. It doesn't look like a performant and reliable solution.
# Chosen solution
This commit disables recursive invocations of `java.io` from `java.nio` adapters.
The chosen solution is tied to specifics of IntelliJ. The reason for introducing java.io over java.nio adapter was to be able to access files from remote machines without rewriting old code. It is not expected that an implementation of `java.nio.file.spi.FileSystemProvider` accesses the file system using `java.io`. The only imaginable way to get a `java.io` call from `java.nio` is class loading. In case of IntelliJ, it's assumed that the class loader never accesses classes and jars from a remote machine.
KWin does not accept the serial number from a "keyboard enter" event in
a window activation request, while a recent input event serial is OK.
Gnome, however, requires the "keyboard enter" event serial.
This patch adds a call to wl_data_offer.finish() upon a successful
completion of a drag-and-drop operation, as well as more synchronized
annotations in WLDataOffer, to match the existing ones.
Calling finish() doesn't seem to be required by most compositors when
performing drag-and-drop, at least within the same window. Other
toolkits, such as Qt, only call it when dealing with cross-application
drag-and-drop. In the interest of maximal compatibility, this patch
implements calling finish() always when a drag-and-drop operation
succeeds.
This patch implements a workaround for a bug that exists on KWin 6.5. For
some reason, KWin sends a wl_data_source.action(0) event immediately
after wl_data_source.dnd_drop_finished(). This makes the drag source
think that the DnD operation failed, even though it succeeded.
The workaround it to ignore the wl_data_source.action() events
after a successful wl_data_source.dnd_drop_finished()
In addition to this, this patch also fixes some inconsistency with
translating between AWT and Wayland DnD operation masks. This doesn't
have any visible effect though, since the mask values happen to be the
same.
* Add null checks for variables that can have null values to prevent hard crash
* Add missing CHECK_EXCEPTION after JNI call
* Add missing DeleteLocalRef for axComponent
(cherry picked from commit 96fcd9e591)
This commit changes how WLToolkit loads libxkbcommon. It will now be
linked as a normal dynamic library at build time, instead of being
loaded via dlopen. This commit also introduces dependency on
libxkbcommon headers and removes the corresponding declarations from
WLKeyboard.c.
Minimal changes for JBR-21: added @try/&@catch(nsexception) in ThreadUtilities.processQueuedCallbacks() to handle any native or java exception and avoid crashing the main run loop
When pressing a modifier key such as Shift or Alt, other toolkits
include the corresponding bit in the modifier mask. Similiarly, when
releasing a modifier key, other toolkits will not include this bit if
the just released modifier key was the last key producing this bit.
When pressing such a key, Wayland compositors first send the
wl_keyboard.key event, and only then the wl_keyboard.modifiers event.
This causes the reported AWT modifier mask to be inconsistent with
XToolkit. This patch fixes this.
Rewritten exception handling to adopt the improved NSApplicationAWT exception handler (log all exceptions, avoid crash GUI)
Fixed JNI_COCOA_EXIT(env) usages to test also pending JNI exceptions
Added JNI_COCOA_EXIT_FATAL(message) used by NSApplicationAWT.sendEvent to report a crash with full details
Unified logException to report both crash and exceptions
Added isAWTCrashOnException() using the system property 'apple.awt.crashOnException' to crash on any exception occuring in NSApplication level
Added missing CHECK_EXCEPTION after (*env)->Call...Method()
Intercept all exception in NSApplicationAWT as NSExceptionHandlerDelegate + added tests in LWCToolkit (native) and Java code to test all exceptions are reported in logs and caught properly