JWM is a cross-platform Java window management and OS integration library.

Overview

Java Window Management library

Vision

JWM is a cross-platform Java window management and OS integration library.

JWM aims to expose an interface that abstracts over window creation, input handling and OS integration. It’s planned to support all the primary desktop platforms:

  • Windows
  • macOS
  • X11
  • Wayland

Primary goals:

  • Native JVM API
  • High-quality OS integration (indistinguishable from native apps)
  • Plays well with (but does not require) Skija

Motto: “Electron for JVM, without Chrome and JS”

Alternatives

Traditionally, Java UIs struggled with high-quality OS integration. JWM plans to bring it to modern standards by implementing those integrations from scratch in modern low-level OS-native APIs. Prior art:

AWT:

  • Bullet-proof, works everywhere
  • Event loop is two-threaded (lags in UI)
  • Dated font management, color management, dpi management
  • No vsync

JavaFX:

  • Fixed threading model
  • Performance is sometimes great, sometimes terrible
  • Even more limited fonts/color/graphics API
  • VSync is weird in multi-monitor case
  • No real extensibility

Winit:

  • Tried at JetBrains
  • Complicated event loop model (tries to unify desktop + web + mobile)

GLFW via LWJGL, SDL2:

  • Game-oriented
  • Bad window management
  • No OS integration
  • Create one window and go full-screen is the main use-case

Electron:

  • Seems great, will use as inspiration

Scope

TBD, but these are a good start:

Status

Proof of concept, do not use.

Repository URL:

https://packages.jetbrains.team/maven/p/jwm/maven
Platform groupId artifactId version
macOS Intel org.jetbrains.jwm jwm-macos-x64 version
macOS M1 org.jetbrains.jwm jwm-macos-arm64 version
Linux N/A N/A N/A
Windows org.jetbrains.jwm jwm-windows-x64 version

Developing

Prerequisites:

Common

Git, CMake, Ninja, C++ compiler, JDK 11+, $JAVA_HOME, Python 3.

Ubuntu 20.04

libxcomposite-dev

Build:

./script/build.py

Run examples:

./script/run.py

Run examples without building (use version from the table above):

./script/run.py --jwm-version 
Issues
  • Possible to attach to existing OS-specific window handle given to the process (not spawn new window + handle)?

    Possible to attach to existing OS-specific window handle given to the process (not spawn new window + handle)?

    Hello, first I'd like to thank the contributors of this library -- it opens up very exciting possibilities and is sorely needed in the ecosystem. So thank you all 😃


    My question:

    I've been browsing the source, trying to understand if the following scenario is possible:

    1. A process is created (let's call it ParentApp) and launches it's own window/UI
    2. ParentApp creates a new window + handle, let's call this ChildWindowHandle, and passes it to our JWM program
    3. We would like to receive this ChildWindowHandle pointer and use it to render/attach our JWM app UI to
      • On Windows this would be an HWND
      • On Linux, this would be an XWindowID
      • On Mac OSx, this would be an NSView or HIView

    If this sounds strange to you/you can't imagine why you would want to do this:

    • One usecase is plugin-based UI's where developers don't control the host program and publish plugins as shared libs (.dll/.so/.dylib)
      • These plugins get loaded by the parent application and are "handed" a pre-made ChildWindowHandle to render into

    A popular example (my usecase): VST Audio Plugins for DAW's

    • https://en.wikipedia.org/wiki/Virtual_Studio_Technology

    It would be amazing to be able to author audio plugins (or at least the UI's) in say, Kotlin. General availability to JVM languages would be revolutionary.

    For a code short example, essentially what I'm asking is if something like this is possible (minus the low-level X11 stuff, just the bit about receiving and using the parentWindowHandle to render):

    import kotlinx.cinterop.*
    import Xlib.*
    
    fun vstOnAttached(parentWindowHandle: COpaquePointer, platform: String) {
        val msg = "Hello, World!"
        
        val d = XOpenDisplay(null)
        if (d == null) {
            println("Cannot open display")
            return
        }
     
        val s = XDefaultScreen(d)
    
      /* Window XCreateSimpleWindow(display, parent, x, y, width, height, border_width, 
                                    border, background) */
        val w = XCreateSimpleWindow(d, parentWindowHandle.reinterpret<Window>, 10, 10, 160, 160, 1,
                                    XBlackPixel(d, s), XWhitePixel(d, s))
        XSelectInput(d, w, ExposureMask or KeyPressMask)
        XMapWindow(d, w)
        val e = nativeHeap.alloc<XEvent>()
     
        while (true) {
            XNextEvent(d, e.ptr)
            if (e.type == Expose) {
                XFillRectangle(d, w, XDefaultGC(d, s), 55, 40, 50, 50)
                XDrawString(d, w, XDefaultGC(d, s), 45, 120, msg, msg.length)
            }
            else if (e.type == KeyPress) break
        }
     
        XCloseDisplay(d)
        nativeHeap.free(e)
    }
    

    Curious if there's any way to accomplish this currently? Thank you


    Boring Contextual Details Below

    The way audio plugins work, is that the host application (generally a DAW) allocates a window handle and gives the plugin the window to render into:

    image

    • https://steinbergmedia.github.io/vst3_doc/base/classSteinberg_1_1IPlugView.html#a9fbc345c1e87f7e6210a8a49fdb96793

      • image
    • https://steinbergmedia.github.io/vst3_doc/base/group__platformUIType.html

      • image
    opened by GavinRay97 14
  • [wip] Windows: system theme

    [wip] Windows: system theme

    • [x] get system theme
    • [x] disable when high contrast mode
    • [x] set theme
    • [x] expose isHighContrast

    Add functions to get window theme and switch light/dark mode.

    I implemented it by referring to winit and this.

    See also:

    • https://github.com/ysc3839/win32-darkmode
    opened by i10416 10
  • [SUGGEST] Introduce sbt

    [SUGGEST] Introduce sbt

    I Introduced sbt in order to make it easier to run test and build scripts.

    • [x] Windows 10
      • [x] run
      • [x] assembly
      • [x] package
    • [x] Linux Ubuntu 20.04 (Example.java setTitle() throws nullPointerException for some reasons.)
      • [x] run
      • [x] assembly
      • [x] package : need ubuntu 18.04 to run jpackage.
    • [ ] macos This PR enables these features below.
    // at project root
    // run cmake and ninja, then copy the binary at <os>/src/main/resources
    sbt packArtifact
    
    // compile
    sbt compile
    
    // clean shared/build, shared/target, <os>/build,<os>/target
    sbt clean
    
    // clean linux/build, linux/target
    sbt linux/clean
    
    // publish to local ivy
    sbt publishLocal
    
    // publish to local m2
    sbt publishM2
    
    // at examples/metrics
    
    // run example application
    sbt run
    
    // generate fat jar
    sbt assembly
    
    // package example application. generate linux pacakge at target/linux ,msi at target/windows
    sbt packageApp
    // note: For some reasons, java 16's jpackage does not work on windows, so I use sbt-native-packager feature.
    

    In this PR

    • Python scripts are replaced with build tasks.
    • jwm-shared, jwm-<platform>, and the example project are also managed by sbt.
    • To use jpackage mentioned #104, I use sbt native packager on Windows as a work around because Java 16's jpackage fails on Windows for some reasons.

    It is possible to replace sbt with maven since sbt uses (almost) the same directory structure as maven or gradle. But I think sbt is much suitable for cross builid application like this.

    opened by i10416 9
  • macOS titlebar options

    macOS titlebar options

    Implements titlebar customization as outlined in #75 for macOS.

    Missing user drag regions Missing some javadocs

    Some behaviors:

    • I am still able to drag the window near the top when using a full size content area.
    • This is using a different method than Electron for custom traffic light position. This method seems more reliable, however it does not allow the buttons to exit the titlebar frame. I have not checked if electron does, but if so and its desired behavior I may need to switch to electrons method.
    • Currently traffic light positioning is ignored if the titlebar is hidden. It is because the underlying buttons are gone when titlebar is removed. I assume this could be worked around (by recreating the buttons), but I am not sure it is worth it. You can create the same effect with WindowMac.setTitle(null) and WindowMac.setFullSizeContentView(true).

    What is the policy on what goes in WindowMac vs existing only in JNI methods?

    opened by mworzala 6
  • [Win/Linux] add a graalvm native image example

    [Win/Linux] add a graalvm native image example

    Add an example sbt project that can build dashboard example app into standalone binary with graal vm native image on Windows and Linux.

    To add an example, I moved examples/* to examples/dashboard/*

    • graalvm-ce-java16:21.1.0
    • Windows 10 amd64
    • ubuntu 20.04 amd64
    git clone [email protected]:HumbleUI/JWM
    git checkout add-example
    cd examples/sbt
    sbt nativeImageCommand nativeImageRunAgent
    sbt nativeImage
    
    ./target/native-image/example
    
    opened by i10416 6
  • AWT interoperability

    AWT interoperability

    Looks like 0.4.x works fine with AWT (tested on macOS OpenJDK 13), where 0.3.x is completely incompatible with AWT on macOS. Also notice that -XstartOnFirstThread seems to be no longer required on mac in 0.4.x. What's the changes behind that?

    And should AWT interoperability be a feature of JWM and be guaranteed in future versions? This feature is quite important to me ;)

    opened by bumfo 5
  • macOS window represented filename

    macOS window represented filename

    See https://www.electronjs.org/docs/latest/tutorial/represented-file

    My proposition for an API is WindowMac#setRepresentedFilename(String filename, boolean iconOnly). There is an option to let the window determine an appropriate name based on the file (just the filename as far as I can tell), otherwise it just sets the icon and allows expanding the dropdown.

    opened by mworzala 5
  • delombok'ed sources give incorrect line pointers in error messages

    delombok'ed sources give incorrect line pointers in error messages

    Delombok changes the number of lines in the sources, thus leading to stacktraces with line numbers (coming from non-delomboked compilations of JWM) being off, making debugging a lot more confusing.

    opened by dzaima 4
  • add website

    add website

    Hi, I added jwm website and workflow to deploy it to gh pages.

    You can check demo page at https://i10416.github.io/JWM .

    If you're happy to publish website, please go settings > pages and configure gh-pages branch's root as a site directory.

    If you are not willing to publish a website, don't hesitate to say so and I will close PR.

    opened by i10416 4
  • LayerWGL.cc:103 Failed to create rendering context

    LayerWGL.cc:103 Failed to create rendering context

    I was to trying to run https://github.com/HumbleUI/JWM/blob/main/docs/GettingStarted.java but got an error like this

    LayerWGL.cc:103 Failed to create rendering context Exception in thread "main" org.jetbrains.jwm.LayerNotSupportedException: Failed to create rendering context at org.jetbrains.jwm.LayerGL._nAttach(Native Method) at org.jetbrains.jwm.LayerGL.attach(LayerGL.java:19) at EventHandler.(GettingStarted.java:22) at GettingStarted.main(GettingStarted.java:8)

    I am using jdk 16. I tried it using jdk 11 but got the same error. I even tried using a version like 0.1.274 , but got a similar error.

    Can anyone explain this.

    Waiting for reply 
    opened by Hilal-Anwar 4
  • Get rid of sleep(0.5ms) in X11 event loop

    Get rid of sleep(0.5ms) in X11 event loop

    https://github.com/JetBrains/JWM/blob/c6762d5c61a8cb06dae5023ca43ddd43b87698cf/linux/cc/WindowManagerX11.cc#L195

    Problem:

    • Can’t use blocking event loop because no way to schedule runOnUIThread from another threads
    • Non-blocking event loop eats lots of CPU

    Ideas:

    • don’t sleep at all
    • provide user-defined lambda to call instead of sleeping
    Help Wanted Platform: X11 Design 
    opened by tonsky 4
  • macOS: implement RESIZE_NESW and RESIZE_NWSE cursors

    macOS: implement RESIZE_NESW and RESIZE_NWSE cursors

    macOS is missing NESW/NWSE right now. I guess the solution here would be to provide custom cursors (I think that’s what both browsers and AWT do), then we can cover all the use-cases

    See #231 for context

    opened by tonsky 2
  • GraalVM native-image on arm macOS

    GraalVM native-image on arm macOS

    Related to #159

    It is now possible to generate a native image using JWM for arm macOS. See the following:

    https://github.com/mworzala/jwm-graalvm

    Will try to get it working with the native-image example (if anything needs to be changed), but I figured I would leave it here for those interested in the mean time.

    opened by mworzala 1
  • macOS: main window shows inside fullscreen if started from fullscreen app

    macOS: main window shows inside fullscreen if started from fullscreen app

    If you start the app from an full screen app, e.g. Intellij IDEA, then the main window is shown inside the fullscreen space, instead of shown in desktop space as normal.

    The behavior is correct in 0.3.x, when using App.init() and App.start() separately.

    opened by bumfo 2
  • X11: AppX11::getScale code could fail

    X11: AppX11::getScale code could fail

    Experienced on:

    • Debian with SwayWM on Wayland
    • WSL2 on Windows 11
    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00007f7255da2ad1, pid=944795, tid=944796
    #
    # JRE version: OpenJDK Runtime Environment (14.0.2+12) (build 14.0.2+12-Debian-2)
    # Java VM: OpenJDK 64-Bit Server VM (14.0.2+12-Debian-2, mixed mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)
    # Problematic frame:
    # C  [libc.so.6+0x15fad1]
    #
    # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
    #
    # If you would like to submit a bug report, please visit:
    #   https://bugs.debian.org/openjdk-14
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #
    
    ---------------  S U M M A R Y ------------
    
    Command Line: clojure.main -m user --interactive
    
    Host: AMD Ryzen 5 2600 Six-Core Processor, 12 cores, 15G, Debian GNU/Linux 11 (bullseye)
    Time: Fri Mar  4 12:58:41 2022 CET elapsed time: 2 seconds (0d 0h 0m 2s)
    
    ---------------  T H R E A D  ---------------
    
    Current thread (0x00007f7250017000):  JavaThread "main" [_thread_in_native, id=944796, stack(0x00007f7254571000,0x00007f7254672000)]
    
    Stack: [0x00007f7254571000,0x00007f7254672000],  sp=0x00007f7254669948,  free space=994k
    Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [libc.so.6+0x15fad1]
    
    Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
    j  io.github.humbleui.jwm.App._nGetScreens()[Lio/github/humbleui/jwm/Screen;+0
    j  io.github.humbleui.jwm.App.getScreens()[Lio/github/humbleui/jwm/Screen;+20
    j  io.github.humbleui.core$screens.invokeStatic()Ljava/lang/Object;+15
    j  io.github.humbleui.core$screens.invoke()Ljava/lang/Object;+0
    j  user$make_window.invokeStatic()Ljava/lang/Object;+18
    j  user$make_window.invoke()Ljava/lang/Object;+0
    j  user$_main$fn__3555.invoke()Ljava/lang/Object;+24
    j  clojure.lang.AFn.run()V+1
    j  io.github.humbleui.jwm.App.lambda$start$0(Ljava/lang/Runnable;)V+39
    j  io.github.humbleui.jwm.App$$Lambda$28.run()V+4
    v  ~StubRoutines::call_stub
    j  io.github.humbleui.jwm.App._nStart(Ljava/lang/Runnable;)V+0
    j  io.github.humbleui.jwm.App.start(Ljava/lang/Runnable;)V+9
    j  io.github.humbleui.core$start.invokeStatic(Ljava/lang/Object;)Ljava/lang/Object;+6
    j  io.github.humbleui.core$start.invoke(Ljava/lang/Object;)Ljava/lang/Object;+3
    j  user$_main.invokeStatic(Lclojure/lang/ISeq;)Ljava/lang/Object;+41
    j  user$_main.doInvoke(Ljava/lang/Object;)Ljava/lang/Object;+6
    J 1088 c1 clojure.lang.RestFn.applyTo(Lclojure/lang/ISeq;)Ljava/lang/Object; (3076 bytes) @ 0x00007f723871e4d4 [0x00007f72387081e0+0x00000000000162f4]
    j  clojure.lang.Var.applyTo(Lclojure/lang/ISeq;)Ljava/lang/Object;+5
    J 1355 c1 clojure.core$apply.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; (21 bytes) @ 0x00007f72387e96e4 [0x00007f72387e9360+0x0000000000000384]
    j  clojure.main$main_opt.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+412
    j  clojure.main$main_opt.invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+6
    j  clojure.main$main.invokeStatic(Lclojure/lang/ISeq;)Ljava/lang/Object;+376
    j  clojure.main$main.doInvoke(Ljava/lang/Object;)Ljava/lang/Object;+6
    J 1088 c1 clojure.lang.RestFn.applyTo(Lclojure/lang/ISeq;)Ljava/lang/Object; (3076 bytes) @ 0x00007f723871e4d4 [0x00007f72387081e0+0x00000000000162f4]
    j  clojure.lang.Var.applyTo(Lclojure/lang/ISeq;)Ljava/lang/Object;+5
    j  clojure.main.main([Ljava/lang/String;)V+20
    v  ~StubRoutines::call_stub
    
    Help Wanted Platform: X11 
    opened by tonsky 0
  • support windows visibility events

    support windows visibility events

    I temporarily named event as EventWindowAppear/Disappear, but I think there would be better candidates.

    Which do you think is better for visibility event name?

    • EventWindowShow/Hidden
    • EventWindowAppear/Disappear
    • EventWindowVisibilityOn/Off
    • EventWindowVisible/Invisible
    • other

    JWM notifies when window's visibility changes. In Windows, visibility is based mainly on WS_VISIBLE property and updated by ShowWindow function and ShowOwnedPopups function.

    see

    • https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/winmsg/window-features.md#window-visibility
    • https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-showwindow
    opened by i10416 2
Owner
JetBrains
JetBrains open source projects
JetBrains
The Leap Motion cross-format, cross-platform declarative serialization library

Introduction to LeapSerial LeapSerial is a cross-format, declarative, serialization and deserialization library written and maintained by Leap Motion.

Leap Motion (Ultraleap) 15 Jan 17, 2022
A cross platform shader language with multi-threaded offline compilation or platform shader source code generation

A cross platform shader language with multi-threaded offline compilation or platform shader source code generation. Output json reflection info and c++ header with your shaders structs, fx-like techniques and compile time branch evaluation via (uber-shader) "permutations".

Alex Dixon 275 Jul 18, 2022
ZXing ("Zebra Crossing") barcode scanning library for Java, Android

Project in Maintenance Mode Only The project is in maintenance mode, meaning, changes are driven by contributed patches. Only bug fixes and minor enha

ZXing Project 29.9k Aug 10, 2022
A simple C++ library with multi language interfaces (Java, NodeJS, Python...)

cpp-to-x A simple C++ library with multi language interfaces (Java, NodeJS, Python...) Why This is just a learning experiment to see how you can write

James Roberts 1 Nov 25, 2021
This is a helper library to abstract away interfacing with floppy disk drives in a cross-platform and open source library.

Adafruit Floppy This is a helper library to abstract away interfacing with floppy disk drives in a cross-platform and open source library. Adafruit Fl

Adafruit Industries 126 Jul 24, 2022
A perfect blend of C, Java, and Python tailored for those who desire a simple yet powerful programming language.

Fastcode A perfect blend of C, Java, and Python tailored for those who desire a simple yet powerful programming language. FastCode is a procedural/str

null 27 May 31, 2022
Get a users HWID in C++ and use it in Java

JNA Example rust version with jni soon What is this? This is example of using c++ and jna to get the hwid of a computer. Why? Your program will be mor

Jake Priddle 21 Sep 22, 2021
RR4J is a tool that records java execution and later allows developers to replay locally.

RR4J [Record Replay 4 Java] RR4J is a tool that records java execution and later allows developers to replay locally. The tool solves one of the chall

Kartik  kalaghatgi 15 Aug 7, 2022
Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control

StockSimulator Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control Features

Dušan Todorović 0 Mar 1, 2022
Solutions to Hackerrank.com practice problems using JAVA, C, Python and MySQL

Solutions to Hackerrank practice problems This repository contains 185 solutions to Hackerrank practice problems. Updated daily :) If it was helpful p

Ankit Seth 1 Dec 28, 2021
It's an 90 days challenge where all important concept of DSA I will be learning and solving using C++ or Java.

#90DaysDSA It's an 90 days challenge where all important concept of DSA I will be learning and solving using C++ or Java. Day 1 & 2 -> Space and Time

Priya_pp 1 Dec 11, 2021
Visual Studio extension for assembly syntax highlighting and code completion in assembly files and the disassembly window

Asm-Dude Assembly syntax highlighting and code assistance for assembly source files and the disassembly window for Visual Studio 2015, 2017 and 2019.

Henk-Jan Lebbink 4k Aug 6, 2022
R integration for edlib, a C/C++ library for pairwise sequence alignment using edit distance (Levenshtein distance).

edlibR Introduction Main Features Usage Background Alignment Methods Algorithmic Design Installation References edlibR: R integration for edlib The R

null 5 Mar 2, 2022
A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code

flutter-hadk A light-weight Flutter Engine Embedder based on HADK ,which for Android devices that runs without any java code 1.Build by android-ndk-to

null 12 Jun 15, 2022
This is the Master Repository for all the different algorithms in the world of DSA, be it in any language C++, Java, Python etc.....

© Dragon ball GT INTRODUCTION The goal of this repository is to have in a single place all possible algorithms and data structures - in multiple langu

Shivanshu Garg 12 May 4, 2022
dwm is an extremely fast, small, and dynamic window manager for X.

dwm - dynamic window manager dwm is an extremely fast, small, and dynamic window manager for X. My Patches This is in the order that I patched everyth

Christian Chiarulli 30 Jun 27, 2022
Small Header-Only Window and OpenGL Manager.

LxDemOWin Linux Demo OpenGL and Window manager A small header-Only Window and OpenGL manager made in C, written in about 2 hours. With some basic code

PipeWarp 5 Jun 4, 2022
Draw a triangle inside Electron's window using DirectX 11, mixing web and native content.

Draw a triangle inside Electron's window using DirectX 11, mixing web and native content. Limitations The native content is rendered over a child wind

UKABUER 9 Jul 12, 2022
Small Header-Only Window and OpenGL Manager.

LxDemOWin Linux Demo OpenGL and Window manager A small header-Only Window and OpenGL manager made in C, written in about 2 hours. With some basic code

pipewarp 4 Dec 11, 2021