Skip to content

Commit 744b3b1

Browse files
committed
Fixed Crash when XCB,X11,Qt grabber were configured and display manager changed to Wayland
1 parent f63322d commit 744b3b1

18 files changed

+261
-78
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6464
- Fixed: Python 3.12 crashes (#1747)
6565
- osX Grabber: Use ScreenCaptureKit under macOS 15 and above
6666
- Removed maximum LED number constraint from Matrix layout schema which was not synced with the UI behaviour (#1804)
67+
- UI: Instance listings are sorted, enabled instances are high-lighted in drop-downs
6768
- Fixed bespoke WebSocket implementation by using of QWebSockets (#1816, #1448, #1247, #1130)
6869
- Fixed mDNS Browser deadlock, plus run in own thread now
6970
- Fixed that LED Buffer and Layout might get out of sync.
@@ -72,7 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7273
- Fixed Last update of an effect event is not removed in sources overview
7374
- Fixed Removed stale _logger object
7475
- Fixed Smoothing (#1863)
75-
- UI: Instance listings are sorted, enabled instances are high-lighted in drop-downs
76+
- Fixed Crash when XCB,X11 was configured and display manager changed to Wayland
7677

7778
**JSON-API**
7879
- Refactored JSON-API to ensure consistent authorization behaviour across sessions and single requests with token authorization.

include/grabber/qt/QtGrabber.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class QtGrabber : public Grabber
7272
///
7373
bool setupDisplay();
7474

75+
///
76+
/// @brief Determine if the grabber is available.
77+
///
78+
/// @return true, on success (i.e. Window Manager is not Wayland), else false
79+
///
80+
bool isAvailable(bool logError = true) override;
81+
7582
///
7683
/// @brief Opens the input device.
7784
///

include/grabber/qt/QtWrapper.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ class QtWrapper: public GrabberWrapper
3838
///
3939
QtWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
4040

41+
///
42+
/// @brief Determine if the grabber is available for usage on the platform
43+
///
44+
/// @return true, on success, else false
45+
///
46+
bool isAvailable() override;
47+
48+
///
49+
/// Starts the grabber, if available
50+
///
51+
bool start() override;
52+
4153
///
4254
/// Starts the grabber which produces led values with the specified update rate
4355
///

include/grabber/x11/X11Grabber.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,14 @@ class X11Grabber : public Grabber , public QAbstractNativeEventFilter
3434

3535
~X11Grabber() override;
3636

37-
bool open();
37+
///
38+
/// @brief Determine if the grabber is available.
39+
///
40+
/// @return true, on success (i.e. Window Manager is not Wayland), else false
41+
///
42+
bool isAvailable(bool logError = true) override;
3843

44+
bool open();
3945
bool setupDisplay();
4046

4147
///

include/grabber/x11/X11Wrapper.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ class X11Wrapper: public GrabberWrapper
3838
///
3939
~X11Wrapper() override;
4040

41+
///
42+
/// @brief Determine if the grabber is available for usage on the platform
43+
///
44+
/// @return true, on success, else false
45+
///
46+
bool isAvailable() override;
47+
48+
///
49+
/// Starts the grabber, if available
50+
///
51+
bool start() override;
52+
53+
///
54+
/// Starts the grabber which produces led values with the specified update rate
55+
///
56+
bool open() override;
57+
4158
public slots:
4259
///
4360
/// Performs a single frame grab and computes the led-colors

include/grabber/xcb/XcbGrabber.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ class XcbGrabber : public Grabber, public QAbstractNativeEventFilter
2929

3030
~XcbGrabber() override;
3131

32+
///
33+
/// @brief Determine if the grabber is available.
34+
///
35+
/// @return true, on success (i.e. Window Manager is not Wayland), else false
36+
///
37+
bool isAvailable(bool logError = true) override;
38+
3239
bool open();
3340
bool setupDisplay();
3441

include/grabber/xcb/XcbWrapper.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ class XcbWrapper: public GrabberWrapper
3737

3838
~XcbWrapper() override;
3939

40+
///
41+
/// @brief Determine if the grabber is available for usage on the platform
42+
///
43+
/// @return true, on success, else false
44+
///
45+
bool isAvailable() override;
46+
47+
///
48+
/// Starts the grabber, if available
49+
///
50+
bool start() override;
51+
52+
///
53+
/// Starts the grabber which produces led values with the specified update rate
54+
///
55+
bool open() override;
56+
4057
public slots:
4158
void action() override;
4259

include/hyperion/Grabber.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class Grabber : public QObject
118118
///
119119
/// @return true, on success (i.e. library is present), else false
120120
///
121-
virtual bool isAvailable() { return _isAvailable; }
121+
virtual bool isAvailable(bool logError = true) { return _isAvailable; }
122122

123123
public slots:
124124

include/hyperion/GrabberWrapper.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ private slots:
168168
/// Will start and stop grabber based on active listeners count
169169
void handleSourceRequest(hyperion::Components component, int hyperionInd, bool listen);
170170

171-
///
172-
173-
174171
protected:
175172

176173
///

libsrc/grabber/qt/QtGrabber.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,34 @@ void QtGrabber::freeResources()
4646
// Qt seems to hold the ownership of the QScreen pointers
4747
}
4848

49-
bool QtGrabber::open()
49+
bool QtGrabber::isAvailable(bool logError)
5050
{
51-
bool rc = false;
52-
53-
#ifndef _WIN32
51+
#ifndef _WIN32
5452
if (getenv("WAYLAND_DISPLAY") != nullptr)
5553
{
54+
ErrorIf(logError, _log, "Grabber does not work under Wayland!");
5655
_isWayland = true;
5756
}
58-
else
59-
#endif
60-
{
61-
rc = true;
62-
}
63-
return rc;
57+
#endif
58+
59+
_isAvailable = !_isWayland;
60+
return _isAvailable;
61+
}
62+
63+
bool QtGrabber::open()
64+
{
65+
return _isAvailable;
6466
}
6567

6668
bool QtGrabber::setupDisplay()
6769
{
68-
bool result = false;
69-
if (!open())
70+
if (!_isAvailable)
7071
{
71-
if (_isWayland)
72-
{
73-
Error(_log, "Grabber does not work under Wayland!");
74-
}
72+
return false;
7573
}
76-
else
74+
75+
bool result = false;
76+
if (open())
7777
{
7878
// cleanup last screen
7979
freeResources();
@@ -385,7 +385,7 @@ QJsonObject QtGrabber::discover(const QJsonObject& params)
385385
DebugIf(verbose, _log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData());
386386

387387
QJsonObject inputsDiscovered;
388-
if (open())
388+
if (isAvailable(false) && open())
389389
{
390390
QList<QScreen*> screens = QGuiApplication::screens();
391391
if (!screens.isEmpty())

libsrc/grabber/qt/QtWrapper.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,26 @@ QtWrapper::QtWrapper(const QJsonDocument& grabberConfig)
1717
GrabberWrapper::DEFAULT_PIXELDECIMATION,
1818
0,0,0,0)
1919
{
20-
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
20+
_isAvailable = _grabber.isAvailable();
21+
if (_isAvailable)
22+
{
23+
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
24+
}
25+
}
26+
27+
bool QtWrapper::isAvailable()
28+
{
29+
return _isAvailable;
30+
}
31+
32+
bool QtWrapper::start()
33+
{
34+
if (_isAvailable)
35+
{
36+
return GrabberWrapper::start();
37+
}
38+
39+
return false;
2140
}
2241

2342
bool QtWrapper::open()
@@ -27,5 +46,10 @@ bool QtWrapper::open()
2746

2847
void QtWrapper::action()
2948
{
49+
if (!_isAvailable)
50+
{
51+
return;
52+
}
53+
3054
transferFrame(_grabber);
3155
}

libsrc/grabber/x11/X11Grabber.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,25 @@ void X11Grabber::setupResources()
113113
}
114114
}
115115

116-
bool X11Grabber::open()
117-
{
118-
bool rc = false;
119116

117+
bool X11Grabber::isAvailable(bool logError)
118+
{
120119
if (getenv("WAYLAND_DISPLAY") != nullptr)
121120
{
121+
ErrorIf(logError, _log, "Grabber does not work under Wayland!");
122122
_isWayland = true;
123123
}
124-
else
124+
125+
_isAvailable = !_isWayland;
126+
return _isAvailable;
127+
}
128+
129+
130+
bool X11Grabber::open()
131+
{
132+
bool rc = false;
133+
134+
if (_isAvailable)
125135
{
126136
_x11Display = XOpenDisplay(nullptr);
127137
if (_x11Display != nullptr)
@@ -134,25 +144,24 @@ bool X11Grabber::open()
134144

135145
bool X11Grabber::setupDisplay()
136146
{
147+
if (!_isAvailable)
148+
{
149+
return false;
150+
}
151+
137152
bool result = false;
138153

139154
if ( ! open() )
140155
{
141-
if ( _isWayland )
156+
if (getenv("DISPLAY") != nullptr)
142157
{
143-
Error(_log, "Grabber does not work under Wayland!");
158+
Error(_log, "Unable to open display [%s]",getenv("DISPLAY"));
144159
}
145160
else
146161
{
147-
if (getenv("DISPLAY") != nullptr)
148-
{
149-
Error(_log, "Unable to open display [%s]",getenv("DISPLAY"));
150-
}
151-
else
152-
{
153-
Error(_log, "DISPLAY environment variable not set");
154-
}
162+
Error(_log, "DISPLAY environment variable not set");
155163
}
164+
156165
}
157166
else
158167
{
@@ -405,7 +414,7 @@ QJsonObject X11Grabber::discover(const QJsonObject& params)
405414
DebugIf(verbose, _log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData());
406415

407416
QJsonObject inputsDiscovered;
408-
if ( open() )
417+
if ( isAvailable(false) && open() )
409418
{
410419
inputsDiscovered["device"] = "x11";
411420
inputsDiscovered["device_name"] = "X11";

libsrc/grabber/x11/X11Wrapper.cpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ X11Wrapper::X11Wrapper(const QJsonDocument& grabberConfig)
1515
GrabberWrapper::DEFAULT_PIXELDECIMATION,
1616
0,0,0,0)
1717
{
18-
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
18+
_isAvailable = _grabber.isAvailable();
19+
if (_isAvailable)
20+
{
21+
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
22+
}
1923
}
2024

2125
X11Wrapper::~X11Wrapper()
@@ -26,22 +30,51 @@ X11Wrapper::~X11Wrapper()
2630
}
2731
}
2832

33+
34+
bool X11Wrapper::isAvailable()
35+
{
36+
return _isAvailable;
37+
}
38+
39+
bool X11Wrapper::start()
40+
{
41+
if (_isAvailable)
42+
{
43+
return GrabberWrapper::start();
44+
}
45+
46+
return false;
47+
}
48+
49+
50+
bool X11Wrapper::open()
51+
{
52+
bool isOpen {false};
53+
if ( _isAvailable && _grabber.setupDisplay())
54+
{
55+
if (_grabber.updateScreenDimensions() >= 0)
56+
{
57+
isOpen = true;
58+
}
59+
}
60+
61+
return isOpen;
62+
}
63+
2964
void X11Wrapper::action()
3065
{
66+
if (!_isAvailable)
67+
{
68+
return;
69+
}
70+
3171
if (! _init )
3272
{
3373
_init = true;
34-
if ( ! _grabber.setupDisplay() )
74+
if ( ! open() )
3575
{
3676
stop();
3777
}
38-
else
39-
{
40-
if (_grabber.updateScreenDimensions() < 0 )
41-
{
42-
stop();
43-
}
44-
}
4578
}
4679

4780
if (isActive())

0 commit comments

Comments
 (0)