screencopy: support hw cursors while sharing with cursor

This commit is contained in:
Vaxry
2025-04-28 20:18:02 +01:00
parent f5c5cfa960
commit c505eb55ff
4 changed files with 10 additions and 31 deletions

View File

@@ -591,13 +591,13 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
return buf;
}
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage, std::optional<Vector2D> overridePos) {
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage, std::optional<Vector2D> overridePos, bool forceRender) {
if (!hasCursor())
return;
auto state = stateFor(pMonitor);
if ((!state->hardwareFailed && state->softwareLocks == 0)) {
if (!state->hardwareFailed && state->softwareLocks == 0 && !forceRender) {
if (currentCursorImage.surface)
currentCursorImage.surface->resource()->frame(now);
return;

View File

@@ -49,7 +49,8 @@ class CPointerManager {
void unlockSoftwareAll();
bool softwareLockedFor(PHLMONITOR pMonitor);
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */,
bool forceRender = false);
// this is needed e.g. during screensharing where
// the software cursors aren't locked during the cursor move, but they

View File

@@ -2,6 +2,7 @@
#include "../Compositor.hpp"
#include "../managers/eventLoop/EventLoopManager.hpp"
#include "../managers/PointerManager.hpp"
#include "../managers/input/InputManager.hpp"
#include "../managers/EventManager.hpp"
#include "../managers/permissions/DynamicPermissionManager.hpp"
#include "../render/Renderer.hpp"
@@ -146,18 +147,6 @@ void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_
PROTO::screencopy->m_vFramesAwaitingWrite.emplace_back(self);
g_pHyprRenderer->m_bDirectScanoutBlocked = true;
if (overlayCursor && !lockedSWCursors) {
lockedSWCursors = true;
// TODO: make it per-monitor
if (!PROTO::screencopy->m_bTimerArmed) {
for (auto const& m : g_pCompositor->m_monitors) {
g_pPointerManager->lockSoftwareForMonitor(m);
}
PROTO::screencopy->m_bTimerArmed = true;
LOGM(LOG, "Locking sw cursors due to screensharing");
}
PROTO::screencopy->m_pSoftwareCursorTimer->updateTimeout(std::chrono::seconds(1));
}
if (!withDamage)
g_pHyprRenderer->damageMonitor(pMonitor.lock());
@@ -219,6 +208,8 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
g_pPointerManager->renderSoftwareCursorsFor(pMonitor.lock(), Time::steadyNow(), fakeDamage, g_pInputManager->getMouseCoordsInternal() - pMonitor->vecPosition - box.pos(),
true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@@ -272,6 +263,8 @@ bool CScreencopyFrame::copyShm() {
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
g_pPointerManager->renderSoftwareCursorsFor(pMonitor.lock(), Time::steadyNow(), fakeDamage, g_pInputManager->getMouseCoordsInternal() - pMonitor->vecPosition - box.pos(),
true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@@ -398,19 +391,7 @@ bool CScreencopyClient::good() {
}
CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
m_pSoftwareCursorTimer = makeShared<CEventLoopTimer>(
std::nullopt,
[this](SP<CEventLoopTimer> self, void* data) {
// TODO: make it per-monitor
for (auto const& m : g_pCompositor->m_monitors) {
g_pPointerManager->unlockSoftwareForMonitor(m);
}
m_bTimerArmed = false;
LOGM(LOG, "Releasing software cursor lock");
},
nullptr);
g_pEventLoopManager->addTimer(m_pSoftwareCursorTimer);
;
}
void CScreencopyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {

View File

@@ -96,9 +96,6 @@ class CScreencopyProtocol : public IWaylandProtocol {
std::vector<WP<CScreencopyFrame>> m_vFramesAwaitingWrite;
std::vector<SP<CScreencopyClient>> m_vClients;
SP<CEventLoopTimer> m_pSoftwareCursorTimer;
bool m_bTimerArmed = false;
void shareAllFrames(PHLMONITOR pMonitor);
void shareFrame(CScreencopyFrame* frame);
void sendFrameDamage(CScreencopyFrame* frame);