/* * MIT License * * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "framelessquickwindow.h" #include "framelessquickwindow_p.h" #include #include #include #include #include FRAMELESSHELPER_BEGIN_NAMESPACE using namespace Global; static constexpr const char QT_QUICKITEM_CLASS_NAME[] = "QQuickItem"; FramelessQuickWindowPrivate::FramelessQuickWindowPrivate(FramelessQuickWindow *q, const UserSettings &settings) : QObject(q) { Q_ASSERT(q); if (!q) { return; } q_ptr = q; m_settings = settings; initialize(); } FramelessQuickWindowPrivate::~FramelessQuickWindowPrivate() = default; FramelessQuickWindowPrivate *FramelessQuickWindowPrivate::get(FramelessQuickWindow *pub) { Q_ASSERT(pub); if (!pub) { return nullptr; } return pub->d_func(); } const FramelessQuickWindowPrivate *FramelessQuickWindowPrivate::get(const FramelessQuickWindow *pub) { Q_ASSERT(pub); if (!pub) { return nullptr; } return pub->d_func(); } bool FramelessQuickWindowPrivate::isHidden() const { Q_Q(const FramelessQuickWindow); return (q->visibility() == FramelessQuickWindow::Hidden); } bool FramelessQuickWindowPrivate::isNormal() const { Q_Q(const FramelessQuickWindow); return (q->visibility() == FramelessQuickWindow::Windowed); } bool FramelessQuickWindowPrivate::isMinimized() const { Q_Q(const FramelessQuickWindow); return (q->visibility() == FramelessQuickWindow::Minimized); } bool FramelessQuickWindowPrivate::isZoomed() const { Q_Q(const FramelessQuickWindow); const FramelessQuickWindow::Visibility visibility = q->visibility(); return ((visibility == FramelessQuickWindow::Maximized) || ((m_settings.options & Option::DontTreatFullScreenAsZoomed) ? false : (visibility == FramelessQuickWindow::FullScreen))); } bool FramelessQuickWindowPrivate::isFullScreen() const { Q_Q(const FramelessQuickWindow); return (q->visibility() == FramelessQuickWindow::FullScreen); } bool FramelessQuickWindowPrivate::isFixedSize() const { if (m_settings.options & Option::DisableResizing) { return true; } Q_Q(const FramelessQuickWindow); if (q->flags() & Qt::MSWindowsFixedSizeDialogHint) { return true; } const QSize minSize = q->minimumSize(); const QSize maxSize = q->maximumSize(); if (!minSize.isEmpty() && !maxSize.isEmpty() && (minSize == maxSize)) { return true; } return false; } QColor FramelessQuickWindowPrivate::getFrameBorderColor() const { #ifdef Q_OS_WINDOWS Q_Q(const FramelessQuickWindow); return Utils::getFrameBorderColor(q->isActive()); #else return {}; #endif } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderTop() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::TopAnchor); } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderBottom() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::BottomAnchor); } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderLeft() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::LeftAnchor); } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderRight() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::RightAnchor); } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderHorizontalCenter() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::HCenterAnchor); } QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderVerticalCenter() const { return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::VCenterAnchor); } void FramelessQuickWindowPrivate::setTitleBarItem(QQuickItem *item) { Q_ASSERT(item); if (!item) { return; } if (m_titleBarItem == item) { return; } m_titleBarItem = item; } void FramelessQuickWindowPrivate::setHitTestVisible(QQuickItem *item) { Q_ASSERT(item); if (!item) { return; } static constexpr const bool visible = true; const bool exists = m_hitTestVisibleItems.contains(item); if (visible && !exists) { m_hitTestVisibleItems.append(item); } if constexpr (!visible && exists) { m_hitTestVisibleItems.removeAll(item); } } void FramelessQuickWindowPrivate::moveToDesktopCenter() { Utils::moveWindowToDesktopCenter(m_params.getWindowScreen, m_params.getWindowSize, m_params.setWindowPosition, true); } void FramelessQuickWindowPrivate::setFixedSize(const bool value, const bool force) { if ((isFixedSize() == value) && !force) { return; } Q_Q(FramelessQuickWindow); if (value) { const QSize size = q->size(); q->setMinimumSize(size); q->setMaximumSize(size); q->setFlags(q->flags() | Qt::MSWindowsFixedSizeDialogHint); } else { q->setFlags(q->flags() & ~Qt::MSWindowsFixedSizeDialogHint); q->setMinimumSize(kDefaultWindowSize); q->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)); } #ifdef Q_OS_WINDOWS Utils::setAeroSnappingEnabled(q->winId(), !value); #endif Q_EMIT q->fixedSizeChanged(); } void FramelessQuickWindowPrivate::bringToFront() { Q_Q(FramelessQuickWindow); if (isHidden()) { q->show(); } if (isMinimized()) { q->showNormal(); // ### FIXME !!! } q->raise(); q->requestActivate(); } void FramelessQuickWindowPrivate::snapToTopBorder(QQuickItem *item, const Anchor itemAnchor, const Anchor topBorderAnchor) { Q_ASSERT(item); if (!item) { return; } const QQuickAnchorLine targetAnchorLine = [this, topBorderAnchor]() -> QQuickAnchorLine { switch (topBorderAnchor) { case Anchor::Top: return getTopBorderTop(); case Anchor::Bottom: return getTopBorderBottom(); case Anchor::Left: return getTopBorderLeft(); case Anchor::Right: return getTopBorderRight(); case Anchor::HorizontalCenter: return getTopBorderHorizontalCenter(); case Anchor::VerticalCenter: return getTopBorderVerticalCenter(); default: break; } return {}; }(); const QQuickItemPrivate * const itemPrivate = QQuickItemPrivate::get(item); QQuickAnchors * const anchors = itemPrivate->anchors(); switch (itemAnchor) { case Anchor::Top: anchors->setTop(targetAnchorLine); break; case Anchor::Bottom: anchors->setBottom(targetAnchorLine); break; case Anchor::Left: anchors->setLeft(targetAnchorLine); break; case Anchor::Right: anchors->setRight(targetAnchorLine); break; case Anchor::HorizontalCenter: anchors->setHorizontalCenter(targetAnchorLine); break; case Anchor::VerticalCenter: anchors->setVerticalCenter(targetAnchorLine); break; case Anchor::Center: anchors->setCenterIn(m_topBorderRectangle.data()); break; } } bool FramelessQuickWindowPrivate::eventFilter(QObject *object, QEvent *event) { Q_ASSERT(object); Q_ASSERT(event); if (!object || !event) { return false; } if (!object->isWindowType()) { return QObject::eventFilter(object, event); } Q_Q(FramelessQuickWindow); const auto window = qobject_cast(object); if (window != q) { return QObject::eventFilter(object, event); } switch (event->type()) { case QEvent::Show: { const auto showEvent = static_cast(event); showEventHandler(showEvent); } break; #ifdef Q_OS_WINDOWS case QEvent::MouseMove: { const auto mouseEvent = static_cast(event); mouseMoveEventHandler(mouseEvent); } break; #else case QEvent::MouseButtonPress: { const auto mouseEvent = static_cast(event); mousePressEventHandler(mouseEvent); } break; #endif case QEvent::MouseButtonRelease: { const auto mouseEvent = static_cast(event); mouseReleaseEventHandler(mouseEvent); } break; case QEvent::MouseButtonDblClick: { const auto mouseEvent = static_cast(event); mouseDoubleClickEventHandler(mouseEvent); } break; default: break; } return QObject::eventFilter(object, event); } void FramelessQuickWindowPrivate::showMinimized2() { Q_Q(FramelessQuickWindow); #ifdef Q_OS_WINDOWS // Work-around a QtQuick bug: https://bugreports.qt.io/browse/QTBUG-69711 // Don't use "SW_SHOWMINIMIZED" because it will activate the current window // instead of the next window in the Z order, which is not the default behavior // of native Win32 applications. ShowWindow(reinterpret_cast(q->winId()), SW_MINIMIZE); #else q->showMinimized(); #endif } void FramelessQuickWindowPrivate::toggleMaximized() { if (isFixedSize()) { return; } Q_Q(FramelessQuickWindow); if (isZoomed()) { q->showNormal(); } else { q->showMaximized(); } } void FramelessQuickWindowPrivate::toggleFullScreen() { if (isFixedSize()) { return; } Q_Q(FramelessQuickWindow); if (isFullScreen()) { q->setVisibility(m_savedVisibility); } else { m_savedVisibility = q->visibility(); q->showFullScreen(); } } void FramelessQuickWindowPrivate::showSystemMenu(const QPoint &pos) { #ifdef Q_OS_WINDOWS Q_Q(FramelessQuickWindow); const QPoint globalPos = q->mapToGlobal(pos); const QPoint nativePos = QPointF(QPointF(globalPos) * q->effectiveDevicePixelRatio()).toPoint(); Utils::showSystemMenu(q->winId(), nativePos, m_settings.systemMenuOffset, false, m_settings.options, m_params.isWindowFixedSize); #else Q_UNUSED(pos); #endif } void FramelessQuickWindowPrivate::startSystemMove2(const QPoint &pos) { Q_Q(FramelessQuickWindow); Utils::startSystemMove(q, pos); } void FramelessQuickWindowPrivate::startSystemResize2(const Qt::Edges edges, const QPoint &pos) { if (isFixedSize()) { return; } if (edges == Qt::Edges{}) { return; } Q_Q(FramelessQuickWindow); Utils::startSystemResize(q, edges, pos); } void FramelessQuickWindowPrivate::initialize() { if (m_initialized) { return; } m_initialized = true; Q_Q(FramelessQuickWindow); m_params.getWindowId = [q]() -> WId { return q->winId(); }; m_params.getWindowFlags = [q]() -> Qt::WindowFlags { return q->flags(); }; m_params.setWindowFlags = [q](const Qt::WindowFlags flags) -> void { q->setFlags(flags); }; m_params.getWindowSize = [q]() -> QSize { return q->size(); }; m_params.setWindowSize = [q](const QSize &size) -> void { q->resize(size); }; m_params.getWindowPosition = [q]() -> QPoint { return q->position(); }; m_params.setWindowPosition = [q](const QPoint &pos) -> void { q->setX(pos.x()); q->setY(pos.y()); }; m_params.getWindowScreen = [q]() -> QScreen * { return q->screen(); }; m_params.isWindowFixedSize = [this]() -> bool { return isFixedSize(); }; m_params.setWindowFixedSize = [this](const bool value) -> void { setFixedSize(value); }; m_params.getWindowState = [q]() -> Qt::WindowState { return q->windowState(); }; m_params.setWindowState = [q](const Qt::WindowState state) -> void { q->setWindowState(state); }; m_params.getWindowHandle = [q]() -> QWindow * { return q; }; m_params.windowToScreen = [q](const QPoint &pos) -> QPoint { return q->mapToGlobal(pos); }; m_params.screenToWindow = [q](const QPoint &pos) -> QPoint { return q->mapFromGlobal(pos); }; m_params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); }; m_params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); }; m_params.getWindowDevicePixelRatio = [q]() -> qreal { return q->effectiveDevicePixelRatio(); }; m_params.setSystemButtonState = [q](const SystemButtonType button, const ButtonState state) -> void { Q_ASSERT(button != SystemButtonType::Unknown); if (button == SystemButtonType::Unknown) { return; } Q_EMIT q->systemButtonStateChanged(button, state); }; if (m_settings.options & Option::DisableResizing) { setFixedSize(true, true); } if (m_settings.options & Option::TransparentWindowBackground) { q->setColor(kDefaultTransparentColor); } FramelessWindowsManager * const manager = FramelessWindowsManager::instance(); manager->addWindow(m_settings, m_params); q->installEventFilter(this); QQuickItem * const rootItem = q->contentItem(); const QQuickItemPrivate * const rootItemPrivate = QQuickItemPrivate::get(rootItem); m_topBorderRectangle.reset(new QQuickRectangle(rootItem)); QQuickPen * const _border = m_topBorderRectangle->border(); _border->setWidth(0.0); _border->setColor(kDefaultTransparentColor); const bool frameBorderVisible = [this]() -> bool { #ifdef Q_OS_WINDOWS return (Utils::isWindowFrameBorderVisible() && !Utils::isWin11OrGreater() && !(m_settings.options & Option::DontDrawTopWindowFrameBorder)); #else Q_UNUSED(this); return false; #endif }(); if (frameBorderVisible) { updateTopBorderHeight(); updateTopBorderColor(); } connect(q, &FramelessQuickWindow::visibilityChanged, this, [this, q, frameBorderVisible](){ if (frameBorderVisible) { updateTopBorderHeight(); } Q_EMIT q->hiddenChanged(); Q_EMIT q->normalChanged(); Q_EMIT q->minimizedChanged(); Q_EMIT q->zoomedChanged(); Q_EMIT q->fullScreenChanged(); }); connect(q, &FramelessQuickWindow::activeChanged, this, &FramelessQuickWindowPrivate::updateTopBorderColor); connect(manager, &FramelessWindowsManager::systemThemeChanged, this, [this, q, frameBorderVisible](){ if (frameBorderVisible) { updateTopBorderColor(); } Q_EMIT q->frameBorderColorChanged(); }); m_topBorderAnchors.reset(new QQuickAnchors(m_topBorderRectangle.data(), m_topBorderRectangle.data())); m_topBorderAnchors->setTop(rootItemPrivate->top()); m_topBorderAnchors->setLeft(rootItemPrivate->left()); m_topBorderAnchors->setRight(rootItemPrivate->right()); } QRect FramelessQuickWindowPrivate::mapItemGeometryToScene(const QQuickItem * const item) const { Q_ASSERT(item); if (!item) { return {}; } const QPointF originPoint = item->mapToScene(QPointF(0.0, 0.0)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) const QSizeF size = item->size(); #else const QSizeF size = {item->width(), item->height()}; #endif return QRectF(originPoint, size).toRect(); } bool FramelessQuickWindowPrivate::isInSystemButtons(const QPoint &pos, SystemButtonType *button) const { Q_ASSERT(button); if (!button) { return false; } *button = SystemButtonType::Unknown; if (!m_settings.windowIconButton && !m_settings.contextHelpButton && !m_settings.minimizeButton && !m_settings.maximizeButton && !m_settings.closeButton) { return false; } if (m_settings.windowIconButton && m_settings.windowIconButton->inherits(QT_QUICKITEM_CLASS_NAME)) { const auto iconBtn = qobject_cast(m_settings.windowIconButton); if (mapItemGeometryToScene(iconBtn).contains(pos)) { *button = SystemButtonType::WindowIcon; return true; } } if (m_settings.contextHelpButton && m_settings.contextHelpButton->inherits(QT_QUICKITEM_CLASS_NAME)) { const auto helpBtn = qobject_cast(m_settings.contextHelpButton); if (mapItemGeometryToScene(helpBtn).contains(pos)) { *button = SystemButtonType::Help; return true; } } if (m_settings.minimizeButton && m_settings.minimizeButton->inherits(QT_QUICKITEM_CLASS_NAME)) { const auto minBtn = qobject_cast(m_settings.minimizeButton); if (mapItemGeometryToScene(minBtn).contains(pos)) { *button = SystemButtonType::Minimize; return true; } } if (m_settings.maximizeButton && m_settings.maximizeButton->inherits(QT_QUICKITEM_CLASS_NAME)) { const auto maxBtn = qobject_cast(m_settings.maximizeButton); if (mapItemGeometryToScene(maxBtn).contains(pos)) { *button = SystemButtonType::Maximize; return true; } } if (m_settings.closeButton && m_settings.closeButton->inherits(QT_QUICKITEM_CLASS_NAME)) { const auto closeBtn = qobject_cast(m_settings.closeButton); if (mapItemGeometryToScene(closeBtn).contains(pos)) { *button = SystemButtonType::Close; return true; } } return false; } bool FramelessQuickWindowPrivate::isInTitleBarDraggableArea(const QPoint &pos) const { if (!m_titleBarItem) { return false; } QRegion region = mapItemGeometryToScene(m_titleBarItem); if (!m_hitTestVisibleItems.isEmpty()) { for (auto &&item : qAsConst(m_hitTestVisibleItems)) { Q_ASSERT(item); if (item) { region -= mapItemGeometryToScene(item); } } } return region.contains(pos); } bool FramelessQuickWindowPrivate::shouldIgnoreMouseEvents(const QPoint &pos) const { Q_Q(const FramelessQuickWindow); const bool withinFrameBorder = [&pos, q]() -> bool { if (pos.y() < kDefaultResizeBorderThickness) { return true; } #ifdef Q_OS_WINDOWS if (Utils::isWindowFrameBorderVisible()) { return false; } #endif return ((pos.x() < kDefaultResizeBorderThickness) || (pos.x() >= (q->width() - kDefaultResizeBorderThickness))); }(); return (isNormal() && withinFrameBorder); } void FramelessQuickWindowPrivate::doStartSystemMove2(QMouseEvent *event) { Q_ASSERT(event); if (!event) { return; } if (m_settings.options & Option::DisableDragging) { return; } #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const QPoint scenePos = event->scenePosition().toPoint(); const QPoint globalPos = event->globalPosition().toPoint(); #else const QPoint scenePos = event->windowPos().toPoint(); const QPoint globalPos = event->screenPos().toPoint(); #endif if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { return; } startSystemMove2(globalPos); } void FramelessQuickWindowPrivate::showEventHandler(QShowEvent *event) { Q_ASSERT(event); if (!event) { return; } if (m_windowExposed) { return; } m_windowExposed = true; if (m_settings.options & Option::DontMoveWindowToDesktopCenter) { if (!m_settings.startupPosition.isNull()) { m_params.setWindowPosition(m_settings.startupPosition); } if (!m_settings.startupSize.isEmpty()) { m_params.setWindowSize(m_settings.startupSize); } if (m_settings.startupState != Qt::WindowNoState) { m_params.setWindowState(m_settings.startupState); } } else { moveToDesktopCenter(); } } void FramelessQuickWindowPrivate::mouseMoveEventHandler(QMouseEvent *event) { #ifdef Q_OS_WINDOWS Q_ASSERT(event); if (!event) { return; } doStartSystemMove2(event); #else Q_UNUSED(event); #endif } void FramelessQuickWindowPrivate::mousePressEventHandler(QMouseEvent *event) { #ifdef Q_OS_WINDOWS Q_UNUSED(event); #else Q_ASSERT(event); if (!event) { return; } doStartSystemMove2(event); #endif } void FramelessQuickWindowPrivate::mouseReleaseEventHandler(QMouseEvent *event) { Q_ASSERT(event); if (!event) { return; } if (m_settings.options & Option::DisableSystemMenu) { return; } if (event->button() != Qt::RightButton) { return; } #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const QPoint scenePos = event->scenePosition().toPoint(); #else const QPoint scenePos = event->windowPos().toPoint(); #endif if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { return; } showSystemMenu(scenePos); } void FramelessQuickWindowPrivate::mouseDoubleClickEventHandler(QMouseEvent *event) { Q_ASSERT(event); if (!event) { return; } if ((m_settings.options & Option::NoDoubleClickMaximizeToggle) || isFixedSize()) { return; } if (event->button() != Qt::LeftButton) { return; } #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const QPoint scenePos = event->scenePosition().toPoint(); #else const QPoint scenePos = event->windowPos().toPoint(); #endif if (shouldIgnoreMouseEvents(scenePos)) { return; } if (!isInTitleBarDraggableArea(scenePos)) { return; } toggleMaximized(); } void FramelessQuickWindowPrivate::updateTopBorderColor() { #ifdef Q_OS_WINDOWS m_topBorderRectangle->setColor(getFrameBorderColor()); #endif } void FramelessQuickWindowPrivate::updateTopBorderHeight() { #ifdef Q_OS_WINDOWS const qreal newHeight = (isNormal() ? 1.0 : 0.0); m_topBorderRectangle->setHeight(newHeight); #endif } FramelessQuickWindow::FramelessQuickWindow(QWindow *parent, const UserSettings &settings) : QQuickWindow(parent) { d_ptr.reset(new FramelessQuickWindowPrivate(this, settings)); } FramelessQuickWindow::~FramelessQuickWindow() = default; bool FramelessQuickWindow::isHidden() const { Q_D(const FramelessQuickWindow); return d->isHidden(); } bool FramelessQuickWindow::isNormal() const { Q_D(const FramelessQuickWindow); return d->isNormal(); } bool FramelessQuickWindow::isMinimized() const { Q_D(const FramelessQuickWindow); return d->isMinimized(); } bool FramelessQuickWindow::isZoomed() const { Q_D(const FramelessQuickWindow); return d->isZoomed(); } bool FramelessQuickWindow::isFullScreen() const { Q_D(const FramelessQuickWindow); return d->isFullScreen(); } bool FramelessQuickWindow::fixedSize() const { Q_D(const FramelessQuickWindow); return d->isFixedSize(); } void FramelessQuickWindow::setFixedSize(const bool value) { Q_D(FramelessQuickWindow); d->setFixedSize(value); } QColor FramelessQuickWindow::frameBorderColor() const { Q_D(const FramelessQuickWindow); return d->getFrameBorderColor(); } void FramelessQuickWindow::setTitleBarItem(QQuickItem *item) { Q_ASSERT(item); if (!item) { return; } Q_D(FramelessQuickWindow); d->setTitleBarItem(item); } void FramelessQuickWindow::setHitTestVisible(QQuickItem *item) { Q_ASSERT(item); if (!item) { return; } Q_D(FramelessQuickWindow); d->setHitTestVisible(item); } void FramelessQuickWindow::moveToDesktopCenter() { Q_D(FramelessQuickWindow); d->moveToDesktopCenter(); } void FramelessQuickWindow::bringToFront() { Q_D(FramelessQuickWindow); d->bringToFront(); } void FramelessQuickWindow::snapToTopBorder(QQuickItem *item, const Anchor itemAnchor, const Anchor topBorderAnchor) { Q_ASSERT(item); if (!item) { return; } Q_D(FramelessQuickWindow); d->snapToTopBorder(item, itemAnchor, topBorderAnchor); } void FramelessQuickWindow::showMinimized2() { Q_D(FramelessQuickWindow); d->showMinimized2(); } void FramelessQuickWindow::toggleMaximized() { Q_D(FramelessQuickWindow); d->toggleMaximized(); } void FramelessQuickWindow::toggleFullScreen() { Q_D(FramelessQuickWindow); d->toggleFullScreen(); } void FramelessQuickWindow::showSystemMenu(const QPoint &pos) { Q_D(FramelessQuickWindow); d->showSystemMenu(pos); } void FramelessQuickWindow::startSystemMove2(const QPoint &pos) { Q_D(FramelessQuickWindow); d->startSystemMove2(pos); } void FramelessQuickWindow::startSystemResize2(const Qt::Edges edges, const QPoint &pos) { if (edges == Qt::Edges{}) { return; } Q_D(FramelessQuickWindow); d->startSystemResize2(edges, pos); } FRAMELESSHELPER_END_NAMESPACE