mirror of
https://git.outfoxxed.me/quickshell/quickshell.git
synced 2026-04-10 06:11:54 +10:00
wayland: hook wl_proxy_get_listener avoiding QTBUG-145022 crash
Co-authored-by: Lemmy <studio@quadbyte.net>
This commit is contained in:
parent
6705e2da77
commit
365bf16b1e
5 changed files with 54 additions and 1 deletions
|
|
@ -58,6 +58,7 @@ set shell id.
|
||||||
- Fixed ToplevelManager not clearing activeToplevel on deactivation.
|
- Fixed ToplevelManager not clearing activeToplevel on deactivation.
|
||||||
- Desktop action order is now preserved.
|
- Desktop action order is now preserved.
|
||||||
- Fixed partial socket reads in greetd and hyprland on slow machines.
|
- Fixed partial socket reads in greetd and hyprland on slow machines.
|
||||||
|
- Worked around Qt bug causing crashes when plugging and unplugging monitors.
|
||||||
|
|
||||||
## Packaging Changes
|
## Packaging Changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ endfunction()
|
||||||
# -----
|
# -----
|
||||||
|
|
||||||
qt_add_library(quickshell-wayland STATIC
|
qt_add_library(quickshell-wayland STATIC
|
||||||
|
wl_proxy_safe_deref.cpp
|
||||||
platformmenu.cpp
|
platformmenu.cpp
|
||||||
popupanchor.cpp
|
popupanchor.cpp
|
||||||
xdgshell.cpp
|
xdgshell.cpp
|
||||||
|
|
@ -80,6 +81,13 @@ qt_add_library(quickshell-wayland STATIC
|
||||||
output_tracking.cpp
|
output_tracking.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# required for wl_proxy_safe_deref
|
||||||
|
target_link_libraries(quickshell-wayland PRIVATE ${CMAKE_DL_LIBS})
|
||||||
|
target_link_options(quickshell PRIVATE
|
||||||
|
"LINKER:--export-dynamic-symbol=wl_proxy_get_listener"
|
||||||
|
"LINKER:--require-defined=wl_proxy_get_listener"
|
||||||
|
)
|
||||||
|
|
||||||
# required to make sure the constructor is linked
|
# required to make sure the constructor is linked
|
||||||
add_library(quickshell-wayland-init OBJECT init.cpp)
|
add_library(quickshell-wayland-init OBJECT init.cpp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "wlr_layershell/wlr_layershell.hpp"
|
#include "wlr_layershell/wlr_layershell.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void installWlProxySafeDeref(); // NOLINT(misc-use-internal-linkage)
|
||||||
void installPlatformMenuHook(); // NOLINT(misc-use-internal-linkage)
|
void installPlatformMenuHook(); // NOLINT(misc-use-internal-linkage)
|
||||||
void installPopupPositioner(); // NOLINT(misc-use-internal-linkage)
|
void installPopupPositioner(); // NOLINT(misc-use-internal-linkage)
|
||||||
|
|
||||||
|
|
@ -33,6 +34,7 @@ class WaylandPlugin: public QsEnginePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() override {
|
void init() override {
|
||||||
|
installWlProxySafeDeref();
|
||||||
installPlatformMenuHook();
|
installPlatformMenuHook();
|
||||||
installPopupPositioner();
|
installPopupPositioner();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
#include <qobjectdefs.h>
|
#include <qobjectdefs.h>
|
||||||
#include <qproperty.h>
|
#include <qproperty.h>
|
||||||
|
|
||||||
|
#include "../../windowmanager/screenprojection.hpp"
|
||||||
#include "../../windowmanager/windowmanager.hpp"
|
#include "../../windowmanager/windowmanager.hpp"
|
||||||
#include "../../windowmanager/windowset.hpp"
|
#include "../../windowmanager/windowset.hpp"
|
||||||
#include "../../windowmanager/screenprojection.hpp"
|
|
||||||
#include "ext_workspace.hpp"
|
#include "ext_workspace.hpp"
|
||||||
|
|
||||||
namespace qs::wm::wayland {
|
namespace qs::wm::wayland {
|
||||||
|
|
|
||||||
42
src/wayland/wl_proxy_safe_deref.cpp
Normal file
42
src/wayland/wl_proxy_safe_deref.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <qlogging.h>
|
||||||
|
#include <qloggingcategory.h>
|
||||||
|
#include <wayland-client-core.h>
|
||||||
|
#include <wayland-util.h>
|
||||||
|
|
||||||
|
#include "../core/logcat.hpp"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QS_LOGGING_CATEGORY(logDeref, "quickshell.wayland.safederef", QtWarningMsg);
|
||||||
|
using wl_proxy_get_listener_t = const void* (*) (wl_proxy*);
|
||||||
|
wl_proxy_get_listener_t original_wl_proxy_get_listener = nullptr; // NOLINT
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
WL_EXPORT const void* wl_proxy_get_listener(struct wl_proxy* proxy) {
|
||||||
|
// Avoid null derefs of protocol objects in qtbase.
|
||||||
|
// https://qt-project.atlassian.net/browse/QTBUG-145022
|
||||||
|
if (!proxy) [[unlikely]] {
|
||||||
|
qCCritical(logDeref) << "wl_proxy_get_listener called with a null proxy!";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return original_wl_proxy_get_listener(proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTBEGIN (concurrency-mt-unsafe)
|
||||||
|
void installWlProxySafeDeref() {
|
||||||
|
dlerror(); // clear old errors
|
||||||
|
|
||||||
|
original_wl_proxy_get_listener =
|
||||||
|
reinterpret_cast<wl_proxy_get_listener_t>(dlsym(RTLD_NEXT, "wl_proxy_get_listener"));
|
||||||
|
|
||||||
|
if (auto* error = dlerror()) {
|
||||||
|
qCCritical(logDeref) << "Failed to find wl_proxy_get_listener for hooking:" << error;
|
||||||
|
} else {
|
||||||
|
qCInfo(logDeref) << "Installed wl_proxy_get_listener hook.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// NOLINTEND
|
||||||
Loading…
Add table
Add a link
Reference in a new issue