diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 1e06ee03..f33f6900 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -153,10 +153,11 @@ void CCompositor::initServer() { wlr_export_dmabuf_manager_v1_create(m_sWLDisplay); wlr_data_control_manager_v1_create(m_sWLDisplay); - wlr_gamma_control_manager_v1_create(m_sWLDisplay); wlr_primary_selection_v1_device_manager_create(m_sWLDisplay); wlr_viewporter_create(m_sWLDisplay); + m_sWLRGammaCtrlMgr = wlr_gamma_control_manager_v1_create(m_sWLDisplay); + m_sWLROutputLayout = wlr_output_layout_create(); m_sWLROutputPowerMgr = wlr_output_power_manager_v1_create(m_sWLDisplay); @@ -294,6 +295,7 @@ void CCompositor::initAllSignals() { addWLSignal(&m_sWLRTextInputMgr->events.text_input, &Events::listen_newTextInput, m_sWLRTextInputMgr, "TextInputMgr"); addWLSignal(&m_sWLRActivation->events.request_activate, &Events::listen_activateXDG, m_sWLRActivation, "ActivationV1"); addWLSignal(&m_sWLRSessionLockMgr->events.new_lock, &Events::listen_newSessionLock, m_sWLRSessionLockMgr, "SessionLockMgr"); + addWLSignal(&m_sWLRGammaCtrlMgr->events.set_gamma, &Events::listen_setGamma, m_sWLRGammaCtrlMgr, "GammaCtrlMgr"); if (m_sWRLDRMLeaseMgr) addWLSignal(&m_sWRLDRMLeaseMgr->events.request, &Events::listen_leaseRequest, &m_sWRLDRMLeaseMgr, "DRM"); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 405136a5..3cb0af62 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -84,6 +84,7 @@ class CCompositor { wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf; wlr_backend* m_sWLRHeadlessBackend; wlr_session_lock_manager_v1* m_sWLRSessionLockMgr; + wlr_gamma_control_manager_v1* m_sWLRGammaCtrlMgr; // ------------------------------------------------- // std::string m_szWLDisplaySocket = ""; diff --git a/src/events/Events.hpp b/src/events/Events.hpp index 472d7cb5..b032b11e 100644 --- a/src/events/Events.hpp +++ b/src/events/Events.hpp @@ -166,4 +166,7 @@ namespace Events { // Session Lock LISTENER(newSessionLock); + + // Gamma control + LISTENER(setGamma); }; diff --git a/src/events/Misc.cpp b/src/events/Misc.cpp index a360090f..da680a00 100644 --- a/src/events/Misc.cpp +++ b/src/events/Misc.cpp @@ -214,3 +214,20 @@ void Events::listener_newSessionLock(wl_listener* listener, void* data) { g_pSessionLockManager->onNewSessionLock((wlr_session_lock_v1*)data); } + +void Events::listener_setGamma(wl_listener* listener, void* data) { + Debug::log(LOG, "New Gamma event at %lx", data); + + const auto E = (wlr_gamma_control_manager_v1_set_gamma_event*)data; + + const auto PMONITOR = g_pCompositor->getMonitorFromOutput(E->output); + + if (!PMONITOR) { + Debug::log(ERR, "Gamma event object references non-existent output %lx ?", E->output); + return; + } + + PMONITOR->gammaChanged = true; + + g_pCompositor->scheduleFrameForMonitor(PMONITOR); +} diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 28dad111..9226e100 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -43,6 +43,7 @@ class CMonitor { bool noFrameSchedule = false; bool scheduledRecalc = false; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; + bool gammaChanged = false; bool dpmsStatus = true; bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index ce8cb0ff..5b61e70f 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -860,6 +860,24 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitor->ID); } + // gamma stuff + if (pMonitor->gammaChanged) { + pMonitor->gammaChanged = false; + + const auto PGAMMACTRL = wlr_gamma_control_manager_v1_get_control(g_pCompositor->m_sWLRGammaCtrlMgr, pMonitor->output); + + if (!wlr_gamma_control_v1_apply(PGAMMACTRL, &pMonitor->output->pending)) { + Debug::log(ERR, "Could not apply gamma control to %s", pMonitor->szName.c_str()); + return; + } + + if (!wlr_output_test(pMonitor->output)) { + Debug::log(ERR, "Output test failed for setting gamma to %s", pMonitor->szName.c_str()); + wlr_output_rollback(pMonitor->output); + wlr_gamma_control_v1_send_failed_and_destroy(PGAMMACTRL); + } + } + // Direct scanout first if (!*PNODIRECTSCANOUT) { if (attemptDirectScanout(pMonitor)) {