diff --git a/effects/kscreen/kscreen.cpp b/effects/kscreen/kscreen.cpp index 2d167110b..ee21ac5c2 100644 --- a/effects/kscreen/kscreen.cpp +++ b/effects/kscreen/kscreen.cpp @@ -1,187 +1,191 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2013 Martin Gräßlin 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 . *********************************************************************/ // own #include "kscreen.h" // KConfigSkeleton #include "kscreenconfig.h" /** * How this effect works: * * Effect announces that it is around through property _KDE_KWIN_KSCREEN_SUPPORT on the root window. * * KScreen watches for this property and when it wants to adjust screens, KScreen goes * through the following protocol: * 1. KScreen sets the property value to 1 * 2. Effect starts to fade out all windows * 3. When faded out the effect sets property value to 2 * 4. KScreen adjusts the screens * 5. KScreen sets property value to 3 * 6. Effect starts to fade in all windows again * 7. Effect sets back property value to 0 * * The property has type 32 bits cardinal. To test it use: * xprop -root -f _KDE_KWIN_KSCREEN_SUPPORT 32c -set _KDE_KWIN_KSCREEN_SUPPORT 1 * * The states are: * 0: normal * 1: fading out * 2: faded out * 3: fading in **/ namespace KWin { KscreenEffect::KscreenEffect() : Effect() , m_state(StateNormal) , m_atom(effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this)) { initConfig(); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), SLOT(propertyNotify(KWin::EffectWindow*,long))); connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this] { m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this); } ); reconfigure(ReconfigureAll); } KscreenEffect::~KscreenEffect() { } void KscreenEffect::reconfigure(ReconfigureFlags flags) { Q_UNUSED(flags) KscreenConfig::self()->read(); m_timeLine.setDuration(animationTime(250)); } void KscreenEffect::prePaintScreen(ScreenPrePaintData &data, int time) { if (m_state == StateFadingIn || m_state == StateFadingOut) { m_timeLine.setCurrentTime(m_timeLine.currentTime() + time); if (m_timeLine.currentValue() >= 1.0) { switchState(); } } effects->prePaintScreen(data, time); } void KscreenEffect::postPaintScreen() { if (m_state == StateFadingIn || m_state == StateFadingOut) { effects->addRepaintFull(); } } void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) { if (m_state != StateNormal) { data.setTranslucent(); } effects->prePaintWindow(w, data, time); } void KscreenEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) { + //fade to black and fully opaque switch (m_state) { - case StateFadingOut: - data.multiplyOpacity(1.0 - m_timeLine.currentValue()); - break; - case StateFadedOut: - data.multiplyOpacity(0.0); - break; - case StateFadingIn: - data.multiplyOpacity(m_timeLine.currentValue()); - break; - default: - // no adjustment - break; + case StateFadingOut: + data.setOpacity(data.opacity() + (1.0 - data.opacity()) * m_timeLine.currentValue()); + data.multiplyBrightness(1.0 - m_timeLine.currentValue()); + break; + case StateFadedOut: + data.multiplyOpacity(0.0); + data.multiplyBrightness(0.0); + break; + case StateFadingIn: + data.setOpacity(data.opacity() + (1.0 - data.opacity()) * (1.0 - m_timeLine.currentValue())); + data.multiplyBrightness(m_timeLine.currentValue()); + break; + default: + // no adjustment + break; } effects->paintWindow(w, mask, region, data); } void KscreenEffect::propertyNotify(EffectWindow *window, long int atom) { if (window || atom != m_atom || m_atom == XCB_ATOM_NONE) { return; } QByteArray byteData = effects->readRootProperty(m_atom, XCB_ATOM_CARDINAL, 32); const uint32_t *data = byteData.isEmpty() ? nullptr : reinterpret_cast(byteData.data()); if (!data // Property was deleted || data[0] == 0) { // normal state - KWin should have switched to it if (m_state != StateNormal) { m_state = StateNormal; effects->addRepaintFull(); } return; } if (data[0] == 2) { // faded out state - KWin should have switched to it if (m_state != StateFadedOut) { m_state = StateFadedOut; effects->addRepaintFull(); } return; } if (data[0] == 1) { // kscreen wants KWin to fade out all windows m_state = StateFadingOut; m_timeLine.setCurrentTime(0); effects->addRepaintFull(); return; } if (data[0] == 3) { // kscreen wants KWin to fade in again m_state = StateFadingIn; m_timeLine.setCurrentTime(0); effects->addRepaintFull(); return; } qCDebug(KWINEFFECTS) << "Incorrect Property state, immediate stop: " << data[0]; m_state = StateNormal; effects->addRepaintFull(); } void KscreenEffect::switchState() { long value = -1l; if (m_state == StateFadingOut) { m_state = StateFadedOut; value = 2l; } else if (m_state == StateFadingIn) { m_state = StateNormal; value = 0l; } if (value != -1l && m_atom != XCB_ATOM_NONE) { xcb_change_property(xcbConnection(), XCB_PROP_MODE_REPLACE, x11RootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value); } } bool KscreenEffect::isActive() const { return m_state != StateNormal; } } // namespace KWin diff --git a/effects/maximize/package/contents/code/maximize.js b/effects/maximize/package/contents/code/maximize.js index d381a6810..4345c04fa 100644 --- a/effects/maximize/package/contents/code/maximize.js +++ b/effects/maximize/package/contents/code/maximize.js @@ -1,98 +1,98 @@ /******************************************************************** This file is part of the KDE project. - Copyright (C) 2012 Martin Gräßlin + Copyright (C) 2012 Martin Gräßlin 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 . *********************************************************************/ /*global effect, effects, animate, animationTime, Effect*/ var maximizeEffect = { duration: animationTime(250), loadConfig: function () { "use strict"; maximizeEffect.duration = animationTime(250); }, maximizeChanged: function (window) { "use strict"; if (!window.oldGeometry) { return; } var oldGeometry, newGeometry; oldGeometry = window.oldGeometry; newGeometry = window.geometry; if (oldGeometry.width == newGeometry.width && oldGeometry.height == newGeometry.height) oldGeometry = window.olderGeometry; window.olderGeometry = window.oldGeometry; window.oldGeometry = newGeometry; window.maximizeAnimation1 = animate({ window: window, duration: maximizeEffect.duration, animations: [{ type: Effect.Size, to: { value1: newGeometry.width, value2: newGeometry.height }, from: { value1: oldGeometry.width, value2: oldGeometry.height } }, { type: Effect.Translation, to: { value1: 0, value2: 0 }, from: { value1: oldGeometry.x - newGeometry.x - (newGeometry.width / 2 - oldGeometry.width / 2), value2: oldGeometry.y - newGeometry.y - (newGeometry.height / 2 - oldGeometry.height / 2) } }] }); if (!window.resize) { window.maximizeAnimation2 =animate({ window: window, duration: maximizeEffect.duration, animations: [{ type: Effect.CrossFadePrevious, to: 1.0, from: 0.0 }] }); } }, geometryChange: function (window, oldGeometry) { "use strict"; if (window.maximizeAnimation1) { if (window.geometry.width != window.oldGeometry.width || window.geometry.height != window.oldGeometry.height) { cancel(window.maximizeAnimation1); delete window.maximizeAnimation1; if (window.maximizeAnimation2) { cancel(window.maximizeAnimation2); delete window.maximizeAnimation2; } } } window.oldGeometry = window.geometry; window.olderGeometry = oldGeometry; }, init: function () { "use strict"; effect.configChanged.connect(maximizeEffect.loadConfig); effects.windowGeometryShapeChanged.connect(maximizeEffect.geometryChange); effects.windowMaximizedStateChanged.connect(maximizeEffect.maximizeChanged); } }; maximizeEffect.init(); diff --git a/effects/morphingpopups/package/contents/code/morphingpopups.js b/effects/morphingpopups/package/contents/code/morphingpopups.js index 9ae52847f..16040dc2b 100644 --- a/effects/morphingpopups/package/contents/code/morphingpopups.js +++ b/effects/morphingpopups/package/contents/code/morphingpopups.js @@ -1,140 +1,140 @@ /******************************************************************** This file is part of the KDE project. - Copyright (C) 2012 Martin Gräßlin + Copyright (C) 2012 Martin Gräßlin Copyright (C) 2016 Marco Martin 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 . *********************************************************************/ /*global effect, effects, animate, animationTime, Effect*/ var morphingEffect = { duration: animationTime(150), loadConfig: function () { "use strict"; morphingEffect.duration = animationTime(150); }, geometryChange: function (window, oldGeometry) { "use strict"; //only tooltips and notifications if (!window.tooltip && !window.notification) { return; } var newGeometry = window.geometry; //only do the transition for near enough tooltips, //don't cross the whole screen: ugly var distance = Math.abs(oldGeometry.x - newGeometry.x) + Math.abs(oldGeometry.y - newGeometry.y); if (distance > (newGeometry.width + newGeometry.height) * 2) { if (window.moveAnimation) { delete window.moveAnimation; } if (window.fadeAnimation) { delete window.fadeAnimation; } return; } //don't resize it "too much", set as four times if ((newGeometry.width / oldGeometry.width) > 4 || (oldGeometry.width / newGeometry.width) > 4 || (newGeometry.height / oldGeometry.height) > 4 || (oldGeometry.height / newGeometry.height) > 4) { return; } //WindowForceBackgroundContrastRole window.setData(7, true); //WindowForceBlurRole window.setData(5, true); var couldRetarget = false; if (window.moveAnimation) { if (window.moveAnimation[0]) { couldRetarget = retarget(window.moveAnimation[0], { value1: newGeometry.width, value2: newGeometry.height }, morphingEffect.duration); } if (couldRetarget && window.moveAnimation[1]) { couldRetarget = retarget(window.moveAnimation[1], { value1: newGeometry.x + newGeometry.width/2, value2: newGeometry.y + newGeometry.height / 2 }, morphingEffect.duration); } if (!couldRetarget) { cancel(window.moveAnimation[0]); } } if (!couldRetarget) { window.moveAnimation = animate({ window: window, duration: morphingEffect.duration, animations: [{ type: Effect.Size, to: { value1: newGeometry.width, value2: newGeometry.height }, from: { value1: oldGeometry.width, value2: oldGeometry.height } }, { type: Effect.Position, to: { value1: newGeometry.x + newGeometry.width / 2, value2: newGeometry.y + newGeometry.height / 2 }, from: { value1: oldGeometry.x + oldGeometry.width / 2, value2: oldGeometry.y + oldGeometry.height / 2 } }] }); } couldRetarget = false; if (window.fadeAnimation) { couldRetarget = retarget(window.fadeAnimation[0], 1.0, morphingEffect.duration); } if (!couldRetarget) { window.fadeAnimation = animate({ window: window, duration: morphingEffect.duration, animations: [{ type: Effect.CrossFadePrevious, to: 1.0, from: 0.0 }] }); } }, init: function () { "use strict"; effect.configChanged.connect(morphingEffect.loadConfig); effects.windowGeometryShapeChanged.connect(morphingEffect.geometryChange); } }; morphingEffect.init();