Skip to content

Commit

Permalink
Workaround for EGL_BAD_SURFACE segfaults introduced with Plasma 5.26+
Browse files Browse the repository at this point in the history
KDE Plasma 5.26 introduced a change whereby an EGL_BAD_SURFACE error
would result in a segfault when using Klassy when opening certain
applications (mainly those applications with custom colour schemes).

The EGL_BAD_SURFACE was caused by a shadow being created at the same
time as the paint() function execution, due to a paletteChanged
signal.

This workaround checks if paint() is under execution before shadow
creation, and aborts the shadow update if this is the case.
  • Loading branch information
paulmcauley committed May 6, 2023
1 parent fe2fd6e commit 972edd0
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ project(breeze)
set(PROJECT_VERSION "4.1.breeze5.25.80")
set(PROJECT_VERSION_MAJOR 5)

add_definitions( -DKLASSY_VERSION="${PROJECT_VERSION}" -DKLASSY_GIT_MASTER=1)
add_definitions( -DKLASSY_VERSION="${PROJECT_VERSION}" -DKLASSY_GIT_MASTER=0)

set(KF5_MIN_VERSION "5.94")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
<a name="overview"/>

## Overview
**WARNING: KDE Plasma 5.26 introduced a change which induces segfaults. Please do not use Klassy with Plasma 5.26. Development of Klassy will continue only once Plasma developers fix their bug.**

_Klassy_ (formerly _ClassiK_/_ClassikStyles_) is a highly customizable binary Window Decoration and Application Style plugin for recent versions of the KDE Plasma desktop. [Initially taking inspiration from the iconography of KDE 1](https://forum.kde.org/viewtopic.php?f=285&t=138602?raw=true), the _Klassy_ defaults are an attempt to create a usable and appealing look for the modern Plasma desktop. Install with the instructions below, and then enable in System Settings -> Appearance -> Window Decorations, and also in System Settings -> Appearance -> Application Style.

![Screenshot of Button icons menu](screenshots/button_icon_menu.png?raw=true "Screenshot of Button icons menu")
Expand Down
13 changes: 13 additions & 0 deletions kdecoration/breezedecoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,8 @@ void Decoration::updateButtonsGeometry()
//________________________________________________________________
void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
{
m_painting = true;

// TODO: optimize based on repaintRegion
auto c = client().toStrongRef();
Q_ASSERT(c);
Expand Down Expand Up @@ -985,6 +987,8 @@ void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
painter->drawRect(rect().adjusted(0, 0, -1, -1));
painter->restore();
}

m_painting = false;
}

void Decoration::calculateWindowAndTitleBarShapes(const bool windowShapeOnly)
Expand Down Expand Up @@ -1270,6 +1274,15 @@ void Decoration::updateShadow(const bool force, const bool noCache, const bool i
auto s = settings();
auto c = client().toStrongRef();
Q_ASSERT(c);

// if the decoration is painting, abandon setting the shadow.
// Setting the shadow at the same time as paint() being executed causes a EGL_BAD_SURFACE error and a SEGFAULT from Plasma 5.26 onwards.
if (m_painting) {
qWarning("Klassy: paint() occuring at same time as shadow creation for \"%s\" - abandonning setting shadow to prevent EGL_BAD_SURFACE.",
c->caption().toLatin1().data());
return;
}

// Animated case, no cached shadow object
if ((m_shadowAnimation->state() == QAbstractAnimation::Running) && (m_shadowOpacity != 0.0) && (m_shadowOpacity != 1.0)) {
setShadow(createShadowObject(0.5 + m_shadowOpacity * 0.5, isThinWindowOutlineOverride));
Expand Down
3 changes: 3 additions & 0 deletions kdecoration/breezedecoration.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ private Q_SLOTS:
KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr;
KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr;

//* Whether the paint() method is active
bool m_painting = false;

//* size grip widget
SizeGrip *m_sizeGrip = nullptr;

Expand Down

0 comments on commit 972edd0

Please sign in to comment.