Commit 5165ee45 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii

[effects] Rewrite the Dim Inactive effect

Summary:
The Dim Inactive effect was rewritten mostly to fix most of issues with
it, e.g. after leaving a full screen effect(e.g. Desktop Grid) windows
sometimes are not dimmed back, or when a window becomes inactive there
is no smooth transition, etc.

{F5956124}
//Before: the window is not smoothly dimmed.//

{F5956127}
//After: the window is smoothly dimmed.//

In combination with an effect that animates the disappearing of windows,
e.g. Glide, the rewritten Dim Inactive effect doesn't "flash" windows.
If an active window has been closed, it will stay bright. If an inactive
window has been closed, it will stay dimmed.

Among other changes, the KCM has been re-designed to follow common KCM
design in Plasma:

{F5956128, layout=center, size=full}

The way the rewritten Dim Inactive effect handles flashing/flickering problem can be
reused in the Dialog Parent effect.

### Demo

{F5959885}
//Before: dimming of a window group.//

{F5959886}
//After: Dimming of a window group.//

Depends on D13740

CCBUG: 359251

Test Plan:
Test plan #1
* Activated the Desktop Grid effect
* Dimmed windows smoothly brightened
* Left desktop grid
* Windows dimmed back

Test plan #2
* Opened Dolphin and its Preferences window
* Clicked on desktop, both Dolphin and the Preferences window dimmed
* Clicked on Dolphin, both windows smoothly brightened back

Reviewers: #kwin, #plasma, #vdg, davidedmundson

Reviewed By: #kwin, #plasma, #vdg, davidedmundson

Subscribers: davidedmundson, abetts, ngraham, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D13720
parent e3815aea
This diff is collapsed.
......@@ -4,6 +4,7 @@
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
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
......@@ -22,66 +23,108 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_DIMINACTIVE_H
#define KWIN_DIMINACTIVE_H
// Include with base class for effects.
// kwineffects
#include <kwineffects.h>
#include <QTimeLine>
namespace KWin
{
class DimInactiveEffect
: public Effect
class DimInactiveEffect : public Effect
{
Q_OBJECT
Q_PROPERTY(bool dimPanels READ isDimPanels)
Q_PROPERTY(bool dimDesktop READ isDimDesktop)
Q_PROPERTY(bool dimKeepAbove READ isDimKeepAbove)
Q_PROPERTY(bool dimByGroup READ isDimByGroup)
Q_PROPERTY(int dimStrength READ configuredDimStrength)
Q_PROPERTY(int dimStrength READ dimStrength)
Q_PROPERTY(bool dimPanels READ dimPanels)
Q_PROPERTY(bool dimDesktop READ dimDesktop)
Q_PROPERTY(bool dimKeepAbove READ dimKeepAbove)
Q_PROPERTY(bool dimByGroup READ dimByGroup)
public:
DimInactiveEffect();
virtual void reconfigure(ReconfigureFlags);
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
int requestedEffectChainPosition() const override {
return 50;
}
// for properties
bool isDimPanels() const {
return dim_panels;
}
bool isDimDesktop() const {
return dim_desktop;
}
bool isDimKeepAbove() const {
return dim_keepabove;
}
bool isDimByGroup() const {
return dim_by_group;
}
int configuredDimStrength() const {
return dim_strength;
}
public Q_SLOTS:
void slotWindowActivated(KWin::EffectWindow* c);
void slotWindowDeleted(KWin::EffectWindow *w);
~DimInactiveEffect() override;
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data, int time) override;
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
void postPaintScreen() override;
int requestedEffectChainPosition() const override;
bool isActive() const override;
int dimStrength() const;
bool dimPanels() const;
bool dimDesktop() const;
bool dimKeepAbove() const;
bool dimByGroup() const;
private Q_SLOTS:
void windowActivated(EffectWindow *w);
void windowClosed(EffectWindow *w);
void windowDeleted(EffectWindow *w);
void activeFullScreenEffectChanged();
private:
bool dimWindow(const EffectWindow* w) const;
QTimeLine timeline;
EffectWindow* active;
EffectWindow* previousActive;
QTimeLine previousActiveTimeline;
int dim_strength; // reduce saturation and brightness by this percentage
bool dim_panels; // do/don't dim also all panels
bool dim_desktop; // do/don't dim the desktop
bool dim_keepabove; // do/don't dim keep-above windows
bool dim_by_group; // keep visible all windows from the active window's group or only the active window
void dimWindow(WindowPaintData &data, qreal strength);
bool canDimWindow(const EffectWindow *w) const;
void scheduleInTransition(EffectWindow *w);
void scheduleGroupInTransition(EffectWindow *w);
void scheduleOutTransition(EffectWindow *w);
void scheduleGroupOutTransition(EffectWindow *w);
void scheduleRepaint(EffectWindow *w);
private:
qreal m_dimStrength;
bool m_dimPanels;
bool m_dimDesktop;
bool m_dimKeepAbove;
bool m_dimByGroup;
EffectWindow *m_activeWindow;
const EffectWindowGroup *m_activeWindowGroup;
QHash<EffectWindow*, TimeLine> m_transitions;
QHash<EffectWindow*, qreal> m_forceDim;
struct {
bool active = false;
TimeLine timeLine;
} m_fullScreenTransition;
};
} // namespace
inline int DimInactiveEffect::requestedEffectChainPosition() const
{
return 50;
}
inline bool DimInactiveEffect::isActive() const
{
return true;
}
inline int DimInactiveEffect::dimStrength() const
{
return qRound(m_dimStrength * 100.0);
}
inline bool DimInactiveEffect::dimPanels() const
{
return m_dimPanels;
}
inline bool DimInactiveEffect::dimDesktop() const
{
return m_dimDesktop;
}
inline bool DimInactiveEffect::dimKeepAbove() const
{
return m_dimKeepAbove;
}
inline bool DimInactiveEffect::dimByGroup() const
{
return m_dimByGroup;
}
} // namespace KWin
#endif
......@@ -3,6 +3,7 @@
This file is part of the KDE project.
Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
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
......@@ -19,20 +20,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "diminactive_config.h"
// KConfigSkeleton
#include "diminactiveconfig.h"
#include <config-kwin.h>
#include <kwineffects_interface.h>
#include <KLocalizedString>
#include <kconfiggroup.h>
#include <KAboutData>
#include <KPluginFactory>
#include <QWidget>
#include <QVBoxLayout>
K_PLUGIN_FACTORY_WITH_JSON(DimInactiveEffectConfigFactory,
"diminactive_config.json",
registerPlugin<KWin::DimInactiveEffectConfig>();)
......@@ -40,35 +37,29 @@ K_PLUGIN_FACTORY_WITH_JSON(DimInactiveEffectConfigFactory,
namespace KWin
{
DimInactiveEffectConfigForm::DimInactiveEffectConfigForm(QWidget* parent) : QWidget(parent)
DimInactiveEffectConfig::DimInactiveEffectConfig(QWidget *parent, const QVariantList &args)
: KCModule(KAboutData::pluginData(QStringLiteral("diminactive")), parent, args)
{
setupUi(this);
m_ui.setupUi(this);
DimInactiveConfig::instance(KWIN_CONFIG);
addConfig(DimInactiveConfig::self(), this);
load();
}
DimInactiveEffectConfig::DimInactiveEffectConfig(QWidget* parent, const QVariantList& args) :
KCModule(KAboutData::pluginData(QStringLiteral("diminactive")), parent, args)
DimInactiveEffectConfig::~DimInactiveEffectConfig()
{
m_ui = new DimInactiveEffectConfigForm(this);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(m_ui);
DimInactiveConfig::instance(KWIN_CONFIG);
addConfig(DimInactiveConfig::self(), m_ui);
load();
}
void DimInactiveEffectConfig::save()
{
KCModule::save();
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Effects"),
QDBusConnection::sessionBus());
interface.reconfigureEffect(QStringLiteral("diminactive"));
}
} // namespace
} // namespace KWin
#include "diminactive_config.moc"
......@@ -3,6 +3,7 @@
This file is part of the KDE project.
Copyright (C) 2007 Christian Nitschkowski <christian.nitschkowski@kdemail.net>
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
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
......@@ -21,32 +22,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_DIMINACTIVE_CONFIG_H
#define KWIN_DIMINACTIVE_CONFIG_H
#include <kcmodule.h>
#include <KCModule>
#include "ui_diminactive_config.h"
namespace KWin
{
class DimInactiveEffectConfigForm : public QWidget, public Ui::DimInactiveEffectConfigForm
{
Q_OBJECT
public:
explicit DimInactiveEffectConfigForm(QWidget* parent);
};
class DimInactiveEffectConfig : public KCModule
{
Q_OBJECT
public:
explicit DimInactiveEffectConfig(QWidget* parent = 0, const QVariantList& args = QVariantList());
explicit DimInactiveEffectConfig(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
~DimInactiveEffectConfig() override;
virtual void save();
void save() override;
private:
DimInactiveEffectConfigForm* m_ui;
::Ui::DimInactiveEffectConfig m_ui;
};
} // namespace
} // namespace KWin
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KWin::DimInactiveEffectConfigForm</class>
<widget class="QWidget" name="KWin::DimInactiveEffectConfigForm">
<class>DimInactiveEffectConfig</class>
<widget class="QWidget" name="DimInactiveEffectConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>298</width>
<height>161</height>
<width>400</width>
<height>160</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="kcfg_DimPanels">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_Strength">
<property name="text">
<string>Apply effect to &amp;panels</string>
<string>Strength:</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="kcfg_DimDesktop">
<property name="text">
<string>Apply effect to the desk&amp;top</string>
<item row="0" column="1">
<widget class="QSpinBox" name="kcfg_Strength">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="kcfg_DimKeepAbove">
<item row="1" column="0">
<widget class="QLabel" name="label_Dim">
<property name="text">
<string>Apply effect to &amp;keep-above windows</string>
<string>Dim:</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="kcfg_DimByGroup">
<item row="1" column="1">
<widget class="QCheckBox" name="kcfg_DimPanels">
<property name="text">
<string>Apply effect to &amp;groups</string>
<string>Docks and panels</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<item row="2" column="1">
<widget class="QCheckBox" name="kcfg_DimDesktop">
<property name="text">
<string>&amp;Strength:</string>
</property>
<property name="buddy">
<cstring>kcfg_Strength</cstring>
<string>Desktop</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="kcfg_sliderStrength">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>25</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="3" column="1">
<widget class="QCheckBox" name="kcfg_DimKeepAbove">
<property name="text">
<string>Keep above windows</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="kcfg_Strength">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>25</number>
<item row="4" column="1">
<widget class="QCheckBox" name="kcfg_DimByGroup">
<property name="text">
<string>By window group</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>kcfg_sliderStrength</tabstop>
<tabstop>kcfg_Strength</tabstop>
<tabstop>kcfg_DimPanels</tabstop>
<tabstop>kcfg_DimDesktop</tabstop>
<tabstop>kcfg_DimByGroup</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>kcfg_Strength</sender>
<signal>valueChanged(int)</signal>
<receiver>kcfg_sliderStrength</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>288</x>
<y>29</y>
</hint>
<hint type="destinationlabel">
<x>195</x>
<y>26</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_sliderStrength</sender>
<signal>valueChanged(int)</signal>
<receiver>kcfg_Strength</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>136</x>
<y>26</y>
</hint>
<hint type="destinationlabel">
<x>288</x>
<y>29</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment