From 542666c89dca1d620f735b475886e76a85550362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20Nam=20Tu=E1=BA=A5n?= Date: Thu, 31 Jul 2025 14:37:54 +0700 Subject: [PATCH] Fix wayland build on older distros This commit add version check to wayland-protocols. Also enforce Qt 6 for Wayland. --- cmake/modules/FindWayland.cmake | 208 --------------------------- src/gui/CMakeLists.txt | 69 +++++---- src/gui/wayland/waylandidletimer.cpp | 4 + src/gui/wayland/waylandutils.cpp | 2 +- 4 files changed, 43 insertions(+), 240 deletions(-) delete mode 100644 cmake/modules/FindWayland.cmake diff --git a/cmake/modules/FindWayland.cmake b/cmake/modules/FindWayland.cmake deleted file mode 100644 index 18a792a7..00000000 --- a/cmake/modules/FindWayland.cmake +++ /dev/null @@ -1,208 +0,0 @@ -# SPDX-FileCopyrightText: 2014 Alex Merry -# SPDX-FileCopyrightText: 2014 Martin Gräßlin -# SPDX-FileCopyrightText: 2025 Trần Nam Tuấn -# -# SPDX-License-Identifier: BSD-3-Clause - -#[=======================================================================[.rst: -FindWayland ------------ - -Try to find Wayland. - -This is a component-based find module, which makes use of the COMPONENTS -and OPTIONAL_COMPONENTS arguments to find_module. The following components -are available:: - - Client Server Cursor Egl - -If no components are specified, this module will act as though all components -were passed to OPTIONAL_COMPONENTS. - -This module will define the following variables, independently of the -components searched for or found: - -``Wayland_FOUND`` - TRUE if (the requested version of) Wayland is available -``Wayland_VERSION`` - Found Wayland version -``Wayland_TARGETS`` - A list of all targets imported by this module (note that there may be more - than the components that were requested) -``Wayland_LIBRARIES`` - This can be passed to target_link_libraries() instead of the imported - targets -``Wayland_INCLUDE_DIRS`` - This should be passed to target_include_directories() if the targets are - not used for linking -``Wayland_DEFINITIONS`` - This should be passed to target_compile_options() if the targets are not - used for linking -``Wayland_DATADIR`` - The core wayland protocols data directory - -For each searched-for components, ``Wayland__FOUND`` will be set to -TRUE if the corresponding Wayland library was found, and FALSE otherwise. If -``Wayland__FOUND`` is TRUE, the imported target -``Wayland::`` will be defined. This module will also attempt to -determine ``Wayland_*_VERSION`` variables for each imported target, although -``Wayland_VERSION`` should normally be sufficient. - -In general we recommend using the imported targets, as they are easier to use -and provide more control. Bear in mind, however, that if any target is in the -link interface of an exported library, it must be made available by the -package config file. -#]=======================================================================] - -include(FindPackageHandleStandardArgs) - -set(Wayland_known_components - Client - Server - Cursor - Egl -) - -foreach(_comp ${Wayland_known_components}) - string(TOLOWER "${_comp}" _lc_comp) - set(Wayland_${_comp}_component_deps) - set(Wayland_${_comp}_pkg_config "wayland-${_lc_comp}") - set(Wayland_${_comp}_lib "wayland-${_lc_comp}") - set(Wayland_${_comp}_header "wayland-${_lc_comp}.h") -endforeach() -set(Wayland_Egl_component_deps Client) - -find_package(PkgConfig REQUIRED) - -foreach(_comp ${Wayland_known_components}) - # Handling components dependencies - foreach(_dep ${Wayland_${_comp}_component_deps}) - list(APPEND _dep_vars "Wayland_${_dep}_FOUND") - list(APPEND _dep_targets "Wayland::${_dep}") - endforeach() - - pkg_check_modules(PKG_Wayland_${_comp} QUIET ${Wayland_${_comp}_pkg_config}) - - find_path(Wayland_${_comp}_INCLUDE_DIR - NAMES ${Wayland_${_comp}_header} - HINTS ${PKG_Wayland_${_comp}_INCLUDE_DIRS} - ) - - find_library(Wayland_${_comp}_LIBRARY - NAMES ${Wayland_${_comp}_lib} - HINTS ${PKG_Wayland_${_comp}_LIBRARY_DIRS} - ) - - set(Wayland_${_comp}_VERSION "${PKG_Wayland_${_comp}_VERSION}") - if(NOT Wayland_VERSION) - set(Wayland_VERSION ${Wayland_${_comp}_VERSION}) - endif() - - set(FPHSA_NAME_MISMATCHED 1) - find_package_handle_standard_args(Wayland_${_comp} - FOUND_VAR - Wayland_${_comp}_FOUND - REQUIRED_VARS - Wayland_${_comp}_LIBRARY - Wayland_${_comp}_INCLUDE_DIR - ${_dep_vars} - VERSION_VAR - Wayland_${_comp}_VERSION - ) - unset(FPHSA_NAME_MISMATCHED) - - mark_as_advanced( - Wayland_${_comp}_LIBRARY - Wayland_${_comp}_INCLUDE_DIR - ) - - if(Wayland_${_comp}_FOUND) - list(APPEND Wayland_LIBRARIES - "${Wayland_${_comp}_LIBRARY}") - list(APPEND Wayland_INCLUDE_DIRS - "${Wayland_${_comp}_INCLUDE_DIR}") - set(Wayland_DEFINITIONS - ${Wayland_DEFINITIONS} - ${PKG_Wayland_${_comp}_DEFINITIONS}) - if(NOT TARGET Wayland::${_comp}) - add_library(Wayland::${_comp} UNKNOWN IMPORTED) - set_target_properties(Wayland::${_comp} PROPERTIES - IMPORTED_LOCATION "${Wayland_${_comp}_LIBRARY}" - INTERFACE_COMPILE_OPTIONS "${PKG_Wayland_${_comp}_DEFINITIONS}" - INTERFACE_INCLUDE_DIRECTORIES "${Wayland_${_comp}_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${_dep_targets}" - ) - endif() - list(APPEND Wayland_TARGETS - "Wayland::${_comp}") - endif() -endforeach() - -if(Wayland_LIBRARIES) - list(REMOVE_DUPLICATES Wayland_LIBRARIES) -endif() - -if(Wayland_INCLUDE_DIRS) - list(REMOVE_DUPLICATES Wayland_INCLUDE_DIRS) -endif() - -if(Wayland_DEFINITIONS) - list(REMOVE_DUPLICATES Wayland_DEFINITIONS) -endif() - -if(Wayland_TARGETS) - list(REMOVE_DUPLICATES Wayland_TARGETS) -endif() - -# If pkg-config didn't provide us with version information, -# try to extract it from wayland-version.h -# (Note that the version from wayland-egl.pc will probably be -# the Mesa version, rather than the Wayland version, but that -# version will be ignored as we always find wayland-client.pc -# first). -if(NOT Wayland_VERSION) - find_file(Wayland_VERSION_HEADER - NAMES wayland-version.h - HINTS ${Wayland_INCLUDE_DIRS} - ) - mark_as_advanced(Wayland_VERSION_HEADER) - if(Wayland_VERSION_HEADER) - file(READ ${Wayland_VERSION_HEADER} _wayland_version_header_contents) - string(REGEX REPLACE - "^.*[ \t]+WAYLAND_VERSION[ \t]+\"([0-9.]*)\".*$" - "\\1" - Wayland_VERSION - "${_wayland_version_header_contents}" - ) - unset(_wayland_version_header_contents) - endif() -endif() - -find_package_handle_standard_args(Wayland - FOUND_VAR - Wayland_FOUND - REQUIRED_VARS - Wayland_LIBRARIES - VERSION_VAR - Wayland_VERSION - HANDLE_COMPONENTS -) - -pkg_get_variable(Wayland_DATADIR wayland-scanner pkgdatadir) -if (CMAKE_CROSSCOMPILING AND (NOT EXISTS "${Wayland_DATADIR}/wayland.xml")) - # PKG_CONFIG_SYSROOT_DIR only applies to -I and -L flags, so pkg-config - # does not prepend CMAKE_SYSROOT when cross-compiling unless you pass - # --define-prefix explicitly. Therefore we have to manually do prepend - # it here when cross-compiling. - # See https://gitlab.kitware.com/cmake/cmake/-/issues/16647#note_844761 - set(Wayland_DATADIR ${CMAKE_SYSROOT}${Wayland_DATADIR}) -endif() -if (NOT EXISTS "${Wayland_DATADIR}/wayland.xml") - message(WARNING "Could not find wayland.xml in ${Wayland_DATADIR}") -endif() - -include(FeatureSummary) -set_package_properties(Wayland PROPERTIES - URL "https://wayland.freedesktop.org/" - DESCRIPTION "C library implementation of the Wayland protocol: a protocol for a compositor to talk to its clients" -) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 3de76cbb..f6d8aa34 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -102,6 +102,10 @@ elseif (LINUX) find_package(Qt5 REQUIRED COMPONENTS X11Extras) endif () message(STATUS "Using Qt${QT_VERSION_MAJOR}") + if (QT_VERSION VERSION_LESS "6" AND USE_WAYLAND) + set(USE_WAYLAND OFF) + message(STATUS "Wayland features disabled (requires Qt 6)") + endif () endif () # Automatically handle MOC, UIC and RCC @@ -413,42 +417,37 @@ elseif (LINUX) ) if (USE_WAYLAND) - find_package(Wayland COMPONENTS Client REQUIRED) - find_package(WaylandProtocols REQUIRED) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS WaylandClient) + find_package(WaylandProtocols 1.27 REQUIRED) - if (QT_VERSION VERSION_GREATER_EQUAL "6.0.0") - if (NOT EXISTS ${WaylandProtocols_DATADIR}/staging/ext-idle-notify/ext-idle-notify-v1.xml) - message(FATAL_ERROR "Wayland ext-idle-notify-v1 protocol is not found. Either install them or pass -DUSE_WAYLAND=0 to disable idle detection.") - endif () + if (NOT EXISTS ${WaylandProtocols_DATADIR}/staging/ext-idle-notify/ext-idle-notify-v1.xml) + message(FATAL_ERROR "Wayland ext-idle-notify-v1 protocol is not found. Either install them or pass -DUSE_WAYLAND=0 to disable idle detection.") + endif () - if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0") - set(private_code_option "PRIVATE_CODE") - endif() - - qt_generate_wayland_protocol_client_sources( - ckb-next - ${private_code_option} - FILES - ${WaylandProtocols_DATADIR}/staging/ext-idle-notify/ext-idle-notify-v1.xml - ) - - target_sources( - ckb-next - PRIVATE - wayland/waylandidletimer.cpp - wayland/waylandidletimer.h - ) - - target_compile_definitions( - ckb-next - PRIVATE - USE_WAYLAND_IDLE_NOTIFY - ) - else() - message(FATAL_ERROR "Wayland idle detection required Qt 6 or later. Either build with Qt 6 or pass -DUSE_WAYLAND=0 to disable idle detection.") + if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0") + set(private_code_option "PRIVATE_CODE") endif() + qt_generate_wayland_protocol_client_sources( + ckb-next + ${private_code_option} + FILES + ${WaylandProtocols_DATADIR}/staging/ext-idle-notify/ext-idle-notify-v1.xml + ) + + target_sources( + ckb-next + PRIVATE + wayland/waylandidletimer.cpp + wayland/waylandidletimer.h + ) + + target_compile_definitions( + ckb-next + PRIVATE + USE_WAYLAND_IDLE_NOTIFY + ) + target_compile_definitions( ckb-next PRIVATE @@ -462,6 +461,14 @@ elseif (LINUX) Qt${QT_VERSION_MAJOR}::WaylandClient ) + if (WaylandProtocols_VERSION VERSION_GREATER_EQUAL "1.40") + target_compile_definitions( + ckb-next + PRIVATE + USE_WAYLAND_INPUT_IDLE_NOTIFY + ) + endif () + if (Qt6_VERSION VERSION_LESS "6.5.0") target_link_libraries( ckb-next diff --git a/src/gui/wayland/waylandidletimer.cpp b/src/gui/wayland/waylandidletimer.cpp index 84661f77..e9f761ca 100644 --- a/src/gui/wayland/waylandidletimer.cpp +++ b/src/gui/wayland/waylandidletimer.cpp @@ -57,11 +57,15 @@ WaylandIdleTimer::WaylandIdleTimer() if (m_supported) { auto seat = WaylandUtils::seat(); m_notifier.reset(new WaylandIdleNotifier()); +#ifdef USE_WAYLAND_INPUT_IDLE_NOTIFY if (WaylandUtils::hasInterface("ext_idle_notifier_v1", 2)) { m_notification.reset(new WaylandIdleNotification(m_notifier->get_input_idle_notification(0, seat))); } else { m_notification.reset(new WaylandIdleNotification(m_notifier->get_idle_notification(0, seat))); } +#else + m_notification.reset(new WaylandIdleNotification(m_notifier->get_idle_notification(0, seat))); +#endif } } diff --git a/src/gui/wayland/waylandutils.cpp b/src/gui/wayland/waylandutils.cpp index 576b3bf4..72063925 100644 --- a/src/gui/wayland/waylandutils.cpp +++ b/src/gui/wayland/waylandutils.cpp @@ -65,7 +65,7 @@ public: return; } - m_seat = static_cast(nativeInterface->nativeResourceForIntegration("m_seat")); + m_seat = static_cast(nativeInterface->nativeResourceForIntegration("m_seat")); if (!m_seat) { m_display = nullptr; return;