core/popupwindow: clean up popup lifecycle and window init
- Makes popup lifecycle less complex - Creates all QWindows lazily - May break live reloading of open popups to some degree
This commit is contained in:
parent
db37dc580a
commit
de1bfe028d
8 changed files with 127 additions and 100 deletions
|
|
@ -12,29 +12,74 @@
|
|||
|
||||
ProxyPopupWindow::ProxyPopupWindow(QObject* parent): ProxyWindowBase(parent) {
|
||||
this->mVisible = false;
|
||||
|
||||
// clang-format off
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::windowChanged, this, &ProxyPopupWindow::parentWindowChanged);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::windowChanged, this, &ProxyPopupWindow::onParentWindowChanged);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::windowRectChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::edgesChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::gravityChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::adjustmentChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(&this->mAnchor, &PopupAnchor::backingWindowVisibilityChanged, this, &ProxyPopupWindow::onParentUpdated);
|
||||
// clang-format on
|
||||
|
||||
this->bTargetVisible.setBinding([this] {
|
||||
auto* window = this->mAnchor.bindableProxyWindow().value();
|
||||
|
||||
if (window == this) {
|
||||
qmlWarning(this) << "Anchor assigned to current window";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!window) return false;
|
||||
|
||||
if (!this->bWantsVisible) return false;
|
||||
return window->bindableBackerVisibility().value();
|
||||
});
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::targetVisibleChanged() {
|
||||
this->ProxyWindowBase::setVisible(this->bTargetVisible);
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::completeWindow() {
|
||||
this->ProxyWindowBase::completeWindow();
|
||||
|
||||
// clang-format off
|
||||
QObject::connect(this->window, &QWindow::visibleChanged, this, &ProxyPopupWindow::onVisibleChanged);
|
||||
QObject::connect(this, &ProxyWindowBase::closed, this, &ProxyPopupWindow::onClosed);
|
||||
QObject::connect(this->window, &QWindow::widthChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyPopupWindow::reposition);
|
||||
// clang-format on
|
||||
|
||||
auto* bw = this->mAnchor.backingWindow();
|
||||
|
||||
if (bw && PopupPositioner::instance()->shouldRepositionOnMove()) {
|
||||
QObject::connect(bw, &QWindow::xChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::yChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::widthChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::heightChanged, this, &ProxyPopupWindow::reposition);
|
||||
}
|
||||
|
||||
this->window->setTransientParent(bw);
|
||||
this->window->setFlag(Qt::ToolTip);
|
||||
|
||||
this->mAnchor.markDirty();
|
||||
PopupPositioner::instance()->reposition(&this->mAnchor, this->window);
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::postCompleteWindow() { this->updateTransientParent(); }
|
||||
void ProxyPopupWindow::postCompleteWindow() {
|
||||
this->ProxyWindowBase::setVisible(this->bTargetVisible);
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::onClosed() { this->bWantsVisible = false; }
|
||||
|
||||
void ProxyPopupWindow::onParentWindowChanged() {
|
||||
// recreate for new parent
|
||||
if (this->bTargetVisible && this->isVisibleDirect()) {
|
||||
this->ProxyWindowBase::setVisibleDirect(false);
|
||||
this->ProxyWindowBase::setVisibleDirect(true);
|
||||
}
|
||||
|
||||
emit this->parentWindowChanged();
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::setParentWindow(QObject* parent) {
|
||||
qmlWarning(this) << "PopupWindow.parentWindow is deprecated. Use PopupWindow.anchor.window.";
|
||||
|
|
@ -43,60 +88,13 @@ void ProxyPopupWindow::setParentWindow(QObject* parent) {
|
|||
|
||||
QObject* ProxyPopupWindow::parentWindow() const { return this->mAnchor.window(); }
|
||||
|
||||
void ProxyPopupWindow::updateTransientParent() {
|
||||
auto* bw = this->mAnchor.backingWindow();
|
||||
|
||||
if (this->window != nullptr && bw != this->window->transientParent()) {
|
||||
if (this->window->transientParent()) {
|
||||
QObject::disconnect(this->window->transientParent(), nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
if (bw && PopupPositioner::instance()->shouldRepositionOnMove()) {
|
||||
QObject::connect(bw, &QWindow::xChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::yChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::widthChanged, this, &ProxyPopupWindow::reposition);
|
||||
QObject::connect(bw, &QWindow::heightChanged, this, &ProxyPopupWindow::reposition);
|
||||
}
|
||||
|
||||
this->window->setTransientParent(bw);
|
||||
}
|
||||
|
||||
this->updateVisible();
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::onParentUpdated() { this->updateTransientParent(); }
|
||||
|
||||
void ProxyPopupWindow::setScreen(QuickshellScreenInfo* /*unused*/) {
|
||||
qmlWarning(
|
||||
this
|
||||
) << "Cannot set screen of popup window, as that is controlled by the parent window";
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::setVisible(bool visible) {
|
||||
if (visible == this->wantsVisible) return;
|
||||
this->wantsVisible = visible;
|
||||
this->updateVisible();
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::updateVisible() {
|
||||
auto target = this->wantsVisible && this->mAnchor.window() != nullptr
|
||||
&& this->mAnchor.proxyWindow()->isVisibleDirect();
|
||||
|
||||
if (target && this->window != nullptr && !this->window->isVisible()) {
|
||||
PopupPositioner::instance()->reposition(&this->mAnchor, this->window);
|
||||
}
|
||||
|
||||
this->ProxyWindowBase::setVisible(target);
|
||||
}
|
||||
|
||||
void ProxyPopupWindow::onVisibleChanged() {
|
||||
// If the window was made invisible without its parent becoming invisible
|
||||
// the compositor probably destroyed it. Without this the window won't ever
|
||||
// be able to become visible again.
|
||||
if (this->window->transientParent() && this->window->transientParent()->isVisible()) {
|
||||
this->wantsVisible = this->window->isVisible();
|
||||
}
|
||||
}
|
||||
void ProxyPopupWindow::setVisible(bool visible) { this->bWantsVisible = visible; }
|
||||
|
||||
void ProxyPopupWindow::setRelativeX(qint32 x) {
|
||||
qmlWarning(this) << "PopupWindow.relativeX is deprecated. Use PopupWindow.anchor.rect.x.";
|
||||
|
|
@ -144,3 +142,5 @@ void ProxyPopupWindow::onPolished() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ProxyPopupWindow::deleteOnInvisible() const { return true; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue