Open TheDrawingCoder-Gamer opened 7 months ago
could it be that like the surface that pointerHandleEnter
gets is the libdecor-internal-window surface, while the one set up in WindowWayland::show
is the outer one that includes decoration, or something like that? or vice versa? (I have no clue)
If so I would assume vice versa, as I'm pretty sure that libdecor instances an outer surface to draw its frame.
The issue is that, if it IS a different surface, then changing back to the _nativeWindowToMy won't work bc it's a different pointer. However that would mean we would just do nothing if it isn't a window
New commit fixes that. However I still have incorrect rendering (and no rendering at all under sway)
!!!
AND IT WORKS WITH HIDPI!
what needs to be done for tomorrow: Repeating on keyboard input Multiple windows (it technically functions but something is very obviously wrong) Make raster layer work
@dzaima, i'm curious on what debugging tools you are using. I am not really using debugging tools, which is why I'm struggling with making this stuff work.
@dzaima, i'm curious on what debugging tools you are using. I am not really using debugging tools, which is why I'm struggling with making this stuff work.
I've been using https://rr-project.org/ with a currently-unpublished GUI I've been working on for it (uses JWM & Skija!), but I don't think it's really been too helpful, especially with rr having some bugs and crashing every now and then. Spamming printf
s goes a long way, main thing rr's been useful for is tracking memory issues but even then it's very time-consuming to jump around & decipher things.
todo tommorow:
tbh i have no idea how i'm going to figure out number 2, bc it's kind of odd, and idk how to really inspect the app. number 1 is also going to be a pain - switching layers isn't working most of the time, and raster only redraws whenever the compositor is like OH CRAP THIS IS SO MANY BUFFERS or an event occurs.
for whatever reason, raster seems to work a lot better if libdecor_dispatch
is called twice after libdecor_frame_map
, not once (and works better more frequently with more libdecor_dispatch
calls). Feels like something that'd happen if some events are sent in the wrong order otherwise?
oh, and btw, changes I need to have it build/work better (some that have been lingering around, some new:)
glfw after libdecor_frame_map
has wl_display_roundtrip
, which seems to be exactly the thing for my hypothesis of wrong event order: https://github.com/glfw/glfw/blob/46cebb5081820418f2a20f3e90b07f9b1bd44b42/src/wl_window.c#L803-L804; things seem to be running reasonably smoothly with libdecor_decorate; libdecor_frame_map; wl_display_roundtrip(_windowManager.display); libdecor_dispatch;
Adding a wl_display_roundtrip(self->_windowManager.display);
after decorFrameCommit
's wl_surface_commit
also affects things.
For me adding a dispatch after roundtrip, it stalls. Bc it blocks waiting for events :/
Frames aren't really drawn while paused, unlike on X11, which is odd. Not sure if this is an incorrectness with X11 or Wayland ( I assume wayland, as it only doesn't draw on Raster.) Again, raster is god awful slow ("swapBuffers" creates a new ShmPool and Buffer, which involves memory mapping a shared object. This is called every frame.) I'm capping at about 11 fps on my laptop, compared to max framerate of EGL.
I considered adding a frame callback, but that just causes the window to never show. I seriously think some form of frame throttling needs to take place bc of how god awful slow this stuff is. Of course down stream in HumbleUI it will never end up being an issue, but it's important for it to at least function.
Switching layers still doesn't work - I even tried doing a hack by closing and reopening, but it didn't work.
just realized that events are never actually sent - how interesting
can't for the life of me figure out why mouse cursor setting isn't working - only the first three (arrow, crosshair, help) load? and text sometimes works???? but I can tell that the hotspot is working??? I hate this
this is like one of the only issues preventing me from marking this as ready for review.
Rebasing is causing issues on sway. God knows why.
Something is obviously wrong bc none of the files touched are related to wayland in any way. How awful
nvm it works. There SHOULD:tm: be no more conflict (even though github is being wrong :( ) A flat copy will work (once ready)
note; you'll need the patch version of skija (pretty sure master branch has the patch, but you have to pull down master and build it). For me it mostly JUST WORKS(TM) on wayland, even with hidpi.
Some jank: Positioning is completely impossible. Too bad. Resizing works only while invisible. Wayland doesn't let you resize yourself non-interactively while mapped. Resizing ALSO is tied to scale. The dimensions must be divisible by the scale, otherwise it returns early (it's implemented as a bool method but this is never exposed in java). Vsync is disabled in general. This SHOULD(TM) be ok for both GL and Raster, as the compositor is what actually handles drawing, and it's syncronized properly. the reason vsync is disabled client-side is because under Sway it blocks the whole application if even 1 window is invisible.
There are a lot of weird function changes you can revert, but iirc I didn't touch X11 at all.
It should JUST WORK(tm) on other platforms bc nothing new changed.
Wayland and X11 work side by side - Wayland is loaded if the envvar WAYLAND_DISPLAY
is set, and x11 otherwise. There isn't really any error checking here (nor with a lot of this)
Yes, I know code organization is GOD AWFUL. I hate it too. Not used to C++ so bear with this god awful code organization.
I think (?) I've stripped all the debug stuff but I'll do another pass-over soon.
edge cases that I totally expect to break things multiple seats (I've never actually seen/used this in the wild, but it's technically part of the spec so I GUESS we should support it) Window being halfway between monitors (I don't expect a full on crash here but I expect scaling to not be correct, esp. when moving from a HiDPI screen to a LoDPI screen)
Otherwise I haven't rigorously tested things, only doing stuff that I saw was outright broken. The test itself works fine.
Rn I need to do animated cursors. Well, idk if I need to, but it would be nice to have. My "wait" mouse being still is very jarring to me.
but rn it's time for eepy : ) have fun reviewing this god awful code in the mean time
resizing interactively is also a bit jank, likely because the buffer is getting updated way too fast.
Keyboard support is also jank, there are some weird things not supported (notably the compose key, and key repeating).
Going to work on key repeating and maybe compose key? Resizing is also probably more important
resizing is now responsive on sway and weston, but on weston it sometimes puts up a black screen. Fully functions under wlroots though (tested on sway & wayfire)
now works without having to use --skija-dir
. Repeating keys also half functions (technically functions but lags in an odd way). Compose key fully (?) functions, but not at parity with X11.
For some file conflicts it only happened bc I open the file and use :wq
instead of :q!
. :wq
adds a newline at the end of the file.
Resizing still jank on weston, but works well enough on wlroots. Need to test on other major compositors (mutter and kwin). It functions by forcing a draw by dispatching a frame event then blocking on the processEvents thing.
It only blocks if the new screen scale is different from old screen scale, because wayland can crash if you set preferred buffer size to e.g. 2 while the dimensions of the buffer aren't multiples of the scale. Previously this was solved by making it a frame callback but that caused jank.
...? it doesn't accept any events while window isn't focused. Bad for clipboard bc of how wayland has clipboard; event loop HAS to be running for clipboard copying to work. No idea what/if anything is blocking. This will cause wl-paste to freeze if i try to paste from it, but it pastes if I focus back. Firefox flat-out doesn't paste at all (likely an attempt to prevent stalling bc of pasting). Painful... No idea what's blocking
it was GL. apparently eglMakeCurrent
resets swap interval. how upsetting.
only real thing is animated cursors but that is going to be so so painful.
please try testing it now - it works enough for me. weston flickers while resizing on GL, but who cares about weston. Test Mutter (gnome) and KWin (KDE).
animated cursor support is basically the last thing I need? again I don't really think it's needed but it will make me endlessly upset if I don't add it.
App.getPrimaryScreen()
appears to still error, which breaks my JWM usage; replacing that with a hard-coded rectangle gets it running.
Scroll wheel is inverted & way too slow for me on Weston, compared to X11 (speed could be a difference between weston config & my native system, but direction shouldn't be).
FPS seems to be uncapped if every frame requests another frame (e.g. in the ./script/run.py
window clicking ctrl+p; also seems that that ctrl+p is sent twice?).
Interacting with the decorations is somewhat buggy, though I don't know how much of that is the fault of whatever outdated versions of libdecor/weston I have from apt.
There are some segfaults/exceptions around closing windows, which I might look into.
perhaps I am just not mentally processing everything I have to for C++. I have never used RAII before outside of rust and rust makes it blatantly obvious. I would wager a guess that a vast majority of these are related to RAII in some way.
In wayland, you are expected to assume that all keys are released, but it's unspecified what you do on enter, when it gives you the keys in an array. I currently process it like they were just pressed, and I assume that's why there is jank on new windows? Very frustrating : / really wish I was writing in either a GC'd language or rust.
Yeah holding down Ctrl-N under sway spawns a ton of windows...
RAII only applies to the C++ JWM-specific parts, which I think work fine? Segfaults usually come from within the wayland library, which has its own memory management rules (and cannot be RAII as the interface is all C pointers)
hmmmm.... does this mean I'm doing something wrong? wonder where.
i've wrapped keyboard and pointer in classes with destructors but idk... I will try to add some extra things to make the compiler not do implicit copies?
yeah I kind of feel like I'm out of my depth with debugging C++. I don't write systems languages outside of rust, and rust practically holds my hand compared to C++. I'm going to take a break for the holidays and rotate what I can do now.
Reverting to draft as well.
as expected nvidia EGL doesn't work. How shocking.
it's just a black window with proprietary drivers. Raster works. Will try to fix this, but sway itself requires me to pass --unsupported-gpu
bc of how god awful the support is.
have a suspicion that there is memory corruption at play somewhere in pointerLeave and mouseUpdateUnscaled. jank
somehow managed to break it JUST on non-nvidia sway. wayfire works?
Have to memory leak frame to prevent crash on close. Jank. This is a bug with the free code of libdecor.
Weston is so buggy on NVIDIA that I don't really think it's worth trying to test it. Sway and Wayfire work so I assume most wlroots work.
I've observed that hooking this up to my local UI toolkit causes the window to be black until an update that forces a redraw is sent.
HumbleUI itself seems to be working with the obvious tweaks to prevent breakage with matching on Platform.
there are some nvidia and mesa exclusive bugs too so it's good I have a laptop and desktop. Getting segfaults on resizing with nvidia that aren't observable in mesa. I think (?) mesa is mostly working but idk. try testing it again to see how busted it is.
tbh i'm okay with nvidia bugs just cause like... if you are on nvidia and using wayland you are doing something wrong. I'm sure that for older cards the open source drivers work, but propreitary drivers are almost universally unsupported. I'll try to fix it but it's not as high priority as it would be on mesa.
re: lock cursor. Should I be receiving mouse motion events on mouse move? if so then locking the cursor won't work, doesn't actually send any events. X11 has no impl so my local machine has no reference.
I would see either way, esp. considering there is a "movementX" and "movementY" argument.
note: compilation now requires wayland-scanner and wayland-protocols (and KDE's extra-cmake-modules, but if this isn't ok I can copy files directly.)
want to say that winit has a bunch of options in certain places, including primary screens. I think it's ok to just add Nullable
to getPrimaryScreen and let the IDE handle it. This will likely break downstream projects (including yours) but I'm ok with that. It's better to say there is no data that makes sense then give data that doesn't make sense.
would like to add touch support but have no touch screen, and afaik my tablet is just a mouse in non supported apps. I can add touch support for my trackpad though.
edit: no I can't. wayland doesn't expose any interface to get finger coordinates.
weston support is blocked by https://gitlab.freedesktop.org/libdecor/libdecor/-/issues/59. any WM that has decorations will cause errors as GTK doesn't work, and I can't figure out how to force Cairo instead of GTK. would be fixed when the related PR up there is merged, or if I figure out how to force Cairo, as my desktop doesn't use GTK and it's functioning better
@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).
Wanted to try this out on the just-released Linux Mint 21.3 experimental wayland, but with on latest commit with sudo apt-get install wayland-protocols wayland-scanner++ extra-cmake-modules
I get this:
-- Java home found automatically at /usr/lib/jvm/java-1.11.0-openjdk-amd64. Set JAVA_HOME environment variable to override.
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/linux2/git/jwm-wayland/x11/build
[7/7] Linking CXX shared library libjwm_x64.so
-- Could NOT find WaylandProtocols: Found unsuitable version "1.25", but required is at least "1.32" (found //usr/share/wayland-protocols)
CMake Error at CMakeLists.txt:15 (message):
No protocols installed
-- Configuring incomplete, errors occurred!
Changing that 1.32
to 1.25
then gives this:
-- Java home found automatically at /usr/lib/jvm/java-1.11.0-openjdk-amd64. Set JAVA_HOME environment variable to override.
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/linux2/git/jwm-wayland/x11/build
ninja: no work to do.
-- Found WaylandProtocols: //usr/share/wayland-protocols (found suitable version "1.25", minimum required is "1.25")
-- Java home found automatically at /usr/lib/jvm/java-1.11.0-openjdk-amd64. Set JAVA_HOME environment variable to override.
-- Configuring done
CMake Error at CMakeLists.txt:38 (add_library):
No SOURCES given to target: protocols
CMake Generate step failed. Build files cannot be regenerated correctly.
switching to a random old commit of 1d7fb1af4fed7bbd0f40b23569a7b1d86bd59a9c
and building there compiled, but running then crashed Cinnamon, killing all apps, including the browser, making me rewrite this comment :/
try latest commit - reduces version requirement + uses a var for protocols instead of directly appending.
Fails to build with
FAILED: CMakeFiles/jwm.dir/cc/Decoration.cc.o
/usr/bin/c++ -Djwm_EXPORTS -I/mnt/linux2/git/jwm-wayland/wayland/../shared/cc -I/mnt/linux2/git/jwm-wayland/wayland/../linux/cc -I/usr/lib/jvm/java-1.11.0-openjdk-amd64/include -I/usr/lib/jvm/java-1.11.0-openjdk-amd64/include/linux -I/mnt/linux2/git/jwm-wayland/wayland/build -O3 -DNDEBUG -fPIC -std=gnu++14 -MD -MT CMakeFiles/jwm.dir/cc/Decoration.cc.o -MF CMakeFiles/jwm.dir/cc/Decoration.cc.o.d -o CMakeFiles/jwm.dir/cc/Decoration.cc.o -c /mnt/linux2/git/jwm-wayland/wayland/cc/Decoration.cc
/mnt/linux2/git/jwm-wayland/wayland/cc/Decoration.cc:196:6: error: field designator 'wm_capabilities' does not refer to any field in type 'xdg_toplevel_listener'
196 | .wm_capabilities = _xdgToplevelWmCapabilities
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
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.
update: i'm probably not going to work on this anymore. anyone else is free to continue this. It works well enough for me but I don't really know what else to do here. I think (?) it's good enough but needs more testing
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