Move window specific signals from EffectsHandler to EffectWindow

This makes the api of EffectWindow more similar to the api of Window. It
also makes more sense to keep such signals in EffectWindow. In the future,
the effect window can be dropped in favor of the window.
This commit is contained in:
Vlad Zahorodnii 2023-09-23 11:13:23 +03:00
parent c1f49d216c
commit 9e10394db1
42 changed files with 512 additions and 467 deletions

View file

@ -1,12 +1,7 @@
effects.windowAdded.connect(function(w) {
w.anim1 = effect.animate(w, Effect.Scale, 100, 1.4, 0.2, 0, QEasingCurve.OutCubic);
sendTestResponse(typeof(w.anim1) == "number");
});
effects.windowUnminimized.connect(function(w) {
cancel(w.anim1);
});
effects.windowMinimized.connect(function(w) {
retarget(w.anim1, 1.5, 200);
w.windowUnminimized.connect(() => cancel(w.anim1));
w.windowMinimized.connect(() => retarget(w.anim1, 1.5, 200));
});

View file

@ -13,12 +13,7 @@ effects.windowAdded.connect(function(w) {
}]
});
sendTestResponse(typeof(w.anim1) == "object" && Array.isArray(w.anim1));
});
effects.windowUnminimized.connect(function(w) {
cancel(w.anim1);
});
effects.windowMinimized.connect(function(w) {
retarget(w.anim1, 1.5, 200);
w.windowUnminimized.connect(() => cancel(w.anim1));
w.windowMinimized.connect(() => retarget(w.anim1, 1.5, 200));
});

View file

@ -8,12 +8,12 @@ effects.windowAdded.connect(function (window) {
to: 1,
keepAlive: false
});
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (complete(window.animation)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -1,16 +1,17 @@
effects.windowAdded.connect(function(window) {
sendTestResponse("windowAdded - " + window.caption);
sendTestResponse("stackingOrder - " + effects.stackingOrder.length + " " + effects.stackingOrder[0].caption);
window.windowMinimized.connect(() => {
sendTestResponse("windowMinimized - " + window.caption);
});
window.windowUnminimized.connect(() => {
sendTestResponse("windowUnminimized - " + window.caption);
});
});
effects.windowClosed.connect(function(window) {
sendTestResponse("windowClosed - " + window.caption);
});
effects.windowMinimized.connect(function(window) {
sendTestResponse("windowMinimized - " + window.caption);
});
effects.windowUnminimized.connect(function(window) {
sendTestResponse("windowUnminimized - " + window.caption);
});
effects.desktopChanged.connect(function(old, current) {
sendTestResponse("desktopChanged - " + old + " " + current);
});

View file

@ -7,12 +7,12 @@ effects.windowAdded.connect(function (window) {
from: 0.0,
to: 1.0
})
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (redirect(window.animation, Effect.Backward, Effect.DontTerminate)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -6,13 +6,13 @@ effects.windowAdded.connect(function (window) {
type: Effect.Opacity,
from: 0.0,
to: 1.0
})
});
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (redirect(window.animation, Effect.Backward, Effect.TerminateAtSource)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -8,12 +8,12 @@ effects.windowAdded.connect(function (window) {
to: 1.0,
keepAlive: false
});
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (redirect(window.animation, Effect.Backward, Effect.DontTerminate)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -8,12 +8,12 @@ effects.windowAdded.connect(function (window) {
to: 1.0,
keepAlive: false
});
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (redirect(window.animation, Effect.Backward, Effect.TerminateAtSource)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -4,12 +4,12 @@ effects.windowAdded.connect(function (window) {
} else {
sendTestResponse('fail');
}
});
effects.windowMinimized.connect(function (window) {
window.windowMinimized.connect(() => {
if (effect.ungrab(window, Effect.WindowAddedGrabRole)) {
sendTestResponse('ok');
} else {
sendTestResponse('fail');
}
});
});

View file

@ -128,7 +128,7 @@ void WobblyWindowsShadeTest::testShadeMove()
workspace()->slotWindowShade();
QVERIFY(window->isShade());
QSignalSpy windowStartUserMovedResizedSpy(e, &EffectsHandler::windowStartUserMovedResized);
QSignalSpy interactiveMoveResizeStartedSpy(window, &Window::interactiveMoveResizeStarted);
// begin move
QVERIFY(workspace()->moveResizeWindow() == nullptr);
@ -136,7 +136,7 @@ void WobblyWindowsShadeTest::testShadeMove()
workspace()->slotWindowMove();
QCOMPARE(workspace()->moveResizeWindow(), window);
QCOMPARE(window->isInteractiveMove(), true);
QCOMPARE(windowStartUserMovedResizedSpy.count(), 1);
QCOMPARE(interactiveMoveResizeStartedSpy.count(), 1);
// wait for frame rendered
QTest::qWait(100);

View file

@ -121,11 +121,6 @@ void MoveResizeWindowTest::testMove()
QSignalSpy interactiveMoveResizeSteppedSpy(window, &Window::interactiveMoveResizeStepped);
QSignalSpy interactiveMoveResizeFinishedSpy(window, &Window::interactiveMoveResizeFinished);
// effects signal handlers
QSignalSpy windowStartUserMovedResizedSpy(effects, &EffectsHandler::windowStartUserMovedResized);
QSignalSpy windowStepUserMovedResizedSpy(effects, &EffectsHandler::windowStepUserMovedResized);
QSignalSpy windowFinishUserMovedResizedSpy(effects, &EffectsHandler::windowFinishUserMovedResized);
// begin move
QVERIFY(workspace()->moveResizeWindow() == nullptr);
QCOMPARE(window->isInteractiveMove(), false);
@ -133,7 +128,6 @@ void MoveResizeWindowTest::testMove()
QCOMPARE(workspace()->moveResizeWindow(), window);
QCOMPARE(interactiveMoveResizeStartedSpy.count(), 1);
QCOMPARE(moveResizedChangedSpy.count(), 1);
QCOMPARE(windowStartUserMovedResizedSpy.count(), 1);
QCOMPARE(window->isInteractiveMove(), true);
QCOMPARE(window->geometryRestore(), QRect());
@ -145,18 +139,15 @@ void MoveResizeWindowTest::testMove()
QEXPECT_FAIL("", "First event is ignored", Continue);
QCOMPARE(interactiveMoveResizeSteppedSpy.count(), 1);
interactiveMoveResizeSteppedSpy.clear();
windowStepUserMovedResizedSpy.clear();
window->keyPressEvent(Qt::Key_Right);
window->updateInteractiveMoveResize(Cursors::self()->mouse()->pos());
QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(16, 0));
QCOMPARE(interactiveMoveResizeSteppedSpy.count(), 1);
QCOMPARE(windowStepUserMovedResizedSpy.count(), 1);
window->keyPressEvent(Qt::Key_Down | Qt::ALT);
window->updateInteractiveMoveResize(Cursors::self()->mouse()->pos());
QCOMPARE(interactiveMoveResizeSteppedSpy.count(), 2);
QCOMPARE(windowStepUserMovedResizedSpy.count(), 2);
QCOMPARE(window->frameGeometry(), QRect(16, 32, 100, 50));
QCOMPARE(Cursors::self()->mouse()->pos(), cursorPos + QPoint(16, 32));
@ -165,7 +156,6 @@ void MoveResizeWindowTest::testMove()
window->keyPressEvent(Qt::Key_Enter);
QCOMPARE(interactiveMoveResizeFinishedSpy.count(), 1);
QCOMPARE(moveResizedChangedSpy.count(), 2);
QCOMPARE(windowFinishUserMovedResizedSpy.count(), 1);
QCOMPARE(window->frameGeometry(), QRect(16, 32, 100, 50));
QCOMPARE(window->isInteractiveMove(), false);
QVERIFY(workspace()->moveResizeWindow() == nullptr);

View file

@ -261,79 +261,10 @@ void EffectsHandlerImpl::unloadAllEffects()
void EffectsHandlerImpl::setupWindowConnections(Window *window)
{
connect(window, &Window::closed, this, [this, window]() {
window->disconnect(this);
if (window->effectWindow()) {
Q_EMIT windowClosed(window->effectWindow());
}
});
connect(window, &Window::maximizedChanged, this, [this, window]() {
if (EffectWindowImpl *w = window->effectWindow()) {
const MaximizeMode mode = window->maximizeMode();
Q_EMIT windowMaximizedStateChanged(w, mode & MaximizeHorizontal, mode & MaximizeVertical);
}
});
connect(window, &Window::maximizedAboutToChange, this, [this, window](MaximizeMode m) {
if (EffectWindowImpl *w = window->effectWindow()) {
Q_EMIT windowMaximizedStateAboutToChange(w, m & MaximizeHorizontal, m & MaximizeVertical);
}
});
connect(window, &Window::frameGeometryAboutToChange, this, [this, window]() {
if (EffectWindowImpl *w = window->effectWindow()) {
Q_EMIT windowFrameGeometryAboutToChange(w);
}
});
connect(window, &Window::interactiveMoveResizeStarted, this, [this, window]() {
Q_EMIT windowStartUserMovedResized(window->effectWindow());
});
connect(window, &Window::interactiveMoveResizeStepped, this, [this, window](const QRectF &geometry) {
Q_EMIT windowStepUserMovedResized(window->effectWindow(), geometry);
});
connect(window, &Window::interactiveMoveResizeFinished, this, [this, window]() {
Q_EMIT windowFinishUserMovedResized(window->effectWindow());
});
connect(window, &Window::opacityChanged, this, &EffectsHandlerImpl::slotOpacityChanged);
connect(window, &Window::minimizedChanged, this, [this, window]() {
if (window->isMinimized()) {
Q_EMIT windowMinimized(window->effectWindow());
} else {
Q_EMIT windowUnminimized(window->effectWindow());
}
});
connect(window, &Window::modalChanged, this, &EffectsHandlerImpl::slotClientModalityChanged);
connect(window, &Window::frameGeometryChanged, this, [this, window](const QRectF &oldGeometry) {
// effectWindow() might be nullptr during tear down of the client.
if (window->effectWindow()) {
Q_EMIT windowFrameGeometryChanged(window->effectWindow(), oldGeometry);
}
});
connect(window, &Window::damaged, this, &EffectsHandlerImpl::slotWindowDamaged);
connect(window, &Window::unresponsiveChanged, this, [this, window](bool unresponsive) {
Q_EMIT windowUnresponsiveChanged(window->effectWindow(), unresponsive);
});
connect(window, &Window::windowShown, this, [this](Window *window) {
Q_EMIT windowShown(window->effectWindow());
});
connect(window, &Window::windowHidden, this, [this](Window *window) {
Q_EMIT windowHidden(window->effectWindow());
});
connect(window, &Window::keepAboveChanged, this, [this, window](bool above) {
Q_EMIT windowKeepAboveChanged(window->effectWindow());
});
connect(window, &Window::keepBelowChanged, this, [this, window](bool below) {
Q_EMIT windowKeepBelowChanged(window->effectWindow());
});
connect(window, &Window::fullScreenChanged, this, [this, window]() {
Q_EMIT windowFullScreenChanged(window->effectWindow());
});
connect(window, &Window::visibleGeometryChanged, this, [this, window]() {
Q_EMIT windowExpandedGeometryChanged(window->effectWindow());
});
connect(window, &Window::decorationChanged, this, [this, window]() {
Q_EMIT windowDecorationChanged(window->effectWindow());
});
connect(window, &Window::desktopsChanged, this, [this, window]() {
Q_EMIT windowDesktopsChanged(window->effectWindow());
});
}
void EffectsHandlerImpl::reconfigure()
@ -448,28 +379,6 @@ void EffectsHandlerImpl::startPaint()
m_currentPaintScreenIterator = m_activeEffects.constBegin();
}
void EffectsHandlerImpl::slotOpacityChanged(Window *window, qreal oldOpacity)
{
if (window->opacity() == oldOpacity || !window->effectWindow()) {
return;
}
Q_EMIT windowOpacityChanged(window->effectWindow(), oldOpacity, (qreal)window->opacity());
}
void EffectsHandlerImpl::slotClientModalityChanged()
{
Q_EMIT windowModalityChanged(static_cast<X11Window *>(sender())->effectWindow());
}
void EffectsHandlerImpl::slotWindowDamaged(Window *window)
{
if (!window->effectWindow()) {
// can happen during tear down of window
return;
}
Q_EMIT windowDamaged(window->effectWindow());
}
void EffectsHandlerImpl::setActiveFullScreenEffect(Effect *e)
{
if (fullscreen_effect == e) {
@ -1845,6 +1754,72 @@ EffectWindowImpl::EffectWindowImpl(Window *window)
m_waylandWindow = qobject_cast<KWin::WaylandWindow *>(window) != nullptr;
m_x11Window = qobject_cast<KWin::X11Window *>(window) != nullptr;
connect(window, &Window::windowShown, this, [this]() {
Q_EMIT windowShown(this);
});
connect(window, &Window::windowHidden, this, [this]() {
Q_EMIT windowHidden(this);
});
connect(window, &Window::maximizedChanged, this, [this, window]() {
const MaximizeMode mode = window->maximizeMode();
Q_EMIT windowMaximizedStateChanged(this, mode & MaximizeHorizontal, mode & MaximizeVertical);
});
connect(window, &Window::maximizedAboutToChange, this, [this](MaximizeMode m) {
Q_EMIT windowMaximizedStateAboutToChange(this, m & MaximizeHorizontal, m & MaximizeVertical);
});
connect(window, &Window::frameGeometryAboutToChange, this, [this]() {
Q_EMIT windowFrameGeometryAboutToChange(this);
});
connect(window, &Window::interactiveMoveResizeStarted, this, [this]() {
Q_EMIT windowStartUserMovedResized(this);
});
connect(window, &Window::interactiveMoveResizeStepped, this, [this](const QRectF &geometry) {
Q_EMIT windowStepUserMovedResized(this, geometry);
});
connect(window, &Window::interactiveMoveResizeFinished, this, [this]() {
Q_EMIT windowFinishUserMovedResized(this);
});
connect(window, &Window::opacityChanged, this, [this](Window *window, qreal oldOpacity) {
Q_EMIT windowOpacityChanged(this, oldOpacity, window->opacity());
});
connect(window, &Window::minimizedChanged, this, [this, window]() {
if (window->isMinimized()) {
Q_EMIT windowMinimized(this);
} else {
Q_EMIT windowUnminimized(this);
}
});
connect(window, &Window::modalChanged, this, [this]() {
Q_EMIT windowModalityChanged(this);
});
connect(window, &Window::frameGeometryChanged, this, [this](const QRectF &oldGeometry) {
Q_EMIT windowFrameGeometryChanged(this, oldGeometry);
});
connect(window, &Window::damaged, this, [this]() {
Q_EMIT windowDamaged(this);
});
connect(window, &Window::unresponsiveChanged, this, [this](bool unresponsive) {
Q_EMIT windowUnresponsiveChanged(this, unresponsive);
});
connect(window, &Window::keepAboveChanged, this, [this]() {
Q_EMIT windowKeepAboveChanged(this);
});
connect(window, &Window::keepBelowChanged, this, [this]() {
Q_EMIT windowKeepBelowChanged(this);
});
connect(window, &Window::fullScreenChanged, this, [this]() {
Q_EMIT windowFullScreenChanged(this);
});
connect(window, &Window::visibleGeometryChanged, this, [this]() {
Q_EMIT windowExpandedGeometryChanged(this);
});
connect(window, &Window::decorationChanged, this, [this]() {
Q_EMIT windowDecorationChanged(this);
});
connect(window, &Window::desktopsChanged, this, [this]() {
Q_EMIT windowDesktopsChanged(this);
});
}
EffectWindowImpl::~EffectWindowImpl()

View file

@ -263,9 +263,6 @@ public Q_SLOTS:
Q_SCRIPTABLE QString debug(const QString &name, const QString &parameter = QString()) const;
protected Q_SLOTS:
void slotOpacityChanged(KWin::Window *window, qreal oldOpacity);
void slotClientModalityChanged();
void slotWindowDamaged(KWin::Window *window);
void slotOutputAdded(Output *output);
void slotOutputRemoved(Output *output);

View file

@ -220,12 +220,10 @@ quint64 AnimationEffect::p_animate(EffectWindow *w, Attribute a, uint meta, int
if (!d->m_isInitialized) {
init(); // needs to ensure the window gets removed if deleted in the same event cycle
}
if (d->m_animations.isEmpty()) {
connect(effects, &EffectsHandler::windowExpandedGeometryChanged,
this, &AnimationEffect::_windowExpandedGeometryChanged);
}
AniMap::iterator it = d->m_animations.find(w);
if (it == d->m_animations.end()) {
connect(w, &EffectWindow::windowExpandedGeometryChanged,
this, &AnimationEffect::_windowExpandedGeometryChanged);
it = d->m_animations.insert(w, QPair<QList<AniData>, QRect>(QList<AniData>(), QRect()));
}
@ -420,11 +418,10 @@ bool AnimationEffect::cancel(quint64 animationId)
}
entry->first.erase(anim); // remove the animation
if (entry->first.isEmpty()) { // no other animations on the window, release it.
disconnect(entry.key(), &EffectWindow::windowExpandedGeometryChanged,
this, &AnimationEffect::_windowExpandedGeometryChanged);
d->m_animations.erase(entry);
}
if (d->m_animations.isEmpty()) {
disconnectGeometryChanges();
}
d->m_animationsTouched = true; // could be called from animationEnded
return true;
}
@ -484,12 +481,6 @@ QRect AnimationEffect::clipRect(const QRect &geo, const AniData &anim) const
return clip;
}
void AnimationEffect::disconnectGeometryChanges()
{
disconnect(effects, &EffectsHandler::windowExpandedGeometryChanged,
this, &AnimationEffect::_windowExpandedGeometryChanged);
}
void AnimationEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
{
Q_D(AnimationEffect);
@ -705,6 +696,8 @@ void AnimationEffect::postPaintScreen()
invalidateLayerRect = damageDirty = true;
}
if (entry->first.isEmpty()) {
disconnect(entry.key(), &EffectWindow::windowExpandedGeometryChanged,
this, &AnimationEffect::_windowExpandedGeometryChanged);
effects->addRepaint(entry->second);
entry = d->m_animations.erase(entry);
} else {
@ -734,11 +727,6 @@ void AnimationEffect::postPaintScreen()
}
}
// janitorial...
if (d->m_animations.isEmpty()) {
disconnectGeometryChanges();
}
effects->postPaintScreen();
}

View file

@ -509,7 +509,6 @@ private:
QRect clipRect(const QRect &windowRect, const AniData &) const;
float interpolated(const AniData &, int i = 0) const;
float progress(const AniData &) const;
void disconnectGeometryChanges();
void updateLayerRepaints();
void validate(Attribute a, uint &meta, FPx2 *from, FPx2 *to, const EffectWindow *w) const;

View file

@ -1501,137 +1501,6 @@ Q_SIGNALS:
* @since 4.7
*/
void windowDeleted(KWin::EffectWindow *w);
/**
* Signal emitted when a user begins a window move or resize operation.
* To figure out whether the user resizes or moves the window use
* isUserMove or isUserResize.
* Whenever the geometry is updated the signal @ref windowStepUserMovedResized
* is emitted with the current geometry.
* The move/resize operation ends with the signal @ref windowFinishUserMovedResized.
* Only one window can be moved/resized by the user at the same time!
* @param w The window which is being moved/resized
* @see windowStepUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
* @since 4.7
*/
void windowStartUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted during a move/resize operation when the user changed the geometry.
* Please note: KWin supports two operation modes. In one mode all changes are applied
* instantly. This means the window's geometry matches the passed in @p geometry. In the
* other mode the geometry is changed after the user ended the move/resize mode.
* The @p geometry differs from the window's geometry. Also the window's pixmap still has
* the same size as before. Depending what the effect wants to do it would be recommended
* to scale/translate the window.
* @param w The window which is being moved/resized
* @param geometry The geometry of the window in the current move/resize step.
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
* @since 4.7
*/
void windowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry);
/**
* Signal emitted when the user finishes move/resize of window @p w.
* @param w The window which has been moved/resized
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
* @since 4.7
*/
void windowFinishUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted when the maximized state of the window @p w changed.
* A window can be in one of four states:
* @li restored: both @p horizontal and @p vertical are @c false
* @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
* @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
* @li completely maximized: both @p horizontal and @p vertical are @c true
* @param w The window whose maximized state changed
* @param horizontal If @c true maximized horizontally
* @param vertical If @c true maximized vertically
* @since 4.7
*/
void windowMaximizedStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical);
/**
* Signal emitted when the maximized state of the window @p w is about to change,
* but before windowMaximizedStateChanged is emitted or any geometry change.
* Useful for OffscreenEffect to grab a window image before any actual change happens
*
* A window can be in one of four states:
* @li restored: both @p horizontal and @p vertical are @c false
* @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
* @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
* @li completely maximized: both @p horizontal and @p vertical are @c true
* @param w The window whose maximized state changed
* @param horizontal If @c true maximized horizontally
* @param vertical If @c true maximized vertically
* @since 5.26
*/
void windowMaximizedStateAboutToChange(KWin::EffectWindow *w, bool horizontal, bool vertical);
/**
* This signal is emitted when the frame geometry of a window changed.
* @param window The window whose geometry changed
* @param oldGeometry The previous geometry
* @since 5.19
*/
void windowFrameGeometryChanged(KWin::EffectWindow *window, const QRectF &oldGeometry);
/**
* This signal is emitted when the frame geometry is about to change, the new one is not known yet.
* Useful for OffscreenEffect to grab a window image before any actual change happens.
*
* @param window The window whose geometry is about to change
* @since 5.26
*/
void windowFrameGeometryAboutToChange(KWin::EffectWindow *window);
/**
* Signal emitted when the windows opacity is changed.
* @param w The window whose opacity level is changed.
* @param oldOpacity The previous opacity level
* @param newOpacity The new opacity level
* @since 4.7
*/
void windowOpacityChanged(KWin::EffectWindow *w, qreal oldOpacity, qreal newOpacity);
/**
* Signal emitted when a window got minimized.
* @param w The window which was minimized
* @since 4.7
*/
void windowMinimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window got unminimized.
* @param w The window which was unminimized
* @since 4.7
*/
void windowUnminimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window either becomes modal (ie. blocking for its main client) or looses that state.
* @param w The window which was unminimized
* @since 4.11
*/
void windowModalityChanged(KWin::EffectWindow *w);
/**
* Signal emitted when a window either became unresponsive (eg. app froze or crashed)
* or respoonsive
* @param w The window that became (un)responsive
* @param unresponsive Whether the window is responsive or unresponsive
* @since 5.10
*/
void windowUnresponsiveChanged(KWin::EffectWindow *w, bool unresponsive);
/**
* Signal emitted when an area of a window is scheduled for repainting.
* Use this signal in an effect if another area needs to be synced as well.
* @param w The window which is scheduled for repainting
* @param r Always empty.
* @since 4.7
*/
void windowDamaged(KWin::EffectWindow *w);
/**
* Signal emitted when a tabbox is added.
* An effect who wants to replace the tabbox with itself should use refTabBox.
@ -1770,29 +1639,6 @@ Q_SIGNALS:
*/
void virtualScreenGeometryChanged();
/**
* The window @p w gets shown again. The window was previously
* initially shown with windowAdded and hidden with windowHidden.
*
* @see windowHidden
* @see windowAdded
* @since 5.8
*/
void windowShown(KWin::EffectWindow *w);
/**
* The window @p w got hidden but not yet closed.
* This can happen when a window is still being used and is supposed to be shown again
* with windowShown. On X11 an example is autohiding panels. On Wayland every
* window first goes through the window hidden state and might get shown again, or might
* get closed the normal way.
*
* @see windowShown
* @see windowClosed
* @since 5.8
*/
void windowHidden(KWin::EffectWindow *w);
/**
* This signal gets emitted when the data on EffectWindow @p w for @p role changed.
*
@ -1839,60 +1685,18 @@ Q_SIGNALS:
*/
void hasActiveFullScreenEffectChanged();
/**
* This signal is emitted when the keep above state of @p w was changed.
*
* @param w The window whose the keep above state was changed.
* @since 5.15
*/
void windowKeepAboveChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the keep below state of @p was changed.
*
* @param w The window whose the keep below state was changed.
* @since 5.15
*/
void windowKeepBelowChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the full screen state of @p w was changed.
*
* @param w The window whose the full screen state was changed.
* @since 5.15
*/
void windowFullScreenChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the session state was changed
* @since 5.18
*/
void sessionStateChanged();
/**
* This signal is emitted when decoration of @p was changed.
*
* @param w The window for which decoration changed
* @since 5.25
*/
void windowDecorationChanged(KWin::EffectWindow *window);
/**
* This signal is emitted when the visible geometry of a window changed.
*/
void windowExpandedGeometryChanged(KWin::EffectWindow *window);
void startupAdded(const QString &id, const QIcon &icon);
void startupChanged(const QString &id, const QIcon &icon);
void startupRemoved(const QString &id);
void inputPanelChanged();
/**
* This signal is emitted when a window enters or leaves a virtual desktop.
*/
void windowDesktopsChanged(KWin::EffectWindow *window);
protected:
QVector<EffectPair> loaded_effects;
// QHash< QString, EffectFactory* > effect_factories;
@ -2618,6 +2422,185 @@ public:
Q_SCRIPTABLE virtual void setData(int role, const QVariant &data) = 0;
Q_SCRIPTABLE virtual QVariant data(int role) const = 0;
Q_SIGNALS:
/**
* Signal emitted when a user begins a window move or resize operation.
* To figure out whether the user resizes or moves the window use
* isUserMove or isUserResize.
* Whenever the geometry is updated the signal @ref windowStepUserMovedResized
* is emitted with the current geometry.
* The move/resize operation ends with the signal @ref windowFinishUserMovedResized.
* Only one window can be moved/resized by the user at the same time!
* @param w The window which is being moved/resized
* @see windowStepUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
*/
void windowStartUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted during a move/resize operation when the user changed the geometry.
* Please note: KWin supports two operation modes. In one mode all changes are applied
* instantly. This means the window's geometry matches the passed in @p geometry. In the
* other mode the geometry is changed after the user ended the move/resize mode.
* The @p geometry differs from the window's geometry. Also the window's pixmap still has
* the same size as before. Depending what the effect wants to do it would be recommended
* to scale/translate the window.
* @param w The window which is being moved/resized
* @param geometry The geometry of the window in the current move/resize step.
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
*/
void windowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry);
/**
* Signal emitted when the user finishes move/resize of window @p w.
* @param w The window which has been moved/resized
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
*/
void windowFinishUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted when the maximized state of the window @p w changed.
* A window can be in one of four states:
* @li restored: both @p horizontal and @p vertical are @c false
* @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
* @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
* @li completely maximized: both @p horizontal and @p vertical are @c true
* @param w The window whose maximized state changed
* @param horizontal If @c true maximized horizontally
* @param vertical If @c true maximized vertically
*/
void windowMaximizedStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical);
/**
* Signal emitted when the maximized state of the window @p w is about to change,
* but before windowMaximizedStateChanged is emitted or any geometry change.
* Useful for OffscreenEffect to grab a window image before any actual change happens
*
* A window can be in one of four states:
* @li restored: both @p horizontal and @p vertical are @c false
* @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
* @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
* @li completely maximized: both @p horizontal and @p vertical are @c true
* @param w The window whose maximized state changed
* @param horizontal If @c true maximized horizontally
* @param vertical If @c true maximized vertically
*/
void windowMaximizedStateAboutToChange(KWin::EffectWindow *w, bool horizontal, bool vertical);
/**
* This signal is emitted when the frame geometry of a window changed.
* @param window The window whose geometry changed
* @param oldGeometry The previous geometry
*/
void windowFrameGeometryChanged(KWin::EffectWindow *window, const QRectF &oldGeometry);
/**
* This signal is emitted when the frame geometry is about to change, the new one is not known yet.
* Useful for OffscreenEffect to grab a window image before any actual change happens.
*
* @param window The window whose geometry is about to change
*/
void windowFrameGeometryAboutToChange(KWin::EffectWindow *window);
/**
* Signal emitted when the windows opacity is changed.
* @param w The window whose opacity level is changed.
* @param oldOpacity The previous opacity level
* @param newOpacity The new opacity level
*/
void windowOpacityChanged(KWin::EffectWindow *w, qreal oldOpacity, qreal newOpacity);
/**
* Signal emitted when a window got minimized.
* @param w The window which was minimized
*/
void windowMinimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window got unminimized.
* @param w The window which was unminimized
*/
void windowUnminimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window either becomes modal (ie. blocking for its main client) or looses that state.
* @param w The window which was unminimized
*/
void windowModalityChanged(KWin::EffectWindow *w);
/**
* Signal emitted when a window either became unresponsive (eg. app froze or crashed)
* or respoonsive
* @param w The window that became (un)responsive
* @param unresponsive Whether the window is responsive or unresponsive
*/
void windowUnresponsiveChanged(KWin::EffectWindow *w, bool unresponsive);
/**
* Signal emitted when an area of a window is scheduled for repainting.
* Use this signal in an effect if another area needs to be synced as well.
* @param w The window which is scheduled for repainting
*/
void windowDamaged(KWin::EffectWindow *w);
/**
* This signal is emitted when the keep above state of @p w was changed.
*
* @param w The window whose the keep above state was changed.
*/
void windowKeepAboveChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the keep below state of @p was changed.
*
* @param w The window whose the keep below state was changed.
*/
void windowKeepBelowChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the full screen state of @p w was changed.
*
* @param w The window whose the full screen state was changed.
*/
void windowFullScreenChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when decoration of @p was changed.
*
* @param w The window for which decoration changed
*/
void windowDecorationChanged(KWin::EffectWindow *window);
/**
* This signal is emitted when the visible geometry of a window changed.
*/
void windowExpandedGeometryChanged(KWin::EffectWindow *window);
/**
* This signal is emitted when a window enters or leaves a virtual desktop.
*/
void windowDesktopsChanged(KWin::EffectWindow *window);
/**
* The window @p w gets shown again. The window was previously
* initially shown with windowAdded and hidden with windowHidden.
*
* @see windowHidden
* @see windowAdded
*/
void windowShown(KWin::EffectWindow *w);
/**
* The window @p w got hidden but not yet closed.
* This can happen when a window is still being used and is supposed to be shown again
* with windowShown. On X11 an example is autohiding panels. On Wayland every
* window first goes through the window hidden state and might get shown again, or might
* get closed the normal way.
*
* @see windowShown
* @see windowClosed
*/
void windowHidden(KWin::EffectWindow *w);
protected:
friend EffectWindowVisibleRef;
virtual void refVisible(const EffectWindowVisibleRef *holder) = 0;

View file

@ -26,19 +26,18 @@ public:
void maybeRender(EffectWindow *window);
private:
std::unique_ptr<GLTexture> m_texture;
std::unique_ptr<GLFramebuffer> m_fbo;
bool m_isDirty = true;
GLShader *m_shader = nullptr;
RenderGeometry::VertexSnappingMode m_vertexSnappingMode = RenderGeometry::VertexSnappingMode::Round;
QMetaObject::Connection m_windowDamagedConnection;
};
class OffscreenEffectPrivate
{
public:
std::map<EffectWindow *, std::unique_ptr<OffscreenData>> windows;
QMetaObject::Connection windowDamagedConnection;
QMetaObject::Connection windowDeletedConnection;
RenderGeometry::VertexSnappingMode vertexSnappingMode = RenderGeometry::VertexSnappingMode::Round;
};
@ -65,6 +64,9 @@ void OffscreenEffect::redirect(EffectWindow *window)
offscreenData = std::make_unique<OffscreenData>();
offscreenData->setVertexSnappingMode(d->vertexSnappingMode);
offscreenData->m_windowDamagedConnection =
connect(window, &EffectWindow::windowDamaged, this, &OffscreenEffect::handleWindowDamaged);
if (d->windows.size() == 1) {
setupConnections();
}
@ -132,6 +134,7 @@ void OffscreenData::maybeRender(EffectWindow *window)
OffscreenData::~OffscreenData()
{
QObject::disconnect(m_windowDamagedConnection);
}
void OffscreenData::setDirty()
@ -256,19 +259,14 @@ void OffscreenEffect::handleWindowDeleted(EffectWindow *window)
void OffscreenEffect::setupConnections()
{
d->windowDamagedConnection =
connect(effects, &EffectsHandler::windowDamaged, this, &OffscreenEffect::handleWindowDamaged);
d->windowDeletedConnection =
connect(effects, &EffectsHandler::windowDeleted, this, &OffscreenEffect::handleWindowDeleted);
}
void OffscreenEffect::destroyConnections()
{
disconnect(d->windowDamagedConnection);
disconnect(d->windowDeletedConnection);
d->windowDamagedConnection = {};
d->windowDeletedConnection = {};
}

View file

@ -114,7 +114,6 @@ BlurEffect::BlurEffect()
connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &BlurEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::screenRemoved, this, &BlurEffect::slotScreenRemoved);
connect(effects, &EffectsHandler::windowDecorationChanged, this, &BlurEffect::setupDecorationConnections);
connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
@ -269,7 +268,9 @@ void BlurEffect::slotWindowAdded(EffectWindow *w)
internal->installEventFilter(this);
}
connect(w, &EffectWindow::windowDecorationChanged, this, &BlurEffect::setupDecorationConnections);
setupDecorationConnections(w);
updateBlurRegion(w);
}

View file

@ -13,6 +13,12 @@ var dialogParentEffect = {
duration: animationTime(300),
windowAdded: function (window) {
"use strict";
window.windowMinimized.connect(dialogParentEffect.cancelAnimationInstant);
window.windowUnminimized.connect(dialogParentEffect.restartAnimation);
window.windowModalityChanged.connect(dialogParentEffect.modalDialogChanged);
window.windowDesktopsChanged.connect(dialogParentEffect.cancelAnimationInstant);
window.windowDesktopsChanged.connect(dialogParentEffect.restartAnimation);
if (window.modal) {
dialogParentEffect.dialogGotModality(window);
}
@ -134,19 +140,13 @@ var dialogParentEffect = {
var i, windows;
effects.windowAdded.connect(dialogParentEffect.windowAdded);
effects.windowClosed.connect(dialogParentEffect.windowClosed);
effects.windowMinimized.connect(dialogParentEffect.cancelAnimationInstant);
effects.windowUnminimized.connect(dialogParentEffect.restartAnimation);
effects.windowModalityChanged.connect(dialogParentEffect.modalDialogChanged)
effects.desktopChanged.connect(dialogParentEffect.desktopChanged);
effects.windowDesktopsChanged.connect(dialogParentEffect.cancelAnimationInstant);
effects.windowDesktopsChanged.connect(dialogParentEffect.restartAnimation);
effects.activeFullScreenEffectChanged.connect(
dialogParentEffect.activeFullScreenEffectChanged);
// start animation
windows = effects.stackingOrder;
for (i = 0; i < windows.length; i += 1) {
dialogParentEffect.restartAnimation(windows[i]);
dialogParentEffect.windowAdded(windows[i]);
}
}
};

View file

@ -40,16 +40,19 @@ DimInactiveEffect::DimInactiveEffect()
connect(effects, &EffectsHandler::windowActivated,
this, &DimInactiveEffect::windowActivated);
connect(effects, &EffectsHandler::windowAdded,
this, &DimInactiveEffect::windowAdded);
connect(effects, &EffectsHandler::windowClosed,
this, &DimInactiveEffect::windowClosed);
connect(effects, &EffectsHandler::windowDeleted,
this, &DimInactiveEffect::windowDeleted);
connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
this, &DimInactiveEffect::activeFullScreenEffectChanged);
connect(effects, &EffectsHandler::windowKeepAboveChanged,
this, &DimInactiveEffect::updateActiveWindow);
connect(effects, &EffectsHandler::windowFullScreenChanged,
this, &DimInactiveEffect::updateActiveWindow);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
windowAdded(window);
}
}
DimInactiveEffect::~DimInactiveEffect()
@ -326,6 +329,14 @@ void DimInactiveEffect::windowActivated(EffectWindow *w)
}
}
void DimInactiveEffect::windowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowKeepAboveChanged,
this, &DimInactiveEffect::updateActiveWindow);
connect(w, &EffectWindow::windowFullScreenChanged,
this, &DimInactiveEffect::updateActiveWindow);
}
void DimInactiveEffect::windowClosed(EffectWindow *w)
{
// When a window is closed, we should force current dim strength that

View file

@ -49,6 +49,7 @@ public:
private Q_SLOTS:
void windowActivated(EffectWindow *w);
void windowAdded(EffectWindow *w);
void windowClosed(EffectWindow *w);
void windowDeleted(EffectWindow *w);
void activeFullScreenEffectChanged();

View file

@ -160,6 +160,9 @@ var dimScreenEffect = {
}
},
slotWindowAdded: function (window) {
window.windowMinimized.connect(dimScreenEffect.cancelAnimationInstant);
window.windowUnminimized.connect(dimScreenEffect.restartAnimation);
// Don't dim authentication agents that just opened.
var agent = activeAuthenticationAgent();
if (agent == window) {
@ -216,11 +219,13 @@ var dimScreenEffect = {
effect.configChanged.connect(dimScreenEffect.loadConfig);
effects.windowActivated.connect(dimScreenEffect.slotWindowActivated);
effects.windowAdded.connect(dimScreenEffect.slotWindowAdded);
effects.windowMinimized.connect(dimScreenEffect.cancelAnimationInstant);
effects.windowUnminimized.connect(dimScreenEffect.restartAnimation);
effects.activeFullScreenEffectChanged.connect(
dimScreenEffect.slotActiveFullScreenEffectChanged);
effects.desktopChanged.connect(dimScreenEffect.slotDesktopChanged);
for (const window of effects.stackingOrder) {
dimScreenEffect.slotWindowAdded(window);
}
}
};

View file

@ -17,10 +17,15 @@ var frozenAppEffect = {
frozenAppEffect.outDuration = animationTime(250);
},
windowAdded: function (window) {
if (!window || !window.unresponsive) {
return;
window.windowMinimized.connect(frozenAppEffect.cancelAnimation);
window.windowUnminimized.connect(frozenAppEffect.restartAnimation);
window.windowUnresponsiveChanged.connect(frozenAppEffect.unresponsiveChanged);
window.windowDesktopsChanged.connect(frozenAppEffect.cancelAnimation);
window.windowDesktopsChanged.connect(frozenAppEffect.restartAnimation);
if (window.unresponsive) {
frozenAppEffect.startAnimation(window, 1);
}
frozenAppEffect.windowBecameUnresponsive(window);
},
windowBecameUnresponsive: function (window) {
if (window.unresponsiveAnimation) {
@ -102,16 +107,11 @@ var frozenAppEffect = {
init: function () {
effects.windowAdded.connect(frozenAppEffect.windowAdded);
effects.windowClosed.connect(frozenAppEffect.windowClosed);
effects.windowMinimized.connect(frozenAppEffect.cancelAnimation);
effects.windowUnminimized.connect(frozenAppEffect.restartAnimation);
effects.windowUnresponsiveChanged.connect(frozenAppEffect.unresponsiveChanged);
effects.desktopChanged.connect(frozenAppEffect.desktopChanged);
effects.windowDesktopsChanged.connect(frozenAppEffect.cancelAnimation);
effects.windowDesktopsChanged.connect(frozenAppEffect.restartAnimation);
var windows = effects.stackingOrder;
for (var i = 0, length = windows.length; i < length; ++i) {
frozenAppEffect.restartAnimation(windows[i]);
frozenAppEffect.windowAdded(windows[i]);
}
}
};

View file

@ -11,12 +11,13 @@
class FullScreenEffect {
constructor() {
effect.configChanged.connect(this.loadConfig.bind(this));
effects.windowFrameGeometryChanged.connect(
this.onWindowFrameGeometryChanged.bind(this));
effects.windowFullScreenChanged.connect(
this.onWindowFullScreenChanged.bind(this));
effect.animationEnded.connect(this.restoreForceBlurState.bind(this));
effects.windowAdded.connect(this.manage.bind(this));
for (const window of effects.stackingOrder) {
this.manage(window);
}
this.loadConfig();
}
@ -24,6 +25,13 @@ class FullScreenEffect {
this.duration = animationTime(250);
}
manage(window) {
window.windowFrameGeometryChanged.connect(
this.onWindowFrameGeometryChanged.bind(this));
window.windowFullScreenChanged.connect(
this.onWindowFullScreenChanged.bind(this));
}
onWindowFullScreenChanged(window) {
if (!window.visible || !window.oldGeometry) {
return;

View file

@ -20,9 +20,13 @@ MagicLampEffect::MagicLampEffect()
{
initConfig<MagicLampConfig>();
reconfigure(ReconfigureAll);
connect(effects, &EffectsHandler::windowAdded, this, &MagicLampEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &MagicLampEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::windowMinimized, this, &MagicLampEffect::slotWindowMinimized);
connect(effects, &EffectsHandler::windowUnminimized, this, &MagicLampEffect::slotWindowUnminimized);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
setVertexSnappingMode(RenderGeometry::VertexSnappingMode::None);
}
@ -365,6 +369,12 @@ void MagicLampEffect::postPaintScreen()
effects->postPaintScreen();
}
void MagicLampEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowMinimized, this, &MagicLampEffect::slotWindowMinimized);
connect(w, &EffectWindow::windowUnminimized, this, &MagicLampEffect::slotWindowUnminimized);
}
void MagicLampEffect::slotWindowDeleted(EffectWindow *w)
{
m_animations.remove(w);

View file

@ -44,6 +44,7 @@ protected:
void apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads) override;
public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w);
void slotWindowMinimized(KWin::EffectWindow *w);
void slotWindowUnminimized(KWin::EffectWindow *w);

View file

@ -49,7 +49,12 @@ MagnifierEffect::MagnifierEffect()
KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::Key_0));
connect(effects, &EffectsHandler::mouseChanged, this, &MagnifierEffect::slotMouseChanged);
connect(effects, &EffectsHandler::windowDamaged, this, &MagnifierEffect::slotWindowDamaged);
connect(effects, &EffectsHandler::windowAdded, this, &MagnifierEffect::slotWindowAdded);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
reconfigure(ReconfigureAll);
}
@ -268,6 +273,11 @@ void MagnifierEffect::slotMouseChanged(const QPointF &pos, const QPointF &old,
}
}
void MagnifierEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowDamaged, this, &MagnifierEffect::slotWindowDamaged);
}
void MagnifierEffect::slotWindowDamaged()
{
if (isActive()) {

View file

@ -43,6 +43,7 @@ private Q_SLOTS:
void slotMouseChanged(const QPointF &pos, const QPointF &old,
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
void slotWindowAdded(EffectWindow *w);
void slotWindowDamaged();
private:

View file

@ -11,13 +11,12 @@
class MaximizeEffect {
constructor() {
effect.configChanged.connect(this.loadConfig.bind(this));
effects.windowFrameGeometryChanged.connect(
this.onWindowFrameGeometryChanged.bind(this));
effects.windowMaximizedStateChanged.connect(
this.onWindowMaximizedStateChanged.bind(this));
effect.animationEnded.connect(this.restoreForceBlurState.bind(this));
effects.windowMaximizedStateAboutToChange.connect(
this.onWindowMaximizedStateAboutToChange.bind(this));
effects.windowAdded.connect(this.manage.bind(this));
for (const window of effects.stackingOrder) {
this.manage(window);
}
this.loadConfig();
}
@ -26,6 +25,12 @@ class MaximizeEffect {
this.duration = animationTime(250);
}
manage(window) {
window.windowFrameGeometryChanged.connect(this.onWindowFrameGeometryChanged.bind(this));
window.windowMaximizedStateChanged.connect(this.onWindowMaximizedStateChanged.bind(this));
window.windowMaximizedStateAboutToChange.connect(this.onWindowMaximizedStateAboutToChange.bind(this));
}
onWindowMaximizedStateAboutToChange(window) {
if (!window.visible) {
return;

View file

@ -16,10 +16,6 @@ var morphingEffect = {
},
handleFrameGeometryAboutToChange: function (window) {
//only tooltips and notifications
if (!window.tooltip && !window.notification && !window.criticalNotification) {
return;
}
var couldRetarget = false;
if (window.fadeAnimation) {
couldRetarget = retarget(window.fadeAnimation[0], 1.0, morphingEffect.duration);
@ -38,11 +34,6 @@ var morphingEffect = {
}
},
handleFrameGeometryChanged: function (window, oldGeometry) {
//only tooltips and notifications
if (!window.tooltip && !window.notification && !window.criticalNotification) {
return;
}
var newGeometry = window.geometry;
//only do the transition for near enough tooltips,
@ -122,10 +113,23 @@ var morphingEffect = {
}
},
manage: function (window) {
//only tooltips and notifications
if (!window.tooltip && !window.notification && !window.criticalNotification) {
return;
}
window.windowFrameGeometryAboutToChange.connect(morphingEffect.handleFrameGeometryAboutToChange);
window.windowFrameGeometryChanged.connect(morphingEffect.handleFrameGeometryChanged);
},
init: function () {
effect.configChanged.connect(morphingEffect.loadConfig);
effects.windowFrameGeometryAboutToChange.connect(morphingEffect.handleFrameGeometryAboutToChange);
effects.windowFrameGeometryChanged.connect(morphingEffect.handleFrameGeometryChanged);
effects.windowAdded.connect(morphingEffect.manage);
for (const window of effects.stackingOrder) {
morphingEffect.manage(window);
}
}
};
morphingEffect.init();

View file

@ -18,10 +18,14 @@ SlideBackEffect::SlideBackEffect()
m_justMapped = m_upmostWindow = nullptr;
connect(effects, &EffectsHandler::windowAdded, this, &SlideBackEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &SlideBackEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::windowUnminimized, this, &SlideBackEffect::slotWindowUnminimized);
connect(effects, &EffectsHandler::tabBoxAdded, this, &SlideBackEffect::slotTabBoxAdded);
connect(effects, &EffectsHandler::stackingOrderChanged, this, &SlideBackEffect::slotStackingOrderChanged);
connect(effects, &EffectsHandler::tabBoxClosed, this, &SlideBackEffect::slotTabBoxClosed);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
}
void SlideBackEffect::slotStackingOrderChanged()
@ -272,6 +276,8 @@ void SlideBackEffect::slotWindowDeleted(EffectWindow *w)
void SlideBackEffect::slotWindowAdded(EffectWindow *w)
{
m_justMapped = w;
connect(w, &EffectWindow::windowUnminimized, this, &SlideBackEffect::slotWindowUnminimized);
}
void SlideBackEffect::slotWindowUnminimized(EffectWindow *w)

View file

@ -57,8 +57,6 @@ SlidingPopupsEffect::SlidingPopupsEffect()
connect(effects, &EffectsHandler::windowClosed, this, &SlidingPopupsEffect::slideOut);
connect(effects, &EffectsHandler::windowDeleted, this, &SlidingPopupsEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::propertyNotify, this, &SlidingPopupsEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::windowShown, this, &SlidingPopupsEffect::slideIn);
connect(effects, &EffectsHandler::windowHidden, this, &SlidingPopupsEffect::slideOut);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_SLIDE"), this);
});
@ -66,7 +64,6 @@ SlidingPopupsEffect::SlidingPopupsEffect()
this, &SlidingPopupsEffect::stopAnimations);
connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
this, &SlidingPopupsEffect::stopAnimations);
connect(effects, &EffectsHandler::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged);
reconfigure(ReconfigureAll);
@ -206,6 +203,10 @@ void SlidingPopupsEffect::postPaintWindow(EffectWindow *w)
void SlidingPopupsEffect::setupSlideData(EffectWindow *w)
{
connect(w, &EffectWindow::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged);
connect(w, &EffectWindow::windowShown, this, &SlidingPopupsEffect::slideIn);
connect(w, &EffectWindow::windowHidden, this, &SlidingPopupsEffect::slideOut);
// X11
if (m_atom != XCB_ATOM_NONE) {
slotPropertyNotify(w, m_atom);

View file

@ -65,10 +65,13 @@ SnapHelperEffect::SnapHelperEffect()
{
reconfigure(ReconfigureAll);
connect(effects, &EffectsHandler::windowAdded, this, &SnapHelperEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &SnapHelperEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowStartUserMovedResized, this, &SnapHelperEffect::slotWindowStartUserMovedResized);
connect(effects, &EffectsHandler::windowFinishUserMovedResized, this, &SnapHelperEffect::slotWindowFinishUserMovedResized);
connect(effects, &EffectsHandler::windowFrameGeometryChanged, this, &SnapHelperEffect::slotWindowFrameGeometryChanged);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
}
SnapHelperEffect::~SnapHelperEffect()
@ -192,6 +195,13 @@ void SnapHelperEffect::postPaintScreen()
effects->postPaintScreen();
}
void SnapHelperEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowStartUserMovedResized, this, &SnapHelperEffect::slotWindowStartUserMovedResized);
connect(w, &EffectWindow::windowFinishUserMovedResized, this, &SnapHelperEffect::slotWindowFinishUserMovedResized);
connect(w, &EffectWindow::windowFrameGeometryChanged, this, &SnapHelperEffect::slotWindowFrameGeometryChanged);
}
void SnapHelperEffect::slotWindowClosed(EffectWindow *w)
{
if (w != m_window) {

View file

@ -32,6 +32,7 @@ public:
bool isActive() const override;
private Q_SLOTS:
void slotWindowAdded(EffectWindow *w);
void slotWindowClosed(EffectWindow *w);
void slotWindowStartUserMovedResized(EffectWindow *w);
void slotWindowFinishUserMovedResized(EffectWindow *w);

View file

@ -145,10 +145,17 @@ var squashEffect = {
]
});
},
slotWindowAdded: function (window) {
window.windowMinimized.connect(squashEffect.slotWindowMinimized);
window.windowUnminimized.connect(squashEffect.slotWindowUnminimized);
},
init: function () {
effect.configChanged.connect(squashEffect.loadConfig);
effects.windowMinimized.connect(squashEffect.slotWindowMinimized);
effects.windowUnminimized.connect(squashEffect.slotWindowUnminimized);
effects.windowAdded.connect(squashEffect.slotWindowAdded);
for (const window of effects.stackingOrder) {
squashEffect.slotWindowAdded(window);
}
}
};

View file

@ -33,10 +33,15 @@ ThumbnailAsideEffect::ThumbnailAsideEffect()
KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << (Qt::META | Qt::CTRL | Qt::Key_T));
connect(a, &QAction::triggered, this, &ThumbnailAsideEffect::toggleCurrentThumbnail);
connect(effects, &EffectsHandler::windowAdded, this, &ThumbnailAsideEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &ThumbnailAsideEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowFrameGeometryChanged, this, &ThumbnailAsideEffect::slotWindowFrameGeometryChanged);
connect(effects, &EffectsHandler::windowDamaged, this, &ThumbnailAsideEffect::slotWindowDamaged);
connect(effects, &EffectsHandler::screenLockingChanged, this, &ThumbnailAsideEffect::repaintAll);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
reconfigure(ReconfigureAll);
}
@ -95,6 +100,12 @@ void ThumbnailAsideEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const
}
}
void ThumbnailAsideEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowFrameGeometryChanged, this, &ThumbnailAsideEffect::slotWindowFrameGeometryChanged);
connect(w, &EffectWindow::windowDamaged, this, &ThumbnailAsideEffect::slotWindowDamaged);
}
void ThumbnailAsideEffect::slotWindowClosed(EffectWindow *w)
{
removeThumbnail(w);

View file

@ -58,6 +58,7 @@ public:
private Q_SLOTS:
void toggleCurrentThumbnail();
void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowClosed(KWin::EffectWindow *w);
void slotWindowFrameGeometryChanged(KWin::EffectWindow *w, const QRectF &old);
void slotWindowDamaged(KWin::EffectWindow *w);

View file

@ -204,19 +204,27 @@ var translucencyEffect = {
}
}
},
manage: function (window) {
window.windowDesktopsChanged.connect(translucencyEffect.cancelAnimations);
window.windowDesktopsChanged.connect(translucencyEffect.startAnimation);
window.windowUnminimized.connect(translucencyEffect.startAnimation);
window.windowMinimized.connect(translucencyEffect.cancelAnimations);
window.windowUnminimized.connect(translucencyEffect.inactive.animate);
window.windowStartUserMovedResized.connect(translucencyEffect.moveResize.start);
window.windowFinishUserMovedResized.connect(translucencyEffect.moveResize.finish);
},
init: function () {
effect.configChanged.connect(translucencyEffect.loadConfig);
effects.windowDesktopsChanged.connect(translucencyEffect.cancelAnimations);
effects.windowDesktopsChanged.connect(translucencyEffect.startAnimation);
effects.windowAdded.connect(translucencyEffect.manage);
effects.windowAdded.connect(translucencyEffect.startAnimation);
effects.windowUnminimized.connect(translucencyEffect.startAnimation);
effects.windowClosed.connect(translucencyEffect.cancelAnimations);
effects.windowMinimized.connect(translucencyEffect.cancelAnimations);
effects.windowUnminimized.connect(translucencyEffect.inactive.animate);
effects.windowStartUserMovedResized.connect(translucencyEffect.moveResize.start);
effects.windowFinishUserMovedResized.connect(translucencyEffect.moveResize.finish);
effects.windowActivated.connect(translucencyEffect.inactive.activated);
effects.desktopChanged.connect(translucencyEffect.desktopChanged);
for (const window of effects.stackingOrder) {
translucencyEffect.manage(window);
}
translucencyEffect.loadConfig();
}
};

View file

@ -123,10 +123,12 @@ WobblyWindowsEffect::WobblyWindowsEffect()
{
initConfig<WobblyWindowsConfig>();
reconfigure(ReconfigureAll);
connect(effects, &EffectsHandler::windowStartUserMovedResized, this, &WobblyWindowsEffect::slotWindowStartUserMovedResized);
connect(effects, &EffectsHandler::windowStepUserMovedResized, this, &WobblyWindowsEffect::slotWindowStepUserMovedResized);
connect(effects, &EffectsHandler::windowFinishUserMovedResized, this, &WobblyWindowsEffect::slotWindowFinishUserMovedResized);
connect(effects, &EffectsHandler::windowMaximizedStateChanged, this, &WobblyWindowsEffect::slotWindowMaximizeStateChanged);
connect(effects, &EffectsHandler::windowAdded, this, &WobblyWindowsEffect::slotWindowAdded);
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
slotWindowAdded(window);
}
setVertexSnappingMode(RenderGeometry::VertexSnappingMode::None);
}
@ -307,6 +309,14 @@ void WobblyWindowsEffect::postPaintScreen()
effects->postPaintScreen();
}
void WobblyWindowsEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowStartUserMovedResized, this, &WobblyWindowsEffect::slotWindowStartUserMovedResized);
connect(w, &EffectWindow::windowStepUserMovedResized, this, &WobblyWindowsEffect::slotWindowStepUserMovedResized);
connect(w, &EffectWindow::windowFinishUserMovedResized, this, &WobblyWindowsEffect::slotWindowFinishUserMovedResized);
connect(w, &EffectWindow::windowMaximizedStateChanged, this, &WobblyWindowsEffect::slotWindowMaximizeStateChanged);
}
void WobblyWindowsEffect::slotWindowStartUserMovedResized(EffectWindow *w)
{
if (w->isSpecialWindow()) {

View file

@ -92,6 +92,7 @@ protected:
void apply(EffectWindow *w, int mask, WindowPaintData &data, WindowQuadList &quads) override;
public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowStartUserMovedResized(KWin::EffectWindow *w);
void slotWindowStepUserMovedResized(KWin::EffectWindow *w, const QRectF &geometry);
void slotWindowFinishUserMovedResized(KWin::EffectWindow *w);

View file

@ -109,7 +109,7 @@ ZoomEffect::ZoomEffect()
timeline.setFrameRange(0, 100);
connect(&timeline, &QTimeLine::frameChanged, this, &ZoomEffect::timelineFrameChanged);
connect(effects, &EffectsHandler::mouseChanged, this, &ZoomEffect::slotMouseChanged);
connect(effects, &EffectsHandler::windowDamaged, this, &ZoomEffect::slotWindowDamaged);
connect(effects, &EffectsHandler::windowAdded, this, &ZoomEffect::slotWindowAdded);
connect(effects, &EffectsHandler::screenRemoved, this, &ZoomEffect::slotScreenRemoved);
#if HAVE_ACCESSIBILITY
@ -117,6 +117,11 @@ ZoomEffect::ZoomEffect()
connect(m_accessibilityIntegration, &ZoomAccessibilityIntegration::focusPointChanged, this, &ZoomEffect::moveFocus);
#endif
const auto windows = effects->stackingOrder();
for (EffectWindow *w : windows) {
slotWindowAdded(w);
}
source_zoom = -1; // used to trigger initialZoom reading
reconfigure(ReconfigureAll);
}
@ -544,6 +549,11 @@ void ZoomEffect::slotMouseChanged(const QPointF &pos, const QPointF &old, Qt::Mo
}
}
void ZoomEffect::slotWindowAdded(EffectWindow *w)
{
connect(w, &EffectWindow::windowDamaged, this, &ZoomEffect::slotWindowDamaged);
}
void ZoomEffect::slotWindowDamaged()
{
if (zoom != 1.0) {

View file

@ -76,6 +76,7 @@ private Q_SLOTS:
void slotMouseChanged(const QPointF &pos, const QPointF &old,
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
void slotWindowAdded(EffectWindow *w);
void slotWindowDamaged();
void slotScreenRemoved(EffectScreen *screen);