summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-05-17 18:03:35 +0100
committerGitHub <noreply@github.com>2025-05-17 19:03:35 +0200
commitbb5cd5b2ddcb2dbe58613aa41fa2062208208339 (patch)
tree8e2ce632127952bb2abe81d0d9e4b3c668094352 /src
parentbb9aa79b216b952c692c2443c50b0a6d7e5b108d (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/protocols/Screencopy.cpp79
-rw-r--r--src/protocols/Screencopy.hpp14
2 files changed, 64 insertions, 29 deletions
diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp
index 1afa477f..5fa7c84e 100644
--- a/src/protocols/Screencopy.cpp
+++ b/src/protocols/Screencopy.cpp
@@ -187,9 +187,43 @@ void CScreencopyFrame::share() {
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) {
- const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
- auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
+ const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
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) {
- 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);
+ if (m_tempFb.isAllocated()) {
+ CBox texbox = {{}, m_box.size()};
+ g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
+ m_tempFb.release();
+ } else
+ renderMon();
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@@ -228,8 +257,7 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
}
bool CScreencopyFrame::copyShm() {
- const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
- auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
+ const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto shm = m_buffer->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) {
- CBox monbox = CBox{0, 0, m_monitor->m_transformedSize.x, m_monitor->m_transformedSize.y}.translate({-m_box.x, -m_box.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);
+ if (m_tempFb.isAllocated()) {
+ CBox texbox = {{}, m_box.size()};
+ g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
+ m_tempFb.release();
+ } else
+ renderMon();
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
@@ -420,8 +445,12 @@ void CScreencopyProtocol::onOutputCommit(PHLMONITOR pMonitor) {
// check permissions
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.
+ }
// otherwise share. If it's denied, it will be black.
diff --git a/src/protocols/Screencopy.hpp b/src/protocols/Screencopy.hpp
index ead8b2ed..665fede1 100644
--- a/src/protocols/Screencopy.hpp
+++ b/src/protocols/Screencopy.hpp
@@ -10,6 +10,7 @@
#include "../managers/HookSystemManager.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/time/Time.hpp"
+#include "../render/Framebuffer.hpp"
#include "../managers/eventLoop/EventLoopTimer.hpp"
#include <aquamarine/buffer/Buffer.hpp>
@@ -72,10 +73,15 @@ class CScreencopyFrame {
int m_shmStride = 0;
CBox m_box = {};
- void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer);
- void copyDmabuf(std::function<void(bool)> callback);
- bool copyShm();
- void share();
+ // if we have a pending perm, hold the buffer.
+ CFramebuffer m_tempFb;
+
+ 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;
};