-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wayland support #278
base: main
Are you sure you want to change the base?
Wayland support #278
Conversation
Changes I needed to make to have it build/run on my (X11) system (i.e. not running any of the actual wayland stuff): diff --git a/linux/cc/ILayer.hh b/linux/cc/ILayer.hh
index f21346a..5b8ee03 100644
--- a/linux/cc/ILayer.hh
+++ b/linux/cc/ILayer.hh
@@ -15,7 +15,7 @@ public:
virtual void makeCurrentForced();
virtual void setVsyncMode(VSync v) = 0;
virtual void close() = 0;
- virtual void resize(int width, int height);
+ virtual void resize(int width, int height) = 0;
static ILayer* _ourCurrentLayer;
diff --git a/wayland/cc/WindowWayland.cc b/wayland/cc/WindowWayland.cc
index ecbd2a9..ecb7c42 100644
--- a/wayland/cc/WindowWayland.cc
+++ b/wayland/cc/WindowWayland.cc
@@ -100,8 +100,10 @@ bool WindowWayland::init()
wl_surface_listener surfaceListener = {
.enter = WindowWayland::surfaceEnter,
.leave = WindowWayland::surfaceLeave,
+#ifdef HAVE_WAYLAND_1_22
.preferred_buffer_scale = WindowWayland::surfacePreferredBufferScale,
.preferred_buffer_transform = WindowWayland::surfacePreferredBufferTransform
+#endif
};
wl_surface_add_listener(_waylandWindow, &surfaceListener, this); |
and here's a bunch of changes, ranging from fixes to hacks to debug utils (i.e. don't blindly copy everything here), to get thatdiff --git a/examples/dashboard/java/Example.java b/examples/dashboard/java/Example.java
index f8a2ee2..fd3e29a 100644
--- a/examples/dashboard/java/Example.java
+++ b/examples/dashboard/java/Example.java
@@ -55,8 +55,9 @@ public class Example implements Consumer<Event> {
var scale = window.getScreen().getScale();
int count = App._windows.size() - 1;
- Screen screen = App.getScreens()[(count / 5) % App.getScreens().length];
- IRect bounds = screen.getWorkArea();
+ // Screen screen = App.getScreens()[(count / 5) % App.getScreens().length];
+ // IRect bounds = screen.getWorkArea();
+ IRect bounds = new IRect(0, 0, 100, 100);
window.setTitle("JWM Window #" + count);
if (window instanceof WindowMac windowMac) {
@@ -202,6 +203,7 @@ public class Example implements Consumer<Event> {
}
}
} else if (e instanceof EventFrame) {
+ System.out.println("frame");
if (!paused)
window.requestFrame();
} else if (e instanceof EventFrameSkija ee) {
diff --git a/examples/dashboard/java/PanelRendering.java b/examples/dashboard/java/PanelRendering.java
index 5ab882b..fde41f2 100644
--- a/examples/dashboard/java/PanelRendering.java
+++ b/examples/dashboard/java/PanelRendering.java
@@ -34,6 +34,8 @@ public class PanelRendering extends Panel {
layers = new String[] { "LayerD3D12Skija", "LayerGLSkija", "SkijaLayerRaster" };
else if (Platform.CURRENT == Platform.X11)
layers = new String[] { "LayerGLSkija", "LayerRasterSkija" };
+ else if (Platform.CURRENT == Platform.WAYLAND)
+ layers = new String[] { "LayerRasterSkija", "LayerGLSkija" };
for (var layerName: layers)
layersStatus.put(layerName, UNKNOWN);
diff --git a/script/build.py b/script/build.py
index 9954d82..589461f 100755
--- a/script/build.py
+++ b/script/build.py
@@ -4,7 +4,7 @@ import argparse, build_utils, common, glob, os, platform, subprocess, sys
def build_native_system(system):
os.chdir(common.basedir + "/" + system)
subprocess.check_call(["cmake",
- "-DCMAKE_BUILD_TYPE=Release",
+ "-DCMAKE_BUILD_TYPE=Debug",
"-B", "build",
"-G", "Ninja",
"-DJWM_ARCH=" + build_utils.arch,
diff --git a/script/run.py b/script/run.py
index 98f3c0e..e90cbe7 100755
--- a/script/run.py
+++ b/script/run.py
@@ -10,9 +10,10 @@ def main():
parser.add_argument('--skija-shared-jar', default=None)
parser.add_argument('--skija-platform-jar', default=None)
parser.add_argument('--types-dir', default=None)
+ parser.add_argument('--just-run', action='store_true')
args = parser.parse_args()
- if not args.jwm_version:
+ if not args.jwm_version and not args.just_run:
build.main()
if args.skija_dir:
diff --git a/shared/java/App.java b/shared/java/App.java
index 268ddc6..7a1c5a7 100644
--- a/shared/java/App.java
+++ b/shared/java/App.java
@@ -52,6 +52,8 @@ public class App {
window = new WindowMac();
else if (Platform.CURRENT == Platform.X11)
window = new WindowX11();
+ else if (Platform.CURRENT == Platform.WAYLAND)
+ window = new WindowWayland();
else
throw new RuntimeException("Unsupported platform: " + Platform.CURRENT);
_windows.add(window);
diff --git a/shared/java/impl/Library.java b/shared/java/impl/Library.java
index 43fd5cb..29a5da5 100644
--- a/shared/java/impl/Library.java
+++ b/shared/java/impl/Library.java
@@ -46,10 +46,10 @@ public class Library {
} else if (Platform.CURRENT == Platform.X11) {
File library = _extract("/", "libjwm_x64.so", tempDir);
System.load(library.getAbsolutePath());
- } /*else if (Platform.CURRENT == Platform.WAYLAND) {
+ } else if (Platform.CURRENT == Platform.WAYLAND) {
File library = _extract("/", "libjwm_x64_wayland.so", tempDir);
System.load(library.getAbsolutePath());
- }*/
+ }
if (tempDir.exists() && version == null) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
diff --git a/wayland/CMakeLists.txt b/wayland/CMakeLists.txt
index 95ca0ad..f13c700 100644
--- a/wayland/CMakeLists.txt
+++ b/wayland/CMakeLists.txt
@@ -15,6 +15,8 @@ if(NOT JWM_ARCH)
endif()
endif()
+find_package(OpenGL REQUIRED)
+
file(GLOB SOURCES_CXX ${CMAKE_CURRENT_LIST_DIR}/../shared/cc/*.cc
${CMAKE_CURRENT_LIST_DIR}/../linux/cc/*.cc
${CMAKE_CURRENT_LIST_DIR}/cc/*.cc )
@@ -44,3 +46,4 @@ set_target_properties(jwm PROPERTIES OUTPUT_NAME "jwm_${JWM_ARCH}_wayland")
target_link_libraries(jwm PRIVATE ${WAYLAND_CLIENT_LIB} ${DECOR_LIB}
${WAYLAND_CURSOR} ${XKBCOMMON})
target_link_libraries(jwm PRIVATE ${EGL} ${WAYLAND_EGL})
+target_link_libraries(jwm PRIVATE OpenGL::GL)
diff --git a/wayland/cc/LayerRasterWayland.cc b/wayland/cc/LayerRasterWayland.cc
index 0462940..2177fdf 100644
--- a/wayland/cc/LayerRasterWayland.cc
+++ b/wayland/cc/LayerRasterWayland.cc
@@ -36,7 +36,6 @@ namespace jwm {
_pool->grow(bufSize);
// LSBFirst means Little endian : )
auto buf = _pool->createBuffer(0, width, height, width * sizeof(uint32_t), WL_SHM_FORMAT_ABGR8888);
-
_buffer = buf.first;
_imageData = buf.second;
}
diff --git a/wayland/cc/WindowManagerWayland.cc b/wayland/cc/WindowManagerWayland.cc
index 2c62963..ee92779 100644
--- a/wayland/cc/WindowManagerWayland.cc
+++ b/wayland/cc/WindowManagerWayland.cc
@@ -75,7 +75,7 @@ WindowManagerWayland::WindowManagerWayland():
.leave = WindowManagerWayland::pointerHandleLeave,
.motion = WindowManagerWayland::pointerHandleMotion,
.button = WindowManagerWayland::pointerHandleButton,
- .axis = WindowManagerWayland::pointerHandleAxis
+ // .axis = WindowManagerWayland::pointerHandleAxis
};
wl_pointer_add_listener(pointer, &pointerListener, this);
}
@@ -112,7 +112,7 @@ void WindowManagerWayland::runLoop() {
}
if (myPoll.revents & POLLIN) {
- while (read(pipes[0], buf, sizeof(buf) == sizeof(buf))) {}
+ while (read(pipes[0], buf, sizeof(buf)) == sizeof(buf)) {}
}
notifyBool.store(false);
}
@@ -166,7 +166,7 @@ void WindowManagerWayland::registryHandleGlobal(void* data, wl_registry *registr
&wl_shm_interface, 1);
} else if (strcmp(interface, "xdg_wm_base") == 0) {
self->xdgShell = (xdg_wm_base*)wl_registry_bind(registry, name,
- &xdg_wm_base_interface, 2);
+ &xdg_wm_base_interface, 1);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
self->deviceManager = (wl_data_device_manager*)wl_registry_bind(registry, name,
&wl_data_device_manager_interface, 1);
diff --git a/wayland/cc/xdg-shell.cc b/wayland/cc/xdg-shell.cc
index 03826cd..4001974 100644
--- a/wayland/cc/xdg-shell.cc
+++ b/wayland/cc/xdg-shell.cc
@@ -28,16 +28,19 @@
* DEALINGS IN THE SOFTWARE.
*/
+
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
+extern "C" {
+
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
+#define WL_PRIVATE __attribute__ ((visibility("hidden"))) extern "C"
#else
#define WL_PRIVATE
#endif
@@ -181,3 +184,5 @@ WL_PRIVATE const struct wl_interface xdg_popup_interface = {
3, xdg_popup_events,
};
+
+}
diff --git a/wayland/java/WindowWayland.java b/wayland/java/WindowWayland.java
index 056f7f4..5c09dd5 100644
--- a/wayland/java/WindowWayland.java
+++ b/wayland/java/WindowWayland.java
@@ -32,14 +32,14 @@ public class WindowWayland extends Window {
public IRect getWindowRect() {
assert _onUIThread() : "Should be run on UI thread";
// very very bad!
- return IRect.makeXYWH(0, 0, 0, 0);
+ return IRect.makeXYWH(0, 0, 100, 100);
}
@Override
public IRect getContentRect() {
assert _onUIThread() : "Should be run on UI thread";
// stop!
- return IRect.makeXYWH(0, 0, 0, 0);
+ return IRect.makeXYWH(0, 0, 100, 100);
}
@Override |
sorry for the bad commit names. this is what I do when stuff DOESN'T WORK |
I have a question about what format the buffer is supposed to be in. I assumed ABGR8888 because of LSBFirst, but is it RGBA8888? |
updates ( i guess): window does now open, but no rendering I've made a surprising amount of progress which is nice. I want to get rendering working before I start hooking up the keyboard. Any help would be appreciated bc I don't fully understand C++ (multiple days were taken up because I didn't realize things were freed at the end of scope). |
Sorry, I wish I could help, but I have no experience with Wayland |
ok here's some digging I've done on the GL issue - within |
I am not using glx though. I'm using egl, which SHOULD work on wayland. |
OH, you mean in skija. Yeah that is likely an upstream issue. |
#0 0x00007f22c3e5c9fe in glXGetCurrentContext () from /lib/x86_64-linux-gnu/libGLX.so.0
#1 0x00007f228af92132 in GrGLMakeGLXInterface() () from /tmp/skija_0.116.1_x64/libskija.so
#2 0x00007f228ae93d72 in GrGLMakeNativeInterface() () from /tmp/skija_0.116.1_x64/libskija.so
#3 0x00007f228aafe498 in GrGLGpu::Make(sk_sp<GrGLInterface const>, GrContextOptions const&, GrDirectContext*) () from /tmp/skija_0.116.1_x64/libskija.so
#4 0x00007f228a9e9a45 in GrDirectContext::MakeGL(sk_sp<GrGLInterface const>, GrContextOptions const&) () from /tmp/skija_0.116.1_x64/libskija.so
#5 0x00007f228a9e9ed7 in GrDirectContext::MakeGL() () from /tmp/skija_0.116.1_x64/libskija.so
#6 0x00007f228a4c2920 in Java_io_github_humbleui_skija_DirectContext__1nMakeGL () from /tmp/skija_0.116.1_x64/libskija.so
#7 0x00007f22b4356b11 in ?? ()
#8 0x00007f22cad16e10 in ?? ()
#9 0x0000000000000000 in ?? () the full gdb stacktrace of the fail fwiw |
oh, is skia in skija built with X11/GLX hard-coded? skia does have a thing that'd supposedly use EGL for |
perhaps a gonna try building that, probably gonna take a while though |
X11 could also be possibly rewritten to use EGL too - it would ensure that all linux targets would work with EGL. (or we could just add an if statement to the constructor of LayerGLSkija : ) ) |
Got a skia build with that to load (ended up Exception in thread "main" java.lang.UnsatisfiedLinkError: /tmp/skija_369211854708109/libskija.so: /tmp/skija_369211854708109/libskija.so: undefined symbol: eglQueryString
at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:331)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:197)
at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:139)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2404)
at java.base/java.lang.Runtime.load0(Runtime.java:785)
at java.base/java.lang.System.load(System.java:2011)
at io.github.humbleui.skija.impl.Library._loadFromFile(Library.java:147)
at io.github.humbleui.skija.impl.Library.load(Library.java:122)
at io.github.humbleui.skija.impl.Library.staticLoad(Library.java:20)
at io.github.humbleui.skija.Font.<clinit>(Font.java:9)
at io.github.humbleui.jwm.examples.Example.<clinit>(Example.java:18) should be easy enough to fix once I find where |
and with a diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 6b352fe..23afd7e 100644
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -84,4 +84,4 @@ endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(FindSkia)
-target_link_libraries(skija skottie sksg svg skparagraph skshaper skunicode skresources skia ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES})
+target_link_libraries(skija skottie sksg svg skparagraph skshaper skunicode skresources skia EGL ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES}) in Skija, JWM now doesn't crash with |
(here's a Skija linux x64 jar file of that; usable for JWM's example thing with |
Seems with this EGL build JWM & Skija still work on X11 with no extra changes? So that's nice (assuming that's correct and not me having forgotten to do something) |
Yeah just unfinished - needs more work. Will make a PR to skia build and skija to include EGL. |
@tonsky it's unhelpful to have this running every time and wasting runtime. idk if you can disable it but please do. I've made local edits to Dockerfile but idk how to really test them. |
not getting anymore crashes related to window closing. Going to remark as ready for review - note for the title bar it no longer uses libdecor and there is no more text - text would require pulling in an extra drawing library on the native level, like cairo, which I'm unsure if wanted. If this is ok point me at a library to use and i'll make it look somewhat nicer. Right now it uses subsurfaces to build a window border for resizing and movement, and subsurface buttons for minimize close and maximize/restore. probably still has issues under nvidia, too bad! will test later but as said previously i'm fine with crashing under jank circumstances on wayland for nvidia, bc they are propreitary drivers that can't be debugged. Notes on vsync: can't really do it (?) Tried delaying the redraw with surface. Causes window not to show, and with extra tinkering to add a force redraw flag, it shows but under sway it doesn't update. Raster will never screen tear as wayland compositors are the ones that actually render out frames. GL may cause screen tearing because the underlying method hooks into the tearing control protocol. This means KWin and Weston may have screen tearing (other compositors don't implement this protocol). All in all I think it's working well enough on Mesa that I would use it downstream. Of course this requires changes downstream in HumbleUI (I already have a local working build). Other things I would suggest are adding ways to tell the end client that a key is now pressed but that it shouldn't react to this in UI (for surface enter). |
Done to make any future work pulling in drawing libraries easier.
only tested on sway; weston is known to not support activation, but mutter and kwin do. need to test there. On sway this is seen as a red flash in the swaybar.
Focus stealing isn't possible in most compositors, and sway uses focus stealing attempts as a way to mark urgency. Focus will simply activate itself (stealing focus) and notify on sway.
Wanted to try this out on the just-released Linux Mint 21.3 experimental wayland, but with on latest commit with
Changing that
switching to a random old commit of |
try latest commit - reduces version requirement + uses a var for protocols instead of directly appending. |
Fails to build with
commenting out that line results in it running though! Doesn't look like that Mint's wayland cinnamon is anywhere near complete enough to test on though, weston manages to be less janky. |
bc of how I bind xdg_shell it's ok to omit these versions. Compositors don't send events to clients that bind to lower versions. |
merge upstread into wayland
Taken from Sodium's nvidia workaround. Disables optimizations for threading on Nvidia, thus preventing some weird crashes.
update: |
c4ee4a9
to
5bdc87b
Compare
Untested (couldn't get javac to work)
Highly expect something here to be extremely broken. Would not be surprised if there was an instant segfault.
bc it's literally a new platform this touches a LOT of files. Will work on merging