summaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-07-31 18:07:59 +0200
committerGitHub <noreply@github.com>2025-07-31 18:07:59 +0200
commit9607e3b5a88f22017af64ab1ba360a39169a4bf7 (patch)
tree28e408434d4c7781c6b6f403b3093f19b56b6d86 /src/protocols
parenta907ecd4ff736a3a09410532b405a437eb48033c (diff)
screencopy: un-hdr screencopy buffers for cm-unaware clients (#11294)
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/ColorManagement.cpp8
-rw-r--r--src/protocols/ColorManagement.hpp5
-rw-r--r--src/protocols/Screencopy.cpp19
-rw-r--r--src/protocols/Screencopy.hpp1
4 files changed, 28 insertions, 5 deletions
diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp
index 215ab5ac..ce00a96b 100644
--- a/src/protocols/ColorManagement.cpp
+++ b/src/protocols/ColorManagement.cpp
@@ -204,6 +204,10 @@ bool CColorManager::good() {
return m_resource->resource();
}
+wl_client* CColorManager::client() {
+ return m_resource->client();
+}
+
CColorManagementOutput::CColorManagementOutput(SP<CWpColorManagementOutputV1> resource, WP<CMonitor> monitor) : m_resource(resource), m_monitor(monitor) {
if UNLIKELY (!good())
return;
@@ -818,6 +822,10 @@ void CColorManagementProtocol::onMonitorImageDescriptionChanged(WP<CMonitor> mon
feedback->onPreferredChanged();
}
+bool CColorManagementProtocol::isClientCMAware(wl_client* client) {
+ return std::ranges::any_of(m_managers, [client](const auto& m) { return m->client() == client; });
+}
+
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; });
}
diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp
index 1d2795ed..06349927 100644
--- a/src/protocols/ColorManagement.hpp
+++ b/src/protocols/ColorManagement.hpp
@@ -18,7 +18,8 @@ class CColorManager {
public:
CColorManager(SP<CWpColorManagerV1> resource);
- bool good();
+ bool good();
+ wl_client* client();
private:
SP<CWpColorManagerV1> m_resource;
@@ -187,6 +188,8 @@ class CColorManagementProtocol : public IWaylandProtocol {
void onImagePreferredChanged(uint32_t preferredId);
void onMonitorImageDescriptionChanged(WP<CMonitor> monitor);
+ bool isClientCMAware(wl_client* client);
+
private:
void destroyResource(CColorManager* resource);
void destroyResource(CColorManagementOutput* resource);
diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp
index ddbb371a..a9e0e5b3 100644
--- a/src/protocols/Screencopy.cpp
+++ b/src/protocols/Screencopy.cpp
@@ -11,6 +11,7 @@
#include "core/Output.hpp"
#include "types/WLBuffer.hpp"
#include "types/Buffer.hpp"
+#include "ColorManagement.hpp"
#include "../helpers/Format.hpp"
#include "../helpers/time/Time.hpp"
#include "XDGShell.hpp"
@@ -191,16 +192,22 @@ void CScreencopyFrame::share() {
}
void CScreencopyFrame::renderMon() {
- auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
+ 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};
+
+ const bool IS_CM_AWARE = PROTO::colorManagement->isClientCMAware(m_client->client());
- CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
+ 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->pushMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false);
- g_pHyprOpenGL->renderTexture(TEXTURE, monbox, {});
+ g_pHyprOpenGL->renderTexture(TEXTURE, monbox,
+ {
+ .cmBackToSRGB = !IS_CM_AWARE,
+ .cmBackToSRGBSource = !IS_CM_AWARE ? m_monitor.lock() : nullptr,
+ });
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->popMonitorTransformEnabled();
@@ -453,6 +460,10 @@ bool CScreencopyClient::good() {
return m_resource->resource();
}
+wl_client* CScreencopyClient::client() {
+ return m_resource ? m_resource->client() : nullptr;
+}
+
CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
;
}
diff --git a/src/protocols/Screencopy.hpp b/src/protocols/Screencopy.hpp
index 665fede1..a44628fd 100644
--- a/src/protocols/Screencopy.hpp
+++ b/src/protocols/Screencopy.hpp
@@ -28,6 +28,7 @@ class CScreencopyClient {
~CScreencopyClient();
bool good();
+ wl_client* client();
WP<CScreencopyClient> m_self;
eClientOwners m_clientOwner = CLIENT_SCREENCOPY;