plugins/colorblindnesscorrection: support adjusting intensity

Though there are 3 common CVD types, each individual can have different
color perception level, and the default intensity might not be suitable
for everyone, so add an intensity slider to select how much the filter
affects the display.
This commit is contained in:
Fushan Wen 2023-10-15 16:00:23 +08:00
parent 1f1c54ca6c
commit f650ebe2fc
No known key found for this signature in database
GPG key ID: 2E48D1487C91DCAA
12 changed files with 63 additions and 24 deletions

View file

@ -6,7 +6,13 @@ kwin_add_builtin_effect(colorblindnesscorrection
colorblindnesscorrection.qrc
main.cpp
)
kconfig_add_kcfg_files(colorblindnesscorrection colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
set(SETTINGS_HEADER "colorblindnesscorrection_settings_singleton")
set(GENERATE_MOC "false")
set(USE_SINGLETON "true")
set(KCFGFILE_ARGS "arg=\"true\"")
configure_file(colorblindnesscorrection_settings.kcfgc.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc @ONLY)
configure_file(colorblindnesscorrection_settings.kcfg.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfg @ONLY)
kconfig_add_kcfg_files(colorblindnesscorrection ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc)
target_link_libraries(colorblindnesscorrection PRIVATE
kwin
@ -19,14 +25,20 @@ if (NOT KWIN_BUILD_KCMS)
return()
endif()
set(SETTINGS_HEADER "colorblindnesscorrection_settings")
kcmutils_add_qml_kcm(kwin_colorblindnesscorrection_config SOURCES colorblindnesscorrection_config.cpp INSTALL_NAMESPACE "kwin/effects/configs" DISABLE_DESKTOP_FILE_GENERATION)
kcmutils_generate_module_data(kwin_colorblindnesscorrection_config
MODULE_DATA_HEADER colorblindnesscorrection_settingsdata.h
MODULE_DATA_CLASS_NAME ColorBlindnessCorrectionSettingsData
SETTINGS_HEADERS colorblindnesscorrection_settings.h
SETTINGS_HEADERS ${SETTINGS_HEADER}.h
SETTINGS_CLASSES ColorBlindnessCorrectionSettings
)
kconfig_add_kcfg_files(kwin_colorblindnesscorrection_config colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
set(GENERATE_MOC "true")
set(USE_SINGLETON "false")
set(KCFGFILE_ARGS "name=\"kwinrc\"")
configure_file(colorblindnesscorrection_settings.kcfgc.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfgc @ONLY)
configure_file(colorblindnesscorrection_settings.kcfg.in ${CMAKE_CURRENT_BINARY_DIR}/${SETTINGS_HEADER}.kcfg @ONLY)
kconfig_add_kcfg_files(kwin_colorblindnesscorrection_config ${CMAKE_CURRENT_BINARY_DIR}/colorblindnesscorrection_settings.kcfgc GENERATE_MOC)
target_link_libraries(kwin_colorblindnesscorrection_config
KF6::ConfigCore
KF6::KCMUtils

View file

@ -6,12 +6,10 @@
#include "colorblindnesscorrection.h"
#include <KSharedConfig>
#include "effect/effecthandler.h"
#include "opengl/glshader.h"
#include "colorblindnesscorrection_settings.h"
#include "colorblindnesscorrection_settings_singleton.h"
Q_LOGGING_CATEGORY(KWIN_COLORBLINDNESS_CORRECTION, "kwin_effect_colorblindnesscorrection", QtWarningMsg)
@ -26,8 +24,11 @@ namespace KWin
ColorBlindnessCorrectionEffect::ColorBlindnessCorrectionEffect()
: OffscreenEffect()
, m_mode(static_cast<Mode>(ColorBlindnessCorrectionSettings().mode()))
{
ColorBlindnessCorrectionSettings::instance(effects->config());
m_mode = static_cast<Mode>(ColorBlindnessCorrectionSettings::mode());
m_intensity = std::clamp<float>(ColorBlindnessCorrectionSettings::intensity(), 0.0f, 1.0f);
loadData();
}
@ -65,6 +66,10 @@ void ColorBlindnessCorrectionEffect::loadData()
return;
}
if (ShaderBinder binder{m_shader.get()}; !m_shader->setUniform("intensity", m_intensity)) {
qCWarning(KWIN_COLORBLINDNESS_CORRECTION) << "Failed to set intensity";
}
for (const auto windows = effects->stackingOrder(); EffectWindow * w : windows) {
correctColor(w);
}
@ -108,12 +113,15 @@ void ColorBlindnessCorrectionEffect::reconfigure(ReconfigureFlags flags)
return;
}
auto newMode = static_cast<Mode>(ColorBlindnessCorrectionSettings().mode());
if (m_mode == newMode) {
ColorBlindnessCorrectionSettings::self()->read();
const auto newMode = static_cast<Mode>(ColorBlindnessCorrectionSettings::mode());
const auto newIntensity = std::clamp<float>(ColorBlindnessCorrectionSettings::intensity(), 0.0f, 1.0f);
if (m_mode == newMode && qFuzzyCompare(m_intensity, newIntensity)) {
return;
}
m_mode = newMode;
m_intensity = newIntensity;
disconnect(effects, &EffectsHandler::windowDeleted, this, &ColorBlindnessCorrectionEffect::slotWindowDeleted);
disconnect(effects, &EffectsHandler::windowAdded, this, &ColorBlindnessCorrectionEffect::correctColor);

View file

@ -48,6 +48,7 @@ private:
void loadData();
Mode m_mode = Protanopia;
float m_intensity = 1.0f;
std::unordered_set<KWin::EffectWindow *> m_windows;
std::unique_ptr<GLShader> m_shader;

View file

@ -7,10 +7,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="kwinrc" />
<kcfgfile @KCFGFILE_ARGS@/>
<group name="Effect-colorblindnesscorrection">
<entry name="Mode" type="UInt">
<default>0</default>
</entry>
<entry name="Intensity" type="Double">
<default>1.0</default>
</entry>
</group>
</kcfg>

View file

@ -1,9 +1,10 @@
# SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
File=colorblindnesscorrection_settings.kcfg
File=@SETTINGS_HEADERS@.kcfg
ClassName=ColorBlindnessCorrectionSettings
DefaultValueGetters=@GENERATE_MOC@
GenerateProperties=@GENERATE_MOC@
ParentInConstructor=@GENERATE_MOC@
Singleton=@USE_SINGLETON@
Mutators=true
DefaultValueGetters=true
GenerateProperties=true
ParentInConstructor=true

View file

@ -3,6 +3,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
varying vec2 texcoord0;
void main()
@ -27,7 +28,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -4,7 +4,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
in vec2 texcoord0;
out vec4 fragColor;
@ -30,7 +30,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -3,6 +3,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
varying vec2 texcoord0;
void main()
@ -27,7 +28,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -4,7 +4,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
in vec2 texcoord0;
out vec4 fragColor;
@ -30,7 +30,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -3,6 +3,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
varying vec2 texcoord0;
void main()
@ -27,7 +28,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -4,7 +4,7 @@
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
uniform float intensity;
in vec2 texcoord0;
out vec4 fragColor;
@ -30,7 +30,7 @@ void main()
vec3 error = vec3((0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
(-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
(-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s));
vec3 diff = tex.rgb - error;
vec3 diff = (tex.rgb - error) * vec3(intensity);
vec3 correction = vec3(0.0,
(diff.r * 0.7) + (diff.g * 1.0),
(diff.r * 0.7) + (diff.b * 1.0));

View file

@ -16,7 +16,7 @@ KCM.SimpleKCM {
id: root
implicitWidth: Kirigami.Units.gridUnit * 30
implicitHeight: Kirigami.Units.gridUnit * 22
implicitHeight: Kirigami.Units.gridUnit * 24
RowLayout {
id: previewArea
@ -67,6 +67,7 @@ KCM.SimpleKCM {
}
QQC.ComboBox {
id: colorComboBox
Kirigami.FormData.label: i18nc("@label", "Mode:")
currentIndex: kcm.settings.mode
textRole: "text"
@ -79,5 +80,15 @@ KCM.SimpleKCM {
onActivated: kcm.settings.mode = currentValue
}
QQC.Slider {
Kirigami.FormData.label: i18nc("@label", "Intensity:")
Layout.preferredWidth: colorComboBox.implicitWidth
from: 0.0
to: 1.0
value: kcm.settings.intensity
onMoved: kcm.settings.intensity = value
}
}
}