Giter Club home page Giter Club logo

waylib's Introduction

waylib

Introduction

waylib is a Wayland compositor development library, based on qwlroots, provides a Qt-style development interface. It is designed to be deeply integrated with QtQuick, taking advantage of QtQuick's Scene Graphics model to simplify the complexity of window management. In waylib, it is possible to attach one or multiple Wayland Outputs to a QQuickWindow, and a corresponding Wayland Surface can be attached to a QQuickItem, allowing it to be mixed with QtQuick's graphics components and supporting QRHI for OpenGL and Vulkan compatibility in a single piece of code.

Creating a Wayland compositor using waylib can be simple and efficient, which, on top of wlroots, provides:

  • QtQuick-based rendering model
  • Qt event model support
  • Session management system (under development)
  • Client/window group policies (under development)
  • Window management abstraction (under development)

Based on the above features, compositor developers need only focus on the business requirements of window management and can develop window compositors as if they were implementing a regular application.

Features

  • Support switch different display backend: DRM, Wayland, X11
  • Support custom input backend, by default it uses libinput
  • Support for rendering cursors in both hardware and software
  • Support for X Window cursor file format and theme
  • Support for running in environments without dri devices
  • Coexistence with Qt platform plug-in system
  • Provides QML components

Building

Step 1: Compiling and Installing wlroots and qwlroots

waylib requires the development version (0.17) of wlroots, which needs to be compiled and installed manually. Arch Linux users can install wlroots-git from AUR.

For qwlroots, it is currently recommended to use the version provided as a submodule. However, you can also compile and install it by yourself.

If using the submodule version, please note the following two points:

  1. Initialize the submodules when you clone the source code: git clone [email protected]:vioken/waylib.git --recursive
  2. Before the final compilation, add the cmake parameter "-DWITH_SUBMODULE_QWLROOTS=ON" to enable the building of the submodule.

Step 2: Installing other dependencies

Debian

# apt install pkg-config qt6-base-private-dev qt6-base-dev-tools qt6-declarative-private-dev wayland-protocols libpixman-1-dev

Archlinux

# pacman -Syu --noconfirm qt6-base qt6-declarative cmake pkgconfig pixman wayland-protocols ninja

NixOS:

It is recommended to manage dependencies using nix-direnv, or you can use the command nix develop to enter the build environment.

You can also packaging by using the command "nix build -v -L".

Step 3: Execute the following commands

cmake -B build -DWITH_SUBMODULE_QWLROOTS=ON
cmake --build build

How to Contribute

This project assumes that you already have experience with Qt and wlroots libraries. In order to better integrate with Qt and wlroots, waylib adheres to Qt's guidelines in terms of interface style, wlroots' modular design philosophy with regards to the underlying design, and Qt's wrapping + layering design for the upper layers that are not directly related to wlroots.

You are free to contribute as much code as you want to this project, provided that you follow the waylib design philosophy and the following types of requirements.

Code Style

  • When modifying existing code, the current code style should be respected.
  • New code: the part that is closely related to wlroots should follow the code style of wlroots, underscore naming convention should be used for the corresponding slot function; other parts should follow the code style of Qt (https://wiki.qt.io/Qt_Coding_Style this link is for reference only. The actual Qt source code shall prevail)
  • There is no absolute right or wrong code style, please consider the big picture, and do not rigidly stick to the small details

Code Architecture Guidelines

  • The code should be simple and easy to understand.
  • Add comments to key nodes whether you change or add new code
  • Security > Compatibility > Extensibility >= Performance

Contribution Guideline

  • Contribution steps.
    1. First login to your Github account and fork the project
    2. Pull the forked project locally using git clone.
    3. Push the new commit to your project using git push.
    4. commit your code to the upstream project on Github using the Pull Requese feature.
  • commit message specification: align with Qt project, use English. Be sure to describe exactly what the commit "does" and "why it was made"
  • A commit only does one thing, and the smaller the code changes, the easier it is to accept the commit. For larger code changes, try to split the commit into multiple commits (satisfying the git commit principle as a prerequisite)
  • Please do your own testing and code review before committing the code, and submit the PR after confirming that the code is working correctly

Roadmap

  • Support of vulkan
  • Support Hardware Plane
  • Support for virtual devices (remote screen projection, mouse, keyboard multi-device sharing)
  • Support multi-platform integration
  • Support high refresh rate (120Hz)
  • Support variable screen refresh rate

waylib's People

Contributors

18202781743 avatar asterwyx avatar blumia avatar comixhe avatar dami-star avatar groveer avatar hillwoodroc avatar justforlxz avatar lbwtw avatar lychee-yycy avatar renovate[bot] avatar wineee avatar zccrs avatar zhongyic00 avatar zsien avatar zzxyb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

waylib's Issues

Use cmake

The qmake is not recommend, should use cmake follow the Qt Project.

Build failure on openSUSE Tumbleweed

It is a link check error:

[ 61s] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: ../../src/server/libwaylibserver.so.0.1.1: undefined reference to QWLRoots::QWLayerSurfaceV1::surfaceAt(QPointF const&, QPointF*) const' [ 61s] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: ../../src/server/libwaylibserver.so.0.1.1: undefined reference to QWLRoots::QWLayerSurfaceV1::surface() const'
[ 61s] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: ../../src/server/libwaylibserver.so.0.1.1: undefined reference to QWLRoots::QWLayerShellV1::create(QWLRoots::QWDisplay*, unsigned int)' [ 61s] /usr/lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/bin/ld: ../../src/server/libwaylibserver.so.0.1.1: undefined reference to QWLRoots::QWLayerSurfaceV1::configure(unsigned int, unsigned int)'
[ 61s] collect2: error: ld returned 1 exit status
[ 61s] make[2]: *** [examples/tinywl/CMakeFiles/tinywl-qtquick.dir/build.make:613: examples/tinywl/tinywl-qtquick] Error 1
[ 61s] make[2]: Leaving directory '/home/abuild/rpmbuild/BUILD/waylib-0.1.1/build'
[ 61s] make[1]: *** [CMakeFiles/Makefile2:677: examples/tinywl/CMakeFiles/tinywl-qtquick.dir/all] Error 2
[ 61s] make: *** [Makefile:136: all] Error 2
[ 61s] error: Bad exit status from /var/tmp/rpm-tmp.sEd9C2 (%build)

Refactor

  • A new QPA plugin for compositor #47
  • using qwlroots from QPA plugin
  • Move part of implementation to qwlroots
  • Re-design namespace, use Vioken replace Waylib?
  • Qt6 only, >= Qt6.4
  • SPDX Style License

Update the READMD.md

Sections

  • Abstract
  • Features
  • Building
    • Debian
    • Archlinux
  • Future Plan
  • Contributing

Languages

  • en_US
  • zh_CN

Support Qt6

The QtQuick and qml has a large of changes in the Qt6, It's better(eg, the qml can compile to c++), and more and more projects is supported the Qt6 now, we should follow them.

Implement wlr_layer_shell_v1

Clients can use this interface to assign the surface_layer role to wl_surfaces. Such surfaces are assigned to a "layer" of the output and rendered with a defined z-depth respective to each other. They may also be anchored to the edges and corners of a screen and specify input handling semantics. This interface should be suitable for the implementation of many desktop shell components, and a broad number of other applications that interact with the desktop.

https://wayland.app/protocols/wlr-layer-shell-unstable-v1

reference implement:

Build issue with wlroots 0.17-dev

wlroots version=0.17.0-dev, major=0, minor=17, patch=0
QT_VERSION_MAJOR 6
Using QWlroots from submodule

[ 26%] Building CXX object qwlroots/src/CMakeFiles/qwlroots.dir/types/qwxdgshell.cpp.o
/home/shtirlic/projects/waylib/qwlroots/src/types/qwxdgshell.cpp: In constructor ‘QWLRoots::QWXdgSurfacePrivate::QWXdgSurfacePrivate(wlr_xdg_surface*, bool, QWLRoots::QWXdgSurface*)’:
/home/shtirlic/projects/waylib/qwlroots/src/types/qwxdgshell.cpp:104:36: error: ‘struct wlr_xdg_surface::<unnamed>’ has no member named ‘map’
  104 |         sc.connect(&handle->events.map, this, &QWXdgSurfacePrivate::on_map);
      |                                    ^~~
/home/shtirlic/projects/waylib/qwlroots/src/types/qwxdgshell.cpp:105:36: error: ‘struct wlr_xdg_surface::<unnamed>’ has no member named ‘unmap’
  105 |         sc.connect(&handle->events.unmap, this, &QWXdgSurfacePrivate::on_unmap);
      |                                    ^~~~~
make[2]: *** [qwlroots/src/CMakeFiles/qwlroots.dir/build.make:272: qwlroots/src/CMakeFiles/qwlroots.dir/types/qwxdgshell.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:216: qwlroots/src/CMakeFiles/qwlroots.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

failed to compile with clang (15.0.6)

Example:

 /usr/src/packages/BUILD/waylib/src/waylib/src/server/qtquick/woutputhelper.cpp:446:5: error: attempt to use a deleted function
     delete texture;
     ^
 /usr/include/qwlroots/qwtexture.h:21:5: note: '~QWTexture' has been explicitly marked deleted here
     ~QWTexture() = delete;
     ^

TODO: cursor alternative names

#278 lost some cursor

reference from kwin

QVector<QByteArray> Cursor::cursorAlternativeNames(const QByteArray &name)
{
    static const QHash<QByteArray, QVector<QByteArray>> alternatives = {
        {QByteArrayLiteral("left_ptr"),       {QByteArrayLiteral("arrow"),
                                                QByteArrayLiteral("dnd-none"),
                                                QByteArrayLiteral("op_left_arrow")}},
        {QByteArrayLiteral("cross"),          {QByteArrayLiteral("crosshair"),
                                                QByteArrayLiteral("diamond-cross"),
                                                QByteArrayLiteral("cross-reverse")}},
        {QByteArrayLiteral("up_arrow"),       {QByteArrayLiteral("center_ptr"),
                                                QByteArrayLiteral("sb_up_arrow"),
                                                QByteArrayLiteral("centre_ptr")}},
        {QByteArrayLiteral("wait"),           {QByteArrayLiteral("watch"),
                                                QByteArrayLiteral("progress")}},
        {QByteArrayLiteral("ibeam"),          {QByteArrayLiteral("xterm"),
                                                QByteArrayLiteral("text")}},
        {QByteArrayLiteral("size_all"),       {QByteArrayLiteral("fleur")}},
        {QByteArrayLiteral("pointing_hand"),  {QByteArrayLiteral("hand2"),
                                                QByteArrayLiteral("hand"),
                                                QByteArrayLiteral("hand1"),
                                                QByteArrayLiteral("pointer"),
                                                QByteArrayLiteral("e29285e634086352946a0e7090d73106"),
                                                QByteArrayLiteral("9d800788f1b08800ae810202380a0822")}},
        {QByteArrayLiteral("size_ver"),       {QByteArrayLiteral("00008160000006810000408080010102"),
                                                QByteArrayLiteral("sb_v_double_arrow"),
                                                QByteArrayLiteral("v_double_arrow"),
                                                QByteArrayLiteral("n-resize"),
                                                QByteArrayLiteral("s-resize"),
                                                QByteArrayLiteral("col-resize"),
                                                QByteArrayLiteral("top_side"),
                                                QByteArrayLiteral("bottom_side"),
                                                QByteArrayLiteral("base_arrow_up"),
                                                QByteArrayLiteral("base_arrow_down"),
                                                QByteArrayLiteral("based_arrow_down"),
                                                QByteArrayLiteral("based_arrow_up")}},
        {QByteArrayLiteral("size_hor"),       {QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"),
                                                QByteArrayLiteral("sb_h_double_arrow"),
                                                QByteArrayLiteral("h_double_arrow"),
                                                QByteArrayLiteral("e-resize"),
                                                QByteArrayLiteral("w-resize"),
                                                QByteArrayLiteral("row-resize"),
                                                QByteArrayLiteral("right_side"),
                                                QByteArrayLiteral("left_side")}},
        {QByteArrayLiteral("size_bdiag"),     {QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"),
                                                QByteArrayLiteral("fd_double_arrow"),
                                                QByteArrayLiteral("bottom_left_corner"),
                                                QByteArrayLiteral("top_right_corner")}},
        {QByteArrayLiteral("size_fdiag"),     {QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"),
                                                QByteArrayLiteral("bd_double_arrow"),
                                                QByteArrayLiteral("bottom_right_corner"),
                                                QByteArrayLiteral("top_left_corner")}},
        {QByteArrayLiteral("whats_this"),     {QByteArrayLiteral("d9ce0ab605698f320427677b458ad60b"),
                                                QByteArrayLiteral("left_ptr_help"),
                                                QByteArrayLiteral("help"),
                                                QByteArrayLiteral("question_arrow"),
                                                QByteArrayLiteral("dnd-ask"),
                                                QByteArrayLiteral("5c6cd98b3f3ebcb1f9c7f1c204630408")}},
        {QByteArrayLiteral("split_h"),        {QByteArrayLiteral("14fef782d02440884392942c11205230"),
                                                QByteArrayLiteral("size_hor")}},
        {QByteArrayLiteral("split_v"),        {QByteArrayLiteral("2870a09082c103050810ffdffffe0204"),
                                                QByteArrayLiteral("size_ver")}},
        {QByteArrayLiteral("forbidden"),      {QByteArrayLiteral("03b6e0fcb3499374a867c041f52298f0"),
                                                QByteArrayLiteral("circle"),
                                                QByteArrayLiteral("dnd-no-drop"),
                                                QByteArrayLiteral("not-allowed")}},
        {QByteArrayLiteral("left_ptr_watch"), {QByteArrayLiteral("3ecb610c1bf2410f44200f48c40d3599"),
                                                QByteArrayLiteral("00000000000000020006000e7e9ffc3f"),
                                                QByteArrayLiteral("08e8e1c95fe2fc01f976f1e063a24ccd")}},
        {QByteArrayLiteral("openhand"),       {QByteArrayLiteral("9141b49c8149039304290b508d208c40"),
                                                QByteArrayLiteral("all_scroll"),
                                                QByteArrayLiteral("all-scroll")}},
        {QByteArrayLiteral("closedhand"),     {QByteArrayLiteral("05e88622050804100c20044008402080"),
                                                QByteArrayLiteral("4498f0e0c1937ffe01fd06f973665830"),
                                                QByteArrayLiteral("9081237383d90e509aa00f00170e968f"),
                                                QByteArrayLiteral("fcf21c00b30f7e3f83fe0dfd12e71cff")}},
        {QByteArrayLiteral("dnd-link"),       {QByteArrayLiteral("link"),
                                                QByteArrayLiteral("alias"),
                                                QByteArrayLiteral("3085a0e285430894940527032f8b26df"),
                                                QByteArrayLiteral("640fb0e74195791501fd1ed57b41487f"),
                                                QByteArrayLiteral("a2a266d0498c3104214a47bd64ab0fc8")}},
        {QByteArrayLiteral("dnd-copy"),       {QByteArrayLiteral("copy"),
                                                QByteArrayLiteral("1081e37283d90000800003c07f3ef6bf"),
                                                QByteArrayLiteral("6407b0e94181790501fd1e167b474872"),
                                                QByteArrayLiteral("b66166c04f8c3109214a4fbd64a50fc8")}},
        {QByteArrayLiteral("dnd-move"),       {QByteArrayLiteral("move")}},
        {QByteArrayLiteral("sw-resize"),        {QByteArrayLiteral("size_bdiag"),
                                                QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"),
                                                QByteArrayLiteral("fd_double_arrow"),
                                                QByteArrayLiteral("bottom_left_corner")}},
        {QByteArrayLiteral("se-resize"),         {QByteArrayLiteral("size_fdiag"),
                                                QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"),
                                                QByteArrayLiteral("bd_double_arrow"),
                                                QByteArrayLiteral("bottom_right_corner")}},
        {QByteArrayLiteral("ne-resize"),         {QByteArrayLiteral("size_bdiag"),
                                                QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"),
                                                QByteArrayLiteral("fd_double_arrow"),
                                                QByteArrayLiteral("top_right_corner")}},
        {QByteArrayLiteral("nw-resize"),         {QByteArrayLiteral("size_fdiag"),
                                                QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"),
                                                QByteArrayLiteral("bd_double_arrow"),
                                                QByteArrayLiteral("top_left_corner")}},
        {QByteArrayLiteral("n-resize"),       {QByteArrayLiteral("size_ver"),
                                                QByteArrayLiteral("00008160000006810000408080010102"),
                                                QByteArrayLiteral("sb_v_double_arrow"),
                                                QByteArrayLiteral("v_double_arrow"),
                                                QByteArrayLiteral("col-resize"),
                                               QByteArrayLiteral("top_side")}},
        {QByteArrayLiteral("e-resize"),       {QByteArrayLiteral("size_hor"),
                                                QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"),
                                                QByteArrayLiteral("sb_h_double_arrow"),
                                                QByteArrayLiteral("h_double_arrow"),
                                                QByteArrayLiteral("row-resize"),
                                                QByteArrayLiteral("left_side")}},
        {QByteArrayLiteral("s-resize"),       {QByteArrayLiteral("size_ver"),
                                                QByteArrayLiteral("00008160000006810000408080010102"),
                                                QByteArrayLiteral("sb_v_double_arrow"),
                                                QByteArrayLiteral("v_double_arrow"),
                                                QByteArrayLiteral("col-resize"),
                                                QByteArrayLiteral("bottom_side")}},
         {QByteArrayLiteral("w-resize"),       {QByteArrayLiteral("size_hor"),
                                                QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"),
                                                QByteArrayLiteral("sb_h_double_arrow"),
                                                QByteArrayLiteral("h_double_arrow"),
                                                QByteArrayLiteral("right_side")}}
    };
    auto it = alternatives.find(name);
    if (it != alternatives.end()) {
        return it.value();
    }
    return QVector<QByteArray>();
}

How to run TinyWL example?

I've compiled the whole project & submodules according to instructions without any error.
And the tinywl-qtquick binary can run and display without crash in tty.
(Run as root, XDG_RUNTIME_DIR set to /run/user/$UID, seatd.sock in /run (require root permission), wayland-0 in /tmp/runtime-$USER/)

However, problems exist that:

  • Cannot run in X11 like weston. Since wlroots-0.17.0 invokes a incompatible GBM func, I disabled it in wlroots. Don't know if this is related.
    image
  • (EE) could not connect to wayland server. The client didn't start in tinywl, although the startDemo func returned true.

00:00:30.706 [INFO] [xwayland/server.c:218] Restarting Xwayland
00:00:30.711 [INFO] [wayland] wl_display_destroy_clients: cannot destroy all clients because new ones were created by destroy callbacks
00:00:30.716 [INFO] [xwayland/server.c:108] Starting Xwayland on :3
(EE) failed to read Wayland events: Broken pipe

Enabling WAYLAND_DEBUG=1 provides a little more log, but is still limited.
logs.txt
strace.txt

TODO: Wayland Protocols

Drop XXXX::nativeInterface template function

Direct return QWXXXX instance in XXXX::handle function, drop WXXXXXHandle type. for an example:

class WCursor : public QObject, public WObject
{
    Q_OBJECT
    W_DECLARE_PRIVATE(WCursor)

public:
    explicit WCursor(QObject *parent = nullptr);

    QWCursor *handle() const;
    static WCursor *fromHandle(const QWCursor *handle);
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.