{"id":13341313,"url":"https://github.com/vector-of-bool/wlxx","last_synced_at":"2025-04-11T03:23:10.717Z","repository":{"id":70180725,"uuid":"102407690","full_name":"vector-of-bool/wlxx","owner":"vector-of-bool","description":"Wayland Client C++ Bindings","archived":false,"fork":false,"pushed_at":"2018-02-20T05:21:11.000Z","size":44,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-03-25T01:20:36.357Z","etag":null,"topics":["bindings","cpp","library","wayland"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vector-of-bool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-04T22:28:11.000Z","updated_at":"2020-04-25T09:20:02.000Z","dependencies_parsed_at":"2023-02-21T11:45:28.488Z","dependency_job_id":null,"html_url":"https://github.com/vector-of-bool/wlxx","commit_stats":{"total_commits":4,"total_committers":1,"mean_commits":4.0,"dds":0.0,"last_synced_commit":"a32733eb7c62eb451183478bc1d6e8f662703627"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vector-of-bool%2Fwlxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vector-of-bool%2Fwlxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vector-of-bool%2Fwlxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vector-of-bool%2Fwlxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vector-of-bool","download_url":"https://codeload.github.com/vector-of-bool/wlxx/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248334349,"owners_count":21086377,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bindings","cpp","library","wayland"],"created_at":"2024-07-29T19:25:24.149Z","updated_at":"2025-04-11T03:23:10.698Z","avatar_url":"https://github.com/vector-of-bool.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IMPORTANT:\n\nThis project is just a little experiment I threw together in a few hours,\nand hasn't been updated or given any proper TLC for several months.\n\nFor a library with the same design goals but proper maintainence and \nsupport, look at [waylandpp](https://github.com/NilsBrause/waylandpp).\n\n**Don't use this for anything important!**\n\n# Wayland Client C++ Bindings\n\nThis library provides modern C++14 bindings to libwayland-client. These\nbindings are *minimal* and provide little additional niceties over what is\nalready provided by the Wayland protocol specification. The following\nC++-isms are provided by the library:\n\n- RAII for all protocol types. (All types are move-only).\n- Type-safety for all protocol types\n- Error checking via exceptions or `std::error_code` output arguments for all\nprotocol requests (methods). For every method, there is an overload that is\n`noexcept` and takes a `std::error_code\u0026` as the final parameter, and another\nthat will throw `std::system_error` upon error.\n- `enum class` scoped to their parent type for Wayland enums.\n\nThe following features are **NOT** present in the library:\n\n- Shared memory facilities. You must bring your own shared memory library\n(like Boost.Interprocess).\n- Thread-safety of event dispatching (It's up to you to dispatch events\nproperly).\n- Drawing and rendering. Bring your own renderer.\n- Additional platform GUI abstractions. It's all the bare bones.\n\n## Show Me the Code!\n\nUsing wl++ is simple:\n\n```c++\n#include \u003cwl/buffer.hpp\u003e\n#include \u003cwl/compositor.hpp\u003e\n#include \u003cwl/display.hpp\u003e\n#include \u003cwl/registry.hpp\u003e\n#include \u003cwl/shell.hpp\u003e\n#include \u003cwl/shell_surface.hpp\u003e\n#include \u003cwl/shm.hpp\u003e\n#include \u003cwl/shm_pool.hpp\u003e\n#include \u003cwl/surface.hpp\u003e\n\n#include \u003cboost/interprocess/managed_shared_memory.hpp\u003e\n\n#include \u003ccstdint\u003e\n#include \u003ciostream\u003e\n#include \u003cthread\u003e\n\n// We'll use Boost.Interprocess for shared memory\nnamespace ipc = boost::interprocess;\n\nint main() {\n    // Connect to the Wayland display server\n    auto disp = wl::display::connect();\n    // Get the object registry\n    auto reg = disp.get_registry();\n    // The server will now pipe us some objects, which we'll need to store to continue\n    wl::compositor comp{nullptr};  // Null objects must be explicitly null-initialized\n    wl::shell shell{nullptr};\n    wl::shm shm{nullptr};\n    reg.on_global([\u0026](auto id, std::string interface, int version) {\n        // Switch on the interface the server sent us\n        std::cout \u003c\u003c \"New \" \u003c\u003c interface \u003c\u003c \"@\" \u003c\u003c id \u003c\u003c \" from registry\\n\";\n        if (interface == wl::compositor::interface_name) {\n            comp = reg.bind\u003cwl::compositor\u003e(id, version);\n        } else if (interface == wl::shell::interface_name) {\n            shell = reg.bind\u003cwl::shell\u003e(id, version);\n        } else if (interface == wl::shm::interface_name) {\n            shm = reg.bind\u003cwl::shm\u003e(id, version);\n        }\n    });\n\n    // Pump events (this calls the on_global handler above)\n    disp.roundtrip();\n\n    // Create our shared memory\n    struct shm_remover_t {\n        shm_remover_t() {\n            ipc::shared_memory_object::remove(\"wlxx-example\");\n        }\n        ~shm_remover_t() {\n            ipc::shared_memory_object::remove(\"wlxx-example\");\n        }\n    } _shm_remover;\n    ipc::shared_memory_object shared_memory{ipc::create_only, \"wlxx-example\", ipc::read_write};\n    // We'll use 8-bit color depth with ARGB layout\n    struct pixel {\n        // Components are in reverse order, because endian?\n        std::uint8_t b;\n        std::uint8_t g;\n        std::uint8_t r;\n        std::uint8_t a;\n    };\n    const auto width = 400;\n    const auto height = 300;\n    const auto n_pixels = width * height;\n    const auto shared_size = n_pixels * sizeof(pixel);\n    shared_memory.truncate(shared_size);\n\n    // Tell Wayland about our shared memory object\n    auto shm_pool = shm.create_pool(shared_memory.get_mapping_handle().handle, shared_size);\n    // Create a buffer. This doesn't allocate anything, it just tells wayland\n    // about memory regions that we intend to use, and how to treat them\n    auto draw_buffer\n        = shm_pool\n              .create_buffer(0,  // Offset in the shared memory region. We start at the beginning\n                             width,\n                             height,\n                             width * sizeof(pixel),  // The \"stride.\" This is the size (in bytes) of\n                                                     // a row of pixels\n                             wl::shm::format::argb8888  // This is the draw format we want\n                             );\n\n    // Map the memory into our address space so we can get writing\n    ipc::mapped_region shared_region{shared_memory, ipc::read_write};\n    // Fill our draw with green pixels\n    pixel green;\n    green.a = 255;\n    green.r = 0;\n    green.g = 200;\n    green.b = 0;\n    const auto pixel_out = static_cast\u003cpixel*\u003e(shared_region.get_address());\n    std::fill(pixel_out, pixel_out + n_pixels, green);\n\n    // Ask the compositor for a new surface (usually, a window)\n    auto surface = comp.create_surface();\n    // shell_surface is an abstraction over the desktop shell\n    auto shell_surface = shell.get_shell_surface(surface);\n    // It's a root window\n    shell_surface.set_toplevel();\n    // Attach the draw buffer to the top left corner (0, 0) of the surface\n    surface.attach(draw_buffer, 0, 0);\n    // Swap the double-buffer, and show our surface!\n    surface.commit();\n    disp.flush();\n    std::this_thread::sleep_for(std::chrono::seconds(10));\n    return 0;\n}\n```\n\n## Documentation?\n\nSince wl++ is simply a very small wrapper of the Wayland protocol, the [protocol documenation](https://wayland.freedesktop.org/docs/html/apa.html) is the best place to understand what APIs are available in wl++. There are only a few small differences:\n\n- Calling any `destroy()` method is unnecessary in the face of destructors.\n- `wl::registry::bind` does not return `void*`. It is a method template that\nreturns an instance of the requested type.\n\n\n### Events\n\nFor each type of event on an object, a method `on_\u003cevent_name\u003e` is present on\nthe class, and can be used to set the event handler. The method takes a\ncallback object that will be called with the event parameters when the event\nfires. **NOTE** that wl++ provides no event loop. It's up to you to dispatch\nevents by calling the proper methods on the `wl::display` instance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvector-of-bool%2Fwlxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvector-of-bool%2Fwlxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvector-of-bool%2Fwlxx/lists"}