diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 958c884..80fa827 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -1,17 +1,82 @@ name: Crash Report (v1) -description: Quickshell has crashed (old) -labels: ["unactionable"] +description: Quickshell has crashed +labels: ["bug", "crash"] body: - - type: markdown + - type: textarea + id: crashinfo attributes: - value: | - Thank you for taking the time to click the report button. - At this point most of the worst issues in 0.2.1 and before have been fixed and we are - preparing for a new release. Please do not submit this report. - - type: checkboxes - id: donotcheck + label: General crash information + description: | + Paste the contents of the `info.txt` file in your crash folder here. + value: "
General information + + + ``` + + + + ``` + + +
" + validations: + required: true + - type: textarea + id: userinfo attributes: - label: Read the text above. Do not submit the report. - options: - - label: Yes I want this report to be deleted. - required: true + label: What caused the crash + description: | + Any information likely to help debug the crash. What were you doing when the crash occurred, + what changes did you make, can you get it to happen again? + - type: textarea + id: dump + attributes: + label: Minidump + description: | + Attach `minidump.dmp.log` here. If it is too big to upload, compress it. + + You may skip this step if quickshell crashed while processing a password + or other sensitive information. If you skipped it write why instead. + validations: + required: true + - type: textarea + id: logs + attributes: + label: Log file + description: | + Attach `log.qslog.log` here. If it is too big to upload, compress it. + + You can preview the log if you'd like using `quickshell read-log `. + validations: + required: true + - type: textarea + id: config + attributes: + label: Configuration + description: | + Attach your configuration here, preferrably in full (not just one file). + Compress it into a zip, tar, etc. + + This will help us reproduce the crash ourselves. + - type: textarea + id: bt + attributes: + label: Backtrace + description: | + If you have gdb installed and use systemd, or otherwise know how to get a backtrace, + we would appreciate one. (You may have gdb installed without knowing it) + + 1. Run `coredumpctl debug ` where `pid` is the number shown after "Crashed process ID" + in the crash reporter. + 2. Once it loads, type `bt -full` (then enter) + 3. Copy the output and attach it as a file or in a spoiler. + - type: textarea + id: exe + attributes: + label: Executable + description: | + If the crash folder contains a executable.txt file, upload it here. If not you can ignore this field. + If it is too big to upload, compress it. + + Note: executable.txt is the quickshell binary. It has a .txt extension due to github's limitations on + filetypes. diff --git a/.github/ISSUE_TEMPLATE/crash2.yml b/.github/ISSUE_TEMPLATE/crash2.yml index 86f490c..84beef8 100644 --- a/.github/ISSUE_TEMPLATE/crash2.yml +++ b/.github/ISSUE_TEMPLATE/crash2.yml @@ -9,21 +9,21 @@ body: description: | Any information likely to help debug the crash. What were you doing when the crash occurred, what changes did you make, can you get it to happen again? - - type: upload + - type: textarea id: report attributes: label: Report file description: Attach `report.txt` here. validations: required: true - - type: upload + - type: textarea id: logs attributes: label: Log file description: | Attach `log.qslog.log` here. If it is too big to upload, compress it. - You can preview the log if you'd like using `qs log -r '*=true'`. + You can preview the log if you'd like using `quickshell read-log `. validations: required: true - type: textarea @@ -31,7 +31,7 @@ body: attributes: label: Configuration description: | - Attach or link your configuration here, preferrably in full (not just one file). + Attach your configuration here, preferrably in full (not just one file). Compress it into a zip, tar, etc. This will help us reproduce the crash ourselves. diff --git a/changelog/next.md b/changelog/next.md index a8981b9..cbfd51b 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -48,7 +48,6 @@ set shell id. - Fixed volumes not initializing if a pipewire device was already loaded before its node. - Fixed hyprland active toplevel not resetting after window closes. - Fixed hyprland ipc window names and titles being reversed. -- Fixed a hyprland ipc crash when refreshing toplevels before workspaces. - Fixed missing signals for system tray item title and description updates. - Fixed asynchronous loaders not working after reload. - Fixed asynchronous loaders not working before window creation. @@ -59,8 +58,6 @@ set shell id. - Fixed ToplevelManager not clearing activeToplevel on deactivation. - Desktop action order is now preserved. - Fixed partial socket reads in greetd and hyprland on slow machines. -- Worked around Qt bug causing crashes when plugging and unplugging monitors. -- Fixed HyprlandFocusGrab crashing if windows were destroyed after being passed to it. ## Packaging Changes diff --git a/src/core/logging.cpp b/src/core/logging.cpp index 893c56e..d24225b 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -31,9 +31,6 @@ #include #include #endif -#ifdef __FreeBSD__ -#include -#endif #include "instanceinfo.hpp" #include "logcat.hpp" @@ -70,7 +67,7 @@ bool copyFileData(int sourceFd, int destFd, qint64 size) { return true; #else std::array buffer = {}; - auto remaining = usize; + auto remaining = totalTarget; while (remaining > 0) { auto chunk = std::min(remaining, buffer.size()); diff --git a/src/core/platformmenu.cpp b/src/core/platformmenu.cpp index d8901e2..427dde0 100644 --- a/src/core/platformmenu.cpp +++ b/src/core/platformmenu.cpp @@ -18,6 +18,7 @@ #include #include "../window/proxywindow.hpp" +#include "../window/windowinterface.hpp" #include "iconprovider.hpp" #include "model.hpp" #include "platformmenu_p.hpp" @@ -90,8 +91,10 @@ bool PlatformMenuEntry::display(QObject* parentWindow, int relativeX, int relati } else if (parentWindow == nullptr) { qCritical() << "Cannot display PlatformMenuEntry with null parent window."; return false; - } else if (auto* proxy = ProxyWindowBase::forObject(parentWindow)) { + } else if (auto* proxy = qobject_cast(parentWindow)) { window = proxy->backingWindow(); + } else if (auto* interface = qobject_cast(parentWindow)) { + window = interface->proxyWindow()->backingWindow(); } else { qCritical() << "PlatformMenuEntry.display() must be called with a window."; return false; diff --git a/src/core/popupanchor.cpp b/src/core/popupanchor.cpp index ca817c9..151dd5d 100644 --- a/src/core/popupanchor.cpp +++ b/src/core/popupanchor.cpp @@ -11,6 +11,7 @@ #include #include "../window/proxywindow.hpp" +#include "../window/windowinterface.hpp" #include "types.hpp" bool PopupAnchorState::operator==(const PopupAnchorState& other) const { @@ -39,8 +40,10 @@ void PopupAnchor::setWindowInternal(QObject* window) { } if (window) { - if (auto* proxy = ProxyWindowBase::forObject(window)) { + if (auto* proxy = qobject_cast(window)) { this->bProxyWindow = proxy; + } else if (auto* interface = qobject_cast(window)) { + this->bProxyWindow = interface->proxyWindow(); } else { qWarning() << "Tried to set popup anchor window to" << window << "which is not a quickshell window."; diff --git a/src/services/pam/conversation.cpp b/src/services/pam/conversation.cpp index 1fb4c04..f8f5a09 100644 --- a/src/services/pam/conversation.cpp +++ b/src/services/pam/conversation.cpp @@ -8,9 +8,6 @@ #include #include #include -#ifdef __FreeBSD__ -#include -#endif #include "../../core/logcat.hpp" #include "ipc.hpp" diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 4a67558..db53f37 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -73,7 +73,6 @@ endfunction() # ----- qt_add_library(quickshell-wayland STATIC - wl_proxy_safe_deref.cpp platformmenu.cpp popupanchor.cpp xdgshell.cpp @@ -81,10 +80,6 @@ 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") - # required to make sure the constructor is linked add_library(quickshell-wayland-init OBJECT init.cpp) diff --git a/src/wayland/hyprland/focus_grab/qml.cpp b/src/wayland/hyprland/focus_grab/qml.cpp index cf1ac24..e26a75a 100644 --- a/src/wayland/hyprland/focus_grab/qml.cpp +++ b/src/wayland/hyprland/focus_grab/qml.cpp @@ -9,6 +9,7 @@ #include #include "../../../window/proxywindow.hpp" +#include "../../../window/windowinterface.hpp" #include "grab.hpp" #include "manager.hpp" @@ -37,51 +38,8 @@ QObjectList HyprlandFocusGrab::windows() const { return this->windowObjects; } void HyprlandFocusGrab::setWindows(QObjectList windows) { if (windows == this->windowObjects) return; - if (this->grab) this->grab->startTransaction(); - - for (auto* obj: this->windowObjects) { - if (windows.contains(obj)) continue; - QObject::disconnect(obj, nullptr, this, nullptr); - - auto* proxy = ProxyWindowBase::forObject(obj); - if (!proxy) continue; - - QObject::disconnect(proxy, nullptr, this, nullptr); - - if (this->grab && proxy->backingWindow()) { - this->grab->removeWindow(proxy->backingWindow()); - } - } - - for (auto it = windows.begin(); it != windows.end();) { - auto* proxy = ProxyWindowBase::forObject(*it); - if (!proxy) { - it = windows.erase(it); - continue; - } - - if (this->windowObjects.contains(*it)) { - ++it; - continue; - } - - QObject::connect(*it, &QObject::destroyed, this, &HyprlandFocusGrab::onObjectDestroyed); - QObject::connect( - proxy, - &ProxyWindowBase::windowConnected, - this, - &HyprlandFocusGrab::onProxyConnected - ); - - if (this->grab && proxy->backingWindow()) { - this->grab->addWindow(proxy->backingWindow()); - } - - ++it; - } - - if (this->grab) this->grab->completeTransaction(); this->windowObjects = std::move(windows); + this->syncWindows(); emit this->windowsChanged(); } @@ -117,18 +75,59 @@ void HyprlandFocusGrab::tryActivate() { QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared); this->grab->startTransaction(); - for (auto* obj: this->windowObjects) { - auto* proxy = ProxyWindowBase::forObject(obj); - if (proxy && proxy->backingWindow()) { + for (auto* proxy: this->trackedProxies) { + if (proxy->backingWindow() != nullptr) { this->grab->addWindow(proxy->backingWindow()); } } this->grab->completeTransaction(); } -void HyprlandFocusGrab::onObjectDestroyed(QObject* object) { - this->windowObjects.removeOne(object); - emit this->windowsChanged(); +void HyprlandFocusGrab::syncWindows() { + auto newProxy = QList(); + for (auto* windowObject: this->windowObjects) { + auto* proxyWindow = qobject_cast(windowObject); + + if (proxyWindow == nullptr) { + if (auto* iface = qobject_cast(windowObject)) { + proxyWindow = iface->proxyWindow(); + } + } + + if (proxyWindow != nullptr) { + newProxy.push_back(proxyWindow); + } + } + + if (this->grab) this->grab->startTransaction(); + + for (auto* oldWindow: this->trackedProxies) { + if (!newProxy.contains(oldWindow)) { + QObject::disconnect(oldWindow, nullptr, this, nullptr); + + if (this->grab != nullptr && oldWindow->backingWindow() != nullptr) { + this->grab->removeWindow(oldWindow->backingWindow()); + } + } + } + + for (auto* newProxy: newProxy) { + if (!this->trackedProxies.contains(newProxy)) { + QObject::connect( + newProxy, + &ProxyWindowBase::windowConnected, + this, + &HyprlandFocusGrab::onProxyConnected + ); + + if (this->grab != nullptr && newProxy->backingWindow() != nullptr) { + this->grab->addWindow(newProxy->backingWindow()); + } + } + } + + this->trackedProxies = newProxy; + if (this->grab) this->grab->completeTransaction(); } } // namespace qs::hyprland diff --git a/src/wayland/hyprland/focus_grab/qml.hpp b/src/wayland/hyprland/focus_grab/qml.hpp index 97a10de..705b0d3 100644 --- a/src/wayland/hyprland/focus_grab/qml.hpp +++ b/src/wayland/hyprland/focus_grab/qml.hpp @@ -96,13 +96,15 @@ private slots: void onGrabActivated(); void onGrabCleared(); void onProxyConnected(); - void onObjectDestroyed(QObject* object); private: void tryActivate(); + void syncWindows(); bool targetActive = false; QObjectList windowObjects; + QList trackedProxies; + QList trackedWindows; focus_grab::FocusGrab* grab = nullptr; }; diff --git a/src/wayland/hyprland/ipc/connection.cpp b/src/wayland/hyprland/ipc/connection.cpp index d15701d..d2d5105 100644 --- a/src/wayland/hyprland/ipc/connection.cpp +++ b/src/wayland/hyprland/ipc/connection.cpp @@ -729,7 +729,7 @@ void HyprlandIpc::refreshToplevels() { } auto* workspace = toplevel->bindableWorkspace().value(); - if (workspace) workspace->insertToplevel(toplevel); + workspace->insertToplevel(toplevel); } }); } diff --git a/src/wayland/hyprland/ipc/hyprland_toplevel.cpp b/src/wayland/hyprland/ipc/hyprland_toplevel.cpp index 43b9838..7b07bc8 100644 --- a/src/wayland/hyprland/ipc/hyprland_toplevel.cpp +++ b/src/wayland/hyprland/ipc/hyprland_toplevel.cpp @@ -72,16 +72,20 @@ void HyprlandToplevel::updateFromObject(const QVariantMap& object) { Qt::beginPropertyUpdateGroup(); bool ok = false; auto address = addressStr.toULongLong(&ok, 16); - if (ok && address) this->setAddress(address); + if (!ok || !address) { + return; + } + this->setAddress(address); this->bTitle = title; auto workspaceMap = object.value("workspace").toMap(); auto workspaceName = workspaceMap.value("name").toString(); - auto* workspace = this->ipc->findWorkspaceByName(workspaceName, true); - if (workspace) this->setWorkspace(workspace); + auto* workspace = this->ipc->findWorkspaceByName(workspaceName, false); + if (!workspace) return; + this->setWorkspace(workspace); this->bLastIpcObject = object; Qt::endPropertyUpdateGroup(); } diff --git a/src/wayland/hyprland/surface/qml.cpp b/src/wayland/hyprland/surface/qml.cpp index 4575842..c4f7d67 100644 --- a/src/wayland/hyprland/surface/qml.cpp +++ b/src/wayland/hyprland/surface/qml.cpp @@ -14,6 +14,7 @@ #include "../../../core/region.hpp" #include "../../../window/proxywindow.hpp" +#include "../../../window/windowinterface.hpp" #include "manager.hpp" #include "surface.hpp" @@ -22,7 +23,13 @@ using QtWaylandClient::QWaylandWindow; namespace qs::hyprland::surface { HyprlandWindow* HyprlandWindow::qmlAttachedProperties(QObject* object) { - auto* proxyWindow = ProxyWindowBase::forObject(object); + auto* proxyWindow = qobject_cast(object); + + if (!proxyWindow) { + if (auto* iface = qobject_cast(object)) { + proxyWindow = iface->proxyWindow(); + } + } if (!proxyWindow) return nullptr; return new HyprlandWindow(proxyWindow); diff --git a/src/wayland/idle_inhibit/inhibitor.cpp b/src/wayland/idle_inhibit/inhibitor.cpp index bfea7a0..efeeae1 100644 --- a/src/wayland/idle_inhibit/inhibitor.cpp +++ b/src/wayland/idle_inhibit/inhibitor.cpp @@ -6,6 +6,7 @@ #include #include "../../window/proxywindow.hpp" +#include "../../window/windowinterface.hpp" #include "proto.hpp" namespace qs::wayland::idle_inhibit { @@ -24,13 +25,27 @@ QObject* IdleInhibitor::window() const { return this->bWindowObject; } void IdleInhibitor::setWindow(QObject* window) { if (window == this->bWindowObject) return; - auto* proxyWindow = ProxyWindowBase::forObject(window); + auto* proxyWindow = qobject_cast(window); + + if (proxyWindow == nullptr) { + if (auto* iface = qobject_cast(window)) { + proxyWindow = iface->proxyWindow(); + } + } + this->bWindowObject = proxyWindow ? window : nullptr; } void IdleInhibitor::boundWindowChanged() { auto* window = this->bBoundWindow.value(); - auto* proxyWindow = ProxyWindowBase::forObject(window); + auto* proxyWindow = qobject_cast(window); + + if (proxyWindow == nullptr) { + if (auto* iface = qobject_cast(window)) { + proxyWindow = iface->proxyWindow(); + } + } + if (proxyWindow == this->proxyWindow) return; if (this->mWaylandWindow) { diff --git a/src/wayland/init.cpp b/src/wayland/init.cpp index 790cebb..e56eee3 100644 --- a/src/wayland/init.cpp +++ b/src/wayland/init.cpp @@ -10,7 +10,6 @@ #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) @@ -34,7 +33,6 @@ class WaylandPlugin: public QsEnginePlugin { } void init() override { - installWlProxySafeDeref(); installPlatformMenuHook(); installPopupPositioner(); } diff --git a/src/wayland/shortcuts_inhibit/inhibitor.cpp b/src/wayland/shortcuts_inhibit/inhibitor.cpp index a91d5e2..2fca9bc 100644 --- a/src/wayland/shortcuts_inhibit/inhibitor.cpp +++ b/src/wayland/shortcuts_inhibit/inhibitor.cpp @@ -9,6 +9,7 @@ #include #include "../../window/proxywindow.hpp" +#include "../../window/windowinterface.hpp" #include "proto.hpp" namespace qs::wayland::shortcuts_inhibit { @@ -47,7 +48,14 @@ ShortcutInhibitor::~ShortcutInhibitor() { void ShortcutInhibitor::onBoundWindowChanged() { auto* window = this->bBoundWindow.value(); - auto* proxyWindow = ProxyWindowBase::forObject(window); + auto* proxyWindow = qobject_cast(window); + + if (!proxyWindow) { + if (auto* iface = qobject_cast(window)) { + proxyWindow = iface->proxyWindow(); + } + } + if (proxyWindow == this->proxyWindow) return; if (this->proxyWindow) { diff --git a/src/wayland/toplevel_management/qml.cpp b/src/wayland/toplevel_management/qml.cpp index cb53381..6a1d96b 100644 --- a/src/wayland/toplevel_management/qml.cpp +++ b/src/wayland/toplevel_management/qml.cpp @@ -9,6 +9,7 @@ #include "../../core/qmlscreen.hpp" #include "../../core/util.hpp" #include "../../window/proxywindow.hpp" +#include "../../window/windowinterface.hpp" #include "../output_tracking.hpp" #include "handle.hpp" #include "manager.hpp" @@ -72,7 +73,13 @@ void Toplevel::fullscreenOn(QuickshellScreenInfo* screen) { } void Toplevel::setRectangle(QObject* window, QRect rect) { - auto* proxyWindow = ProxyWindowBase::forObject(window); + auto* proxyWindow = qobject_cast(window); + + if (proxyWindow == nullptr) { + if (auto* iface = qobject_cast(window)) { + proxyWindow = iface->proxyWindow(); + } + } if (proxyWindow != this->rectWindow) { if (this->rectWindow != nullptr) { diff --git a/src/wayland/windowmanager/windowset.cpp b/src/wayland/windowmanager/windowset.cpp index 74e273d..796cfe2 100644 --- a/src/wayland/windowmanager/windowset.cpp +++ b/src/wayland/windowmanager/windowset.cpp @@ -8,9 +8,9 @@ #include #include -#include "../../windowmanager/screenprojection.hpp" #include "../../windowmanager/windowmanager.hpp" #include "../../windowmanager/windowset.hpp" +#include "../../windowmanager/screenprojection.hpp" #include "ext_workspace.hpp" namespace qs::wm::wayland { diff --git a/src/wayland/wl_proxy_safe_deref.cpp b/src/wayland/wl_proxy_safe_deref.cpp deleted file mode 100644 index 2664a99..0000000 --- a/src/wayland/wl_proxy_safe_deref.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include -#include - -#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(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 diff --git a/src/wayland/wlr_layershell/surface.cpp b/src/wayland/wlr_layershell/surface.cpp index 0b0e7d7..4a5015e 100644 --- a/src/wayland/wlr_layershell/surface.cpp +++ b/src/wayland/wlr_layershell/surface.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "../../window/panelinterface.hpp" #include "shell_integration.hpp" @@ -248,19 +247,9 @@ void LayerSurface::commit() { } void LayerSurface::attachPopup(QtWaylandClient::QWaylandShellSurface* popup) { -#ifdef __FreeBSD__ - // FreeBSD uses an alternate RTTI matching strategy by default which does - // not work across modules, preventing std::any from downcasting. On - // FreeBSD, Qt is built with a patch to expose the surface role through a - // pointer instead of an any, which does not have this problem. - // See https://bugs.kde.org/show_bug.cgi?id=479679 - if (auto* xdgPopup = static_cast<::xdg_popup*>(popup->nativeResource("xdg_popup"))) { - this->get_popup(xdgPopup); - return; - } -#endif - auto role = popup->surfaceRole(); // NOLINT - if (auto* popupRole = std::any_cast<::xdg_popup*>(&role)) { + std::any role = popup->surfaceRole(); + + if (auto* popupRole = std::any_cast<::xdg_popup*>(&role)) { // NOLINT this->get_popup(*popupRole); } else { qWarning() << "Cannot attach popup" << popup << "to shell surface" << this diff --git a/src/window/proxywindow.cpp b/src/window/proxywindow.cpp index 8a20dfa..62126bd 100644 --- a/src/window/proxywindow.cpp +++ b/src/window/proxywindow.cpp @@ -57,12 +57,6 @@ ProxyWindowBase::ProxyWindowBase(QObject* parent) ProxyWindowBase::~ProxyWindowBase() { this->deleteWindow(true); } -ProxyWindowBase* ProxyWindowBase::forObject(QObject* obj) { - if (auto* proxy = qobject_cast(obj)) return proxy; - if (auto* iface = qobject_cast(obj)) return iface->proxyWindow(); - return nullptr; -} - void ProxyWindowBase::onReload(QObject* oldInstance) { if (this->mVisible) this->window = this->retrieveWindow(oldInstance); auto wasVisible = this->window != nullptr && this->window->isVisible(); diff --git a/src/window/proxywindow.hpp b/src/window/proxywindow.hpp index 9ff66c4..aec821e 100644 --- a/src/window/proxywindow.hpp +++ b/src/window/proxywindow.hpp @@ -66,8 +66,6 @@ public: explicit ProxyWindowBase(QObject* parent = nullptr); ~ProxyWindowBase() override; - static ProxyWindowBase* forObject(QObject* obj); - ProxyWindowBase(ProxyWindowBase&) = delete; ProxyWindowBase(ProxyWindowBase&&) = delete; void operator=(ProxyWindowBase&) = delete;