From ea954494024cb596aaf9a40c77c3e0fcaf0e0322 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:25:29 +0100 Subject: [PATCH] core: Move tearing to hyprwayland-scanner (#5657) Adds a new dependency: hyprwayland-scanner https://github.com/hyprwm/hyprwayland-scanner --------- Co-authored-by: Mihai Fufezan --- .github/actions/setup_base/action.yml | 8 ++-- .gitignore | 4 +- CMakeLists.txt | 17 ++++++- flake.lock | 24 ++++++++++ flake.nix | 6 +++ nix/default.nix | 2 + nix/overlays.nix | 1 + protocols/meson.build | 29 ++++++++++-- src/managers/ProtocolManager.cpp | 2 +- src/protocols/TearingControl.cpp | 68 +++++++-------------------- src/protocols/TearingControl.hpp | 25 ++++------ 11 files changed, 108 insertions(+), 78 deletions(-) diff --git a/.github/actions/setup_base/action.yml b/.github/actions/setup_base/action.yml index 648253cc..5b952bec 100644 --- a/.github/actions/setup_base/action.yml +++ b/.github/actions/setup_base/action.yml @@ -25,6 +25,7 @@ runs: glslang \ go \ hyprlang \ + hyprcursor \ jq \ libc++ \ libdisplay-info \ @@ -44,6 +45,7 @@ runs: pango \ pixman \ pkgconf \ + pugixml \ scdoc \ seatd \ systemd \ @@ -58,11 +60,11 @@ runs: libzip \ librsvg - - name: Get hyprcursor-git + - name: Get hyprwayland-scanner-git shell: bash run: | - git clone https://github.com/hyprwm/hyprcursor --recursive - cd hyprcursor + git clone https://github.com/hyprwm/hyprwayland-scanner --recursive + cd hyprwayland-scanner cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF` cmake --install build diff --git a/.gitignore b/.gitignore index b8423e8f..3601f422 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,8 @@ result* .cache *.o -*-protocol.c -*-protocol.h +protocols/*.c* +protocols/*.h* .ccls-cache *.so diff --git a/CMakeLists.txt b/CMakeLists.txt index b056402a..e5917e63 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ pkg_get_variable(WaylandScanner wayland-scanner wayland_scanner) message(STATUS "Found WaylandScanner at ${WaylandScanner}") pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}") +find_program(HYPRWAYLAND_SCANNER NAMES hyprwayland-scanner REQUIRED) if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) message(STATUS "Configuring Hyprland in Debug with CMake") @@ -238,6 +239,19 @@ function(protocol protoPath protoName external) target_sources(Hyprland PRIVATE protocols/${protoName}-protocol.c) endif() endfunction() +function(protocolNew protoPath protoName external) + if (external) + execute_process( + COMMAND hyprwayland-scanner ${protoPath} ${CMAKE_SOURCE_DIR}/protocols/ + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + target_sources(Hyprland PRIVATE protocols/${protoName}.cpp) + else() + execute_process( + COMMAND hyprwayland-scanner ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${CMAKE_SOURCE_DIR}/protocols/ + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + target_sources(Hyprland PRIVATE protocols/${protoName}.cpp) + endif() +endfunction() target_link_libraries(Hyprland ${CMAKE_SOURCE_DIR}/subprojects/wlroots-hyprland/build/libwlroots.a @@ -260,10 +274,9 @@ protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false) protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false) protocol("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false) protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false) -protocol("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false) protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false) protocol("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false) -protocol("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false) +protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false) # tools add_subdirectory(hyprctl) diff --git a/flake.lock b/flake.lock index c237ba74..1c260ca9 100644 --- a/flake.lock +++ b/flake.lock @@ -72,6 +72,29 @@ "type": "github" } }, + "hyprwayland-scanner": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1713612394, + "narHash": "sha256-uWA8iPYzrdpCT9d8I9YHrxkjBdooqOZIH6ZOHoQiOUc=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "f58a3f56e89857dc7ab7166cff2f971345026634", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1712963716, @@ -93,6 +116,7 @@ "hyprcursor": "hyprcursor", "hyprland-protocols": "hyprland-protocols", "hyprlang": "hyprlang", + "hyprwayland-scanner": "hyprwayland-scanner", "nixpkgs": "nixpkgs", "systems": "systems", "wlroots": "wlroots", diff --git a/flake.nix b/flake.nix index 9cb17179..ba09acb7 100644 --- a/flake.nix +++ b/flake.nix @@ -34,6 +34,12 @@ inputs.systems.follows = "systems"; }; + hyprwayland-scanner = { + url = "github:hyprwm/hyprwayland-scanner"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.systems.follows = "systems"; + }; + xdph = { url = "github:hyprwm/xdg-desktop-portal-hyprland"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/nix/default.nix b/nix/default.nix index a7679672..2d86366a 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -12,6 +12,7 @@ hyprcursor, hyprland-protocols, hyprlang, + hyprwayland-scanner, jq, libGL, libdrm, @@ -86,6 +87,7 @@ in ''; nativeBuildInputs = [ + hyprwayland-scanner jq makeWrapper meson diff --git a/nix/overlays.nix b/nix/overlays.nix index 97e66912..fe5a5ed6 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -24,6 +24,7 @@ in { inputs.hyprcursor.overlays.default inputs.hyprland-protocols.overlays.default inputs.hyprlang.overlays.default + inputs.hyprwayland-scanner.overlays.default self.overlays.wlroots-hyprland self.overlays.udis86 # Hyprland packages themselves diff --git a/protocols/meson.build b/protocols/meson.build index 857df50f..76dbcacb 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -17,6 +17,11 @@ wayland_scanner = find_program( wayland_scanner_dep.get_variable('wayland_scanner'), native: true, ) +hyprwayland_scanner_dep = dependency('hyprwayland-scanner', native: true) +hyprwayland_scanner = find_program( + hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'), + native: true, +) protocols = [ [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], @@ -25,7 +30,6 @@ protocols = [ [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], [wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'], [wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'], - [wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'], ['wlr-foreign-toplevel-management-unstable-v1.xml'], ['wlr-layer-shell-unstable-v1.xml'], ['wlr-output-power-management-unstable-v1.xml'], @@ -36,8 +40,14 @@ protocols = [ [hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'], [hl_protocol_dir, 'protocols/hyprland-global-shortcuts-v1.xml'] ] + +new_protocols = [ + [wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'], +] + wl_protos_src = [] wl_protos_headers = [] + foreach p : protocols xml = join_paths(p) wl_protos_src += custom_target( @@ -56,15 +66,28 @@ foreach p : protocols ) endforeach +new_wl_protos = [] +foreach p : new_protocols + xml = join_paths(p) + new_wl_protos += custom_target( + xml.underscorify(), + input: xml, + install: true, + install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')], + output: ['@BASENAME@.cpp', '@BASENAME@.hpp'], + command: [hyprwayland_scanner, '@INPUT@', '@OUTDIR@'], + ) +endforeach + wayland_server = dependency('wayland-server', version: '>=1.20.0') lib_server_protos = static_library( 'server_protos', - wl_protos_src + wl_protos_headers, + wl_protos_src + wl_protos_headers + new_wl_protos, dependencies: wayland_server.partial_dependency(compile_args: true), ) server_protos = declare_dependency( link_with: lib_server_protos, - sources: wl_protos_headers, + sources: wl_protos_headers + new_wl_protos, ) diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index f6cb66df..31220276 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -3,7 +3,7 @@ #include "../protocols/TearingControl.hpp" #include "xdg-output-unstable-v1-protocol.h" -#include "tearing-control-v1-protocol.h" +#include "tearing-control-v1.hpp" CProtocolManager::CProtocolManager() { m_pToplevelExportProtocolManager = std::make_unique(); diff --git a/src/protocols/TearingControl.cpp b/src/protocols/TearingControl.cpp index f3c17bfb..679f2404 100644 --- a/src/protocols/TearingControl.cpp +++ b/src/protocols/TearingControl.cpp @@ -1,40 +1,20 @@ #include "TearingControl.hpp" -#include "tearing-control-v1-protocol.h" #include "../managers/ProtocolManager.hpp" #include "../desktop/Window.hpp" #include "../Compositor.hpp" -static void destroyManager(wl_client* client, wl_resource* resource) { - RESOURCE_OR_BAIL(PRESOURCE); - reinterpret_cast(PRESOURCE->data())->onManagerResourceDestroy(resource); -} - -static void getTearingControl(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface) { - RESOURCE_OR_BAIL(PRESOURCE); - reinterpret_cast(PRESOURCE->data())->onGetController(client, resource, id, wlr_surface_from_resource(surface)); -} - -// - CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { g_pHookSystem->hookDynamic("destroyWindow", [this](void* self, SCallbackInfo& info, std::any param) { this->onWindowDestroy(std::any_cast(param)); }); } -static const struct wp_tearing_control_manager_v1_interface MANAGER_IMPL = { - .destroy = ::destroyManager, - .get_tearing_control = ::getTearingControl, -}; - void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, &wp_tearing_control_manager_v1_interface, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + RESOURCE->setOnDestroy([this](CWpTearingControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); - if (!RESOURCE->good()) { - Debug::log(LOG, "Couldn't bind TearingControlMgr"); - return; - } - - RESOURCE->setImplementation(&MANAGER_IMPL, nullptr); - RESOURCE->setData(this); + RESOURCE->setDestroy([this](CWpTearingControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); + RESOURCE->setGetTearingControl([this](CWpTearingControlManagerV1* pMgr, uint32_t id, wl_resource* surface) { + this->onGetController(wl_resource_get_client(pMgr->resource()), pMgr->resource(), id, wlr_surface_from_resource(surface)); + }); } void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) { @@ -42,10 +22,8 @@ void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) { } void CTearingControlProtocol::onGetController(wl_client* client, wl_resource* resource, uint32_t id, wlr_surface* surf) { - const auto CONTROLLER = m_vTearingControllers - .emplace_back(std::make_unique( - std::make_shared(client, &wp_tearing_control_v1_interface, wl_resource_get_version(resource), id), surf)) - .get(); + const auto CONTROLLER = + m_vTearingControllers.emplace_back(std::make_unique(std::make_shared(client, wl_resource_get_version(resource), id), surf)).get(); if (!CONTROLLER->good()) { m_vTearingControllers.pop_back(); @@ -66,25 +44,11 @@ void CTearingControlProtocol::onWindowDestroy(CWindow* pWindow) { // -static void destroyController(wl_client* client, wl_resource* resource) { - RESOURCE_OR_BAIL(PRESOURCE); - PROTO::tearing->onControllerDestroy(reinterpret_cast(PRESOURCE->data())); -} - -static void setPresentationHint(wl_client* client, wl_resource* resource, uint32_t hint) { - RESOURCE_OR_BAIL(PRESOURCE); - reinterpret_cast(PRESOURCE->data())->onHint(hint); -} - -static const struct wp_tearing_control_v1_interface CONTROLLER_IMPL = { - .set_presentation_hint = ::setPresentationHint, - .destroy = ::destroyController, -}; - -CTearingControl::CTearingControl(SP resource_, wlr_surface* surf_) : resource(resource_) { - resource->setImplementation(&CONTROLLER_IMPL, nullptr); +CTearingControl::CTearingControl(SP resource_, wlr_surface* surf_) : resource(resource_) { resource->setData(this); - resource->setOnDestroyHandler([](CWaylandResource* res) { PROTO::tearing->onControllerDestroy(reinterpret_cast(res->data())); }); + resource->setOnDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); }); + resource->setDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); }); + resource->setSetPresentationHint([this](CWpTearingControlV1* res, wpTearingControlV1PresentationHint hint) { this->onHint(hint); }); for (auto& w : g_pCompositor->m_vWindows) { if (w->m_pWLSurface.wlr() == surf_) { @@ -94,8 +58,8 @@ CTearingControl::CTearingControl(SP resource_, wlr_surface* su } } -void CTearingControl::onHint(uint32_t hint_) { - hint = hint_ == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC ? TEARING_VSYNC : TEARING_ASYNC; +void CTearingControl::onHint(wpTearingControlV1PresentationHint hint_) { + hint = hint_; updateWindow(); } @@ -103,9 +67,9 @@ void CTearingControl::updateWindow() { if (!pWindow) return; - pWindow->m_bTearingHint = hint == TEARING_ASYNC; + pWindow->m_bTearingHint = hint == PRESENTATION_HINT_ASYNC; } bool CTearingControl::good() { - return resource->good(); + return resource->resource(); } diff --git a/src/protocols/TearingControl.hpp b/src/protocols/TearingControl.hpp index f0dd8bfa..fbd0e1fc 100644 --- a/src/protocols/TearingControl.hpp +++ b/src/protocols/TearingControl.hpp @@ -2,21 +2,16 @@ #include #include "WaylandProtocol.hpp" +#include "tearing-control-v1.hpp" class CWindow; - -enum eTearingPresentationHint { - TEARING_VSYNC = 0, - TEARING_ASYNC, -}; - class CTearingControlProtocol; class CTearingControl { public: - CTearingControl(SP resource_, wlr_surface* surf_); + CTearingControl(SP resource_, wlr_surface* surf_); - void onHint(uint32_t hint_); + void onHint(wpTearingControlV1PresentationHint hint_); bool good(); @@ -29,11 +24,11 @@ class CTearingControl { } private: - void updateWindow(); + void updateWindow(); - SP resource; - CWindow* pWindow = nullptr; - eTearingPresentationHint hint = TEARING_VSYNC; + SP resource; + CWindow* pWindow = nullptr; + wpTearingControlV1PresentationHint hint = PRESENTATION_HINT_VSYNC; friend class CTearingControlProtocol; }; @@ -49,10 +44,10 @@ class CTearingControlProtocol : public IWaylandProtocol { void onGetController(wl_client* client, wl_resource* resource, uint32_t id, wlr_surface* surf); private: - void onWindowDestroy(CWindow* pWindow); + void onWindowDestroy(CWindow* pWindow); - std::vector> m_vManagers; - std::vector> m_vTearingControllers; + std::vector> m_vManagers; + std::vector> m_vTearingControllers; }; namespace PROTO {