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
|
|
@ -73,6 +73,7 @@ endfunction()
|
|||
# -----
|
||||
|
||||
qt_add_library(quickshell-wayland STATIC
|
||||
wl_proxy_safe_deref.cpp
|
||||
platformmenu.cpp
|
||||
popupanchor.cpp
|
||||
xdgshell.cpp
|
||||
|
|
@ -80,6 +81,13 @@ qt_add_library(quickshell-wayland STATIC
|
|||
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
|
||||
add_library(quickshell-wayland-init OBJECT init.cpp)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "wlr_layershell/wlr_layershell.hpp"
|
||||
#endif
|
||||
|
||||
void installWlProxySafeDeref(); // NOLINT(misc-use-internal-linkage)
|
||||
void installPlatformMenuHook(); // NOLINT(misc-use-internal-linkage)
|
||||
void installPopupPositioner(); // NOLINT(misc-use-internal-linkage)
|
||||
|
||||
|
|
@ -33,6 +34,7 @@ class WaylandPlugin: public QsEnginePlugin {
|
|||
}
|
||||
|
||||
void init() override {
|
||||
installWlProxySafeDeref();
|
||||
installPlatformMenuHook();
|
||||
installPopupPositioner();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
#include <qobjectdefs.h>
|
||||
#include <qproperty.h>
|
||||
|
||||
#include "../../windowmanager/screenprojection.hpp"
|
||||
#include "../../windowmanager/windowmanager.hpp"
|
||||
#include "../../windowmanager/windowset.hpp"
|
||||
#include "../../windowmanager/screenprojection.hpp"
|
||||
#include "ext_workspace.hpp"
|
||||
|
||||
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