summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2025-07-15 20:33:14 +0300
committerGitHub <noreply@github.com>2025-07-15 19:33:14 +0200
commite15014e031589e1df2dc29a5ce94325676796ac4 (patch)
tree5d56992b9e6c458dd1830c4b9ea235c0391fedd8 /src
parentbc764f7065c8e46b4e62cbb511b419034712c509 (diff)
protocols/cm: Fix preferred image description (#11026)
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp2
-rw-r--r--src/helpers/Monitor.cpp11
-rw-r--r--src/protocols/ColorManagement.cpp20
-rw-r--r--src/protocols/ColorManagement.hpp8
-rw-r--r--src/protocols/core/Compositor.cpp15
-rw-r--r--src/protocols/core/Compositor.hpp2
6 files changed, 50 insertions, 8 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 8873d7f2..abfa8d84 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -3090,7 +3090,7 @@ SImageDescription CCompositor::getPreferredImageDescription() {
}
Debug::log(WARN, "FIXME: color management protocol is enabled, determine correct preferred image description");
// should determine some common settings to avoid unnecessary transformations while keeping maximum displayable precision
- return SImageDescription{.primaries = NColorPrimaries::BT709};
+ return m_monitors.size() == 1 ? m_monitors[0]->m_imageDescription : SImageDescription{.primaries = NColorPrimaries::BT709};
}
bool CCompositor::shouldChangePreferredImageDescription() {
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index 3b440e56..4e5c4080 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -412,6 +412,7 @@ void CMonitor::onDisconnect(bool destroy) {
}
void CMonitor::applyCMType(eCMType cmType) {
+ auto oldImageDescription = m_imageDescription;
switch (cmType) {
case CM_SRGB: m_imageDescription = {}; break; // assumes SImageDescirption defaults to sRGB
case CM_WIDE:
@@ -461,6 +462,11 @@ void CMonitor::applyCMType(eCMType cmType) {
m_imageDescription.luminances.max = m_maxLuminance;
if (m_maxAvgLuminance >= 0)
m_imageDescription.luminances.reference = m_maxAvgLuminance;
+
+ if (oldImageDescription != m_imageDescription) {
+ m_imageDescription.updateId();
+ PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
+ }
}
bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
@@ -783,8 +789,7 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
m_supportsWideColor = RULE->supportsHDR;
m_supportsHDR = RULE->supportsHDR;
- auto oldImageDescription = m_imageDescription;
- m_cmType = RULE->cmType;
+ m_cmType = RULE->cmType;
switch (m_cmType) {
case CM_AUTO: m_cmType = m_enabled10bit && supportsWideColor() ? CM_WIDE : CM_SRGB; break;
case CM_EDID: m_cmType = m_output->parsedEDID.chromaticityCoords.has_value() ? CM_EDID : CM_SRGB; break;
@@ -801,8 +806,6 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
m_maxAvgLuminance = RULE->maxAvgLuminance;
applyCMType(m_cmType);
- if (oldImageDescription != m_imageDescription)
- PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
m_sdrSaturation = RULE->sdrSaturation;
m_sdrBrightness = RULE->sdrBrightness;
diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp
index 502fbe45..aa01a365 100644
--- a/src/protocols/ColorManagement.cpp
+++ b/src/protocols/ColorManagement.cpp
@@ -410,14 +410,27 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP<CWpColorMana
m_currentPreferred = RESOURCE;
m_currentPreferred->m_settings = m_surface->getPreferredImageDescription();
- if (!PROTO::colorManagement->m_debug && m_currentPreferred->m_settings.icc.fd) {
+ m_currentPreferredId = m_currentPreferred->m_settings.updateId();
+
+ if (!PROTO::colorManagement->m_debug && m_currentPreferred->m_settings.icc.fd >= 0) {
LOGM(ERR, "FIXME: parse icc profile");
r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported");
return;
}
- RESOURCE->resource()->sendReady(m_currentPreferred->m_settings.updateId());
+ RESOURCE->resource()->sendReady(m_currentPreferredId);
});
+
+ m_listeners.enter = m_surface->m_events.enter.listen([this](const auto& monitor) { onPreferredChanged(); });
+ m_listeners.leave = m_surface->m_events.leave.listen([this](const auto& monitor) { onPreferredChanged(); });
+}
+
+void CColorManagementFeedbackSurface::onPreferredChanged() {
+ if (m_surface->m_enteredOutputs.size() == 1) {
+ const auto newId = m_surface->getPreferredImageDescription().updateId();
+ if (m_currentPreferredId != newId)
+ m_resource->sendPreferredChanged(newId);
+ }
}
bool CColorManagementFeedbackSurface::good() {
@@ -796,6 +809,9 @@ void CColorManagementProtocol::onMonitorImageDescriptionChanged(WP<CMonitor> mon
if (output->m_monitor == monitor)
output->m_resource->sendImageDescriptionChanged();
}
+ // recheck feedbacks
+ for (auto const& feedback : m_feedbackSurfaces)
+ feedback->onPreferredChanged();
}
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp
index fc3a8d54..1d2795ed 100644
--- a/src/protocols/ColorManagement.hpp
+++ b/src/protocols/ColorManagement.hpp
@@ -89,6 +89,14 @@ class CColorManagementFeedbackSurface {
wl_client* m_client = nullptr;
WP<CColorManagementImageDescription> m_currentPreferred;
+ uint32_t m_currentPreferredId = 0;
+
+ struct {
+ CHyprSignalListener enter;
+ CHyprSignalListener leave;
+ } m_listeners;
+
+ void onPreferredChanged();
friend class CColorManagementProtocol;
};
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index 58d7810c..21f9e0a7 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -307,6 +307,7 @@ void CWLSurfaceResource::enter(PHLMONITOR monitor) {
m_enteredOutputs.emplace_back(monitor);
m_resource->sendEnter(output->getResource().get());
+ m_events.enter.emit(monitor);
}
void CWLSurfaceResource::leave(PHLMONITOR monitor) {
@@ -323,6 +324,7 @@ void CWLSurfaceResource::leave(PHLMONITOR monitor) {
std::erase(m_enteredOutputs, monitor);
m_resource->sendLeave(output->getResource().get());
+ m_events.leave.emit(monitor);
}
void CWLSurfaceResource::sendPreferredTransform(wl_output_transform t) {
@@ -539,7 +541,18 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) {
}
SImageDescription CWLSurfaceResource::getPreferredImageDescription() {
- return m_enteredOutputs.size() == 1 ? m_enteredOutputs[0]->m_imageDescription : g_pCompositor->getPreferredImageDescription();
+ auto parent = m_self;
+ if (parent->m_role->role() == SURFACE_ROLE_SUBSURFACE) {
+ auto subsurface = ((CSubsurfaceRole*)parent->m_role.get())->m_subsurface.lock();
+ parent = subsurface->t1Parent();
+ }
+ WP<CMonitor> monitor;
+ if (parent->m_enteredOutputs.size() == 1)
+ monitor = parent->m_enteredOutputs[0];
+ else if (m_hlSurface.valid() && m_hlSurface->getWindow())
+ monitor = m_hlSurface->getWindow()->m_monitor;
+
+ return monitor ? monitor->m_imageDescription : g_pCompositor->getPreferredImageDescription();
}
void CWLSurfaceResource::updateCursorShm(CRegion damage) {
diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp
index 8f1f8064..cfbc3ea8 100644
--- a/src/protocols/core/Compositor.hpp
+++ b/src/protocols/core/Compositor.hpp
@@ -87,6 +87,8 @@ class CWLSurfaceResource {
CSignalT<> unmap;
CSignalT<SP<CWLSubsurfaceResource>> newSubsurface;
CSignalT<> destroy;
+ CSignalT<SP<CMonitor>> enter;
+ CSignalT<SP<CMonitor>> leave;
} m_events;
SSurfaceState m_current;