254 lines
8.6 KiB
C++
254 lines
8.6 KiB
C++
|
#include "layershell.hpp"
|
||
|
|
||
|
#include <LayerShellQt/window.h>
|
||
|
#include <qmargins.h>
|
||
|
#include <qobject.h>
|
||
|
#include <qqmllist.h>
|
||
|
#include <qquickitem.h>
|
||
|
#include <qquickwindow.h>
|
||
|
#include <qscreen.h>
|
||
|
#include <qtypes.h>
|
||
|
#include <qwindow.h>
|
||
|
|
||
|
#include "proxywindow.hpp"
|
||
|
#include "qmlscreen.hpp"
|
||
|
|
||
|
void ProxyShellWindow::earlyInit(QObject* old) {
|
||
|
ProxyWindowBase::earlyInit(old);
|
||
|
|
||
|
QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyShellWindow::screenChanged);
|
||
|
|
||
|
this->shellWindow = LayerShellQt::Window::get(this->window);
|
||
|
|
||
|
// dont want to steal focus unless actually configured to
|
||
|
this->shellWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityNone);
|
||
|
|
||
|
// this dosent reset if its unset
|
||
|
this->shellWindow->setExclusiveZone(0);
|
||
|
|
||
|
// clang-format off
|
||
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::anchorsChanged, this, &ProxyShellWindow::anchorsChanged);
|
||
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::marginsChanged, this, &ProxyShellWindow::marginsChanged);
|
||
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::layerChanged, this, &ProxyShellWindow::layerChanged);
|
||
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::keyboardInteractivityChanged, this, &ProxyShellWindow::keyboardFocusChanged);
|
||
|
// clang-format on
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::componentComplete() {
|
||
|
this->complete = true;
|
||
|
|
||
|
// The default anchor settings are a hazard because they cover the entire screen.
|
||
|
// We opt for 0 anchors by default to avoid blocking user input.
|
||
|
this->setAnchors(this->stagingAnchors);
|
||
|
|
||
|
// Make sure we signal changes from anchors, but only if this is a reload.
|
||
|
// If we do it on first load then it sends an extra change at 0px.
|
||
|
if (this->stagingAnchors.mLeft && this->stagingAnchors.mRight && this->width() != 0)
|
||
|
this->widthChanged(this->width());
|
||
|
if (this->stagingAnchors.mTop && this->stagingAnchors.mBottom && this->height() != 0)
|
||
|
this->heightChanged(this->height());
|
||
|
|
||
|
this->window->setVisible(this->stagingVisible);
|
||
|
|
||
|
ProxyWindowBase::componentComplete();
|
||
|
}
|
||
|
|
||
|
QQuickWindow* ProxyShellWindow::disownWindow() {
|
||
|
QObject::disconnect(this->shellWindow, nullptr, this, nullptr);
|
||
|
return ProxyWindowBase::disownWindow();
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setVisible(bool visible) {
|
||
|
if (!this->complete) this->stagingVisible = visible;
|
||
|
else ProxyWindowBase::setVisible(visible);
|
||
|
}
|
||
|
|
||
|
bool ProxyShellWindow::isVisible() {
|
||
|
return this->complete ? ProxyWindowBase::isVisible() : this->stagingVisible;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setWidth(qint32 width) {
|
||
|
this->requestedWidth = width;
|
||
|
|
||
|
// only update the actual size if not blocked by anchors
|
||
|
auto anchors = this->anchors();
|
||
|
if (this->complete && (!anchors.mLeft || !anchors.mRight)) ProxyWindowBase::setWidth(width);
|
||
|
}
|
||
|
|
||
|
qint32 ProxyShellWindow::width() {
|
||
|
return this->complete ? ProxyWindowBase::width() : this->requestedWidth;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setHeight(qint32 height) {
|
||
|
this->requestedHeight = height;
|
||
|
|
||
|
// only update the actual size if not blocked by anchors
|
||
|
auto anchors = this->anchors();
|
||
|
if (this->complete && (!anchors.mTop || !anchors.mBottom)) ProxyWindowBase::setHeight(height);
|
||
|
}
|
||
|
|
||
|
qint32 ProxyShellWindow::height() {
|
||
|
return this->complete ? ProxyWindowBase::height() : this->requestedHeight;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setScreen(QtShellScreenInfo* screen) {
|
||
|
this->window->setScreen(screen->screen);
|
||
|
}
|
||
|
|
||
|
QtShellScreenInfo* ProxyShellWindow::screen() const {
|
||
|
return new QtShellScreenInfo(
|
||
|
const_cast<ProxyShellWindow*>(this), // NOLINT
|
||
|
this->window->screen()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setAnchors(Anchors anchors) {
|
||
|
if (!this->complete) {
|
||
|
this->stagingAnchors = anchors;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
auto lsAnchors = LayerShellQt::Window::Anchors();
|
||
|
if (anchors.mLeft) lsAnchors |= LayerShellQt::Window::AnchorLeft;
|
||
|
if (anchors.mRight) lsAnchors |= LayerShellQt::Window::AnchorRight;
|
||
|
if (anchors.mTop) lsAnchors |= LayerShellQt::Window::AnchorTop;
|
||
|
if (anchors.mBottom) lsAnchors |= LayerShellQt::Window::AnchorBottom;
|
||
|
|
||
|
if (!anchors.mLeft || !anchors.mRight) ProxyWindowBase::setWidth(this->requestedWidth);
|
||
|
if (!anchors.mTop || !anchors.mBottom) ProxyWindowBase::setHeight(this->requestedHeight);
|
||
|
|
||
|
this->shellWindow->setAnchors(lsAnchors);
|
||
|
}
|
||
|
|
||
|
Anchors ProxyShellWindow::anchors() const {
|
||
|
if (!this->complete) return this->stagingAnchors;
|
||
|
|
||
|
auto lsAnchors = this->shellWindow->anchors();
|
||
|
|
||
|
Anchors anchors;
|
||
|
anchors.mLeft = lsAnchors.testFlag(LayerShellQt::Window::AnchorLeft);
|
||
|
anchors.mRight = lsAnchors.testFlag(LayerShellQt::Window::AnchorRight);
|
||
|
anchors.mTop = lsAnchors.testFlag(LayerShellQt::Window::AnchorTop);
|
||
|
anchors.mBottom = lsAnchors.testFlag(LayerShellQt::Window::AnchorBottom);
|
||
|
|
||
|
return anchors;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setExclusiveZone(qint32 zone) { this->shellWindow->setExclusiveZone(zone); }
|
||
|
|
||
|
qint32 ProxyShellWindow::exclusiveZone() const { return this->shellWindow->exclusionZone(); }
|
||
|
|
||
|
void ProxyShellWindow::setMargins(Margins margins) {
|
||
|
auto lsMargins = QMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom);
|
||
|
this->shellWindow->setMargins(lsMargins);
|
||
|
}
|
||
|
|
||
|
Margins ProxyShellWindow::margins() const {
|
||
|
auto lsMargins = this->shellWindow->margins();
|
||
|
|
||
|
auto margins = Margins();
|
||
|
margins.mLeft = lsMargins.left();
|
||
|
margins.mRight = lsMargins.right();
|
||
|
margins.mTop = lsMargins.top();
|
||
|
margins.mBottom = lsMargins.bottom();
|
||
|
|
||
|
return margins;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setLayer(Layer::Enum layer) {
|
||
|
auto lsLayer = LayerShellQt::Window::LayerBackground;
|
||
|
|
||
|
// clang-format off
|
||
|
switch (layer) {
|
||
|
case Layer::Background: lsLayer = LayerShellQt::Window::LayerBackground; break;
|
||
|
case Layer::Bottom: lsLayer = LayerShellQt::Window::LayerBottom; break;
|
||
|
case Layer::Top: lsLayer = LayerShellQt::Window::LayerTop; break;
|
||
|
case Layer::Overlay: lsLayer = LayerShellQt::Window::LayerOverlay; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
this->shellWindow->setLayer(lsLayer);
|
||
|
}
|
||
|
|
||
|
Layer::Enum ProxyShellWindow::layer() const {
|
||
|
auto layer = Layer::Top;
|
||
|
auto lsLayer = this->shellWindow->layer();
|
||
|
|
||
|
// clang-format off
|
||
|
switch (lsLayer) {
|
||
|
case LayerShellQt::Window::LayerBackground: layer = Layer::Background; break;
|
||
|
case LayerShellQt::Window::LayerBottom: layer = Layer::Bottom; break;
|
||
|
case LayerShellQt::Window::LayerTop: layer = Layer::Top; break;
|
||
|
case LayerShellQt::Window::LayerOverlay: layer = Layer::Overlay; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
return layer;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setScope(const QString& scope) { this->shellWindow->setScope(scope); }
|
||
|
|
||
|
QString ProxyShellWindow::scope() const { return this->shellWindow->scope(); }
|
||
|
|
||
|
void ProxyShellWindow::setKeyboardFocus(KeyboardFocus::Enum focus) {
|
||
|
auto lsFocus = LayerShellQt::Window::KeyboardInteractivityNone;
|
||
|
|
||
|
// clang-format off
|
||
|
switch (focus) {
|
||
|
case KeyboardFocus::None: lsFocus = LayerShellQt::Window::KeyboardInteractivityNone; break;
|
||
|
case KeyboardFocus::Exclusive: lsFocus = LayerShellQt::Window::KeyboardInteractivityExclusive; break;
|
||
|
case KeyboardFocus::OnDemand: lsFocus = LayerShellQt::Window::KeyboardInteractivityOnDemand; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
this->shellWindow->setKeyboardInteractivity(lsFocus);
|
||
|
}
|
||
|
|
||
|
KeyboardFocus::Enum ProxyShellWindow::keyboardFocus() const {
|
||
|
auto focus = KeyboardFocus::None;
|
||
|
auto lsFocus = this->shellWindow->keyboardInteractivity();
|
||
|
|
||
|
// clang-format off
|
||
|
switch (lsFocus) {
|
||
|
case LayerShellQt::Window::KeyboardInteractivityNone: focus = KeyboardFocus::None; break;
|
||
|
case LayerShellQt::Window::KeyboardInteractivityExclusive: focus = KeyboardFocus::Exclusive; break;
|
||
|
case LayerShellQt::Window::KeyboardInteractivityOnDemand: focus = KeyboardFocus::OnDemand; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
return focus;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setScreenConfiguration(ScreenConfiguration::Enum configuration) {
|
||
|
auto lsConfiguration = LayerShellQt::Window::ScreenFromQWindow;
|
||
|
|
||
|
// clang-format off
|
||
|
switch (configuration) {
|
||
|
case ScreenConfiguration::Window: lsConfiguration = LayerShellQt::Window::ScreenFromQWindow; break;
|
||
|
case ScreenConfiguration::Compositor: lsConfiguration = LayerShellQt::Window::ScreenFromCompositor; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
this->shellWindow->setScreenConfiguration(lsConfiguration);
|
||
|
}
|
||
|
|
||
|
ScreenConfiguration::Enum ProxyShellWindow::screenConfiguration() const {
|
||
|
auto configuration = ScreenConfiguration::Window;
|
||
|
auto lsConfiguration = this->shellWindow->screenConfiguration();
|
||
|
|
||
|
// clang-format off
|
||
|
switch (lsConfiguration) {
|
||
|
case LayerShellQt::Window::ScreenFromQWindow: configuration = ScreenConfiguration::Window; break;
|
||
|
case LayerShellQt::Window::ScreenFromCompositor: configuration = ScreenConfiguration::Compositor; break;
|
||
|
}
|
||
|
// clang-format on
|
||
|
|
||
|
return configuration;
|
||
|
}
|
||
|
|
||
|
void ProxyShellWindow::setCloseOnDismissed(bool close) {
|
||
|
this->shellWindow->setCloseOnDismissed(close);
|
||
|
}
|
||
|
|
||
|
bool ProxyShellWindow::closeOnDismissed() const { return this->shellWindow->closeOnDismissed(); }
|