1- // Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd.
2- // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
1+ // Copyright (C) 2019 ~ 2026 Deepin Technology Co., Ltd.
2+ // SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
33//
44// SPDX-License-Identifier: GPL-3.0-or-later
55
1717#include < QFileDialog>
1818#include < QStandardPaths>
1919#include < QTimer>
20+ #include < QWindow>
21+ #include < QShowEvent>
2022
2123#define MOVENUM 1
2224
@@ -57,8 +59,14 @@ void MainWindow::initMainWindow()
5759 m_ocrInterface = nullptr ;
5860 m_toolBar = nullptr ;
5961 // 去菜单栏,置顶窗口
60- setWindowFlags (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint);
61- qCDebug (dsrApp) << " Set window flags." ;
62+ if (PUtils::isTreelandMode) {
63+ // Treeland: 由合成器管理主窗口移动,工具栏作为 subsurface 跟随。
64+ setWindowFlags (Qt::FramelessWindowHint | Qt::Window | Qt::WindowStaysOnTopHint);
65+ qCDebug (dsrApp) << " Set window flags for Treeland mode." ;
66+ } else {
67+ setWindowFlags (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint);
68+ qCDebug (dsrApp) << " Set window flags." ;
69+ }
6270
6371 // 设置可以进行鼠标操作
6472 setMouseTracking (true );
@@ -432,18 +440,28 @@ void MainWindow::mousePressEvent(QMouseEvent *event)
432440{
433441 // qCDebug(dsrApp) << this << __FUNCTION__ << __LINE__ ;
434442 switch (event->button ()) {
435- case Qt::LeftButton:
443+ case Qt::LeftButton: {
444+ const QPointF globalPress = event->globalPosition ();
445+ if (PUtils::isTreelandMode) {
446+ region (globalPress.toPoint ());
447+ if (dir == NONE && windowHandle ()) {
448+ windowHandle ()->startSystemMove ();
449+ event->accept ();
450+ return ;
451+ }
452+ }
436453 isLeftPressDown = true ;
437454 if (dir != NONE ) {
438455 this ->mouseGrabber ();
439456 } else {
440- dragPosition = (event-> globalPosition () - this ->frameGeometry ().topLeft ()).toPoint ();
457+ dragPosition = (globalPress - this ->frameGeometry ().topLeft ()).toPoint ();
441458 }
442- // 鼠标按下时隐藏工具栏
443- if (!m_toolBar->isHidden ())
459+ // 鼠标按下时隐藏工具栏;Treeland 下工具栏是 subsurface,可随主窗口移动。
460+ if (!PUtils::isTreelandMode && ! m_toolBar->isHidden ())
444461 m_toolBar->hide ();
445462 // qCDebug(dsrApp) << this << __FUNCTION__ << __LINE__ ;
446463 break ;
464+ }
447465 case Qt::RightButton:
448466 handleMouseRightBtn (event);
449467 break ;
@@ -465,7 +483,7 @@ void MainWindow::mouseMoveEvent(QMouseEvent *event)
465483 this ->region (gloPoint);
466484 } else {
467485 // 确保在拖动过程中隐藏工具栏
468- if (!m_toolBar->isHidden ()) {
486+ if (!PUtils::isTreelandMode && ! m_toolBar->isHidden ()) {
469487 m_toolBar->hide ();
470488 }
471489
@@ -604,23 +622,30 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
604622 int x = this ->pos ().x ();
605623 int y = this ->pos ().y ();
606624 bool isNeedUpdateToolBar = false ;
625+ const auto applyWindowMove = [this ](int nx, int ny) {
626+ if (PUtils::isTreelandMode && windowHandle ()) {
627+ windowHandle ()->setPosition (nx, ny);
628+ } else {
629+ move (nx, ny);
630+ }
631+ };
607632 if (event->key () == Qt::Key_Left) {
608- this -> move (x - MOVENUM , y);
633+ applyWindowMove (x - MOVENUM , y);
609634 isNeedUpdateToolBar = true ;
610635 } else if (event->key () == Qt::Key_Right) {
611- this -> move (x + MOVENUM , y);
636+ applyWindowMove (x + MOVENUM , y);
612637 isNeedUpdateToolBar = true ;
613638 } else if (event->key () == Qt::Key_Up) {
614639 // 适配wayland
615640 if (y - MOVENUM < 0 ) {
616- this -> move (x, 0 );
641+ applyWindowMove (x, 0 );
617642 } else {
618- this -> move (x, y - MOVENUM );
643+ applyWindowMove (x, y - MOVENUM );
619644 }
620645
621646 isNeedUpdateToolBar = true ;
622647 } else if (event->key () == Qt::Key_Down) {
623- this -> move (x, y + MOVENUM );
648+ applyWindowMove (x, y + MOVENUM );
624649 isNeedUpdateToolBar = true ;
625650 }
626651
@@ -686,7 +711,7 @@ bool MainWindow::eventFilter(QObject *watched, QEvent *event)
686711
687712 // 检查鼠标是否在工具栏上,如果是则不隐藏工具栏
688713 QPoint globalPos = QCursor::pos ();
689- if (m_toolBar->isActiveWindow () || m_toolBar->geometry ().contains (globalPos))
714+ if (m_toolBar->isActiveWindow () || m_toolBar->rect ().contains (m_toolBar-> mapFromGlobal ( globalPos) ))
690715 return false ;
691716
692717 // 检查是否有菜单正在显示
@@ -861,7 +886,6 @@ void MainWindow::sendNotify(QString savePath, bool bSaveState)
861886 onExit ();
862887}
863888
864- // 更新工具栏显示位置
865889void MainWindow::updateToolBarPosition ()
866890{
867891 // 获取贴图界面右下角的点
@@ -893,11 +917,25 @@ void MainWindow::updateToolBarPosition()
893917 } else if (x + m_toolBar->width () > m_screenSize.width ()) {
894918 x = m_screenSize.width () - m_toolBar->width ();
895919 }
896- m_toolBar->showAt (QPoint (x, y), m_isfirstTime);
897- m_toolBar->activateWindow ();
920+ QPoint toolbarPos (x, y);
921+ if (toolbarAttachedToWindow ()) {
922+ toolbarPos = mapFromGlobal (toolbarPos);
923+ }
924+ m_toolBar->showAt (toolbarPos, m_isfirstTime);
925+ // Treeland subsurface 下工具栏 QWindow 已 setParent,非顶层;activateWindow 会触发 Qt Warning
926+ if (!(PUtils::isTreelandMode && toolbarAttachedToWindow ())) {
927+ m_toolBar->activateWindow ();
928+ }
898929 m_isfirstTime = false ;
899930}
900931
932+ bool MainWindow::toolbarAttachedToWindow () const
933+ {
934+ const QWindow *mainWindow = windowHandle ();
935+ const QWindow *toolbarWindow = m_toolBar ? m_toolBar->windowHandle () : nullptr ;
936+ return mainWindow && toolbarWindow && toolbarWindow->parent () == mainWindow;
937+ }
938+
901939void MainWindow::checkToolbarVisibility ()
902940{
903941 m_hideToolbarTimer->stop ();
@@ -924,13 +962,14 @@ void MainWindow::checkToolbarVisibility()
924962 }
925963 }
926964
927- const bool mouseOnToolBar = m_toolBar && m_toolBar->isVisible () && m_toolBar->geometry ().contains (globalPos);
965+ const bool mouseOnToolBar = m_toolBar && m_toolBar->isVisible ()
966+ && m_toolBar->rect ().contains (m_toolBar->mapFromGlobal (globalPos));
928967
929968 bool mouseOnMenu = false ;
930969 if (m_toolBar && m_toolBar->isVisible ()) {
931970 QList<QMenu*> menus = m_toolBar->findChildren <QMenu*>();
932971 for (QMenu* menu : menus) {
933- if (menu->isVisible () && menu->geometry ().contains (globalPos)) {
972+ if (menu->isVisible () && menu->rect ().contains (menu-> mapFromGlobal ( globalPos) )) {
934973 mouseOnMenu = true ;
935974 break ;
936975 }
@@ -948,6 +987,26 @@ void MainWindow::checkToolbarVisibility()
948987 }
949988}
950989
990+ void MainWindow::showEvent (QShowEvent *event)
991+ {
992+ DWidget::showEvent (event);
993+ if (!PUtils::isTreelandMode || !m_toolBar) {
994+ return ;
995+ }
996+
997+ createWinId ();
998+ m_toolBar->createWinId ();
999+ if (!windowHandle () || !m_toolBar->windowHandle () || toolbarAttachedToWindow ()) {
1000+ return ;
1001+ }
1002+
1003+ m_toolBar->windowHandle ()->setParent (windowHandle ());
1004+ m_toolBar->hide ();
1005+ m_toolBar->show ();
1006+ qCDebug (dsrApp) << " [Treeland] pin toolbar QWindow::setParent (subsurface with custom style)" ;
1007+ updateToolBarPosition ();
1008+ }
1009+
9511010void MainWindow::enterEvent (QEnterEvent *event)
9521011{
9531012 Q_UNUSED (event);
0 commit comments