diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -82,6 +82,7 @@ flipswitch/flipswitch.cpp glide/glide.cpp invert/invert.cpp + colorsimulation/colorsimulation.cpp lookingglass/lookingglass.cpp magiclamp/magiclamp.cpp magnifier/magnifier.cpp @@ -173,6 +174,7 @@ add_subdirectory( flipswitch ) add_subdirectory( glide ) add_subdirectory( invert ) +add_subdirectory( colorsimulation ) add_subdirectory( lookingglass ) add_subdirectory( magnifier ) add_subdirectory( mouseclick ) diff --git a/effects/colorsimulation/CMakeLists.txt b/effects/colorsimulation/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/CMakeLists.txt @@ -0,0 +1,26 @@ +####################################### +# Effect + +####################################### +# Config +set(kwin_colorsimulation_config_SRCS colorsimulation_config.cpp) +qt5_add_dbus_interface(kwin_colorsimulation_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface) + +add_library(kwin_colorsimulation_config MODULE ${kwin_colorsimulation_config_SRCS}) + +target_link_libraries(kwin_colorsimulation_config + KF5::ConfigWidgets + KF5::GlobalAccel + KF5::I18n + KF5::Service + KF5::XmlGui +) + +kcoreaddons_desktop_to_json(kwin_colorsimulation_config colorsimulation_config.desktop SERVICE_TYPES kcmodule.desktop) + +install( + TARGETS + kwin_colorsimulation_config + DESTINATION + ${PLUGIN_INSTALL_DIR}/kwin/effects/configs +) diff --git a/effects/colorsimulation/colorsimulation.h b/effects/colorsimulation/colorsimulation.h new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/colorsimulation.h @@ -0,0 +1,88 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks +Copyright (C) 2008 Lucas Murray +Copyright (C) 2017 Volker Krause +Copyright (C) 2017 Frederik Gladhorn + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#ifndef KWIN_COLORSIMULATION_H +#define KWIN_COLORSIMULATION_H + +#include + +namespace KWin +{ + +class GLShader; + +/** + * ColorSimulations desktop's colors + **/ +class ColorSimulationEffect + : public Effect +{ + Q_OBJECT +public: + enum SimulationType { + Deuteranopia, + Deuteranomaly, + Protanopia, + Protanomaly, + Tritanopia, + Tritanomaly, + Monochromacy, + PartialMonochromacy, + NoSimulation + }; + + ColorSimulationEffect(); + ~ColorSimulationEffect(); + + virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data); + virtual void prePaintScreen(ScreenPrePaintData &data, int time); + virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time); + virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data); + virtual void paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity); + virtual bool isActive() const; + virtual bool provides(Feature); + + static bool supported(); + +public Q_SLOTS: + void toggleFullScreenSimulation(); + void toggleWindow(); + void slotWindowClosed(KWin::EffectWindow *w); + +protected: + bool loadData(); + void cycleSimulationType(); + +private: + bool m_inited; + bool m_valid; + SimulationType m_type; + GLShader* m_shader; + bool m_allWindows; + EffectWindow* m_window; + QScopedPointer m_effectLabel; +}; + +} // namespace + +#endif diff --git a/effects/colorsimulation/colorsimulation.cpp b/effects/colorsimulation/colorsimulation.cpp new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/colorsimulation.cpp @@ -0,0 +1,240 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks +Copyright (C) 2008 Lucas Murray +Copyright (C) 2017 Volker Krause +Copyright (C) 2017 Frederik Gladhorn + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#include "colorsimulation.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace KWin +{ + +struct SimulationParameters +{ + const char *name; + float blindness_cp_uv_1; + float blindness_cp_uv_2; + float blindness_am; + float blindness_ayi; + float anomalize; +}; + +static const SimulationParameters simu_params[] { + { I18N_NOOP("Deuteranopia"), 1.14, -0.14, 0.968437165845054, 0.003331901843109, 1.0 }, + { I18N_NOOP("Deuteranomaly"), 1.14, -0.14, 0.968437165845054, 0.003331901843109, 0.66 }, + { I18N_NOOP("Protanopia"), 0.735, 0.265, 1.27346303764196, -0.073894934000202, 1.0 }, + { I18N_NOOP("Protanomaly"), 0.735, 0.265, 1.27346303764196, -0.073894934000202, 0.66 }, + { I18N_NOOP("Tritanopia"), 0.171, -0.003, 0.062921822838841, 0.292119915539522, 1.0 }, + { I18N_NOOP("Tritanomaly"), 0.171, -0.003, 0.062921822838841, 0.292119915539522, 0.66 }, + { I18N_NOOP("Monochromacy"), 0, 0, 0, 0, -1.0 }, + { I18N_NOOP("Partial Monochromacy"), 0, 0, 0, 0, -0.66 } +}; + +ColorSimulationEffect::ColorSimulationEffect() + : m_inited(false), + m_valid(true), + m_type(NoSimulation), + m_shader(NULL), + m_allWindows(false), + m_window(nullptr), + m_effectLabel(effects->effectFrame(EffectFrameUnstyled, false)) +{ + m_effectLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); + cycleSimulationType(); + + QAction* a = new QAction(this); + a->setObjectName(QStringLiteral("ColorSimulation")); + a->setText(i18n("Toggle ColorSimulation Effect")); + KGlobalAccel::self()->setDefaultShortcut(a, QList() << Qt::CTRL + Qt::META + Qt::Key_I); + KGlobalAccel::self()->setShortcut(a, QList() << Qt::CTRL + Qt::META + Qt::Key_I); + effects->registerGlobalShortcut(Qt::CTRL + Qt::META + Qt::Key_I, a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(toggleFullScreenSimulation())); + + QAction* b = new QAction(this); + b->setObjectName(QStringLiteral("ColorSimulationWindow")); + b->setText(i18n("Toggle ColorSimulation Effect on Window")); + KGlobalAccel::self()->setDefaultShortcut(b, QList() << Qt::CTRL + Qt::META + Qt::Key_U); + KGlobalAccel::self()->setShortcut(b, QList() << Qt::CTRL + Qt::META + Qt::Key_U); + effects->registerGlobalShortcut(Qt::CTRL + Qt::META + Qt::Key_U, b); + connect(b, SIGNAL(triggered(bool)), this, SLOT(toggleWindow())); + + connect(effects, SIGNAL(windowClosed(KWin::EffectWindow*)), this, SLOT(slotWindowClosed(KWin::EffectWindow*))); +} + +ColorSimulationEffect::~ColorSimulationEffect() +{ + delete m_shader; +} + +bool ColorSimulationEffect::supported() +{ + return effects->compositingType() == OpenGL2Compositing; +} + +bool ColorSimulationEffect::loadData() +{ + m_inited = true; + + m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("colorsimulation.frag")); + if (!m_shader->isValid()) { + qCCritical(KWINEFFECTS) << "The shader failed to load!"; + return false; + } + + return true; +} + +void ColorSimulationEffect::prePaintScreen(ScreenPrePaintData &data, int time) +{ + effects->prePaintScreen(data, time); +} + +void ColorSimulationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) +{ + if (m_valid && (m_window == w)) { + data.mask |= PAINT_WINDOW_TRANSFORMED; + } + effects->prePaintWindow(w, data, time); +} + +void ColorSimulationEffect::paintScreen(int mask, QRegion region, ScreenPaintData &data) +{ + effects->paintScreen(mask, region, data); + double opacity = 1.0; + double frameOpacity = 1.0; + if (m_allWindows) { + m_effectLabel->render(infiniteRegion(), opacity, frameOpacity); + } +} + +void ColorSimulationEffect::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) +{ + // Load if we haven't already + if (m_valid && !m_inited) + m_valid = loadData(); + + bool useShader = m_valid && (m_window == w || m_allWindows); + if (useShader) { + ShaderManager *shaderManager = ShaderManager::instance(); + shaderManager->pushShader(m_shader); + + m_shader->setUniform("blindness_cp_uv", QVector2D(simu_params[m_type].blindness_cp_uv_1, simu_params[m_type].blindness_cp_uv_2)); + m_shader->setUniform("blindness_am", simu_params[m_type].blindness_am); + m_shader->setUniform("blindness_ayi", simu_params[m_type].blindness_ayi); + m_shader->setUniform("anomalize", simu_params[m_type].anomalize); + + data.shader = m_shader; + } + + effects->drawWindow(w, mask, region, data); + + if (useShader) { + ShaderManager::instance()->popShader(); + if (m_window) { + m_effectLabel->setPosition(w->pos() + QPoint(10, 10)); + m_effectLabel->render(region); + } + } +} + +void ColorSimulationEffect::paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity) +{ + if (m_valid && m_allWindows) { + frame->setShader(m_shader); + ShaderBinder binder(m_shader); + effects->paintEffectFrame(frame, region, opacity, frameOpacity); + } else { + effects->paintEffectFrame(frame, region, opacity, frameOpacity); + } +} + +void ColorSimulationEffect::slotWindowClosed(EffectWindow* w) +{ + if (w == m_window) { + m_window = nullptr; + } +} + +void ColorSimulationEffect::cycleSimulationType() +{ + m_type = static_cast((m_type + 1) % (NoSimulation + 1)); + if (m_type == NoSimulation) { + m_window = nullptr; + m_allWindows = false; + } else { + m_effectLabel->setText(i18n("Simulating: %1", i18n(simu_params[m_type].name))); + } +} + +void ColorSimulationEffect::toggleFullScreenSimulation() +{ + m_allWindows = true; + if (m_window) { + m_window = nullptr; + } else { + cycleSimulationType(); + } + + m_effectLabel->setPosition(QPoint(10, 10)); + effects->addRepaintFull(); +} + +void ColorSimulationEffect::toggleWindow() +{ + if (m_allWindows) { + effects->addRepaintFull(); + } + + if (!effects->activeWindow()) { + return; + } + if (m_window != effects->activeWindow()) { + m_window = effects->activeWindow(); + if (!m_allWindows) + cycleSimulationType(); + } else { + cycleSimulationType(); + } + m_allWindows = false; + effects->activeWindow()->addRepaintFull(); +} + +bool ColorSimulationEffect::isActive() const +{ + return m_valid && (m_allWindows || m_window); +} + +bool ColorSimulationEffect::provides(Feature f) +{ + return f == ColorSimulation; +} + +} // namespace + diff --git a/effects/colorsimulation/colorsimulation_config.h b/effects/colorsimulation/colorsimulation_config.h new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/colorsimulation_config.h @@ -0,0 +1,49 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#ifndef KWIN_COLORSIMULATION_CONFIG_H +#define KWIN_COLORSIMULATION_CONFIG_H + +#include + +class KShortcutsEditor; + +namespace KWin +{ + +class ColorSimulationEffectConfig : public KCModule +{ + Q_OBJECT +public: + explicit ColorSimulationEffectConfig(QWidget* parent = 0, const QVariantList& args = QVariantList()); + ~ColorSimulationEffectConfig(); + +public Q_SLOTS: + virtual void save(); + virtual void load(); + virtual void defaults(); + +private: + KShortcutsEditor* mShortcutEditor; +}; + +} // namespace + +#endif diff --git a/effects/colorsimulation/colorsimulation_config.cpp b/effects/colorsimulation/colorsimulation_config.cpp new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/colorsimulation_config.cpp @@ -0,0 +1,107 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#include "colorsimulation_config.h" +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +K_PLUGIN_FACTORY_WITH_JSON(ColorSimulationEffectConfigFactory, + "colorsimulation_config.json", + registerPlugin();) + +namespace KWin +{ + +ColorSimulationEffectConfig::ColorSimulationEffectConfig(QWidget* parent, const QVariantList& args) : + KCModule(KAboutData::pluginData(QStringLiteral("colorsimulation")), parent, args) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + + // Shortcut config. The shortcut belongs to the component "kwin"! + KActionCollection *actionCollection = new KActionCollection(this, QStringLiteral("kwin")); + actionCollection->setComponentDisplayName(i18n("KWin")); + + QAction* a = actionCollection->addAction(QStringLiteral("ColorSimulation")); + a->setText(i18n("Toggle ColorSimulation Effect")); + a->setProperty("isConfigurationAction", true); + KGlobalAccel::self()->setDefaultShortcut(a, QList() << Qt::CTRL + Qt::META + Qt::Key_I); + KGlobalAccel::self()->setShortcut(a, QList() << Qt::CTRL + Qt::META + Qt::Key_I); + + QAction* b = actionCollection->addAction(QStringLiteral("ColorSimulationWindow")); + b->setText(i18n("Toggle ColorSimulation Effect on Window")); + b->setProperty("isConfigurationAction", true); + KGlobalAccel::self()->setDefaultShortcut(b, QList() << Qt::CTRL + Qt::META + Qt::Key_U); + KGlobalAccel::self()->setShortcut(b, QList() << Qt::CTRL + Qt::META + Qt::Key_U); + + mShortcutEditor = new KShortcutsEditor(actionCollection, this, + KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed); + connect(mShortcutEditor, SIGNAL(keyChange()), this, SLOT(changed())); + layout->addWidget(mShortcutEditor); + + load(); +} + +ColorSimulationEffectConfig::~ColorSimulationEffectConfig() +{ + // Undo (only) unsaved changes to global key shortcuts + mShortcutEditor->undoChanges(); +} + +void ColorSimulationEffectConfig::load() +{ + KCModule::load(); + + emit changed(false); +} + +void ColorSimulationEffectConfig::save() +{ + KCModule::save(); + + mShortcutEditor->save(); // undo() will restore to this state from now on + + emit changed(false); + OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), + QStringLiteral("/Effects"), + QDBusConnection::sessionBus()); + interface.reconfigureEffect(QStringLiteral("colorsimulation")); +} + +void ColorSimulationEffectConfig::defaults() +{ + mShortcutEditor->allDefault(); + + emit changed(true); +} + + +} // namespace + +#include "colorsimulation_config.moc" diff --git a/effects/colorsimulation/colorsimulation_config.desktop b/effects/colorsimulation/colorsimulation_config.desktop new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/colorsimulation_config.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kwin_colorsimulation_config +X-KDE-ParentComponents=colorsimulation + +Name=Simulate Color Vision Deficiencies + diff --git a/effects/colorsimulation/data/1.40/colorsimulation.frag b/effects/colorsimulation/data/1.40/colorsimulation.frag new file mode 100644 --- /dev/null +++ b/effects/colorsimulation/data/1.40/colorsimulation.frag @@ -0,0 +1,117 @@ +/* + Based on: + https://github.com/michelf/sim-daltonism/blob/master/Filter/SimDaltonismFilter.m + + Copyright 2005-2017 Michel Fortin + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Which in turn took the simulation algorithm from: + http://colorlab.wickline.org/colorblind/colorlab/engine.js + + Copyright (c) 2000-2001 by Matthew Wickline and the + Human-Computer Interaction Resource Network ( http://hcirn.com/ ) + + This work is licensed under a + Creative Commons Attribution-ShareAlike 4.0 International License. + http://creativecommons.org/licenses/by-sa/4.0/ +*/ +#version 140 +uniform sampler2D sampler; + +in vec2 texcoord0; + +out vec4 fragColor; + +uniform vec2 blindness_cp_uv; +uniform float blindness_am; +uniform float blindness_ayi; +uniform float anomalize; + +void main() +{ + const vec4 white_xyz0 = vec4(0.312713, 0.329016, 0.358271, 0.); + const float gamma_value = 2.2; + const mat3 xyz_from_rgb_matrix = mat3( + vec3(0.430574, 0.341550, 0.178325), + vec3(0.222015, 0.706655, 0.071330), + vec3(0.020183, 0.129553, 0.939180) + ); + const mat3 rgb_from_xyz_matrix = mat3( + vec3( 3.063218, -1.393325, -0.475802), + vec3(-0.969243, 1.875966, 0.041555), + vec3( 0.067871, -0.228834, 1.069251) + ); + + vec4 pixel = texture2D(sampler, texcoord0); + if (anomalize <= 0.0) { // shortcut path + // less than zero means monochromacy filter + float m = dot(pixel.rgb, vec3(.299, .587, .114)); + fragColor = mix(pixel, vec4(m,m,m,pixel.a), -anomalize); + return; + } + + vec3 c_rgb; vec2 c_uv; vec3 c_xyz; + vec3 s_rgb; vec4 s_xyz0; + vec3 d_rgb; vec2 d_uv; vec3 d_xyz; + + // map RGB input into XYZ space... + c_rgb = pow(pixel.rgb, vec3(gamma_value, gamma_value, gamma_value)); + c_xyz = c_rgb * xyz_from_rgb_matrix; + float sum_xyz = dot(c_xyz, vec3(1., 1., 1.)); + + // map into uvY space... + c_uv = c_xyz.xy / sum_xyz; + // find neutral grey at this luminosity (we keep the same Y value) + vec4 n_xyz0 = white_xyz0 * c_xyz.yyyy / white_xyz0.yyyy; + + float clm; float clyi; + float adjust; vec4 adj; + + // cl is "confusion line" between our color and the confusion point + // clm is cl's slope, and clyi is cl's "y-intercept" (actually on the "v" axis at u=0) + vec2 cp_uv_minus_c_uv = blindness_cp_uv - c_uv; + clm = cp_uv_minus_c_uv.y / cp_uv_minus_c_uv.x; + + clyi = dot(c_uv, vec2(-clm, 1.)); + + // find the change in the u and v dimensions (no Y change) + d_uv.x = (blindness_ayi - clyi) / (clm - blindness_am); + d_uv.y = (clm * d_uv.x) + clyi; + + // find the simulated color's XYZ coords + float d_u_div_d_v = d_uv.x / d_uv.y; + s_xyz0 = c_xyz.yyyy * vec4(d_u_div_d_v, 1., ( 1. / d_uv.y - (d_u_div_d_v + 1.) ), 0.); + // and then try to plot the RGB coords + s_rgb = s_xyz0.xyz * rgb_from_xyz_matrix; + + // note the RGB differences between sim color and our neutral color + d_xyz = n_xyz0.xwz - s_xyz0.xwz; + d_rgb = d_xyz * rgb_from_xyz_matrix; + + // find out how much to shift sim color toward neutral to fit in RGB space: + adj.rgb = ( 1. - s_rgb ) / d_rgb; + adj.a = 0.; + + adj = sign(1.-adj) * adj; + adjust = max(max(0., adj.r), max(adj.g, adj.b)); + + // now shift *all* three proportional to the greatest shift... + s_rgb = s_rgb + ( adjust * d_rgb ); + + // anomalize + s_rgb = mix(c_rgb, s_rgb, anomalize); + + pixel.rgb = pow(s_rgb, vec3(1./gamma_value, 1./gamma_value, 1./gamma_value)); + fragColor = pixel; +} diff --git a/effects/effect_builtins.h b/effects/effect_builtins.h --- a/effects/effect_builtins.h +++ b/effects/effect_builtins.h @@ -48,6 +48,7 @@ Glide, HighlightWindow, Invert, + ColorSimulation, Kscreen, LookingGlass, MagicLamp, diff --git a/effects/effect_builtins.cpp b/effects/effect_builtins.cpp --- a/effects/effect_builtins.cpp +++ b/effects/effect_builtins.cpp @@ -52,6 +52,7 @@ #include "flipswitch/flipswitch.h" #include "glide/glide.h" #include "invert/invert.h" +#include "colorsimulation/colorsimulation.h" #include "lookingglass/lookingglass.h" #include "magnifier/magnifier.h" #include "mouseclick/mouseclick.h" @@ -306,6 +307,21 @@ &InvertEffect::supported, nullptr #endif +EFFECT_FALLBACK + }, { + QStringLiteral("colorsimulation"), + i18ndc("kwin_effects", "Name of a KWin Effect", "Color Simulation"), + i18ndc("kwin_effects", "Comment describing the KWin Effect", "Color Simulation"), + QStringLiteral("Accessibility"), + QString(), + QUrl(QStringLiteral()), + false, + false, +#ifdef EFFECT_BUILTINS + &createHelper, + &ColorSimulationEffect::supported, + nullptr +#endif EFFECT_FALLBACK }, { QStringLiteral("kscreen"), diff --git a/effects/shaders.qrc b/effects/shaders.qrc --- a/effects/shaders.qrc +++ b/effects/shaders.qrc @@ -17,6 +17,7 @@ cube/data/1.40/cylinder.vert cube/data/1.40/sphere.vert invert/data/1.40/invert.frag + colorsimulation/data/1.40/colorsimulation.frag logout/data/1.40/logout-blur.frag lookingglass/data/1.40/lookingglass.frag diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -356,7 +356,7 @@ }; enum Feature { - Nothing = 0, Resize, GeometryTip, Outline, ScreenInversion, Blur, Contrast, HighlightWindows + Nothing = 0, Resize, GeometryTip, Outline, ScreenInversion, Blur, Contrast, HighlightWindows, ColorSimulation }; /**