509daa60a1
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
265 lines
9.2 KiB
C++
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
|