File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -58,6 +58,7 @@ set shell id.
5858- Fixed ToplevelManager not clearing activeToplevel on deactivation.
5959- Desktop action order is now preserved.
6060- Fixed partial socket reads in greetd and hyprland on slow machines.
61+ - Worked around Qt bug causing crashes when plugging and unplugging monitors.
6162
6263## Packaging Changes
6364
Original file line number Diff line number Diff line change @@ -73,13 +73,21 @@ endfunction()
7373# -----
7474
7575qt_add_library (quickshell-wayland STATIC
76+ wl_proxy_safe_deref.cpp
7677 platformmenu.cpp
7778 popupanchor.cpp
7879 xdgshell.cpp
7980 util.cpp
8081 output_tracking.cpp
8182)
8283
84+ # required for wl_proxy_safe_deref
85+ target_link_libraries (quickshell-wayland PRIVATE ${CMAKE_DL_LIBS} )
86+ target_link_options (quickshell PRIVATE
87+ "LINKER:--export-dynamic-symbol=wl_proxy_get_listener"
88+ "LINKER:--require-defined=wl_proxy_get_listener"
89+ )
90+
8391# required to make sure the constructor is linked
8492add_library (quickshell-wayland-init OBJECT init.cpp )
8593
Original file line number Diff line number Diff line change 1010#include " wlr_layershell/wlr_layershell.hpp"
1111#endif
1212
13+ void installWlProxySafeDeref (); // NOLINT(misc-use-internal-linkage)
1314void installPlatformMenuHook (); // NOLINT(misc-use-internal-linkage)
1415void installPopupPositioner (); // NOLINT(misc-use-internal-linkage)
1516
@@ -33,6 +34,7 @@ class WaylandPlugin: public QsEnginePlugin {
3334 }
3435
3536 void init () override {
37+ installWlProxySafeDeref ();
3638 installPlatformMenuHook ();
3739 installPopupPositioner ();
3840 }
Original file line number Diff line number Diff line change 88#include < qobjectdefs.h>
99#include < qproperty.h>
1010
11+ #include " ../../windowmanager/screenprojection.hpp"
1112#include " ../../windowmanager/windowmanager.hpp"
1213#include " ../../windowmanager/windowset.hpp"
13- #include " ../../windowmanager/screenprojection.hpp"
1414#include " ext_workspace.hpp"
1515
1616namespace qs ::wm::wayland {
Original file line number Diff line number Diff line change 1+
2+ #include < dlfcn.h>
3+ #include < qlogging.h>
4+ #include < qloggingcategory.h>
5+ #include < wayland-client-core.h>
6+ #include < wayland-util.h>
7+
8+ #include " ../core/logcat.hpp"
9+
10+ namespace {
11+ QS_LOGGING_CATEGORY (logDeref, " quickshell.wayland.safederef" , QtWarningMsg);
12+ using wl_proxy_get_listener_t = const void * (*) (wl_proxy*);
13+ wl_proxy_get_listener_t original_wl_proxy_get_listener = nullptr ; // NOLINT
14+ } // namespace
15+
16+ extern " C" {
17+ WL_EXPORT const void * wl_proxy_get_listener (struct wl_proxy * proxy) {
18+ // Avoid null derefs of protocol objects in qtbase.
19+ // https://qt-project.atlassian.net/browse/QTBUG-145022
20+ if (!proxy) [[unlikely]] {
21+ qCCritical (logDeref) << " wl_proxy_get_listener called with a null proxy!" ;
22+ return nullptr ;
23+ }
24+
25+ return original_wl_proxy_get_listener (proxy);
26+ }
27+ }
28+
29+ // NOLINTBEGIN (concurrency-mt-unsafe)
30+ void installWlProxySafeDeref () {
31+ dlerror (); // clear old errors
32+
33+ original_wl_proxy_get_listener =
34+ reinterpret_cast <wl_proxy_get_listener_t >(dlsym (RTLD_NEXT, " wl_proxy_get_listener" ));
35+
36+ if (auto * error = dlerror ()) {
37+ qCCritical (logDeref) << " Failed to find wl_proxy_get_listener for hooking:" << error;
38+ } else {
39+ qCInfo (logDeref) << " Installed wl_proxy_get_listener hook." ;
40+ }
41+ }
42+ // NOLINTEND
You can’t perform that action at this time.
0 commit comments