Page MenuHome

GHOST/Wayland: support client-side window decorations
ClosedPublic

Authored by Christian Rauch (christian.rauch) on Jun 10 2020, 11:50 PM.

Details

Summary

This implements client-side window decorations for moving and resizing windows and HiDPI support.

This functionality depends on the external project 'libdecor' that is currently a build option: WITH_GHOST_WAYLAND_LIBDECOR.

Diff Detail

Repository
rB Blender
Branch
TEMP-WAYLAND-LIBDECOR (branched from master)
Build Status
Buildable 22667
Build 22667: arc lint + arc unit

Event Timeline

detect own toplevel surfaces

This doesn't compile for me here:

In file included from /home/hans/Blender-Git/blender/intern/ghost/intern/GHOST_ISystem.cpp:33:
/home/hans/Blender-Git/blender/intern/ghost/intern/GHOST_SystemWayland.h:30:10: fatal error: libdecoration/libdecoration.h: No such file or directory
   30 | #include <libdecoration/libdecoration.h>
      |          ^~~~~~

It seemed to get further in the process of setting up libdecoration each time I started compilation but never finished.

Generally I think extern is the place where smaller dependencies like this are added, and larger library dependencies are in ../lib rather than Blender source but have patches in blender/build_files/build_environment. Take that with a grain of salt though, I don't have much experience there.

It seemed to get further in the process of setting up libdecoration each time I started compilation but never finished.

I could use some help with the integration of the dependency into the build script to make sure it's built before Blender. For now, I have to add it as a dependency on some other CMake target and I cannot force to build it before that target is defined.

You can force to build this dependency by running ninja libdecoration in the build folder.

Alternatively, you can manually install libdecoration from https://gitlab.gnome.org/jadahl/libdecoration. It comes with a pkg-config file to infer the header and library locations.

We can not use ExternalProject as part of the main Blender build. We don't want a build to automatically download data from external sources.

There's a few possibilities:

  • Ideally libdecoration is widely installed along with other Wayland packages, and there is no need to build it as part of Blender at all.
  • Linux distributes have packages for libdecoration that their Blender packages can depend on, and for official releases we build it as part of our precompiled libraries in build_files/build_environment/CMakeLists.txt
  • There is no expectation for this library to be packaged in Linux distributions, in which case we bundle the source code in extern/, which we prefer not to do if at all possible.

add libdecoration to external source tree

There's a few possibilities:

  • Ideally libdecoration is widely installed along with other Wayland packages, and there is no need to build it as part of Blender at all.
  • Linux distributes have packages for libdecoration that their Blender packages can depend on, and for official releases we build it as part of our precompiled libraries in build_files/build_environment/CMakeLists.txt

I think the first two options ("widely installed" and "distributions have packages") represent the same condition in that a libdecoration package is available in all Linux distributions. This is not the case at the moment. Even if it gets packaged for all the major distributions now, it will take a long time until it will become widely available in stable distributions. The only realistic option is to provide it as part of the external source tree or fetch it on-demand.

  • There is no expectation for this library to be packaged in Linux distributions, in which case we bundle the source code in extern/, which we prefer not to do if at all possible.

To this end, I added libdecoration to the extern source tree and use ExternalProject_Add with SOURCE_DIR to directly build from this source. The add_dependencies(blender libdecoration) should make sure that libdecoration is built and installed before the blender executable.

Ok, extern/ is reasonable then.

But this seems like it adds dependencies on meson, ninja, dbus? And also cairo I think (though it's not in the meson build file)? Can you clarify this?

We should add a Blender specific CMake file to compile this, we don't want to require meson for building Blender. Using a different mechanism to detect compilers and external libraries can also lead to problems.

But this seems like it adds dependencies on meson, ninja, dbus? And also cairo I think (though it's not in the meson build file)? Can you clarify this?

Yes, the project is built with meson+ninja. cairo is a dependency for the actual bitmap manipulation and drawing routines. The D-Bus dependency is optional and used to query the current cursor size and theme name to match the user's settings. Removing this functionality will lead to inconsistent cursor themes and sizes, which I would not recommend. There is a Wayland protocol in the making that allows to query these properties, but it is far away from being available in compositor and we thus have to rely on D-Bus.

We should add a Blender specific CMake file to compile this, we don't want to require meson for building Blender. Using a different mechanism to detect compilers and external libraries can also lead to problems.

Is this really required? It is quite tedious to create and maintain a parallel build script and make sure that both behave the same. I am also sure that the upstream project will not accept a second build system.

Why can't Blender dependencies use alternative build systems? meson is now widely available in Linux distributions and can even be installed as normal user via pip (pip install meson).

Yes, the project is built with meson+ninja. cairo is a dependency for the actual bitmap manipulation and drawing routines. The D-Bus dependency is optional and used to query the current cursor size and theme name to match the user's settings. Removing this functionality will lead to inconsistent cursor themes and sizes, which I would not recommend. There is a Wayland protocol in the making that allows to query these properties, but it is far away from being available in compositor and we thus have to rely on D-Bus.

Thanks for the info. The decision to add more dependencies needs to be taken carefully. My understanding is that with this change, Blender releases would only run on Linux systems that have Cairo and D-Bus installed, with a recent enough versions of them. It's not obvious to me that these are installed by default on all important Linux distributions that have X11 / Wayland, maybe they are? But probably not on headless machines for render farms?

Is this really required? It is quite tedious to create and maintain a parallel build script and make sure that both behave the same. I am also sure that the upstream project will not accept a second build system.

Why can't Blender dependencies use alternative build systems? meson is now widely available in Linux distributions and can even be installed as normal user via pip (pip install meson).

If it's an external library we'll use whatever build system it uses. But we try to keep building Blender itself simple for users and developers, with platform maintainers making the precompiled libraries and dealing with those problems. Meson might use a different compiler, use different compile flags, detect different external libraries, or cause build failures in some other way that CMake doesn't.

Anyway, I'd like @Campbell Barton (campbellbarton) and @Sergey Sharybin (sergey)'s opinion on the right direction here.

It's not obvious to me that these are installed by default on all important Linux distributions that have X11 / Wayland, maybe they are? But probably not on headless machines for render farms?

On desktops, it is very likely that the cairo and dbus libraries are installed. dbus is used by gtk and qt, and cairo is the low-level drawing library that gtk is built on. So yes, if you have X11 and gtk installed, I am certain that these two dependencies are already present. However, the development versions (i.e. -dev) have to be installed additionally when building Blender from source.

I don't expect those libraries to be present on headless systems. But I also wouldn't expect any of the X11 or GUI libraries to be present either. For headless builds of Blender, there should be a dedicated "window-less" GHOST wrapper that simply renders to EGL pixel buffers.

If it's an external library we'll use whatever build system it uses. But we try to keep building Blender itself simple for users and developers, with platform maintainers making the precompiled libraries and dealing with those problems. Meson might use a different compiler, use different compile flags, detect different external libraries, or cause build failures in some other way that CMake doesn't.

It's unfortunate, but unless someone implements server-side decorations in GNOME/mutter, Wayland clients have to draw their own window decorations. libdecoration was specifically created for this purpose to provide these client-side decorations without many dependencies so that it can be used by projects that do not want to implement their own decorations.

However - if Blender at some point indeed decides to provide custom client-side decorations on all platforms (e.g. like Mozilla Firefox or Google Chrome do), then such a library would not be required anymore. Using client-side decorations has the benefits that the application can use the screen space more efficiently. Right now, Blender's title bar on X11 takes screen space that could otherwise be used by UI elements.

fix libdecoration dependency tracking in CMake

get cursor theme and size via D-Bus

@Campbell Barton (campbellbarton) @Brecht Van Lommel (brecht) Is this ready to be merged? This finalises the Wayland implementation as it should now support all the expected features.

I have very mixed feelings about this. First of all, I find the GNOME idea to require client side decorations... questionable, to say it in the nicest possible way. Blender could be a strong voice opposing that decision, rather than just accepting it and ignoring that this throws smaller projects under a bus. Somehow GNOME already seems to support server side decorations for X11 applications btw, so it's not like it's not there at all (might very well be a hack of course).
If we have to do such build-system changes as done here (libdecoration & Meson & D-Bus & Cairo?), just to support Gnome+Wayland, I'd say don't do it and keep using X for until there's a better solution or no other choice.

Using our own decorations is something we wanted to do for a while, I did a number of experiments with it some time ago. It's not exactly a weekend project, but something we could look at before too long. We're not in a hurry to get Wayland ready.
I'm sorry if this sounds in any way dismissive towards your work, I really don't mean to. It's just that GNOME forces us into an unpleasant position and we have to find the best way forward.

(We shouldn't need to include the demo directory btw.)

  • update libdecoration
  • remove demo
  • rebase master

I have very mixed feelings about this. First of all, I find the GNOME idea to require client side decorations... questionable, to say it in the nicest possible way.

I understand you. I was at this point when first using Wayland and discovered that I have to implement decorations myself.

However, what a lot of people are missing is that Wayland is not a toolkit or graphics library, it is really just the low-level IPC between a client and the compositor. This is in contrast to Windows and macOS where you have a standard API/toolkit for graphical applications and you rarely use, if possible at all, the underlying IPC layer. Since there is no "Linux SDK" or default toolkit, you have to choose one (GTK, Qt, ...) or implement the drawing yourself.

ignoring that this throws smaller projects under a bus.

Having a library that implements the decorations so that other projects don't have to do this is exactly the aim of libdecoration.

Somehow GNOME already seems to support server side decorations for X11 applications btw, so it's not like it's not there at all (might very well be a hack of course).

I don't have a full grasp too, why the X11 server-decorations cannot be used on Wayland too. I think the main reason is that GNOME does not want the compositor (i.e. the Wayland server) to depend on a toolkit. Ideally, the compositor should just do the compositing job, i.e. show the image buffers that the clients provided. This includes the decoration and cursor image buffer.

If we have to do such build-system changes as done here (libdecoration & Meson & D-Bus & Cairo?), just to support Gnome+Wayland, I'd say don't do it and keep using X for until there's a better solution or no other choice.

I think these dependencies are not so uncommon. If you want to support Wayland, you likely want to use D-Bus to fetch the correct cursor settings. If you really do not want to use D-Bus and use a default cursor instead, this dependency can be deactivated at build-time. If you want decorations, something (Cairo) has to draw them. You could implement the drawing in OpenGL of course, but then you have to implement your own text rendering etc. If you are using a modern Linux desktop you most certainly will have cairo installed already. If meson is the blocking issue, then I can probably rewrite this part in CMake.

Using our own decorations is something we wanted to do for a while, I did a number of experiments with it some time ago. It's not exactly a weekend project, but something we could look at before too long. We're not in a hurry to get Wayland ready.

If you decide to use client-side decorations that integrate into the Blender UI, then a dedicated library such as libdecoration is not required of course. If this is the case, I can work on the Wayland side of things.

I'm sorry if this sounds in any way dismissive towards your work, I really don't mean to. It's just that GNOME forces us into an unpleasant position and we have to find the best way forward.

I understand you, but at least you do not have to implement these decorations yourself :-)

(We shouldn't need to include the demo directory btw.)

I removed the demo subfolder and its reference in the meson build script.

Finally, I want to share why I think you should support Wayland.

Ugly and glitchy window resizes on X11 (Blender 2.91.2):

Buttery smooth and perfect window resizes on Wayland (this patch):

... this is what "every frame is perfect" means when you talk to people that used to work on X11 and know all about its flaws.

@Julian Eisel (Severin) - Using our own decorations is something we wanted to do for a while...

Me too on Windows. That is part of my desire for moving "Scene" and "View Layer" out of TopBar (through better maintenance in Outliner and Properties), so we have more room to lay it out nicely.

use system libdecor-0.1 and update API

Rebase on master and updates:

  • Use CMake option WITH_GHOST_WAYLAND_LIBDECOR, keep XDG support.
  • Fix crash on startup (see libdecor_dispatch), replace multiple calls to wl_display_roundtrip.
  • Use decor_ prefix for members relating to libdecor.
  • Remove unrelated changes.

I have very mixed feelings about this. First of all, I find the GNOME idea to require client side decorations... questionable, to say it in the nicest possible way. Blender could be a strong voice opposing that decision, rather than just accepting it and ignoring that this throws smaller projects under a bus. Somehow GNOME already seems to support server side decorations for X11 applications btw, so it's not like it's not there at all (might very well be a hack of course).
If we have to do such build-system changes as done here (libdecoration & Meson & D-Bus & Cairo?), just to support Gnome+Wayland, I'd say don't do it and keep using X for until there's a better solution or no other choice.

Agree, but I get the impression they're not going to budge on this. See: https://gitlab.gnome.org/GNOME/mutter/-/issues/217

Using our own decorations is something we wanted to do for a while, I did a number of experiments with it some time ago. It's not exactly a weekend project, but something we could look at before too long. We're not in a hurry to get Wayland ready.
I'm sorry if this sounds in any way dismissive towards your work, I really don't mean to. It's just that GNOME forces us into an unpleasant position and we have to find the best way forward.

While I'm not against this, it doesn't seem like a near-term project either. As not having a title bar seems to be one of the main missing features blocking Wayland, I think it's reasonable to use an existing solution which could be replaced later if we want.

  • Disable WITH_GHOST_WAYLAND_LIBDECOR by default

Why can't Blender dependencies use alternative build systems? meson is now widely available in Linux distributions and can even be installed as normal user via pip (pip install meson).

If it's an external library we'll use whatever build system it uses. But we try to keep building Blender itself simple for users and developers, with platform maintainers making the precompiled libraries and dealing with those problems. Meson might use a different compiler, use different compile flags, detect different external libraries, or cause build failures in some other way that CMake doesn't.

Anyway, I'd like @Campbell Barton (campbellbarton) and @Sergey Sharybin (sergey)'s opinion on the right direction here.

Suggest the following:

  • Use a stub for libdecor so it can be dynamically loaded (similar to SDL or dynamically loaded Wayland, see: D15250).
    • Linux distros can depend on libdecor (no stub needed).
    • For our own portable builds we could either bundle library (it could for e.g. be in ../lib/ but not in ./extern/), or, if the main Linux distributions include this by default - rely on the stub to find the system library. Either way running Blender on render-farms, X11 etc wont depend on libdecor/cairo/pango ... etc.

This patch has been updated to use an option WITH_GHOST_WAYLAND_LIBDECOR, so unless there are reservations about using libdecor altogether, I think we could consider committing this for further testing & development.

Sounds like a good plan.

This revision is now accepted and ready to land.Jun 24 2022, 3:59 PM
Campbell Barton (campbellbarton) retitled this revision from Wayland client-side window decorations to GHOST/Wayland: support client-side window decorations.