Skip to content

Commit

Permalink
kde-plasma/kwin: Fix runtime crashes
Browse files Browse the repository at this point in the history
Backported from 5.14 branch.

Package-Manager: Portage-2.3.51, Repoman-2.3.12
Signed-off-by: Andreas Sturmlechner <[email protected]>
  • Loading branch information
a17r committed Nov 13, 2018
1 parent 07d9641 commit 881b0b0
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 0 deletions.
72 changes: 72 additions & 0 deletions kde-plasma/kwin/files/kwin-5.14.3-resizewindows-crash.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
From 406b70b04e093c13faf763e2d885797ae037d806 Mon Sep 17 00:00:00 2001
From: Vlad Zagorodniy <[email protected]>
Date: Mon, 12 Nov 2018 17:45:14 +0200
Subject: [wayland] Don't crash when resizing windows

Summary:
If you resize a decorated client by using the resize user action(press
Alt + F3 > More Actions > Resize), then KWin will crash because it gets
stuck in an infinite loop (AbstractClient::performMoveResize <->
ShellClient::setGeometry).

Here's how KWin gets stuck in that loop:
* when you finish resizing the client, AbstractClient::keyPressEvent
will call AbstractClient::finishMoveResize;
* the first thing that finishMoveResize does is block geometry updates,
then it does some clean up (e.g. reset the value of isMoveResize(), etc),
updates the geometry of the client and when it's done, it will emit
clientFinishUserMoveResized signal;
* when PointerInputRedirection notices that signal, it will call
processDecorationMove on the client, which in its turn will indirectly
call AbstractClient::startMoveResize;
* when it's time to go back to AbstractClient::keyPressEvent, geometry
updates are unblocked and if there are any pending geometry updates,
then ShellClient::setGeometry will be called;
* ShellClient::setGeometry will eventually call ShellClient::doSetGeometry;
* ShellClient::doSetGeometry will call AbstractClient::performMoveResize
because AbstractClient::processDecorationMove indirectly called
AbstractClient::startMoveResize;
* AbstractClient::performMoveResize calls ShellClient::setGeometry;
* (at this point, KWin got stuck in the infinite loop)

This change swaps setMoveResizePointerButtonDown and finishMoveResize,
so processDecorationMove won't indirectly call startMoveResize.

BUG: 397577
FIXED-IN: 5.14.4

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D16846
---
abstract_client.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/abstract_client.cpp b/abstract_client.cpp
index b4628f2..ed72b9c 100644
--- a/abstract_client.cpp
+++ b/abstract_client.cpp
@@ -1457,13 +1457,13 @@ void AbstractClient::keyPressEvent(uint key_code)
case Qt::Key_Space:
case Qt::Key_Return:
case Qt::Key_Enter:
- finishMoveResize(false);
setMoveResizePointerButtonDown(false);
+ finishMoveResize(false);
updateCursor();
break;
case Qt::Key_Escape:
- finishMoveResize(true);
setMoveResizePointerButtonDown(false);
+ finishMoveResize(true);
updateCursor();
break;
default:
--
cgit v0.11.2
137 changes: 137 additions & 0 deletions kde-plasma/kwin/files/kwin-5.14.3-virtualdesktop-crash.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
From ad28da84e78c7eb7ff1e608c4819707b2142daea Mon Sep 17 00:00:00 2001
From: Vlad Zagorodniy <[email protected]>
Date: Mon, 5 Nov 2018 14:59:42 +0200
Subject: [effects/slidingpopups] Don't crash when sliding virtual desktops

Summary:
If you switch virtual desktops while krunner is sliding in, then
depending on whether your distro strips assert statements away,
KWin can crash.

The reason why it crashes is the sliding popups effect tries to unref
deleted windows that it hasn't referenced before (if there is an active
full screen effect, then popups won't be slided out, which in its turn
means that we won't reference deleted windows). So, in the end, the
refcount of those windows can be -1. That triggers an assert statement
in the destructor of the Deleted class, which checks whether the
refcount is equal to 0.

Popups are not slided while there is an active full screen effect because
we don't know what the full screen effect does.

This patch adjusts the sliding popups effect so it stops all active
animations when user switches virtual desktops or when a full screen
effect kicks in. We need to do that so the effect won't try to
unreference windows in postPaintWindow.

Visually, it doesn't look quite nice, but for now that's good enough.
A proper fix would be more complex: we would need to make sure that
full screen effects ignore sliding popups (and also maybe docks) and
perform some input redirection.

BUG: 400170
FIXED-IN: 5.14.4

Test Plan: I'm not able anymore to reproduce bug 400170.

Reviewers: #kwin, graesslin

Reviewed By: #kwin, graesslin

Subscribers: davidedmundson, graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D16731
---
effects/slidingpopups/slidingpopups.cpp | 22 ++++++++++++++++++++++
effects/slidingpopups/slidingpopups.h | 6 +++---
2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/effects/slidingpopups/slidingpopups.cpp b/effects/slidingpopups/slidingpopups.cpp
index a104a5c..066b2a3 100644
--- a/effects/slidingpopups/slidingpopups.cpp
+++ b/effects/slidingpopups/slidingpopups.cpp
@@ -3,6 +3,7 @@
This file is part of the KDE project.

Copyright (C) 2009 Marco Martin [email protected]
+Copyright (C) 2018 Vlad Zagorodniy <[email protected]>

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
@@ -53,6 +54,11 @@ SlidingPopupsEffect::SlidingPopupsEffect()
m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_SLIDE"), this);
}
);
+ connect(effects, qOverload<int, int, EffectWindow *>(&EffectsHandler::desktopChanged),
+ this, &SlidingPopupsEffect::stopAnimations);
+ connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
+ this, &SlidingPopupsEffect::stopAnimations);
+
reconfigure(ReconfigureAll);
}

@@ -434,6 +440,22 @@ void SlidingPopupsEffect::slideOut(EffectWindow *w)
w->addRepaintFull();
}

+void SlidingPopupsEffect::stopAnimations()
+{
+ for (auto it = m_animations.constBegin(); it != m_animations.constEnd(); ++it) {
+ EffectWindow *w = it.key();
+
+ if (w->isDeleted()) {
+ w->unrefWindow();
+ } else {
+ w->setData(WindowForceBackgroundContrastRole, QVariant());
+ w->setData(WindowForceBlurRole, QVariant());
+ }
+ }
+
+ m_animations.clear();
+}
+
bool SlidingPopupsEffect::isActive() const
{
return !m_animations.isEmpty();
diff --git a/effects/slidingpopups/slidingpopups.h b/effects/slidingpopups/slidingpopups.h
index 821640a..32e8fb5 100644
--- a/effects/slidingpopups/slidingpopups.h
+++ b/effects/slidingpopups/slidingpopups.h
@@ -3,6 +3,7 @@
This file is part of the KDE project.

Copyright (C) 2009 Marco Martin [email protected]
+Copyright (C) 2018 Vlad Zagorodniy <[email protected]>

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
@@ -49,8 +50,6 @@ public:

static bool supported();

- // TODO react also on virtual desktop changes
-
int slideInDuration() const;
int slideOutDuration() const;

@@ -62,6 +61,7 @@ private Q_SLOTS:

void slideIn(EffectWindow *w);
void slideOut(EffectWindow *w);
+ void stopAnimations();

private:
void setupAnimData(EffectWindow *w);
@@ -81,7 +81,7 @@ private:
AnimationKind kind;
TimeLine timeLine;
};
- QHash<const EffectWindow*, Animation> m_animations;
+ QHash<EffectWindow *, Animation> m_animations;

enum class Location {
Left,
--
cgit v0.11.2
111 changes: 111 additions & 0 deletions kde-plasma/kwin/kwin-5.14.3-r1.ebuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Copyright 1999-2018 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=6

KDE_HANDBOOK="optional"
KDE_TEST="optional"
VIRTUALX_REQUIRED="test"
inherit kde5

DESCRIPTION="KDE window manager"
LICENSE="GPL-2+"
KEYWORDS="~amd64 ~arm ~arm64 ~x86"
IUSE="caps gles2 multimedia"

COMMON_DEPEND="
$(add_frameworks_dep kactivities)
$(add_frameworks_dep kauth)
$(add_frameworks_dep kcmutils)
$(add_frameworks_dep kcompletion)
$(add_frameworks_dep kconfig)
$(add_frameworks_dep kconfigwidgets)
$(add_frameworks_dep kcoreaddons)
$(add_frameworks_dep kcrash)
$(add_frameworks_dep kdeclarative)
$(add_frameworks_dep kglobalaccel '' '' '5=')
$(add_frameworks_dep ki18n)
$(add_frameworks_dep kiconthemes)
$(add_frameworks_dep kidletime '' '' '5=')
$(add_frameworks_dep kinit)
$(add_frameworks_dep kio)
$(add_frameworks_dep knewstuff)
$(add_frameworks_dep knotifications)
$(add_frameworks_dep kpackage)
$(add_frameworks_dep kservice)
$(add_frameworks_dep ktextwidgets)
$(add_frameworks_dep kwayland)
$(add_frameworks_dep kwidgetsaddons)
$(add_frameworks_dep kwindowsystem X)
$(add_frameworks_dep kxmlgui)
$(add_frameworks_dep plasma)
$(add_plasma_dep breeze)
$(add_plasma_dep kdecoration)
$(add_plasma_dep kscreenlocker)
$(add_qt_dep qtdbus)
$(add_qt_dep qtdeclarative)
$(add_qt_dep qtgui 'gles2=' '' '5=')
$(add_qt_dep qtscript)
$(add_qt_dep qtsensors)
$(add_qt_dep qtwidgets)
$(add_qt_dep qtx11extras)
>=dev-libs/libinput-1.9
>=dev-libs/wayland-1.2
media-libs/fontconfig
media-libs/freetype
media-libs/libepoxy
media-libs/mesa[egl,gbm,gles2?,wayland]
virtual/libudev:=
x11-libs/libICE
x11-libs/libSM
x11-libs/libX11
x11-libs/libXi
x11-libs/libdrm
>=x11-libs/libxcb-1.10
>=x11-libs/libxkbcommon-0.7.0
x11-libs/xcb-util-cursor
x11-libs/xcb-util-image
x11-libs/xcb-util-keysyms
x11-libs/xcb-util-wm
caps? ( sys-libs/libcap )
"
RDEPEND="${COMMON_DEPEND}
$(add_qt_dep qtquickcontrols)
$(add_qt_dep qtquickcontrols2)
$(add_qt_dep qtvirtualkeyboard)
multimedia? ( $(add_qt_dep qtmultimedia 'gstreamer,qml') )
!kde-plasma/kwin:4
!kde-plasma/systemsettings:4
"
DEPEND="${COMMON_DEPEND}
$(add_qt_dep designer)
$(add_qt_dep qtconcurrent)
x11-base/xorg-proto
"
PDEPEND="
$(add_plasma_dep kde-cli-tools)
"

RESTRICT+=" test"

PATCHES=(
"${FILESDIR}/${PN}-5.14.3-virtualdesktop-crash.patch"
"${FILESDIR}/${PN}-5.14.3-resizewindows-crash.patch"
)

src_prepare() {
kde5_src_prepare
use multimedia || eapply "${FILESDIR}/${PN}-gstreamer-optional.patch"

# Access violations, bug #640432
sed -e "s/^ecm_find_qmlmodule.*QtMultimedia/#&/" \
-i CMakeLists.txt || die
}

src_configure() {
local mycmakeargs=(
$(cmake-utils_use_find_package caps Libcap)
)

kde5_src_configure
}

0 comments on commit 881b0b0

Please sign in to comment.