forked from quickshell/quickshell
wayland/toplevel: refactor toplevel output tracking to its own file
This commit is contained in:
parent
20c3da01f1
commit
27f97c3283
6 changed files with 119 additions and 82 deletions
|
@ -77,6 +77,7 @@ qt_add_library(quickshell-wayland STATIC
|
||||||
popupanchor.cpp
|
popupanchor.cpp
|
||||||
xdgshell.cpp
|
xdgshell.cpp
|
||||||
util.cpp
|
util.cpp
|
||||||
|
output_tracking.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# required to make sure the constructor is linked
|
# required to make sure the constructor is linked
|
||||||
|
|
73
src/wayland/output_tracking.cpp
Normal file
73
src/wayland/output_tracking.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include "output_tracking.hpp"
|
||||||
|
|
||||||
|
#include <private/qwaylanddisplay_p.h>
|
||||||
|
#include <private/qwaylandintegration_p.h>
|
||||||
|
#include <private/qwaylandscreen_p.h>
|
||||||
|
#include <qguiapplication.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qscreen.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
|
||||||
|
namespace qs::wayland {
|
||||||
|
|
||||||
|
void WlOutputTracker::addOutput(::wl_output* output) {
|
||||||
|
auto* display = QtWaylandClient::QWaylandIntegration::instance()->display();
|
||||||
|
|
||||||
|
if (auto* platformScreen = display->screenForOutput(output)) {
|
||||||
|
auto* screen = platformScreen->screen();
|
||||||
|
this->mScreens.append(screen);
|
||||||
|
emit this->screenAdded(screen);
|
||||||
|
} else {
|
||||||
|
QObject::connect(
|
||||||
|
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
||||||
|
&QGuiApplication::screenAdded,
|
||||||
|
this,
|
||||||
|
&WlOutputTracker::onQScreenAdded,
|
||||||
|
Qt::UniqueConnection
|
||||||
|
);
|
||||||
|
|
||||||
|
this->mOutputs.append(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WlOutputTracker::removeOutput(::wl_output* output) {
|
||||||
|
auto* display = QtWaylandClient::QWaylandIntegration::instance()->display();
|
||||||
|
|
||||||
|
if (auto* platformScreen = display->screenForOutput(output)) {
|
||||||
|
auto* screen = platformScreen->screen();
|
||||||
|
this->mScreens.removeOne(screen);
|
||||||
|
emit this->screenRemoved(screen);
|
||||||
|
} else {
|
||||||
|
this->mOutputs.removeOne(output);
|
||||||
|
|
||||||
|
if (this->mOutputs.isEmpty()) {
|
||||||
|
QObject::disconnect(
|
||||||
|
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
||||||
|
nullptr,
|
||||||
|
this,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WlOutputTracker::onQScreenAdded(QScreen* screen) {
|
||||||
|
if (auto* platformScreen = dynamic_cast<QtWaylandClient::QWaylandScreen*>(screen->handle())) {
|
||||||
|
if (this->mOutputs.removeOne(platformScreen->output())) {
|
||||||
|
this->mScreens.append(screen);
|
||||||
|
emit this->screenAdded(screen);
|
||||||
|
|
||||||
|
if (this->mOutputs.isEmpty()) {
|
||||||
|
QObject::disconnect(
|
||||||
|
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
||||||
|
nullptr,
|
||||||
|
this,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qs::wayland
|
34
src/wayland/output_tracking.hpp
Normal file
34
src/wayland/output_tracking.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qlist.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qscreen.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
|
||||||
|
struct wl_output;
|
||||||
|
|
||||||
|
namespace qs::wayland {
|
||||||
|
|
||||||
|
class WlOutputTracker: public QObject {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] const QList<QScreen*>& screens() const { return this->mScreens; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void screenAdded(QScreen* screen);
|
||||||
|
void screenRemoved(QScreen* screen);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addOutput(::wl_output* output);
|
||||||
|
void removeOutput(::wl_output* output);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onQScreenAdded(QScreen* screen);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<QScreen*> mScreens;
|
||||||
|
QList<::wl_output*> mOutputs;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qs::wayland
|
|
@ -23,7 +23,6 @@ namespace qs::wayland::toplevel_management::impl {
|
||||||
|
|
||||||
QString ToplevelHandle::appId() const { return this->mAppId; }
|
QString ToplevelHandle::appId() const { return this->mAppId; }
|
||||||
QString ToplevelHandle::title() const { return this->mTitle; }
|
QString ToplevelHandle::title() const { return this->mTitle; }
|
||||||
QVector<QScreen*> ToplevelHandle::visibleScreens() const { return this->mVisibleScreens; }
|
|
||||||
ToplevelHandle* ToplevelHandle::parent() const { return this->mParent; }
|
ToplevelHandle* ToplevelHandle::parent() const { return this->mParent; }
|
||||||
bool ToplevelHandle::activated() const { return this->mActivated; }
|
bool ToplevelHandle::activated() const { return this->mActivated; }
|
||||||
bool ToplevelHandle::maximized() const { return this->mMaximized; }
|
bool ToplevelHandle::maximized() const { return this->mMaximized; }
|
||||||
|
@ -181,59 +180,13 @@ void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_state(wl_array* stateArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_output_enter(wl_output* output) {
|
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_output_enter(wl_output* output) {
|
||||||
auto* display = QtWaylandClient::QWaylandIntegration::instance()->display();
|
qCDebug(logToplevelManagement) << this << "got output enter" << output;
|
||||||
|
this->visibleScreens.addOutput(output);
|
||||||
auto* platformScreen = display->screenForOutput(output);
|
|
||||||
if (!platformScreen) {
|
|
||||||
qCDebug(logToplevelManagement) << this << "got pending output enter" << output;
|
|
||||||
|
|
||||||
if (this->mPendingVisibleScreens.isEmpty()) {
|
|
||||||
QObject::connect(
|
|
||||||
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
|
||||||
&QGuiApplication::screenAdded,
|
|
||||||
this,
|
|
||||||
&ToplevelHandle::onScreenAdded
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->mPendingVisibleScreens.append(output);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* screen = platformScreen->screen();
|
|
||||||
|
|
||||||
qCDebug(logToplevelManagement) << this << "got output enter" << screen;
|
|
||||||
|
|
||||||
this->mVisibleScreens.append(screen);
|
|
||||||
emit this->visibleScreenAdded(screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_output_leave(wl_output* output) {
|
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_output_leave(wl_output* output) {
|
||||||
auto* display = QtWaylandClient::QWaylandIntegration::instance()->display();
|
qCDebug(logToplevelManagement) << this << "got output leave" << output;
|
||||||
auto* platformScreen = display->screenForOutput(output);
|
this->visibleScreens.removeOutput(output);
|
||||||
|
|
||||||
if (!this->mPendingVisibleScreens.isEmpty()) {
|
|
||||||
this->mPendingVisibleScreens.removeOne(output);
|
|
||||||
|
|
||||||
if (this->mPendingVisibleScreens.isEmpty()) {
|
|
||||||
qCDebug(logToplevelManagement) << this << "got pending output leave" << output;
|
|
||||||
|
|
||||||
QObject::disconnect(
|
|
||||||
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
|
||||||
nullptr,
|
|
||||||
this,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!platformScreen) return;
|
|
||||||
auto* screen = platformScreen->screen();
|
|
||||||
|
|
||||||
qCDebug(logToplevelManagement) << this << "got output leave" << screen;
|
|
||||||
|
|
||||||
this->mVisibleScreens.removeOne(screen);
|
|
||||||
emit this->visibleScreenRemoved(screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_parent(
|
void ToplevelHandle::zwlr_foreign_toplevel_handle_v1_parent(
|
||||||
|
@ -262,26 +215,4 @@ void ToplevelHandle::onParentClosed() {
|
||||||
emit this->parentChanged();
|
emit this->parentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToplevelHandle::onScreenAdded(QScreen* screen) {
|
|
||||||
auto* waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen*>(screen->handle());
|
|
||||||
if (!waylandScreen) return;
|
|
||||||
|
|
||||||
auto* output = waylandScreen->output();
|
|
||||||
|
|
||||||
if (this->mPendingVisibleScreens.removeOne(output)) {
|
|
||||||
qCDebug(logToplevelManagement) << this << "got pending entered output init" << screen;
|
|
||||||
this->mVisibleScreens.append(screen);
|
|
||||||
emit this->visibleScreenAdded(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->mPendingVisibleScreens.isEmpty()) {
|
|
||||||
QObject::disconnect(
|
|
||||||
static_cast<QGuiApplication*>(QGuiApplication::instance()), // NOLINT
|
|
||||||
nullptr,
|
|
||||||
this,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace qs::wayland::toplevel_management::impl
|
} // namespace qs::wayland::toplevel_management::impl
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <qwayland-wlr-foreign-toplevel-management-unstable-v1.h>
|
#include <qwayland-wlr-foreign-toplevel-management-unstable-v1.h>
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
|
|
||||||
|
#include "../output_tracking.hpp"
|
||||||
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
#include "wayland-wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
namespace qs::wayland::toplevel_management::impl {
|
namespace qs::wayland::toplevel_management::impl {
|
||||||
|
@ -18,7 +19,6 @@ class ToplevelHandle
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] QString appId() const;
|
[[nodiscard]] QString appId() const;
|
||||||
[[nodiscard]] QString title() const;
|
[[nodiscard]] QString title() const;
|
||||||
[[nodiscard]] QVector<QScreen*> visibleScreens() const;
|
|
||||||
[[nodiscard]] ToplevelHandle* parent() const;
|
[[nodiscard]] ToplevelHandle* parent() const;
|
||||||
[[nodiscard]] bool activated() const;
|
[[nodiscard]] bool activated() const;
|
||||||
[[nodiscard]] bool maximized() const;
|
[[nodiscard]] bool maximized() const;
|
||||||
|
@ -32,6 +32,8 @@ public:
|
||||||
void fullscreenOn(QScreen* screen);
|
void fullscreenOn(QScreen* screen);
|
||||||
void setRectangle(QWindow* window, QRect rect);
|
void setRectangle(QWindow* window, QRect rect);
|
||||||
|
|
||||||
|
WlOutputTracker visibleScreens;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// sent after the first done event.
|
// sent after the first done event.
|
||||||
void ready();
|
void ready();
|
||||||
|
@ -40,8 +42,6 @@ signals:
|
||||||
|
|
||||||
void appIdChanged();
|
void appIdChanged();
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
void visibleScreenAdded(QScreen* screen);
|
|
||||||
void visibleScreenRemoved(QScreen* screen);
|
|
||||||
void parentChanged();
|
void parentChanged();
|
||||||
void activatedChanged();
|
void activatedChanged();
|
||||||
void maximizedChanged();
|
void maximizedChanged();
|
||||||
|
@ -51,7 +51,6 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void onParentClosed();
|
void onParentClosed();
|
||||||
void onRectWindowDestroyed();
|
void onRectWindowDestroyed();
|
||||||
void onScreenAdded(QScreen* screen);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void zwlr_foreign_toplevel_handle_v1_done() override;
|
void zwlr_foreign_toplevel_handle_v1_done() override;
|
||||||
|
@ -66,8 +65,6 @@ private:
|
||||||
bool isReady = false;
|
bool isReady = false;
|
||||||
QString mAppId;
|
QString mAppId;
|
||||||
QString mTitle;
|
QString mTitle;
|
||||||
QVector<QScreen*> mVisibleScreens;
|
|
||||||
QVector<wl_output*> mPendingVisibleScreens;
|
|
||||||
ToplevelHandle* mParent = nullptr;
|
ToplevelHandle* mParent = nullptr;
|
||||||
bool mActivated = false;
|
bool mActivated = false;
|
||||||
bool mMaximized = false;
|
bool mMaximized = false;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "../../core/util.hpp"
|
#include "../../core/util.hpp"
|
||||||
#include "../../window/proxywindow.hpp"
|
#include "../../window/proxywindow.hpp"
|
||||||
#include "../../window/windowinterface.hpp"
|
#include "../../window/windowinterface.hpp"
|
||||||
|
#include "../output_tracking.hpp"
|
||||||
#include "handle.hpp"
|
#include "handle.hpp"
|
||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
|
|
||||||
|
@ -22,8 +23,8 @@ Toplevel::Toplevel(impl::ToplevelHandle* handle, QObject* parent): QObject(paren
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::titleChanged, this, &Toplevel::titleChanged);
|
QObject::connect(handle, &impl::ToplevelHandle::titleChanged, this, &Toplevel::titleChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::parentChanged, this, &Toplevel::parentChanged);
|
QObject::connect(handle, &impl::ToplevelHandle::parentChanged, this, &Toplevel::parentChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::activatedChanged, this, &Toplevel::activatedChanged);
|
QObject::connect(handle, &impl::ToplevelHandle::activatedChanged, this, &Toplevel::activatedChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::visibleScreenAdded, this, &Toplevel::screensChanged);
|
QObject::connect(&handle->visibleScreens, &WlOutputTracker::screenAdded, this, &Toplevel::screensChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::visibleScreenRemoved, 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::maximizedChanged, this, &Toplevel::maximizedChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::minimizedChanged, this, &Toplevel::minimizedChanged);
|
QObject::connect(handle, &impl::ToplevelHandle::minimizedChanged, this, &Toplevel::minimizedChanged);
|
||||||
QObject::connect(handle, &impl::ToplevelHandle::fullscreenChanged, this, &Toplevel::fullscreenChanged);
|
QObject::connect(handle, &impl::ToplevelHandle::fullscreenChanged, this, &Toplevel::fullscreenChanged);
|
||||||
|
@ -50,7 +51,7 @@ bool Toplevel::activated() const { return this->handle->activated(); }
|
||||||
QList<QuickshellScreenInfo*> Toplevel::screens() const {
|
QList<QuickshellScreenInfo*> Toplevel::screens() const {
|
||||||
QList<QuickshellScreenInfo*> screens;
|
QList<QuickshellScreenInfo*> screens;
|
||||||
|
|
||||||
for (auto* screen: this->handle->visibleScreens()) {
|
for (auto* screen: this->handle->visibleScreens.screens()) {
|
||||||
screens.push_back(QuickshellTracked::instance()->screenInfo(screen));
|
screens.push_back(QuickshellTracked::instance()->screenInfo(screen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue