core: avoid having the toplevel mgr bound all the time

This commit is contained in:
Vaxry 2023-12-25 15:05:30 +01:00
parent f5c3576c3b
commit 24141c05c2
4 changed files with 57 additions and 11 deletions

View file

@ -235,8 +235,7 @@ void CPortalManager::onGlobal(void* data, struct wl_registry* registry, uint32_t
m_sWaylandConnection.shm = (wl_shm*)wl_registry_bind(registry, name, &wl_shm_interface, version); m_sWaylandConnection.shm = (wl_shm*)wl_registry_bind(registry, name, &wl_shm_interface, version);
else if (INTERFACE == zwlr_foreign_toplevel_manager_v1_interface.name) else if (INTERFACE == zwlr_foreign_toplevel_manager_v1_interface.name)
m_sHelpers.toplevel = m_sHelpers.toplevel = std::make_unique<CToplevelManager>(registry, name, version);
std::make_unique<CToplevelManager>((zwlr_foreign_toplevel_manager_v1*)wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, version));
} }
void CPortalManager::onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name) { void CPortalManager::onGlobalRemoved(void* data, struct wl_registry* registry, uint32_t name) {

View file

@ -285,6 +285,8 @@ static const hyprland_toplevel_export_frame_v1_listener hyprlandFrameListener =
void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) { void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) {
sdbus::ObjectPath requestHandle, sessionHandle; sdbus::ObjectPath requestHandle, sessionHandle;
g_pPortalManager->m_sHelpers.toplevel->activate();
call >> requestHandle; call >> requestHandle;
call >> sessionHandle; call >> sessionHandle;
@ -307,6 +309,9 @@ void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) {
} }
PSESSION->session.release(); PSESSION->session.release();
Debug::log(LOG, "[screencopy] Session destroyed"); Debug::log(LOG, "[screencopy] Session destroyed");
// deactivate toplevel so it doesn't listen and waste battery
g_pPortalManager->m_sHelpers.toplevel->deactivate();
}; };
PSESSION->request = createDBusRequest(requestHandle); PSESSION->request = createDBusRequest(requestHandle);
PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); }; PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); };

View file

@ -1,5 +1,6 @@
#include "ToplevelManager.hpp" #include "ToplevelManager.hpp"
#include "../helpers/Log.hpp" #include "../helpers/Log.hpp"
#include "../core/PortalManager.hpp"
static void toplevelTitle(void* data, zwlr_foreign_toplevel_handle_v1* zwlr_foreign_toplevel_handle_v1, const char* title) { static void toplevelTitle(void* data, zwlr_foreign_toplevel_handle_v1* zwlr_foreign_toplevel_handle_v1, const char* title) {
const auto PTL = (SToplevelHandle*)data; const auto PTL = (SToplevelHandle*)data;
@ -81,11 +82,6 @@ inline const zwlr_foreign_toplevel_manager_v1_listener managerListener = {
.finished = managerFinished, .finished = managerFinished,
}; };
CToplevelManager::CToplevelManager(zwlr_foreign_toplevel_manager_v1* mgr) {
m_pManager = mgr;
zwlr_foreign_toplevel_manager_v1_add_listener(mgr, &managerListener, this);
}
bool CToplevelManager::exists(zwlr_foreign_toplevel_handle_v1* handle) { bool CToplevelManager::exists(zwlr_foreign_toplevel_handle_v1* handle) {
for (auto& h : m_vToplevels) { for (auto& h : m_vToplevels) {
if (h->handle == handle) if (h->handle == handle)
@ -94,3 +90,38 @@ bool CToplevelManager::exists(zwlr_foreign_toplevel_handle_v1* handle) {
return false; return false;
} }
CToplevelManager::CToplevelManager(wl_registry* registry, uint32_t name, uint32_t version) {
m_sWaylandConnection = {registry, name, version};
}
void CToplevelManager::activate() {
m_iActivateLocks++;
Debug::log(LOG, "[toplevel] (activate) locks: {}", m_iActivateLocks);
if (m_pManager || m_iActivateLocks < 1)
return;
m_pManager = (zwlr_foreign_toplevel_manager_v1*)wl_registry_bind(m_sWaylandConnection.registry, m_sWaylandConnection.name, &zwlr_foreign_toplevel_manager_v1_interface,
m_sWaylandConnection.version);
zwlr_foreign_toplevel_manager_v1_add_listener(m_pManager, &managerListener, this);
wl_display_roundtrip(g_pPortalManager->m_sWaylandConnection.display);
Debug::log(LOG, "[toplevel] Activated, bound to {:x}, toplevels: {}", (uintptr_t)m_pManager, m_vToplevels.size());
}
void CToplevelManager::deactivate() {
m_iActivateLocks--;
Debug::log(LOG, "[toplevel] (deactivate) locks: {}", m_iActivateLocks);
if (!m_pManager || m_iActivateLocks > 0)
return;
zwlr_foreign_toplevel_manager_v1_destroy(m_pManager);
m_pManager = nullptr;
m_vToplevels.clear();
Debug::log(LOG, "[toplevel] unbound manager");
}

View file

@ -17,12 +17,23 @@ struct SToplevelHandle {
class CToplevelManager { class CToplevelManager {
public: public:
CToplevelManager(zwlr_foreign_toplevel_manager_v1* mgr); CToplevelManager(wl_registry* registry, uint32_t name, uint32_t version);
void activate();
void deactivate();
bool exists(zwlr_foreign_toplevel_handle_v1* handle); bool exists(zwlr_foreign_toplevel_handle_v1* handle);
std::vector<std::unique_ptr<SToplevelHandle>> m_vToplevels; std::vector<std::unique_ptr<SToplevelHandle>> m_vToplevels;
private: private:
zwlr_foreign_toplevel_manager_v1* m_pManager; zwlr_foreign_toplevel_manager_v1* m_pManager = nullptr;
int64_t m_iActivateLocks = 0;
struct {
wl_registry* registry = nullptr;
uint32_t name = 0;
uint32_t version = 0;
} m_sWaylandConnection;
}; };