33#include " ../helpers/MiscFunctions.hpp"
44
55#include < pipewire/pipewire.h>
6- #include < poll.h>
76#include < sys/mman.h>
87#include < fcntl.h>
98#include < unistd.h>
@@ -19,12 +18,21 @@ SOutput::SOutput(SP<CCWlOutput> output_) : output(output_) {
1918
2019 Debug::log (LOG, " Found output name {}" , name);
2120 });
22- output->setMode ([this ](CCWlOutput* r, uint32_t flags, int32_t width , int32_t height , int32_t refresh) { //
21+ output->setMode ([this ](CCWlOutput* r, uint32_t flags, int32_t width_ , int32_t height_ , int32_t refresh) {
2322 refreshRate = refresh;
23+ width = width_;
24+ height = height_;
2425 });
25- output->setGeometry ([this ](CCWlOutput* r, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char * make, const char * model,
26- int32_t transform_) { //
27- transform = (wl_output_transform)transform_;
26+ output->setGeometry (
27+ [this ](CCWlOutput* r, int32_t x_, int32_t y_, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char * make, const char * model, int32_t transform_) {
28+ transform = (wl_output_transform)transform_;
29+ x = x_;
30+ y = y_;
31+ });
32+ output->setScale ([this ](CCWlOutput* r, uint32_t factor_) { scale = factor_; });
33+ output->setDone ([](CCWlOutput* r) {
34+ if (g_pPortalManager->m_sPortals .inputCapture != nullptr )
35+ g_pPortalManager->m_sPortals .inputCapture ->zonesChanged ();
2836 });
2937}
3038
@@ -63,7 +71,9 @@ void CPortalManager::onGlobal(uint32_t name, const char* interface, uint32_t ver
6371 m_sPortals.globalShortcuts = std::make_unique<CGlobalShortcutsPortal>(makeShared<CCHyprlandGlobalShortcutsManagerV1>(
6472 (wl_proxy*)wl_registry_bind ((wl_registry*)m_sWaylandConnection.registry ->resource (), name, &hyprland_global_shortcuts_manager_v1_interface, version)));
6573 }
66-
74+ if (INTERFACE == hyprland_input_capture_manager_v1_interface.name )
75+ m_sPortals.inputCapture = std::make_unique<CInputCapturePortal>(makeShared<CCHyprlandInputCaptureManagerV1>(
76+ (wl_proxy*)wl_registry_bind ((wl_registry*)m_sWaylandConnection.registry ->resource (), name, &hyprland_input_capture_manager_v1_interface, version)));
6777 else if (INTERFACE == hyprland_toplevel_export_manager_v1_interface.name ) {
6878 m_sWaylandConnection.hyprlandToplevelMgr = makeShared<CCHyprlandToplevelExportManagerV1>(
6979 (wl_proxy*)wl_registry_bind ((wl_registry*)m_sWaylandConnection.registry ->resource (), name, &hyprland_toplevel_export_manager_v1_interface, version));
@@ -293,32 +303,21 @@ void CPortalManager::init() {
293303}
294304
295305void CPortalManager::startEventLoop () {
306+ addFdToEventLoop (m_pConnection->getEventLoopPollData ().fd , POLLIN, nullptr );
307+ addFdToEventLoop (wl_display_get_fd (m_sWaylandConnection.display ), POLLIN, nullptr );
308+ addFdToEventLoop (pw_loop_get_fd (m_sPipewire.loop ), POLLIN, nullptr );
296309
297- pollfd pollfds[] = {
298- {
299- .fd = m_pConnection->getEventLoopPollData ().fd ,
300- .events = POLLIN,
301- },
302- {
303- .fd = wl_display_get_fd (m_sWaylandConnection.display ),
304- .events = POLLIN,
305- },
306- {
307- .fd = pw_loop_get_fd (m_sPipewire.loop ),
308- .events = POLLIN,
309- },
310- };
311-
312- std::thread pollThr ([this , &pollfds]() {
310+ std::thread pollThr ([this ]() {
313311 while (1 ) {
314- int ret = poll (pollfds, 3 , 5000 /* 5 seconds, reasonable. It's because we might need to terminate */ );
312+
313+ int ret = poll (m_sEventLoopInternals.pollFds .data (), m_sEventLoopInternals.pollFds .size (), 5000 /* 5 seconds, reasonable. It's because we might need to terminate */ );
315314 if (ret < 0 ) {
316315 Debug::log (CRIT, " [core] Polling fds failed with {}" , strerror (errno));
317316 g_pPortalManager->terminate ();
318317 }
319318
320319 for (size_t i = 0 ; i < 3 ; ++i) {
321- if (pollfds[i]. revents & POLLHUP) {
320+ if (m_sEventLoopInternals. pollFds . data ()-> revents & POLLHUP) {
322321 Debug::log (CRIT, " [core] Disconnected from pollfd id {}" , i);
323322 g_pPortalManager->terminate ();
324323 }
@@ -391,13 +390,13 @@ void CPortalManager::startEventLoop() {
391390
392391 m_mEventLock.lock ();
393392
394- if (pollfds [0 ].revents & POLLIN /* dbus */ ) {
393+ if (m_sEventLoopInternals. pollFds [0 ].revents & POLLIN /* dbus */ ) {
395394 while (m_pConnection->processPendingEvent ()) {
396395 ;
397396 }
398397 }
399398
400- if (pollfds [1 ].revents & POLLIN /* wl */ ) {
399+ if (m_sEventLoopInternals. pollFds [1 ].revents & POLLIN /* wl */ ) {
401400 wl_display_flush (m_sWaylandConnection.display );
402401 if (wl_display_prepare_read (m_sWaylandConnection.display ) == 0 ) {
403402 wl_display_read_events (m_sWaylandConnection.display );
@@ -407,12 +406,18 @@ void CPortalManager::startEventLoop() {
407406 }
408407 }
409408
410- if (pollfds [2 ].revents & POLLIN /* pw */ ) {
409+ if (m_sEventLoopInternals. pollFds [2 ].revents & POLLIN /* pw */ ) {
411410 while (pw_loop_iterate (m_sPipewire.loop , 0 ) != 0 ) {
412411 ;
413412 }
414413 }
415414
415+ for (pollfd p : m_sEventLoopInternals.pollFds ) {
416+ if (p.revents & POLLIN && m_sEventLoopInternals.pollCallbacks .contains (p.fd )) {
417+ m_sEventLoopInternals.pollCallbacks [p.fd ]();
418+ }
419+ }
420+
416421 std::vector<CTimer*> toRemove;
417422 for (auto & t : m_sTimersThread.timers ) {
418423 if (t->passed ()) {
@@ -441,6 +446,7 @@ void CPortalManager::startEventLoop() {
441446 m_sPortals.screencopy .reset ();
442447 m_sPortals.screenshot .reset ();
443448 m_sHelpers.toplevel .reset ();
449+ m_sPortals.inputCapture .reset ();
444450
445451 m_pConnection.reset ();
446452 pw_loop_destroy (m_sPipewire.loop );
@@ -462,6 +468,10 @@ SOutput* CPortalManager::getOutputFromName(const std::string& name) {
462468 return nullptr ;
463469}
464470
471+ std::vector<std::unique_ptr<SOutput>> const & CPortalManager::getAllOutputs () {
472+ return m_vOutputs;
473+ }
474+
465475static char * gbm_find_render_node (drmDevice* device) {
466476 drmDevice* devices[64 ];
467477 char * render_node = NULL ;
@@ -511,6 +521,20 @@ void CPortalManager::addTimer(const CTimer& timer) {
511521 m_sTimersThread.loopSignal .notify_all ();
512522}
513523
524+ void CPortalManager::addFdToEventLoop (int fd, short events, std::function<void ()> callback) {
525+ m_sEventLoopInternals.pollFds .emplace_back (pollfd{.fd = fd, .events = POLLIN});
526+
527+ if (callback == nullptr )
528+ return ;
529+
530+ m_sEventLoopInternals.pollCallbacks [fd] = callback;
531+ }
532+
533+ void CPortalManager::removeFdFromEventLoop (int fd) {
534+ std::erase_if (m_sEventLoopInternals.pollFds , [fd](const pollfd& p) { return p.fd == fd; });
535+ m_sEventLoopInternals.pollCallbacks .erase (fd);
536+ }
537+
514538void CPortalManager::terminate () {
515539 m_bTerminate = true ;
516540
0 commit comments