JWM - Cross-platform window management and OS integration library for Java

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”

Comparison to other UI/window libraries

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:

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:

Dependency

Key Value
groupId io.github.humbleui
artifactId jwm
version version

Getting started

See Getting Started

Status

Alpha. Expect API breakages.

App

Windows macOS X11
init
makeWindow #121
start
getScreens
getPrimaryScreen
runOnUIThread #113
terminate
Show notification

Theme

Windows macOS X11
isHighContrast
isDark #161
isInverted #161

Window

Windows macOS X11
setEventListener
setTextInputClient
setTextInputEnabled
unmarkText
show
getWindowRect #109
getContentRect
setWindowPosition
setWindowSize #109
setContentSize
getScreen
requestFrame #113
close #107
minimize
maximize
restore
setTitle
setIcon #95
Set system cursor #99
Remove decorations #75 #75 #75
Set custom cursor
openFile
openFolder
Transparency
Toggle Fullscreen
setMinimumSize
setMaximumSize
setResizable

Events

Windows macOS X11
EventFrame
EventKey
EventMouseButton
EventMouseMove
EventMouseScroll #115 #115
EventTextInput #105
EventTextInputMarked
EventWindowCloseRequest
EventWindowMove #116
EventWindowResize
EventWindowMinimize #96
EventWindowMaximize #96
EventWindowRestore #96
EventWindowVisible #140 #140 #140
EventWindowScreenChange #117 #117 #117
Drag & Drop
Touch events
Theme Changed

Screen

Windows macOS X11
id
isPrimary
bounds
scale
workArea #119
colorSpace #122 #122 #122

Clipboard

Windows macOS X11
set #51
get #51
getFormats #51
clear #51
registerFormat #51

Layers

Windows macOS X11
Raster #81
OpenGL
DirectX 11
DirectX 12
Metal
Vulkan

Packaging

Windows macOS X11
Run on GraalVM
App package

Building from source

Prerequisites:

  • Shared: Git, CMake(3.11+), Ninja, C++ compiler, JDK 11+, $JAVA_HOME, Python 3
  • Windows 10: Microsoft Visual C++ (MSVC), x64 Native Tools Command Prompt for VS
  • Ubuntu 20.04: libxcomposite-dev libxrandr-dev libgl1-mesa-dev libxi-dev libxcursor-dev

Run:

./script/build.py

Run examples:

./script/run.py

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

./script/run.py --jwm-version <version>

Contributing

PRs & issue reports are welcome!

Please read Conventions first.

If you are looking where to start, there’s a label: Good first issue.

Issues labeled “Design” and “Not sure” require prior discussion—leave a comment with your ideas!

Contributors

Development sponsored by:

Comments
  • 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
  • X11 (Cinnamon?): _NET_WM_SYNC_REQUEST stops working after releasing resize while still dragging mouse

    X11 (Cinnamon?): _NET_WM_SYNC_REQUEST stops working after releasing resize while still dragging mouse

    Very cryptic problem, but it's annoying me to no end.

    1. hold a corner of the window
    2. drag around
    3. while still dragging the mouse around, release left click (will not happen if you hold mouse, stop moving, and release while keeping the mouse pointer still)
    4. observe that on future resizing its glitchy

    Might be a Cinnamon/Linux Mint issue (would love to hear if this is reproducable on other systems), might be an issue with JWM's _NET_WM_SYNC_REQUEST usage/implementation.

    edit: behavior in random other apps: GIMP & Krita have the same issue; Sublime Text, Nemo, and Gnome Terminal don't.

    opened by dzaima 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
  • Detect display’s color space

    Detect display’s color space

    https://github.com/chromium/chromium/blob/main/ui/gfx/mac/display_icc_profiles.cc https://github.com/chromium/chromium/blob/main/ui/gfx/color_space.cc https://github.com/chromium/chromium/blob/main/ui/gfx/color_space_win.cc https://github.com/chromium/chromium/blob/main/ui/gfx/display_color_spaces.h

    opened by tonsky 0
  • X11: Scroll not reported while some other mouse button is held down

    X11: Scroll not reported while some other mouse button is held down

    So far I've traced it down to this:

    While no mouse buttons are held, that gets two events, one with deviceEvent->deviceid being 2 and one with it being 10; the 10 fails the if and thus doesn't get processed.

    Whereas when some mouse button is held down, only the 10==deviceEvent->deviceid event happens, and so nothing gets processed.

    Hard-coding deviceEvent->deviceid there to always be 2 does give scroll updates, proving that receiving scroll updates while a button is held is possible, but of course such hard-coding won't work for an actual solution.

    opened by dzaima 0
  • 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
Owner
Humble UI
Humble UI
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 278 Sep 29, 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 30.2k Oct 2, 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 130 Sep 28, 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 28 Aug 19, 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 16 Aug 20, 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 Sep 29, 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
Implementation of Library management in C using Data Structures.

Implementation of Library Management in C using data structure This includes following : BOOK.txt :- Which Contains the books list stored in library w

null 2 Dec 22, 2021
C Language project - Library Management System

Library Management System This is C Language project based on the file-handling. It basically provides the functionalities of Adding, Searching, Delet

Anmol Arora 1 Jan 22, 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 31 Sep 22, 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