wayland/toplevel: reorganize toplevel management
This commit is contained in:
parent
d1760ed1f3
commit
7d1c9a9c67
20 changed files with 163 additions and 199 deletions
|
|
@ -105,7 +105,7 @@ if (WAYLAND_SESSION_LOCK)
|
|||
endif()
|
||||
|
||||
if (WAYLAND_TOPLEVEL_MANAGEMENT)
|
||||
add_subdirectory(toplevel_management)
|
||||
add_subdirectory(toplevel)
|
||||
list(APPEND WAYLAND_MODULES Quickshell.Wayland._ToplevelManagement)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "../../../core/logcat.hpp"
|
||||
#include "../../../core/model.hpp"
|
||||
#include "../../../core/qmlscreen.hpp"
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "hyprland_toplevel.hpp"
|
||||
#include "monitor.hpp"
|
||||
#include "toplevel_mapping.hpp"
|
||||
|
|
@ -139,11 +139,10 @@ void HyprlandIpc::eventSocketReady() {
|
|||
}
|
||||
|
||||
void HyprlandIpc::toplevelAddressed(
|
||||
wayland::toplevel_management::impl::ToplevelHandle* handle,
|
||||
wayland::toplevel::wlr::ToplevelHandle* handle,
|
||||
quint64 address
|
||||
) {
|
||||
auto* waylandToplevel =
|
||||
wayland::toplevel_management::ToplevelManager::instance()->forImpl(handle);
|
||||
auto* waylandToplevel = wayland::toplevel::ToplevelManager::instance()->forImpl(handle);
|
||||
|
||||
if (!waylandToplevel) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "../../../core/model.hpp"
|
||||
#include "../../../core/qmlscreen.hpp"
|
||||
#include "../../../core/streamreader.hpp"
|
||||
#include "../../../wayland/toplevel_management/handle.hpp"
|
||||
#include "../../../wayland/toplevel/wlr_toplevel.hpp"
|
||||
|
||||
namespace qs::hyprland::ipc {
|
||||
|
||||
|
|
@ -128,10 +128,7 @@ private slots:
|
|||
void eventSocketStateChanged(QLocalSocket::LocalSocketState state);
|
||||
void eventSocketReady();
|
||||
|
||||
void toplevelAddressed(
|
||||
qs::wayland::toplevel_management::impl::ToplevelHandle* handle,
|
||||
quint64 address
|
||||
);
|
||||
void toplevelAddressed(qs::wayland::toplevel::wlr::ToplevelHandle* handle, quint64 address);
|
||||
|
||||
void onFocusedMonitorDestroyed();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@
|
|||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "../../toplevel_management/qml.hpp"
|
||||
#include "../../toplevel/qml.hpp"
|
||||
#include "connection.hpp"
|
||||
#include "toplevel_mapping.hpp"
|
||||
#include "workspace.hpp"
|
||||
|
||||
using namespace qs::wayland::toplevel_management;
|
||||
using namespace qs::wayland::toplevel;
|
||||
|
||||
namespace qs::hyprland::ipc {
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ Toplevel* HyprlandToplevel::waylandHandle() {
|
|||
return ToplevelManager::instance()->forImpl(this->mWaylandHandle);
|
||||
}
|
||||
|
||||
void HyprlandToplevel::setWaylandHandle(impl::ToplevelHandle* handle) {
|
||||
void HyprlandToplevel::setWaylandHandle(wlr::ToplevelHandle* handle) {
|
||||
if (this->mWaylandHandle == handle) return;
|
||||
if (this->mWaylandHandle) {
|
||||
QObject::disconnect(this->mWaylandHandle, nullptr, this, nullptr);
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel_management/qml.hpp"
|
||||
#include "../../toplevel/qml.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "connection.hpp"
|
||||
|
||||
namespace qs::hyprland::ipc {
|
||||
|
|
@ -30,7 +30,7 @@ class HyprlandToplevel: public QObject {
|
|||
/// Will be null until the address is reported
|
||||
Q_PROPERTY(HyprlandToplevel* handle READ hyprlandHandle NOTIFY hyprlandHandleChanged);
|
||||
/// The wayland toplevel handle. Will be null intil the address is reported
|
||||
Q_PROPERTY(qs::wayland::toplevel_management::Toplevel* wayland READ waylandHandle NOTIFY waylandHandleChanged);
|
||||
Q_PROPERTY(qs::wayland::toplevel::Toplevel* wayland READ waylandHandle NOTIFY waylandHandleChanged);
|
||||
/// The title of the toplevel
|
||||
Q_PROPERTY(QString title READ default NOTIFY titleChanged BINDABLE bindableTitle);
|
||||
/// Whether the toplevel is active or not
|
||||
|
|
@ -53,7 +53,7 @@ public:
|
|||
/// When invoked from HyprlandIpc, reacting to Hyprland's IPC events.
|
||||
explicit HyprlandToplevel(HyprlandIpc* ipc);
|
||||
/// When attached from a Toplevel
|
||||
explicit HyprlandToplevel(HyprlandIpc* ipc, qs::wayland::toplevel_management::Toplevel* toplevel);
|
||||
explicit HyprlandToplevel(HyprlandIpc* ipc, qs::wayland::toplevel::Toplevel* toplevel);
|
||||
|
||||
static HyprlandToplevel* qmlAttachedProperties(QObject* object);
|
||||
|
||||
|
|
@ -69,8 +69,8 @@ public:
|
|||
[[nodiscard]] HyprlandToplevel* hyprlandHandle() { return this->mHyprlandHandle; }
|
||||
void setHyprlandHandle(HyprlandToplevel* handle);
|
||||
|
||||
[[nodiscard]] wayland::toplevel_management::Toplevel* waylandHandle();
|
||||
void setWaylandHandle(wayland::toplevel_management::impl::ToplevelHandle* handle);
|
||||
[[nodiscard]] wayland::toplevel::Toplevel* waylandHandle();
|
||||
void setWaylandHandle(wayland::toplevel::wlr::ToplevelHandle* handle);
|
||||
// clang-format on
|
||||
|
||||
[[nodiscard]] QBindable<QString> bindableTitle() { return &this->bTitle; }
|
||||
|
|
@ -105,7 +105,7 @@ private:
|
|||
quint64 mAddress = 0;
|
||||
HyprlandIpc* ipc;
|
||||
|
||||
qs::wayland::toplevel_management::impl::ToplevelHandle* mWaylandHandle = nullptr;
|
||||
qs::wayland::toplevel::wlr::ToplevelHandle* mWaylandHandle = nullptr;
|
||||
HyprlandToplevel* mHyprlandHandle = nullptr;
|
||||
|
||||
// clang-format off
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
#include <qtypes.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "../../toplevel_management/manager.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
|
||||
using namespace qs::wayland::toplevel_management::impl;
|
||||
using namespace qs::wayland::toplevel::wlr;
|
||||
|
||||
namespace qs::hyprland::ipc {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include <qwayland-hyprland-toplevel-mapping-v1.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "wayland-hyprland-toplevel-mapping-v1-client-protocol.h"
|
||||
|
||||
namespace qs::hyprland::ipc {
|
||||
|
|
@ -16,7 +16,7 @@ namespace qs::hyprland::ipc {
|
|||
class HyprlandToplevelMappingHandle: QtWayland::hyprland_toplevel_window_mapping_handle_v1 {
|
||||
public:
|
||||
explicit HyprlandToplevelMappingHandle(
|
||||
qs::wayland::toplevel_management::impl::ToplevelHandle* handle,
|
||||
qs::wayland::toplevel::wlr::ToplevelHandle* handle,
|
||||
::hyprland_toplevel_window_mapping_handle_v1* mapping
|
||||
)
|
||||
: QtWayland::hyprland_toplevel_window_mapping_handle_v1(mapping)
|
||||
|
|
@ -34,7 +34,7 @@ protected:
|
|||
void hyprland_toplevel_window_mapping_handle_v1_failed() override;
|
||||
|
||||
private:
|
||||
qs::wayland::toplevel_management::impl::ToplevelHandle* handle;
|
||||
qs::wayland::toplevel::wlr::ToplevelHandle* handle;
|
||||
};
|
||||
|
||||
class HyprlandToplevelMappingManager
|
||||
|
|
@ -48,22 +48,18 @@ public:
|
|||
static HyprlandToplevelMappingManager* instance();
|
||||
|
||||
[[nodiscard]] quint64
|
||||
getToplevelAddress(qs::wayland::toplevel_management::impl::ToplevelHandle* handle) const;
|
||||
getToplevelAddress(qs::wayland::toplevel::wlr::ToplevelHandle* handle) const;
|
||||
|
||||
signals:
|
||||
void toplevelAddressed(
|
||||
qs::wayland::toplevel_management::impl::ToplevelHandle* handle,
|
||||
quint64 address
|
||||
);
|
||||
void toplevelAddressed(qs::wayland::toplevel::wlr::ToplevelHandle* handle, quint64 address);
|
||||
|
||||
private slots:
|
||||
void onToplevelReady(qs::wayland::toplevel_management::impl::ToplevelHandle* handle);
|
||||
void onToplevelReady(qs::wayland::toplevel::wlr::ToplevelHandle* handle);
|
||||
void onToplevelDestroyed(QObject* object);
|
||||
|
||||
private:
|
||||
void
|
||||
assignAddress(qs::wayland::toplevel_management::impl::ToplevelHandle* handle, quint64 address);
|
||||
QHash<wayland::toplevel_management::impl::ToplevelHandle*, quint64> addresses;
|
||||
void assignAddress(qs::wayland::toplevel::wlr::ToplevelHandle* handle, quint64 address);
|
||||
QHash<wayland::toplevel::wlr::ToplevelHandle*, quint64> addresses;
|
||||
|
||||
friend class HyprlandToplevelMappingHandle;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ description = "Wayland specific Quickshell types"
|
|||
headers = [
|
||||
"wlr_layershell/wlr_layershell.hpp",
|
||||
"session_lock.hpp",
|
||||
"toplevel_management/qml.hpp",
|
||||
"toplevel/qml.hpp",
|
||||
"screencopy/view.hpp",
|
||||
"idle_inhibit/inhibitor.hpp",
|
||||
"idle_notify/monitor.hpp",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <wayland-hyprland-toplevel-export-v1-client-protocol.h>
|
||||
|
||||
#include "../../../core/logcat.hpp"
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "../manager.hpp"
|
||||
#include "hyprland_screencopy_p.hpp"
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ HyprlandScreencopyManager* HyprlandScreencopyManager::instance() {
|
|||
}
|
||||
|
||||
ScreencopyContext* HyprlandScreencopyManager::captureToplevel(
|
||||
toplevel_management::impl::ToplevelHandle* handle,
|
||||
toplevel::wlr::ToplevelHandle* handle,
|
||||
bool paintCursors
|
||||
) {
|
||||
return new HyprlandScreencopyContext(this, handle, paintCursors);
|
||||
|
|
@ -37,7 +37,7 @@ ScreencopyContext* HyprlandScreencopyManager::captureToplevel(
|
|||
|
||||
HyprlandScreencopyContext::HyprlandScreencopyContext(
|
||||
HyprlandScreencopyManager* manager,
|
||||
toplevel_management::impl::ToplevelHandle* handle,
|
||||
toplevel::wlr::ToplevelHandle* handle,
|
||||
bool paintCursors
|
||||
)
|
||||
: manager(manager)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <qwayland-hyprland-toplevel-export-v1.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "../manager.hpp"
|
||||
|
||||
namespace qs::wayland::screencopy::hyprland {
|
||||
|
|
@ -12,8 +12,7 @@ class HyprlandScreencopyManager
|
|||
: public QWaylandClientExtensionTemplate<HyprlandScreencopyManager>
|
||||
, public QtWayland::hyprland_toplevel_export_manager_v1 {
|
||||
public:
|
||||
ScreencopyContext*
|
||||
captureToplevel(toplevel_management::impl::ToplevelHandle* handle, bool paintCursors);
|
||||
ScreencopyContext* captureToplevel(toplevel::wlr::ToplevelHandle* handle, bool paintCursors);
|
||||
|
||||
static HyprlandScreencopyManager* instance();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <qtclasshelpermacros.h>
|
||||
#include <qwayland-hyprland-toplevel-export-v1.h>
|
||||
|
||||
#include "../../toplevel_management/handle.hpp"
|
||||
#include "../../toplevel/wlr_toplevel.hpp"
|
||||
#include "../manager.hpp"
|
||||
|
||||
namespace qs::wayland::screencopy::hyprland {
|
||||
|
|
@ -16,7 +16,7 @@ class HyprlandScreencopyContext
|
|||
public:
|
||||
explicit HyprlandScreencopyContext(
|
||||
HyprlandScreencopyManager* manager,
|
||||
toplevel_management::impl::ToplevelHandle* handle,
|
||||
toplevel::wlr::ToplevelHandle* handle,
|
||||
bool paintCursors
|
||||
);
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ private:
|
|||
buffer::WlBufferRequest request;
|
||||
bool copiedFirstFrame = false;
|
||||
|
||||
toplevel_management::impl::ToplevelHandle* handle;
|
||||
toplevel::wlr::ToplevelHandle* handle;
|
||||
bool paintCursors;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#endif
|
||||
|
||||
#if SCREENCOPY_HYPRLAND_TOPLEVEL
|
||||
#include "../toplevel_management/qml.hpp"
|
||||
#include "../toplevel/qml.hpp"
|
||||
#include "hyprland_screencopy/hyprland_screencopy.hpp"
|
||||
#endif
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ ScreencopyContext* ScreencopyManager::createContext(QObject* object, bool paintC
|
|||
}
|
||||
#endif
|
||||
#if SCREENCOPY_HYPRLAND_TOPLEVEL
|
||||
} else if (auto* toplevel = qobject_cast<toplevel_management::Toplevel*>(object)) {
|
||||
} else if (auto* toplevel = qobject_cast<toplevel::Toplevel*>(object)) {
|
||||
auto* manager = hyprland::HyprlandScreencopyManager::instance();
|
||||
if (manager->isActive()) {
|
||||
return manager->captureToplevel(toplevel->implHandle(), paintCursors);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
qt_add_library(quickshell-wayland-toplevel-management STATIC
|
||||
manager.cpp
|
||||
handle.cpp
|
||||
wlr_toplevel.cpp
|
||||
qml.cpp
|
||||
)
|
||||
|
||||
|
|
@ -10,23 +10,22 @@
|
|||
#include "../../core/util.hpp"
|
||||
#include "../../window/proxywindow.hpp"
|
||||
#include "../output_tracking.hpp"
|
||||
#include "handle.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "wlr_toplevel.hpp"
|
||||
|
||||
namespace qs::wayland::toplevel_management {
|
||||
namespace qs::wayland::toplevel {
|
||||
|
||||
Toplevel::Toplevel(impl::ToplevelHandle* handle, QObject* parent): QObject(parent), handle(handle) {
|
||||
Toplevel::Toplevel(wlr::ToplevelHandle* handle, QObject* parent): QObject(parent), handle(handle) {
|
||||
// clang-format off
|
||||
QObject::connect(handle, &impl::ToplevelHandle::closed, this, &Toplevel::onClosed);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::appIdChanged, this, &Toplevel::appIdChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::titleChanged, this, &Toplevel::titleChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::parentChanged, this, &Toplevel::parentChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::activatedChanged, this, &Toplevel::activatedChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::closed, this, &Toplevel::onClosed);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::appIdChanged, this, &Toplevel::appIdChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::titleChanged, this, &Toplevel::titleChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::parentChanged, this, &Toplevel::parentChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::activatedChanged, this, &Toplevel::activatedChanged);
|
||||
QObject::connect(&handle->visibleScreens, &WlOutputTracker::screenAdded, this, &Toplevel::screensChanged);
|
||||
QObject::connect(&handle->visibleScreens, &WlOutputTracker::screenRemoved, this, &Toplevel::screensChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::maximizedChanged, this, &Toplevel::maximizedChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::minimizedChanged, this, &Toplevel::minimizedChanged);
|
||||
QObject::connect(handle, &impl::ToplevelHandle::fullscreenChanged, this, &Toplevel::fullscreenChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::maximizedChanged, this, &Toplevel::maximizedChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::minimizedChanged, this, &Toplevel::minimizedChanged);
|
||||
QObject::connect(handle, &wlr::ToplevelHandle::fullscreenChanged, this, &Toplevel::fullscreenChanged);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
|
@ -114,11 +113,11 @@ void Toplevel::onRectangleProxyDestroyed() {
|
|||
}
|
||||
|
||||
ToplevelManager::ToplevelManager() {
|
||||
auto* manager = impl::ToplevelManager::instance();
|
||||
auto* manager = wlr::ToplevelManager::instance();
|
||||
|
||||
QObject::connect(
|
||||
manager,
|
||||
&impl::ToplevelManager::toplevelReady,
|
||||
&wlr::ToplevelManager::toplevelReady,
|
||||
this,
|
||||
&ToplevelManager::onToplevelReady
|
||||
);
|
||||
|
|
@ -128,7 +127,7 @@ ToplevelManager::ToplevelManager() {
|
|||
}
|
||||
}
|
||||
|
||||
Toplevel* ToplevelManager::forImpl(impl::ToplevelHandle* impl) const {
|
||||
Toplevel* ToplevelManager::forImpl(wlr::ToplevelHandle* impl) const {
|
||||
if (impl == nullptr) return nullptr;
|
||||
|
||||
for (auto* toplevel: this->mToplevels.valueList()) {
|
||||
|
|
@ -140,7 +139,7 @@ Toplevel* ToplevelManager::forImpl(impl::ToplevelHandle* impl) const {
|
|||
|
||||
ObjectModel<Toplevel>* ToplevelManager::toplevels() { return &this->mToplevels; }
|
||||
|
||||
void ToplevelManager::onToplevelReady(impl::ToplevelHandle* handle) {
|
||||
void ToplevelManager::onToplevelReady(wlr::ToplevelHandle* handle) {
|
||||
auto* toplevel = new Toplevel(handle, this);
|
||||
|
||||
// clang-format off
|
||||
|
|
@ -191,4 +190,4 @@ Toplevel* ToplevelManagerQml::activeToplevel() {
|
|||
return ToplevelManager::instance()->activeToplevel();
|
||||
}
|
||||
|
||||
} // namespace qs::wayland::toplevel_management
|
||||
} // namespace qs::wayland::toplevel
|
||||
|
|
@ -11,12 +11,12 @@
|
|||
#include "../../core/util.hpp"
|
||||
#include "../../window/proxywindow.hpp"
|
||||
|
||||
namespace qs::wayland::toplevel_management {
|
||||
namespace qs::wayland::toplevel {
|
||||
|
||||
namespace impl {
|
||||
namespace wlr {
|
||||
class ToplevelManager; // NOLINT
|
||||
class ToplevelHandle;
|
||||
} // namespace impl
|
||||
} // namespace wlr
|
||||
|
||||
///! Window from another application.
|
||||
/// A window/toplevel from another application, retrievable from
|
||||
|
|
@ -26,7 +26,7 @@ class Toplevel: public QObject {
|
|||
Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged);
|
||||
Q_PROPERTY(QString title READ title NOTIFY titleChanged);
|
||||
/// Parent toplevel if this toplevel is a modal/dialog, otherwise null.
|
||||
Q_PROPERTY(qs::wayland::toplevel_management::Toplevel* parent READ parent NOTIFY parentChanged);
|
||||
Q_PROPERTY(qs::wayland::toplevel::Toplevel* parent READ parent NOTIFY parentChanged);
|
||||
/// If the window is currently activated or focused.
|
||||
///
|
||||
/// Activation can be requested with the @@activate() function.
|
||||
|
|
@ -56,7 +56,7 @@ class Toplevel: public QObject {
|
|||
QML_UNCREATABLE("Toplevels must be acquired from the ToplevelManager.");
|
||||
|
||||
public:
|
||||
explicit Toplevel(impl::ToplevelHandle* handle, QObject* parent);
|
||||
explicit Toplevel(wlr::ToplevelHandle* handle, QObject* parent);
|
||||
|
||||
/// Request that this toplevel is activated.
|
||||
/// The request may be ignored by the compositor.
|
||||
|
|
@ -91,7 +91,7 @@ public:
|
|||
[[nodiscard]] bool fullscreen() const;
|
||||
void setFullscreen(bool fullscreen);
|
||||
|
||||
[[nodiscard]] impl::ToplevelHandle* implHandle() const { return this->handle; }
|
||||
[[nodiscard]] wlr::ToplevelHandle* implHandle() const { return this->handle; }
|
||||
|
||||
signals:
|
||||
void closed();
|
||||
|
|
@ -110,7 +110,7 @@ private slots:
|
|||
void onRectangleProxyDestroyed();
|
||||
|
||||
private:
|
||||
impl::ToplevelHandle* handle;
|
||||
wlr::ToplevelHandle* handle;
|
||||
ProxyWindowBase* rectWindow = nullptr;
|
||||
QRect rectangle;
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ class ToplevelManager: public QObject {
|
|||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
Toplevel* forImpl(impl::ToplevelHandle* impl) const;
|
||||
Toplevel* forImpl(wlr::ToplevelHandle* impl) const;
|
||||
|
||||
[[nodiscard]] ObjectModel<Toplevel>* toplevels();
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ signals:
|
|||
void activeToplevelChanged();
|
||||
|
||||
private slots:
|
||||
void onToplevelReady(impl::ToplevelHandle* handle);
|
||||
void onToplevelReady(wlr::ToplevelHandle* handle);
|
||||
void onToplevelActiveChanged();
|
||||
void onToplevelClosed();
|
||||
|
||||
|
|
@ -158,13 +158,13 @@ class ToplevelManagerQml: public QObject {
|
|||
Q_OBJECT;
|
||||
// clang-format off
|
||||
/// All toplevel windows exposed by the compositor.
|
||||
QSDOC_TYPE_OVERRIDE(ObjectModel<qs::wayland::toplevel_management::Toplevel>*);
|
||||
QSDOC_TYPE_OVERRIDE(ObjectModel<qs::wayland::toplevel::Toplevel>*);
|
||||
Q_PROPERTY(UntypedObjectModel* toplevels READ toplevels CONSTANT);
|
||||
/// Active toplevel or null.
|
||||
///
|
||||
/// > [!INFO] If multiple are active, this will be the most recently activated one.
|
||||
/// > Usually compositors will not report more than one toplevel as active at a time.
|
||||
Q_PROPERTY(qs::wayland::toplevel_management::Toplevel* activeToplevel READ activeToplevel NOTIFY activeToplevelChanged);
|
||||
Q_PROPERTY(qs::wayland::toplevel::Toplevel* activeToplevel READ activeToplevel NOTIFY activeToplevelChanged);
|
||||
// clang-format on
|
||||
QML_NAMED_ELEMENT(ToplevelManager);
|
||||
QML_SINGLETON;
|
||||
|
|
@ -179,4 +179,4 @@ signals:
|
|||
void activeToplevelChanged();
|
||||
};
|
||||
|
||||
} // namespace qs::wayland::toplevel_management
|
||||
} // namespace qs::wayland::toplevel
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "handle.hpp"
|
||||
#include "wlr_toplevel.hpp"
|
||||
#include <cstddef>
|
||||
|
||||
#include <private/qwaylanddisplay_p.h>
|
||||
|
|
@ -13,13 +13,66 @@
|
|||
#include <qobject.h>
|
||||
#include <qscreen.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include "manager.hpp"
|
||||
#include "../../core/logcat.hpp"
|
||||
#include "qwayland-wlr-foreign-toplevel-management-unstable-v1.h"
|
||||
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
|
||||
namespace qs::wayland::toplevel_management::impl {
|
||||
namespace qs::wayland::toplevel::wlr {
|
||||
|
||||
QS_LOGGING_CATEGORY(logToplevelManagement, "quickshell.wayland.toplevelManagement", QtWarningMsg);
|
||||
|
||||
ToplevelManager::ToplevelManager(): QWaylandClientExtensionTemplate(3) { this->initialize(); }
|
||||
|
||||
bool ToplevelManager::available() const { return this->isActive(); }
|
||||
|
||||
const QVector<ToplevelHandle*>& ToplevelManager::readyToplevels() const {
|
||||
return this->mReadyToplevels;
|
||||
}
|
||||
|
||||
ToplevelHandle* ToplevelManager::handleFor(::zwlr_foreign_toplevel_handle_v1* toplevel) {
|
||||
if (toplevel == nullptr) return nullptr;
|
||||
|
||||
for (auto* other: this->mToplevels) {
|
||||
if (other->object() == toplevel) return other;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ToplevelManager* ToplevelManager::instance() {
|
||||
static auto* instance = new ToplevelManager(); // NOLINT
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ToplevelManager::zwlr_foreign_toplevel_manager_v1_toplevel(
|
||||
::zwlr_foreign_toplevel_handle_v1* toplevel
|
||||
) {
|
||||
auto* handle = new ToplevelHandle();
|
||||
QObject::connect(handle, &ToplevelHandle::closed, this, &ToplevelManager::onToplevelClosed);
|
||||
QObject::connect(handle, &ToplevelHandle::ready, this, &ToplevelManager::onToplevelReady);
|
||||
|
||||
qCDebug(logToplevelManagement) << "Toplevel handle created" << handle;
|
||||
this->mToplevels.push_back(handle);
|
||||
|
||||
// Not done in constructor as a close could technically be picked up immediately on init,
|
||||
// making touching the handle a UAF.
|
||||
handle->init(toplevel);
|
||||
}
|
||||
|
||||
void ToplevelManager::onToplevelReady() {
|
||||
auto* handle = qobject_cast<ToplevelHandle*>(this->sender());
|
||||
this->mReadyToplevels.push_back(handle);
|
||||
emit this->toplevelReady(handle);
|
||||
}
|
||||
|
||||
void ToplevelManager::onToplevelClosed() {
|
||||
auto* handle = qobject_cast<ToplevelHandle*>(this->sender());
|
||||
this->mReadyToplevels.removeOne(handle);
|
||||
this->mToplevels.removeOne(handle);
|
||||
}
|
||||
|
||||
QString ToplevelHandle::appId() const { return this->mAppId; }
|
||||
QString ToplevelHandle::title() const { return this->mTitle; }
|
||||
|
|
@ -215,4 +268,4 @@ void ToplevelHandle::onParentClosed() {
|
|||
emit this->parentChanged();
|
||||
}
|
||||
|
||||
} // namespace qs::wayland::toplevel_management::impl
|
||||
} // namespace qs::wayland::toplevel::wlr
|
||||
|
|
@ -1,15 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
#include <qrect.h>
|
||||
#include <qscreen.h>
|
||||
#include <qstring.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qvector.h>
|
||||
#include <qwayland-wlr-foreign-toplevel-management-unstable-v1.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
#include <qwindow.h>
|
||||
|
||||
#include "../../core/logcat.hpp"
|
||||
#include "../output_tracking.hpp"
|
||||
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
|
||||
namespace qs::wayland::toplevel_management::impl {
|
||||
namespace qs::wayland::toplevel::wlr {
|
||||
|
||||
QS_DECLARE_LOGGING_CATEGORY(logToplevelManagement);
|
||||
|
||||
class ToplevelHandle
|
||||
: public QObject
|
||||
|
|
@ -73,4 +81,34 @@ private:
|
|||
QWindow* rectWindow = nullptr;
|
||||
};
|
||||
|
||||
} // namespace qs::wayland::toplevel_management::impl
|
||||
class ToplevelManager
|
||||
: public QWaylandClientExtensionTemplate<ToplevelManager>
|
||||
, public QtWayland::zwlr_foreign_toplevel_manager_v1 {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
[[nodiscard]] bool available() const;
|
||||
[[nodiscard]] const QVector<ToplevelHandle*>& readyToplevels() const;
|
||||
[[nodiscard]] ToplevelHandle* handleFor(::zwlr_foreign_toplevel_handle_v1* toplevel);
|
||||
|
||||
static ToplevelManager* instance();
|
||||
|
||||
signals:
|
||||
void toplevelReady(ToplevelHandle* toplevel);
|
||||
|
||||
protected:
|
||||
explicit ToplevelManager();
|
||||
|
||||
void
|
||||
zwlr_foreign_toplevel_manager_v1_toplevel(::zwlr_foreign_toplevel_handle_v1* toplevel) override;
|
||||
|
||||
private slots:
|
||||
void onToplevelReady();
|
||||
void onToplevelClosed();
|
||||
|
||||
private:
|
||||
QVector<ToplevelHandle*> mToplevels;
|
||||
QVector<ToplevelHandle*> mReadyToplevels;
|
||||
};
|
||||
|
||||
} // namespace qs::wayland::toplevel::wlr
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qlogging.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "../../core/logcat.hpp"
|
||||
#include "handle.hpp"
|
||||
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
|
||||
namespace qs::wayland::toplevel_management::impl {
|
||||
|
||||
QS_LOGGING_CATEGORY(logToplevelManagement, "quickshell.wayland.toplevelManagement", QtWarningMsg);
|
||||
|
||||
ToplevelManager::ToplevelManager(): QWaylandClientExtensionTemplate(3) { this->initialize(); }
|
||||
|
||||
bool ToplevelManager::available() const { return this->isActive(); }
|
||||
|
||||
const QVector<ToplevelHandle*>& ToplevelManager::readyToplevels() const {
|
||||
return this->mReadyToplevels;
|
||||
}
|
||||
|
||||
ToplevelHandle* ToplevelManager::handleFor(::zwlr_foreign_toplevel_handle_v1* toplevel) {
|
||||
if (toplevel == nullptr) return nullptr;
|
||||
|
||||
for (auto* other: this->mToplevels) {
|
||||
if (other->object() == toplevel) return other;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ToplevelManager* ToplevelManager::instance() {
|
||||
static auto* instance = new ToplevelManager(); // NOLINT
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ToplevelManager::zwlr_foreign_toplevel_manager_v1_toplevel(
|
||||
::zwlr_foreign_toplevel_handle_v1* toplevel
|
||||
) {
|
||||
auto* handle = new ToplevelHandle();
|
||||
QObject::connect(handle, &ToplevelHandle::closed, this, &ToplevelManager::onToplevelClosed);
|
||||
QObject::connect(handle, &ToplevelHandle::ready, this, &ToplevelManager::onToplevelReady);
|
||||
|
||||
qCDebug(logToplevelManagement) << "Toplevel handle created" << handle;
|
||||
this->mToplevels.push_back(handle);
|
||||
|
||||
// Not done in constructor as a close could technically be picked up immediately on init,
|
||||
// making touching the handle a UAF.
|
||||
handle->init(toplevel);
|
||||
}
|
||||
|
||||
void ToplevelManager::onToplevelReady() {
|
||||
auto* handle = qobject_cast<ToplevelHandle*>(this->sender());
|
||||
this->mReadyToplevels.push_back(handle);
|
||||
emit this->toplevelReady(handle);
|
||||
}
|
||||
|
||||
void ToplevelManager::onToplevelClosed() {
|
||||
auto* handle = qobject_cast<ToplevelHandle*>(this->sender());
|
||||
this->mReadyToplevels.removeOne(handle);
|
||||
this->mToplevels.removeOne(handle);
|
||||
}
|
||||
|
||||
} // namespace qs::wayland::toplevel_management::impl
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qwayland-wlr-foreign-toplevel-management-unstable-v1.h>
|
||||
#include <qwaylandclientextension.h>
|
||||
|
||||
#include "../../core/logcat.hpp"
|
||||
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
|
||||
namespace qs::wayland::toplevel_management::impl {
|
||||
|
||||
class ToplevelHandle;
|
||||
|
||||
QS_DECLARE_LOGGING_CATEGORY(logToplevelManagement);
|
||||
|
||||
class ToplevelManager
|
||||
: public QWaylandClientExtensionTemplate<ToplevelManager>
|
||||
, public QtWayland::zwlr_foreign_toplevel_manager_v1 {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
[[nodiscard]] bool available() const;
|
||||
[[nodiscard]] const QVector<ToplevelHandle*>& readyToplevels() const;
|
||||
[[nodiscard]] ToplevelHandle* handleFor(::zwlr_foreign_toplevel_handle_v1* toplevel);
|
||||
|
||||
static ToplevelManager* instance();
|
||||
|
||||
signals:
|
||||
void toplevelReady(ToplevelHandle* toplevel);
|
||||
|
||||
protected:
|
||||
explicit ToplevelManager();
|
||||
|
||||
void
|
||||
zwlr_foreign_toplevel_manager_v1_toplevel(::zwlr_foreign_toplevel_handle_v1* toplevel) override;
|
||||
|
||||
private slots:
|
||||
void onToplevelReady();
|
||||
void onToplevelClosed();
|
||||
|
||||
private:
|
||||
QVector<ToplevelHandle*> mToplevels;
|
||||
QVector<ToplevelHandle*> mReadyToplevels;
|
||||
};
|
||||
|
||||
} // namespace qs::wayland::toplevel_management::impl
|
||||
Loading…
Add table
Add a link
Reference in a new issue