JetBrains Platform
Plugin and extension development for JetBrains products.
Wayland Support for IntelliJ-based IDEs
For Linux users of IntelliJ-based IDEs, an exciting advancement is on the horizon – the upcoming support of the Wayland display server protocol. This update is set to bring a host of benefits, including solving the age-old fractional scaling problem and elevating desktop integration when working with Windows Subsystem for Linux (WSLg), which runs a Wayland server under the hood. While Wayland support is far from complete, the already existing features allow us to run some Java Swing and AWT applications on Wayland. In this blog post, we’ll delve into these advancements and explore some technical challenges posed by this novel approach to the display server.
Wayland
Wayland, a modern display server protocol, aims to replace the X Window System by offering a more efficient, secure, and adaptable architecture for graphical environments. It brings new paradigms in many important areas, for example:
- Wayland does not provide any drawing primitives – it only facilitates the display of pixels on the screen that your application must prepare in advance. It also does not decorate your windows for you, though some implementations aim to help with that via custom protocols.
- It isolates applications from one another and from the desktop itself. There are no built-in capabilities to position the window on the screen at certain coordinates, nor are there ways to query said position or other window’s pixels.
- For all actions that are ostensibly initiated by a human – such as moving a window or copying text to the clipboard – Wayland’s protocols require the application to prove that it is indeed acting on behalf of the user, usually by providing a pointer to the event that it has recently received from Wayland so that the server can then verify it independently from the client.
- Wayland protocols are transactional in that they allow you to build up the new state gradually and then commit the result as a whole, ensuring that the user never sees the UI in an inconsistent state.
- Wayland embraces a modular design where different servers can support various protocols, extending Wayland’s capabilities to cater to diverse use cases. However, it’s important to note that not all servers support the same set of protocols. For example, the most modern wp_fractional_scale_manager_v1 protocol is supported only by one out of five popular servers (as of August, 2023).
State of the art
The graphical applications that do not (yet) communicate with Wayland directly were offered a transitional path with XWayland, an implementation of X11 running on top of a Wayland session. This is how all Java applications, including all JetBrains’ IntelliJ-based IDEs, display their UI and get their mouse and keyboard input. And this arrangement works well for the most part… except when it doesn’t.
There are issues with drag and drop, window switching, and popup menus, and you can’t screenshot outside of your window bounds, for example. Some of these problems can be addressed even within the XWayland framework (and some were actually addressed in the latest OpenJDK). Others seem as though they’ll never be solved, especially considering that X11 is rapidly becoming a legacy technology not many are willing to invest in.
Perhaps the most pressing issue with XWayland is that of scaling. With fractional scaling enabled, the “legacy” X11 applications render to a lower resolution than that of the display and then get upscaled by Wayland, making any text visibly blurry. The reason for this is the absence of any method by which an application can tell the X server that it is “HiDPI-aware”, so the server has to assume the worst and provide a “helping” hand by scaling the window pixels up. Wayland, however, does have the capability to tell the server the window’s scale, so this becomes a non-issue as soon as we switch to using Wayland.
Challenges
Making Java Wayland native is, however, easier said than done. In terms of JDK, this amounts to creating a new Toolkit, which is the birthplace of practically everything related to GUI. This includes graphics, mouse pointer handling, keystroke translation, splash screen display, and input method provision – all of this must be implemented from scratch. For example, the X11 toolkit is around 50,000 lines of Java and 20,000 lines of native code, only a fraction of which is reusable in Wayland.
From a very high-level point of view, the task is quite straightforward: one API, Wayland, needs to be translated to another, Java, and vice versa. Wayland has wl_keyboard:event:key for keystrokes, Java has KeyEvent. Java has the SurfaceData class to store the window’s pixels, Wayland has wl_buffer, and so on. The details of those APIs differ quite a bit, though. To give a simple example, the Wayland server will not generate individual keyboard events when a key is pressed for a long time, you only get one. However, the rest of the Java desktop subsystem expects to receive KeyEvent reports periodically in this case, and it is the responsibility of the toolkit to make such arrangements.
On the positive side, not everything has to be implemented before even a simple program can be launched. For example, Swing applications don’t rely on AWT UI elements. This enables you to prioritize in a flexible fashion and deliver important features first, leaving others for later.
Another stroke of luck is in the clever design of the Java graphical subsystem that never relied on the X11 drawing primitives. This made it possible to quickly get the software-based rendering running on Wayland with virtually no modification of the common platform-independent code.
The Wayland toolkit
The development of the Wayland toolkit started as a joint effort with the Oracle desktop team and is called Project Wakefield. The code is based on OpenJDK 21. As of August 2023, the toolkit delivers:
- Software-based rendering.
- Minimal window decorations.
- Interactive resizing and repositioning of the window, including support for maximizing, minimizing, and going full screen.
- Popup windows, including those that are used for top-level menus.
- HiDPI and multi-monitor support, including with different per-monitor scales.
- Mouse and keyboard, including international characters.
The immediate priorities for the next few months are:
- Vulkan-based accelerated rendering.
- Input methods.
- Clipboard and drag and drop support.
- Splash screen.
- Switching between windows with a keyboard shortcut (which, given the Wayland’s tough security model, is a surprisingly complicated endeavor).
A slightly more detailed progress report can be found on the project’s wiki: https://wiki.openjdk.org/display/wakefield/Work+breakdown, which is updated regularly.
Navigating the future: IntelliJ-based IDEs on Wayland
Wayland’s architecture offers inherent benefits in terms of performance and security. By sidestepping the complexities of the aging X11 protocol, Wayland provides a more streamlined mechanism for communication between applications and the display server. This translates to faster rendering and a reduced likelihood of security vulnerabilities stemming from X11’s outdated design. As a result, IntelliJ-based IDEs running on Wayland are expected to exhibit improved stability and responsiveness.
The effort to make IntelliJ-based IDEs a first-class citizen of the Wayland desktop is ongoing. The software-based rendering already delivers performance in terms of FPS (frames per second) on par with the current X11 toolkit. The focus now is on identifying the remaining gaps in the toolkit’s implementation so that it can sustain an IDE running natively on Wayland.
References
- https://wayland.freedesktop.org/
- https://wiki.openjdk.org/display/wakefield/Known+problems+and+solutions
- Blurry text when using Sway or fractional scaling on Wayland