Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package xdg-desktop-portal-hyprland for openSUSE:Factory checked in at 2023-09-26 22:01:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xdg-desktop-portal-hyprland (Old) and /work/SRC/openSUSE:Factory/.xdg-desktop-portal-hyprland.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xdg-desktop-portal-hyprland" Tue Sep 26 22:01:47 2023 rev:6 rq:1113549 version:unknown Changes: -------- --- /work/SRC/openSUSE:Factory/xdg-desktop-portal-hyprland/xdg-desktop-portal-hyprland.changes 2023-09-10 13:12:33.467543795 +0200 +++ /work/SRC/openSUSE:Factory/.xdg-desktop-portal-hyprland.new.1770/xdg-desktop-portal-hyprland.changes 2023-09-26 22:15:48.067044881 +0200 @@ -1,0 +2,14 @@ +Mon Sep 25 21:46:16 UTC 2023 - Soc Virnyl Estela <uncomfy+openbuildserv...@uncomfyhalomacro.pl> + +- Remove 0000-sdbus-c++-cmake-lists.patch +- Remove conflicts with XDG-wlr. XDP 0.18.0 introduces flexible + configuration of portals. +- Update to version 1.1.0: + * core: rework event loop for polling and C++-style awaits + * internal: make frame callbacks log a trace + * internal: add a notification on missing qt-wayland packages + * drop unused dependencies + * fix build system + * add double escaping + +------------------------------------------------------------------- Old: ---- 0000-sdbus-c++-cmake-lists.patch xdg-desktop-portal-hyprland-1.0.0.tar.gz New: ---- xdg-desktop-portal-hyprland-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xdg-desktop-portal-hyprland.spec ++++++ --- /var/tmp/diff_new_pack.NeJ0vA/_old 2023-09-26 22:15:49.171084841 +0200 +++ /var/tmp/diff_new_pack.NeJ0vA/_new 2023-09-26 22:15:49.171084841 +0200 @@ -18,7 +18,7 @@ %define _protocol_version 0.2 Name: xdg-desktop-portal-hyprland -Version: 1.0.0 +Version: 1.1.0 Release: 0 Summary: Extended xdg-desktop-portal backend for Hyprland License: MIT @@ -49,7 +49,7 @@ BuildRequires: pkgconfig(uuid) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-protocols) >= 1.24 -Patch0: 0000-sdbus-c++-cmake-lists.patch + # Screencasting won't work without pipewire, but it's not a hard dependency. Recommends: pipewire >= 0.3.41 @@ -59,9 +59,6 @@ Requires: xdg-desktop-portal -# As this is a fork of XDPW, installing this will conflict with XDPH -Conflicts: xdg-desktop-portal-wlr - %description A fork of xdg-desktop-portal backend for wlroots for Hyprland. It supports other wlroots-based Wayland compositors too with some limitations. @@ -92,19 +89,15 @@ %meson %meson_build -# Hyprland Share Picker -%cmake -%cmake_build - %install -%meson_install -install -Dm0755 -t %{buildroot}%{_bindir} ./build/hyprland-share-picker/hyprland-share-picker -# Install it as well +# Install the protocols pushd subprojects/hyprland-protocols %meson_install popd +%meson_install + %pre %systemd_user_pre %{name}.service ++++++ xdg-desktop-portal-hyprland-1.0.0.tar.gz -> xdg-desktop-portal-hyprland-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/CMakeLists.txt new/xdg-desktop-portal-hyprland-1.1.0/CMakeLists.txt --- old/xdg-desktop-portal-hyprland-1.0.0/CMakeLists.txt 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/CMakeLists.txt 2023-09-18 19:10:57.000000000 +0200 @@ -30,10 +30,9 @@ message(STATUS "Checking deps...") add_subdirectory(subprojects/sdbus-cpp) add_subdirectory(hyprland-share-picker) -find_package(Threads REQUIRED) find_package(PkgConfig REQUIRED) -pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg libpipewire-0.3 libspa-0.2 libdrm gbm) +pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols libpipewire-0.3 libspa-0.2 libdrm gbm) file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") add_executable(xdg-desktop-portal-hyprland ${SRCFILES}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/Makefile new/xdg-desktop-portal-hyprland-1.1.0/Makefile --- old/xdg-desktop-portal-hyprland-1.0.0/Makefile 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/Makefile 2023-09-18 19:10:57.000000000 +0200 @@ -15,7 +15,8 @@ install: $(MAKE) release - cp ./build/hyprland-share-picker/hyprland-share-picker ${PREFIX}/bin - cp ./build/xdg-desktop-portal-hyprland ${LIBEXEC}/ - cp ./hyprland.portal ${SHARE}/xdg-desktop-portal/portals/ - cp ./org.freedesktop.impl.portal.desktop.hyprland.service ${SHARE}/dbus-1/services/ \ No newline at end of file + cp -f ./build/hyprland-share-picker/hyprland-share-picker ${PREFIX}/bin + cp -f ./build/xdg-desktop-portal-hyprland ${LIBEXEC}/ + cp -f ./hyprland.portal ${SHARE}/xdg-desktop-portal/portals/ + sed "s|@libexecdir@|${LIBEXEC}|g" ./org.freedesktop.impl.portal.desktop.hyprland.service.in > ${SHARE}/dbus-1/services/org.freedesktop.impl.portal.desktop.hyprland + sed "s|@libexecdir@|${LIBEXEC}|g" ./contrib/systemd/xdg-desktop-portal-hyprland.service.in > ${LIBEXEC}/systemd/user/xdg-desktop-portal-hyprland.service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/VERSION new/xdg-desktop-portal-hyprland-1.1.0/VERSION --- old/xdg-desktop-portal-hyprland-1.0.0/VERSION 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/VERSION 2023-09-18 19:10:57.000000000 +0200 @@ -1 +1 @@ -1.0.0 +1.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/flake.lock new/xdg-desktop-portal-hyprland-1.1.0/flake.lock --- old/xdg-desktop-portal-hyprland-1.0.0/flake.lock 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/flake.lock 2023-09-18 19:10:57.000000000 +0200 @@ -25,11 +25,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1693844670, - "narHash": "sha256-t69F2nBB8DNQUWHD809oJZJVE+23XBrth4QZuVd6IE0=", + "lastModified": 1694183432, + "narHash": "sha256-YyPGNapgZNNj51ylQMw9lAgvxtM2ai1HZVUu3GS8Fng=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3c15feef7770eb5500a4b8792623e2d6f598c9c1", + "rev": "db9208ab987cdeeedf78ad9b4cf3c55f5ebd269b", "type": "github" }, "original": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/flake.nix new/xdg-desktop-portal-hyprland-1.1.0/flake.nix --- old/xdg-desktop-portal-hyprland-1.0.0/flake.nix 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/flake.nix 2023-09-18 19:10:57.000000000 +0200 @@ -28,15 +28,13 @@ overlays = [ inputs.hyprland-protocols.overlays.default self.overlays.xdg-desktop-portal-hyprland - self.overlays.hyprland-share-picker - self.overlays.package-overrides ]; }); in { overlays = import ./nix/overlays.nix {inherit self inputs lib;}; packages = eachSystem (system: { - inherit (pkgsFor.${system}) xdg-desktop-portal-hyprland hyprland-share-picker; + inherit (pkgsFor.${system}) xdg-desktop-portal-hyprland; default = self.packages.${system}.xdg-desktop-portal-hyprland; }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/hyprland-share-picker/main.cpp new/xdg-desktop-portal-hyprland-1.1.0/hyprland-share-picker/main.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/hyprland-share-picker/main.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/hyprland-share-picker/main.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -114,6 +114,7 @@ ID = ID.substr(ID.find_last_of('(') + 1); ID = ID.substr(0, ID.find_last_of(')')); + std::cout << "[SELECTION]"; std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : ""); std::cout << "/"; @@ -141,6 +142,7 @@ mainPickerPtr->windowIDs[button] = window.id; QObject::connect(button, &QPushButton::clicked, [=]() { + std::cout << "[SELECTION]"; std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : ""); std::cout << "/"; @@ -199,6 +201,7 @@ REGION = REGION.substr(REGION.find_first_of(' ') + 1); const auto H = std::stoi(REGION); + std::cout << "[SELECTION]"; std::cout << (ALLOWTOKENBUTTON->isChecked() ? "r" : ""); std::cout << "/"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/hyprland-share-picker/meson.build new/xdg-desktop-portal-hyprland-1.1.0/hyprland-share-picker/meson.build --- old/xdg-desktop-portal-hyprland-1.0.0/hyprland-share-picker/meson.build 1970-01-01 01:00:00.000000000 +0100 +++ new/xdg-desktop-portal-hyprland-1.1.0/hyprland-share-picker/meson.build 2023-09-18 19:10:57.000000000 +0200 @@ -0,0 +1,21 @@ +# select either qt6 or qt5 +qtdep = dependency('qt6', 'qt5', modules: ['Widgets']) +qtver = qtdep.version() +qt = import('qt' + qtver[0]) + +ui_files = qt.compile_ui(sources: 'mainpicker.ui') +moc = qt.compile_moc(headers: 'mainpicker.h') + +sources = files([ + 'main.cpp', + 'mainpicker.cpp', + 'mainpicker.h', +]) + +executable('hyprland-share-picker', + sources, + ui_files, + moc, + dependencies: qtdep, + install: true +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/meson.build new/xdg-desktop-portal-hyprland-1.1.0/meson.build --- old/xdg-desktop-portal-hyprland-1.0.0/meson.build 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/meson.build 2023-09-18 19:10:57.000000000 +0200 @@ -41,7 +41,6 @@ systemd_service_file = 'xdg-desktop-portal-hyprland.service' user_unit_dir = systemd.get_variable(pkgconfig: 'systemduserunitdir', pkgconfig_define: ['prefix', get_option('prefix')]) - conf_data.set('systemd_service', 'SystemdService=' + systemd_service_file) configure_file( configuration: conf_data, @@ -67,3 +66,4 @@ subdir('protocols') subdir('src') +subdir('hyprland-share-picker') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/nix/default.nix new/xdg-desktop-portal-hyprland-1.1.0/nix/default.nix --- old/xdg-desktop-portal-hyprland-1.0.0/nix/default.nix 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/nix/default.nix 2023-09-18 19:10:57.000000000 +0200 @@ -5,18 +5,18 @@ meson, ninja, pkg-config, - cairo, - hyprland-share-picker, libdrm, - libjpeg, mesa, - pango, pipewire, sdbus-cpp, systemd, wayland-protocols, wayland-scanner, - grim, + qtbase, + qttools, + qtwayland, + wrapQtAppsHook, + hyprland, slurp, hyprland-protocols, wayland, @@ -34,24 +34,32 @@ pkg-config wayland-scanner makeWrapper + wrapQtAppsHook ]; buildInputs = [ - cairo hyprland-protocols libdrm - libjpeg mesa - pango pipewire + qtbase + qttools + qtwayland sdbus-cpp systemd wayland wayland-protocols ]; + dontWrapQtApps = true; + postInstall = '' - wrapProgram $out/libexec/xdg-desktop-portal-hyprland --prefix PATH ":" ${lib.makeBinPath [hyprland-share-picker grim slurp]} + wrapProgramShell $out/bin/hyprland-share-picker \ + "''${qtWrapperArgs[@]}" \ + --prefix PATH ":" ${lib.makeBinPath [slurp hyprland]} + + wrapProgramShell $out/libexec/xdg-desktop-portal-hyprland \ + --prefix PATH ":" ${lib.makeBinPath [(placeholder "out")]} ''; meta = with lib; { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/nix/hyprland-share-picker.nix new/xdg-desktop-portal-hyprland-1.1.0/nix/hyprland-share-picker.nix --- old/xdg-desktop-portal-hyprland-1.0.0/nix/hyprland-share-picker.nix 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/nix/hyprland-share-picker.nix 1970-01-01 01:00:00.000000000 +0100 @@ -1,35 +0,0 @@ -{ - stdenv, - lib, - cmake, - qtbase, - qtwayland, - makeShellWrapper, - wrapQtAppsHook, - hyprland, - slurp, - version ? "git", -}: -stdenv.mkDerivation { - pname = "hyprland-share-picker"; - inherit version; - src = ../hyprland-share-picker; - - nativeBuildInputs = [ - cmake - wrapQtAppsHook - makeShellWrapper - ]; - buildInputs = [ - qtbase - qtwayland - ]; - - dontWrapQtApps = true; - - postInstall = '' - wrapProgramShell $out/bin/hyprland-share-picker \ - "''${qtWrapperArgs[@]}" \ - --prefix PATH ":" ${lib.makeBinPath [slurp hyprland]} - ''; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/nix/overlays.nix new/xdg-desktop-portal-hyprland-1.1.0/nix/overlays.nix --- old/xdg-desktop-portal-hyprland-1.0.0/nix/overlays.nix 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/nix/overlays.nix 2023-09-18 19:10:57.000000000 +0200 @@ -18,31 +18,13 @@ in { default = mkJoinedOverlays (with self.overlays; [ xdg-desktop-portal-hyprland - hyprland-share-picker - package-overrides ]); xdg-desktop-portal-hyprland = final: prev: { xdg-desktop-portal-hyprland = final.callPackage ./default.nix { stdenv = prev.gcc13Stdenv; - inherit (final) hyprland-protocols hyprland-share-picker; + inherit (final) hyprland-protocols; + inherit (final.qt6) qtbase qttools wrapQtAppsHook qtwayland; inherit version; }; }; - hyprland-share-picker = final: prev: { - hyprland-share-picker = final.callPackage ./hyprland-share-picker.nix { - inherit (final.qt6) qtbase wrapQtAppsHook qtwayland; - inherit version; - }; - }; - package-overrides = final: prev: { - sdbus-cpp = prev.sdbus-cpp.overrideAttrs (self: super: { - version = "1.3.0"; - src = prev.fetchFromGitHub { - repo = "sdbus-cpp"; - owner = "Kistler-Group"; - rev = "v${self.version}"; - hash = "sha256-S/8/I2wmWukpP+RGPxKbuO44wIExzeYZL49IO+KOqg4="; - }; - }); - }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/org.freedesktop.impl.portal.desktop.hyprland.service new/xdg-desktop-portal-hyprland-1.1.0/org.freedesktop.impl.portal.desktop.hyprland.service --- old/xdg-desktop-portal-hyprland-1.0.0/org.freedesktop.impl.portal.desktop.hyprland.service 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/org.freedesktop.impl.portal.desktop.hyprland.service 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=org.freedesktop.impl.portal.desktop.hyprland -Exec=/usr/lib/xdg-desktop-portal-hyprland -SystemdService=xdg-desktop-portal-hyprland.service \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/org.freedesktop.impl.portal.desktop.hyprland.service.in new/xdg-desktop-portal-hyprland-1.1.0/org.freedesktop.impl.portal.desktop.hyprland.service.in --- old/xdg-desktop-portal-hyprland-1.0.0/org.freedesktop.impl.portal.desktop.hyprland.service.in 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/org.freedesktop.impl.portal.desktop.hyprland.service.in 2023-09-18 19:10:57.000000000 +0200 @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.impl.portal.desktop.hyprland Exec=@libexecdir@/xdg-desktop-portal-hyprland -@systemd_service@ +SystemdService=xdg-desktop-portal-hyprland.service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/core/PortalManager.cpp new/xdg-desktop-portal-hyprland-1.1.0/src/core/PortalManager.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/core/PortalManager.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/core/PortalManager.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -290,16 +290,125 @@ wl_display_roundtrip(m_sWaylandConnection.display); - while (1) { - // dbus events + startEventLoop(); +} + +void CPortalManager::startEventLoop() { + + pollfd pollfds[] = { + { + .fd = m_pConnection->getEventLoopPollData().fd, + .events = POLLIN, + }, + { + .fd = wl_display_get_fd(m_sWaylandConnection.display), + .events = POLLIN, + }, + { + .fd = pw_loop_get_fd(m_sPipewire.loop), + .events = POLLIN, + }, + }; + + std::thread pollThr([this, &pollfds]() { + while (1) { + int ret = poll(pollfds, 3, -1); + if (ret < 0) { + Debug::log(CRIT, "[core] Polling fds failed with {}", strerror(errno)); + exit(1); + } + + for (size_t i = 0; i < 3; ++i) { + if (pollfds[0].revents & POLLHUP) { + Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i); + exit(1); + } + } + + { + Debug::log(TRACE, "[core] got poll event"); + std::lock_guard<std::mutex> lg(m_sEventLoopInternals.loopRequestMutex); + m_sEventLoopInternals.shouldProcess = true; + m_sEventLoopInternals.loopSignal.notify_all(); + } + } + }); + + m_sTimersThread.thread = std::make_unique<std::thread>([this] { + while (1) { + std::unique_lock lk(m_sTimersThread.loopMutex); + + // find nearest timer ms + m_mEventLock.lock(); + float nearest = 60000; /* reasonable timeout */ + for (auto& t : m_sTimersThread.timers) { + float until = t->duration() - t->passedMs(); + if (until < nearest) + nearest = until; + } + m_mEventLock.unlock(); + + m_sTimersThread.loopSignal.wait_for(lk, std::chrono::milliseconds((int)nearest), [this] { return m_sTimersThread.shouldProcess; }); + m_sTimersThread.shouldProcess = false; + + // awakened. Check if any timers passed + m_mEventLock.lock(); + bool notify = false; + for (auto& t : m_sTimersThread.timers) { + if (t->passed()) { + Debug::log(TRACE, "[core] got timer event"); + notify = true; + break; + } + } + m_mEventLock.unlock(); + + if (notify) { + std::lock_guard<std::mutex> lg(m_sEventLoopInternals.loopRequestMutex); + m_sEventLoopInternals.shouldProcess = true; + m_sEventLoopInternals.loopSignal.notify_all(); + } + } + }); + + while (1) { // dbus events + // wait for being awakened + m_sEventLoopInternals.loopRequestMutex.unlock(); // unlock, we are ready to take events + + std::unique_lock lk(m_sEventLoopInternals.loopMutex); + if (m_sEventLoopInternals.shouldProcess == false) // avoid a lock if a thread managed to request something already since we .unlock()ed + m_sEventLoopInternals.loopSignal.wait(lk, [this] { return m_sEventLoopInternals.shouldProcess == true; }); // wait for events + + m_sEventLoopInternals.loopRequestMutex.lock(); // lock incoming events + + m_sEventLoopInternals.shouldProcess = false; + m_mEventLock.lock(); - while (m_pConnection->processPendingRequest()) { - ; + if (pollfds[0].revents & POLLIN /* dbus */) { + while (m_pConnection->processPendingRequest()) { + ; + } + } + + if (pollfds[1].revents & POLLIN /* wl */) { + wl_display_flush(m_sWaylandConnection.display); + if (wl_display_prepare_read(m_sWaylandConnection.display) == 0) { + wl_display_read_events(m_sWaylandConnection.display); + wl_display_dispatch_pending(m_sWaylandConnection.display); + } else { + wl_display_dispatch(m_sWaylandConnection.display); + } + } + + if (pollfds[2].revents & POLLIN /* pw */) { + while (pw_loop_iterate(m_sPipewire.loop, 0) != 0) { + ; + } } std::vector<CTimer*> toRemove; - for (auto& t : m_vTimers) { + for (auto& t : m_sTimersThread.timers) { if (t->passed()) { t->m_fnCallback(); toRemove.emplace_back(t.get()); @@ -307,26 +416,21 @@ } } - while (pw_loop_iterate(m_sPipewire.loop, 0) != 0) { - ; - } - - wl_display_flush(m_sWaylandConnection.display); - if (wl_display_prepare_read(m_sWaylandConnection.display) == 0) { - wl_display_read_events(m_sWaylandConnection.display); - wl_display_dispatch_pending(m_sWaylandConnection.display); - } else { - wl_display_dispatch(m_sWaylandConnection.display); - } + // finalize wayland dispatching. Dispatch pending on the queue + int ret = 0; + do { + ret = wl_display_dispatch_pending(m_sWaylandConnection.display); + wl_display_flush(m_sWaylandConnection.display); + } while (ret > 0); if (!toRemove.empty()) - std::erase_if(m_vTimers, + std::erase_if(m_sTimersThread.timers, [&](const auto& t) { return std::find_if(toRemove.begin(), toRemove.end(), [&](const auto& other) { return other == t.get(); }) != toRemove.end(); }); m_mEventLock.unlock(); - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); } + + m_sTimersThread.thread.release(); } sdbus::IConnection* CPortalManager::getConnection() { @@ -382,3 +486,10 @@ free(renderNode); return gbm_create_device(fd); } + +void CPortalManager::addTimer(const CTimer& timer) { + Debug::log(TRACE, "[core] adding timer for {}ms", timer.duration()); + m_sTimersThread.timers.emplace_back(std::make_unique<CTimer>(timer)); + m_sTimersThread.shouldProcess = true; + m_sTimersThread.loopSignal.notify_all(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/core/PortalManager.hpp new/xdg-desktop-portal-hyprland-1.1.0/src/core/PortalManager.hpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/core/PortalManager.hpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/core/PortalManager.hpp 2023-09-18 19:10:57.000000000 +0200 @@ -65,13 +65,30 @@ } dma; } m_sWaylandConnection; - std::vector<SDMABUFModifier> m_vDMABUFMods; + std::vector<SDMABUFModifier> m_vDMABUFMods; - std::vector<std::unique_ptr<CTimer>> m_vTimers; + void addTimer(const CTimer& timer); - gbm_device* createGBMDevice(drmDevice* dev); + gbm_device* createGBMDevice(drmDevice* dev); private: + void startEventLoop(); + + struct { + std::condition_variable loopSignal; + std::mutex loopMutex; + std::atomic<bool> shouldProcess = false; + std::mutex loopRequestMutex; + } m_sEventLoopInternals; + + struct { + std::condition_variable loopSignal; + std::mutex loopMutex; + bool shouldProcess = false; + std::vector<std::unique_ptr<CTimer>> timers; + std::unique_ptr<std::thread> thread; + } m_sTimersThread; + std::unique_ptr<sdbus::IConnection> m_pConnection; std::vector<std::unique_ptr<SOutput>> m_vOutputs; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/MiscFunctions.cpp new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/MiscFunctions.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/MiscFunctions.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/MiscFunctions.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -3,6 +3,8 @@ #include "../helpers/Log.hpp" std::string execAndGet(const char* cmd) { + Debug::log(LOG, "execAndGet: {}", cmd); + std::array<char, 128> buffer; std::string result; const std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose); @@ -14,4 +16,11 @@ result += buffer.data(); } return result; +} + +void addHyprlandNotification(const std::string& icon, float timeMs, const std::string& color, const std::string& message) { + const std::string CMD = std::format("hyprctl notify {} {} {} \"{}\"", icon, timeMs, color, message); + Debug::log(LOG, "addHyprlandNotification: {}", CMD); + if (fork() == 0) + execl("/bin/sh", "/bin/sh", "-c", CMD.c_str(), nullptr); } \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/MiscFunctions.hpp new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/MiscFunctions.hpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/MiscFunctions.hpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/MiscFunctions.hpp 2023-09-18 19:10:57.000000000 +0200 @@ -1,4 +1,5 @@ #pragma once #include <string> -std::string execAndGet(const char* cmd); \ No newline at end of file +std::string execAndGet(const char* cmd); +void addHyprlandNotification(const std::string& icon, float timeMs, const std::string& color, const std::string& message); \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/Timer.cpp new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/Timer.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/Timer.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/Timer.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -8,4 +8,12 @@ bool CTimer::passed() const { return std::chrono::high_resolution_clock::now() > (m_tStart + std::chrono::milliseconds((uint64_t)m_fDuration)); +} + +float CTimer::passedMs() const { + return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - m_tStart).count(); +} + +float CTimer::duration() const { + return m_fDuration; } \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/Timer.hpp new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/Timer.hpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/helpers/Timer.hpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/helpers/Timer.hpp 2023-09-18 19:10:57.000000000 +0200 @@ -8,6 +8,8 @@ CTimer(float ms, std::function<void()> callback); bool passed() const; + float passedMs() const; + float duration() const; std::function<void()> m_fnCallback; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/meson.build new/xdg-desktop-portal-hyprland-1.1.0/src/meson.build --- old/xdg-desktop-portal-hyprland-1.0.0/src/meson.build 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/meson.build 2023-09-18 19:10:57.000000000 +0200 @@ -4,15 +4,10 @@ executable('xdg-desktop-portal-hyprland', [src, wl_proto_files], dependencies: [ - dependency('cairo'), dependency('gbm'), dependency('libdrm'), - dependency('libjpeg'), dependency('libpipewire-0.3'), - dependency('pango'), - dependency('pangocairo'), dependency('sdbus-c++'), - dependency('threads'), dependency('wayland-client'), ], include_directories: inc, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/portals/Screencopy.cpp new/xdg-desktop-portal-hyprland-1.1.0/src/portals/Screencopy.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/portals/Screencopy.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/portals/Screencopy.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -645,7 +645,7 @@ else if (pSession->sharingData.windowFrameCallback) hyprland_toplevel_export_frame_v1_add_listener(pSession->sharingData.windowFrameCallback, &hyprlandFrameListener, pSession); - Debug::log(LOG, "[screencopy] frame callbacks initialized"); + Debug::log(TRACE, "[screencopy] frame callbacks initialized"); } void CScreencopyPortal::queueNextShareFrame(CScreencopyPortal::SSession* pSession) { @@ -654,8 +654,7 @@ if (PSTREAM && !PSTREAM->streamState) return; - g_pPortalManager->m_vTimers.emplace_back( - std::make_unique<CTimer>(1000.0 / pSession->sharingData.framerate, [pSession]() { g_pPortalManager->m_sPortals.screencopy->startFrameCopy(pSession); })); + g_pPortalManager->addTimer({1000.0 / pSession->sharingData.framerate, [pSession]() { g_pPortalManager->m_sPortals.screencopy->startFrameCopy(pSession); }}); } bool CScreencopyPortal::hasToplevelCapabilities() { return m_sState.toplevel; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xdg-desktop-portal-hyprland-1.0.0/src/shared/ScreencopyShared.cpp new/xdg-desktop-portal-hyprland-1.1.0/src/shared/ScreencopyShared.cpp --- old/xdg-desktop-portal-hyprland-1.0.0/src/shared/ScreencopyShared.cpp 2023-09-06 20:36:48.000000000 +0200 +++ new/xdg-desktop-portal-hyprland-1.1.0/src/shared/ScreencopyShared.cpp 2023-09-18 19:10:57.000000000 +0200 @@ -11,6 +11,8 @@ std::string sanitizeNameForWindowList(const std::string& name) { std::string result = name; + if (result[0] == '\"') + result[0] = ' '; for (size_t i = 1; i < result.size(); ++i) { if (result[i - 1] == '>' && result[i] == ']') result[i] = ' '; @@ -42,15 +44,28 @@ const char* HYPRLAND_INSTANCE_SIGNATURE = getenv("HYPRLAND_INSTANCE_SIGNATURE"); std::string cmd = - std::format("WAYLAND_DISPLAY={} QT_QPA_PLATFORM=\"wayland\" XCURSOR_SIZE={} HYPRLAND_INSTANCE_SIGNATURE={} XDPH_WINDOW_SHARING_LIST=\"{}\" hyprland-share-picker", + std::format("WAYLAND_DISPLAY={} QT_QPA_PLATFORM=\"wayland\" XCURSOR_SIZE={} HYPRLAND_INSTANCE_SIGNATURE={} XDPH_WINDOW_SHARING_LIST=\"{}\" hyprland-share-picker 2>&1", WAYLAND_DISPLAY ? WAYLAND_DISPLAY : "", XCURSOR_SIZE ? XCURSOR_SIZE : "24", HYPRLAND_INSTANCE_SIGNATURE ? HYPRLAND_INSTANCE_SIGNATURE : "0", buildWindowList()); const auto RETVAL = execAndGet(cmd.c_str()); - Debug::log(LOG, "[sc] Selection: {}", RETVAL); + if (!RETVAL.contains("[SELECTION]")) { + // failed - const auto FLAGS = RETVAL.substr(0, RETVAL.find_first_of('/')); - const auto SEL = RETVAL.substr(RETVAL.find_first_of('/') + 1); + if (RETVAL.contains("qt.qpa.plugin: Could not find the Qt platform plugin")) { + // prompt the user to install qt5-wayland and qt6-wayland + addHyprlandNotification("3", 7000, "0", "[xdph] Could not open the picker: qt5-wayland or qt6-wayland doesn't seem to be installed."); + } + + return data; + } + + const auto SELECTION = RETVAL.substr(RETVAL.find("[SELECTION]") + 11); + + Debug::log(LOG, "[sc] Selection: {}", SELECTION); + + const auto FLAGS = SELECTION.substr(0, SELECTION.find_first_of('/')); + const auto SEL = SELECTION.substr(SELECTION.find_first_of('/') + 1); for (auto& flag : FLAGS) { if (flag == 'r') {