kwin/effects/translucency/translucency.cpp
Martin Gräßlin 509daa60a1 Use KConfigXT in Translucency Effect
Port the KCM to use KConfigXT which means that the complete custom code
for loading, saving and setting to defaults can be dropped.

Also in the effect in brings some advantages as we basically get compile
time checks whether the accessed config is named correctly.

The saved values for translucency are now UInts in [0,100] instead of
doubles in [0.0,1.0], so an update script is needed.

REVIEW: 106310
2012-11-09 08:53:22 +01:00

265 lines
9.2 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "translucency.h"
// KConfigSkeleton
#include "translucencyconfig.h"
#include <kconfiggroup.h>
namespace KWin
{
KWIN_EFFECT(translucency, TranslucencyEffect)
TranslucencyEffect::TranslucencyEffect()
: m_activeDecorations(false)
, m_activeMoveResize(false)
, m_activeDialogs(false)
, m_activeInactive(false)
, m_activeCombobox(false)
, m_activeMenus(false)
, m_active(false)
{
reconfigure(ReconfigureAll);
active = effects->activeWindow();
connect(effects, SIGNAL(windowActivated(KWin::EffectWindow*)), this, SLOT(slotWindowActivated(KWin::EffectWindow*)));
connect(effects, SIGNAL(windowAdded(KWin::EffectWindow*)), this, SLOT(checkIsActive()));
connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(checkIsActive()));
connect(effects, SIGNAL(windowStartUserMovedResized(KWin::EffectWindow*)), this, SLOT(slotWindowStartStopUserMovedResized(KWin::EffectWindow*)));
connect(effects, SIGNAL(windowFinishUserMovedResized(KWin::EffectWindow*)), this, SLOT(slotWindowStartStopUserMovedResized(KWin::EffectWindow*)));
}
void TranslucencyEffect::reconfigure(ReconfigureFlags)
{
TranslucencyConfig::self()->readConfig();
decoration = TranslucencyConfig::decoration()/100.0;
moveresize = TranslucencyConfig::moveResize()/100.0;
dialogs = TranslucencyConfig::dialogs()/100.0;
inactive = TranslucencyConfig::inactive()/100.0;
comboboxpopups = TranslucencyConfig::comboboxPopups()/100.0;
menus = TranslucencyConfig::menus()/100.0;
individualmenuconfig = TranslucencyConfig::individualMenuConfig();
if (individualmenuconfig) {
dropdownmenus = TranslucencyConfig::dropdownMenus()/100.0;
popupmenus = TranslucencyConfig::popupMenus()/100.0;
tornoffmenus = TranslucencyConfig::tornOffMenus()/100.0;
} else {
dropdownmenus = menus;
popupmenus = menus;
tornoffmenus = menus;
}
m_activeDecorations = !qFuzzyCompare(decoration, 1.0);
m_activeMoveResize = !qFuzzyCompare(moveresize, 1.0);
m_activeDialogs = !qFuzzyCompare(dialogs, 1.0);
m_activeInactive = !qFuzzyCompare(inactive, 1.0);
m_activeCombobox = !qFuzzyCompare(comboboxpopups, 1.0);
m_activeMenus = !qFuzzyCompare(menus, 1.0);
if (!m_activeMenus && individualmenuconfig) {
m_activeMenus = !qFuzzyCompare(dropdownmenus, 1.0) ||
!qFuzzyCompare(popupmenus, 1.0) ||
!qFuzzyCompare(tornoffmenus, 1.0);
}
checkIsActive();
// Repaint the screen just in case the user changed the inactive opacity
effects->addRepaintFull();
}
void TranslucencyEffect::checkIsActive()
{
m_active = m_activeDecorations ||
m_activeMoveResize ||
m_activeDialogs ||
m_activeInactive ||
m_activeCombobox ||
m_activeMenus;
if (!m_active) {
// all individual options are disabled, no window state can activate it
return;
}
if (m_activeDecorations) {
// we can assume that there is at least one decorated window, so the effect is active
return;
}
if (m_activeInactive) {
// we can assume that there is at least one inactive window, so the effect is active
// TODO: maybe only if inactive window is not obscured?
return;
}
// for all other options we go through the list of window and search for a Window being affected
bool activeDropdown, activePopup, activeTornoff;
activeDropdown = activePopup = activeTornoff = false;
if (individualmenuconfig) {
activeDropdown = !qFuzzyCompare(dropdownmenus, 1.0);
activePopup = !qFuzzyCompare(popupmenus, 1.0);
activeTornoff = !qFuzzyCompare(activeTornoff, 1.0);
}
foreach (EffectWindow *w, effects->stackingOrder()) {
if (w->isDeleted()) {
// ignore deleted windows
continue;
}
if (m_activeMoveResize && (w->isUserMove() || w->isUserResize())) {
return;
}
if (m_activeDialogs && w->isDialog()) {
return;
}
if (m_activeCombobox && w->isComboBox()) {
return;
}
if (m_activeMenus) {
if (individualmenuconfig) {
if (activeDropdown && w->isDropdownMenu()) {
return;
}
if (activePopup && w->isPopupMenu()) {
return;
}
if (activeTornoff && w->isMenu()) {
return;
}
} else {
if (w->isMenu() || w->isDropdownMenu() || w->isPopupMenu()) {
return;
}
}
}
}
// no matching window, disable effect
m_active = false;
}
void TranslucencyEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
{
if (m_activeDecorations && w->hasDecoration()) {
data.mask |= PAINT_WINDOW_TRANSLUCENT;
// don't clear PAINT_WINDOW_OPAQUE, contents are not affected
data.clip &= w->contentsRect().translated(w->pos()); // decoration cannot clip
}
if (m_activeInactive && isInactive(w))
data.setTranslucent();
else if (m_activeMoveResize && (w->isUserMove() || w->isUserResize())) {
data.setTranslucent();
}
else if (m_activeDialogs && w->isDialog()) {
data.setTranslucent();
}
else if (m_activeMenus && (dropdownmenus != 1.0 && w->isDropdownMenu())
|| (popupmenus != 1.0 && w->isPopupMenu())
|| (tornoffmenus != 1.0 && w->isMenu())
|| (comboboxpopups != 1.0 && w->isComboBox())) {
data.setTranslucent();
}
effects->prePaintWindow(w, data, time);
}
void TranslucencyEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
{
if (w->isDesktop() || w->isDock()) {
effects->paintWindow(w, mask, region, data);
return;
}
// Handling active and inactive windows
if (m_activeInactive && isInactive(w)) {
data.multiplyOpacity(inactive);
} else {
// decoration and dialogs
if (m_activeDecorations && w->hasDecoration())
data.multiplyDecorationOpacity(decoration);
if (m_activeDialogs && w->isDialog())
data.multiplyOpacity(dialogs);
// Handling moving and resizing
if (m_activeMoveResize && (w->isUserMove() || w->isUserResize())) {
data.multiplyOpacity(moveresize);
}
// Menus and combos
if (m_activeMenus) {
if (dropdownmenus != 1.0 && w->isDropdownMenu())
data.multiplyOpacity(dropdownmenus);
if (popupmenus != 1.0 && w->isPopupMenu())
data.multiplyOpacity(popupmenus);
if (tornoffmenus != 1.0 && w->isMenu())
data.multiplyOpacity(tornoffmenus);
if (comboboxpopups != 1.0 && w->isComboBox())
data.multiplyOpacity(comboboxpopups);
}
}
effects->paintWindow(w, mask, region, data);
}
bool TranslucencyEffect::isInactive(const EffectWindow* w) const
{
if (active == w || w->isDock() || !w->isManaged())
return false;
if (NULL != active && NULL != active->group())
if (active->group() == w->group())
return false;
if (!w->isNormalWindow() && !w->isDialog() && !w->isDock())
return false;
return true;
}
void TranslucencyEffect::slotWindowStartStopUserMovedResized(EffectWindow* w)
{
if (m_activeMoveResize) {
checkIsActive();
w->addRepaintFull();
}
}
void TranslucencyEffect::slotWindowActivated(EffectWindow* w)
{
if (m_activeInactive) {
if (NULL != active && active != w) {
if ((NULL == w || w->group() != active->group()) &&
NULL != active->group()) {
// Active group has changed. so repaint old group
foreach (EffectWindow * tmp, active->group()->members())
tmp->addRepaintFull();
} else
active->addRepaintFull();
}
if (NULL != w) {
if (NULL != w->group()) {
// Repaint windows in new group
foreach (EffectWindow * tmp, w->group()->members())
tmp->addRepaintFull();
} else
w->addRepaintFull();
}
}
active = w;
checkIsActive();
}
bool TranslucencyEffect::isActive() const
{
return m_active;
}
} // namespace