screencopy: store a fb before permission popup if the permission is pending (#10455)

stops rendering the permission popup on stuff like grim when it asks
This commit is contained in:
Vaxry 2025-05-17 18:03:35 +01:00 committed by GitHub
parent bb9aa79b21
commit bb5cd5b2dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 29 deletions

View File

@ -187,9 +187,43 @@ void CScreencopyFrame::share() {
callback(copyShm()); callback(copyShm());
} }
void CScreencopyFrame::renderMon() {
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
if (m_overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
}
void CScreencopyFrame::storeTempFB() {
g_pHyprRenderer->makeEGLCurrent();
m_tempFb.alloc(m_box.w, m_box.h);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &m_tempFb, true)) {
LOGM(ERR, "Can't copy: failed to begin rendering to temp fb");
return;
}
renderMon();
g_pHyprRenderer->endRender();
}
void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) { void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY); const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX}; CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
@ -200,17 +234,12 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
} }
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) { if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y} if (m_tempFb.isAllocated()) {
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh. CBox texbox = {{}, m_box.size()};
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y); g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
g_pHyprOpenGL->setMonitorTransformEnabled(true); m_tempFb.release();
g_pHyprOpenGL->setRenderModifEnabled(false); } else
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1); renderMon();
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
if (m_overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) } else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK); g_pHyprOpenGL->clear(Colors::BLACK);
else { else {
@ -228,8 +257,7 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
} }
bool CScreencopyFrame::copyShm() { bool CScreencopyFrame::copyShm() {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY); const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
auto shm = m_buffer->shm(); auto shm = m_buffer->shm();
auto [pixelData, fmt, bufLen] = m_buffer->beginDataPtr(0); // no need for end, cuz it's shm auto [pixelData, fmt, bufLen] = m_buffer->beginDataPtr(0); // no need for end, cuz it's shm
@ -247,15 +275,12 @@ bool CScreencopyFrame::copyShm() {
} }
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) { if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
CBox monbox = CBox{0, 0, m_monitor->m_transformedSize.x, m_monitor->m_transformedSize.y}.translate({-m_box.x, -m_box.y}); if (m_tempFb.isAllocated()) {
g_pHyprOpenGL->setMonitorTransformEnabled(true); CBox texbox = {{}, m_box.size()};
g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1); m_tempFb.release();
g_pHyprOpenGL->setRenderModifEnabled(true); } else
g_pHyprOpenGL->setMonitorTransformEnabled(false); renderMon();
if (m_overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) } else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK); g_pHyprOpenGL->clear(Colors::BLACK);
else { else {
@ -420,8 +445,12 @@ void CScreencopyProtocol::onOutputCommit(PHLMONITOR pMonitor) {
// check permissions // check permissions
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->m_resource->client(), PERMISSION_TYPE_SCREENCOPY); const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) {
if (!f->m_tempFb.isAllocated())
f->storeTempFB(); // make a snapshot before the popup
continue; // pending an answer, don't do anything yet. continue; // pending an answer, don't do anything yet.
}
// otherwise share. If it's denied, it will be black. // otherwise share. If it's denied, it will be black.

View File

@ -10,6 +10,7 @@
#include "../managers/HookSystemManager.hpp" #include "../managers/HookSystemManager.hpp"
#include "../helpers/time/Timer.hpp" #include "../helpers/time/Timer.hpp"
#include "../helpers/time/Time.hpp" #include "../helpers/time/Time.hpp"
#include "../render/Framebuffer.hpp"
#include "../managers/eventLoop/EventLoopTimer.hpp" #include "../managers/eventLoop/EventLoopTimer.hpp"
#include <aquamarine/buffer/Buffer.hpp> #include <aquamarine/buffer/Buffer.hpp>
@ -72,10 +73,15 @@ class CScreencopyFrame {
int m_shmStride = 0; int m_shmStride = 0;
CBox m_box = {}; CBox m_box = {};
void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer); // if we have a pending perm, hold the buffer.
void copyDmabuf(std::function<void(bool)> callback); CFramebuffer m_tempFb;
bool copyShm();
void share(); void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer);
void copyDmabuf(std::function<void(bool)> callback);
bool copyShm();
void renderMon();
void storeTempFB();
void share();
friend class CScreencopyProtocol; friend class CScreencopyProtocol;
}; };