From c0f80b74ffb8384e2aeb6c1038cf7c537afc3f08 Mon Sep 17 00:00:00 2001 From: chenjun <104487271+chenjun1982@users.noreply.github.com> Date: Fri, 14 Oct 2022 09:01:35 +0600 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E7=95=8C=E9=9D=A2=E6=98=BE=E7=A4=BA=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E4=BD=BF=E7=94=A8=E6=BB=9A=E5=8A=A8=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E5=8A=A0=E8=BD=BD=E9=A2=84=E8=A7=88=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=20(#705)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化应用预览界面显示方式,使用滚动方式加载预览界面 在打开应用程序很多时,无法显示更多预览界面,不方便切换预览 Log: 修复可多开的应用打开超过20个后,任务栏预览效果不能全部展示的问题 Bug: https://pms.uniontech.com/bug-view-152143.html Bug: https://pms.uniontech.com/bug-view-162757.html Influence: 可多开的应用打开超过20个后,预览界面可以滚动选择未显示的界面 --- frame/item/appitem.cpp | 67 +------ frame/item/appitem.h | 1 - frame/item/components/appsnapshot.cpp | 15 +- frame/item/components/appsnapshot.h | 2 + frame/item/components/floatingpreview.cpp | 9 - frame/item/components/previewcontainer.cpp | 222 ++++++++++++++++----- frame/item/components/previewcontainer.h | 19 +- frame/item/dockitem.cpp | 6 + frame/item/dockitem.h | 2 + frame/window/mainwindow.cpp | 1 + tests/item/ut_appitem.cpp | 1 - 11 files changed, 221 insertions(+), 124 deletions(-) diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index 9faf501f2..eed9c53ba 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -332,10 +332,6 @@ void AppItem::mouseMoveEvent(QMouseEvent *e) { e->accept(); - // handle preview - // if (e->buttons() == Qt::NoButton) - // return showPreview(); - // handle drag if (e->buttons() != Qt::LeftButton) return; @@ -343,10 +339,6 @@ void AppItem::mouseMoveEvent(QMouseEvent *e) const QPoint pos = e->pos(); if (!rect().contains(pos)) return; - - const QPoint distance = pos - MousePressPos; - if (distance.manhattanLength() > APP_DRAG_THRESHOLD) - return startDrag(); } void AppItem::wheelEvent(QWheelEvent *e) @@ -473,57 +465,6 @@ QWidget *AppItem::popupTips() return &appNameTips; } -void AppItem::startDrag() -{ - // 拖拽实现放到mainpanelcontrol - - /* - if (!acceptDrops()) - return; - - if (checkGSettingsControl()) { - return; - } - - m_dragging = true; - update(); - - const QPixmap &dragPix = m_appIcon; - - m_drag = new AppDrag(this); - m_drag->setMimeData(new QMimeData); - - // handle drag finished here - connect(m_drag->appDragWidget(), &AppDragWidget::destroyed, this, [ = ] { - m_dragging = false; - m_drag.clear(); - setVisible(true); - update(); - }); - - if (m_wmHelper->hasComposite()) { - m_drag->setPixmap(dragPix); - m_drag->appDragWidget()->setOriginPos(mapToGlobal(appIconPosition())); - emit dragStarted(); - m_drag->exec(Qt::MoveAction); - } else { - m_drag->QDrag::setPixmap(dragPix); - m_drag->setHotSpot(dragPix.rect().center() / dragPix.devicePixelRatioF()); - emit dragStarted(); - m_drag->QDrag::exec(Qt::MoveAction); - } - - // MainPanel will put this item to Item-Container when received this signal(MainPanel::itemDropped) - //emit itemDropped(m_drag->target()); - - if (!m_wmHelper->hasComposite()) { - if (!m_drag->target()) { - m_itemEntryInter->RequestUndock(); - } - } - */ -} - bool AppItem::hasAttention() const { auto it = std::find_if(m_windowInfos.constBegin(), m_windowInfos.constEnd(), [ = ] (const auto &info) { @@ -635,6 +576,7 @@ void AppItem::showPreview() return; m_appPreviewTips = new PreviewContainer; + m_appPreviewTips->updateDockSize(DockSize); m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntryInter->GetAllowedCloseWindows().value()); m_appPreviewTips->updateLayoutDirection(DockPosition); @@ -654,6 +596,13 @@ void AppItem::showPreview() m_appPreviewTips->setTitleDisplayMode(config->value("showWindowName").toInt()); delete config; + // 设置预览界面是否开启左右两边的圆角 + if (!PopupWindow.isNull() && m_wmHelper->hasComposite()) { + PopupWindow->setLeftRightRadius(true); + } else { + PopupWindow->setLeftRightRadius(false); + } + showPopupWindow(m_appPreviewTips, true); } diff --git a/frame/item/appitem.h b/frame/item/appitem.h index ffacedc92..68d033da1 100644 --- a/frame/item/appitem.h +++ b/frame/item/appitem.h @@ -67,7 +67,6 @@ private: void invokedMenuItem(const QString &itemId, const bool checked) override; const QString contextMenu() const override; QWidget *popupTips() override; - void startDrag(); bool hasAttention() const; QPoint appIconPosition() const; diff --git a/frame/item/components/appsnapshot.cpp b/frame/item/components/appsnapshot.cpp index e05e566e7..dea485d96 100644 --- a/frame/item/components/appsnapshot.cpp +++ b/frame/item/components/appsnapshot.cpp @@ -50,6 +50,8 @@ AppSnapshot::AppSnapshot(const WId wid, QWidget *parent) , m_wmHelper(DWindowManagerHelper::instance()) , m_dockDaemonInter(new DockDaemonInter("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", QDBusConnection::sessionBus(), this)) { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_closeBtn2D->setFixedSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH); m_closeBtn2D->setIconSize(QSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH)); m_closeBtn2D->setObjectName("closebutton-2d"); @@ -66,7 +68,6 @@ AppSnapshot::AppSnapshot(const WId wid, QWidget *parent) setLayout(centralLayout); setAcceptDrops(true); - resize(SNAP_WIDTH / 2, SNAP_HEIGHT / 2); connect(m_closeBtn2D, &DIconButton::clicked, this, &AppSnapshot::closeWindow, Qt::QueuedConnection); connect(m_wmHelper, &DWindowManagerHelper::hasCompositeChanged, this, &AppSnapshot::compositeChanged, Qt::QueuedConnection); @@ -165,8 +166,18 @@ void AppSnapshot::setWindowInfo(const WindowInfo &info) { m_windowInfo = info; QFontMetrics fm(m_title->font()); - QString strTtile = m_title->fontMetrics().elidedText(m_windowInfo.title, Qt::ElideRight, SNAP_WIDTH - SNAP_CLOSE_BTN_WIDTH - SNAP_CLOSE_BTN_MARGIN); + QString strTtile = m_title->fontMetrics().elidedText(m_windowInfo.title, Qt::ElideRight, SNAP_WIDTH_WITHOUT_COMPOSITE - SNAP_CLOSE_BTN_WIDTH - 2 *SNAP_CLOSE_BTN_MARGIN); m_title->setText(strTtile); + m_title->adjustSize(); + + // 设置单个预览界面大小 + if (m_wmHelper->hasComposite()) { + setMinimumSize(SNAP_WIDTH, SNAP_HEIGHT); + setFixedSize(SNAP_WIDTH, SNAP_HEIGHT); + } else { + setMinimumSize(m_title->width() + SNAP_CLOSE_BTN_WIDTH + 2 * SNAP_CLOSE_BTN_MARGIN, SNAP_HEIGHT_WITHOUT_COMPOSITE); + } + updateTitle(); // 只有在X11下,才能通过XGetWindowProperty获取窗口属性 diff --git a/frame/item/components/appsnapshot.h b/frame/item/components/appsnapshot.h index 4dc26463d..3b2aa8b7e 100644 --- a/frame/item/components/appsnapshot.h +++ b/frame/item/components/appsnapshot.h @@ -21,6 +21,8 @@ DGUI_USE_NAMESPACE #define SNAP_WIDTH 200 #define SNAP_HEIGHT 130 +#define SNAP_HEIGHT_WITHOUT_COMPOSITE 30 +#define SNAP_WIDTH_WITHOUT_COMPOSITE 300 #define SNAP_CLOSE_BTN_WIDTH (24) #define SNAP_CLOSE_BTN_MARGIN (5) diff --git a/frame/item/components/floatingpreview.cpp b/frame/item/components/floatingpreview.cpp index 74c795b77..7264bf10a 100644 --- a/frame/item/components/floatingpreview.cpp +++ b/frame/item/components/floatingpreview.cpp @@ -77,12 +77,6 @@ void FloatingPreview::trackWindow(AppSnapshot *const snap) // 显示此标题的前提条件:配置了标题跟随鼠标显示 // 此对象是共用的,鼠标移动到哪个预览图,title就移动到哪里显示,所以他的text统一snap获取,不再重复计算显示长度 m_titleBtn->setText(snap->appTitle()); - - QTimer::singleShot(0, this, [ = ] { - // 此处获取的snap->geometry()有可能是错误的,所以做个判断并且在resizeEvent中也做处理 - if(snap->width() == SNAP_WIDTH) - setGeometry(snap->geometry()); - }); } void FloatingPreview::paintEvent(QPaintEvent *e) @@ -143,9 +137,6 @@ bool FloatingPreview::eventFilter(QObject *watched, QEvent *event) m_tracked = nullptr; hide(); } - - if (event->type() == QEvent::Resize && m_tracked->width() == SNAP_WIDTH) - setGeometry(m_tracked->geometry()); } return QWidget::eventFilter(watched, event); diff --git a/frame/item/components/previewcontainer.cpp b/frame/item/components/previewcontainer.cpp index 0e00a80e2..74995efec 100644 --- a/frame/item/components/previewcontainer.cpp +++ b/frame/item/components/previewcontainer.cpp @@ -13,26 +13,66 @@ #include #include #include +#include +#include #define SPACING 0 #define MARGIN 0 -#define SNAP_HEIGHT_WITHOUT_COMPOSITE 30 PreviewContainer::PreviewContainer(QWidget *parent) : QWidget(parent) , m_needActivate(false) + , m_canPreview(true) + , m_dockSize(40) , m_floatingPreview(new FloatingPreview(this)) + , m_preparePreviewTimer(new QTimer(this)) , m_mouseLeaveTimer(new QTimer(this)) , m_wmHelper(DWindowManagerHelper::instance()) , m_titleMode(HoverShow) { - m_windowListLayout = new QBoxLayout(QBoxLayout::LeftToRight, this); + m_windowListLayout = new QBoxLayout(QBoxLayout::LeftToRight); m_windowListLayout->setSpacing(SPACING); m_windowListLayout->setContentsMargins(MARGIN, MARGIN, MARGIN, MARGIN); + m_windowListWidget = new QWidget(this); + m_windowListWidget->setAccessibleName("centralLayoutWidget"); + m_windowListWidget->setLayout(m_windowListLayout); + m_windowListWidget->setMinimumSize(SNAP_WIDTH, SNAP_HEIGHT); + m_windowListWidget->installEventFilter(this); + m_windowListWidget->setAttribute(Qt::WA_TranslucentBackground); + m_windowListWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + m_scrollArea = new QScrollArea(this); + m_scrollArea->setAccessibleName("Preview_scrollArea"); + m_scrollArea->setWidgetResizable(false); + m_scrollArea->setFrameStyle(QFrame::NoFrame); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setContentsMargins(0, 0, 0, 0); + m_scrollArea->setBackgroundRole(QPalette::Base); + m_scrollArea->setWidget(m_windowListWidget); + m_scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QVBoxLayout * mainLayout = new QVBoxLayout; + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + mainLayout->addWidget(m_scrollArea); + setLayout(mainLayout); + + // 设置触摸屏手势识别 + QScroller::grabGesture(m_scrollArea->viewport(), QScroller::LeftMouseButtonGesture); + QScroller *scroller = QScroller::scroller(m_scrollArea->viewport()); + m_sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootWhenScrollable); + m_sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootWhenScrollable); + scroller->setScrollerProperties(m_sp); + m_mouseLeaveTimer->setSingleShot(true); m_mouseLeaveTimer->setInterval(300); + m_preparePreviewTimer->setSingleShot(true); + m_preparePreviewTimer->setInterval(300); + + m_floatingPreview->installEventFilter(this); m_floatingPreview->setVisible(false); m_waitForShowPreviewTimer = new QTimer(this); @@ -44,15 +84,38 @@ PreviewContainer::PreviewContainer(QWidget *parent) connect(m_mouseLeaveTimer, &QTimer::timeout, this, &PreviewContainer::checkMouseLeave, Qt::QueuedConnection); connect(m_waitForShowPreviewTimer, &QTimer::timeout, this, &PreviewContainer::previewFloating); + + // 预览界面在滚动时,暂时不允许预览,避免在滚动时频繁切换预览造成闪屏 + connect(m_scrollArea->horizontalScrollBar(), &QScrollBar::valueChanged, this, [ = ]{ + m_floatingPreview->setVisible(false); + m_canPreview = false; + if (m_preparePreviewTimer->isActive()) { + m_preparePreviewTimer->stop(); + } + m_preparePreviewTimer->start(); + }); + connect(m_scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, this, [ = ]{ + m_floatingPreview->setVisible(false); + m_canPreview = false; + if (m_preparePreviewTimer->isActive()) { + m_preparePreviewTimer->stop(); + } + m_preparePreviewTimer->start(); + }); + + // 停止滚动后允许预览 + connect(m_preparePreviewTimer, &QTimer::timeout, this, [ = ]{ + m_canPreview = true; + if (m_wmHelper->hasComposite()) { + m_waitForShowPreviewTimer->start(); + } + }); } void PreviewContainer::setWindowInfos(const WindowInfoMap &infos, const WindowList &allowClose) { // check removed window for (auto it(m_snapshots.begin()); it != m_snapshots.end();) { - //初始化预览界面边距 - it.value()->setContentsMargins(0, 0, 0, 0); - if (!infos.contains(it.key())) { m_windowListLayout->removeWidget(it.value()); it.value()->deleteLater(); @@ -94,14 +157,32 @@ void PreviewContainer::setTitleDisplayMode(int mode) void PreviewContainer::updateLayoutDirection(const Dock::Position dockPos) { - if (m_wmHelper->hasComposite() && (dockPos == Dock::Top || dockPos == Dock::Bottom)) + m_dockPos = dockPos; + if (m_wmHelper->hasComposite() && (dockPos == Dock::Top || dockPos == Dock::Bottom)) { m_windowListLayout->setDirection(QBoxLayout::LeftToRight); - else + + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + m_sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + m_sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootWhenScrollable); + } else { + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_windowListLayout->setDirection(QBoxLayout::TopToBottom); + m_sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootWhenScrollable); + m_sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + } + adjustSize(m_wmHelper->hasComposite()); } +void PreviewContainer::updateDockSize(const int size) +{ + m_dockSize = size; +} + void PreviewContainer::checkMouseLeave() { const bool hover = underMouse(); @@ -131,64 +212,46 @@ void PreviewContainer::prepareHide() void PreviewContainer::adjustSize(bool composite) { - int count = m_snapshots.size(); + const bool horizontal = m_windowListLayout->direction() == QBoxLayout::LeftToRight; + const int count = m_snapshots.size(); + const int screenWidth = QDesktopWidget().screenGeometry(this).width(); const int screenHeight = QDesktopWidget().screenGeometry(this).height(); //先根据屏幕宽高计算出能预览的最大数量,然后根据数量计算界面宽高 if (composite) { - // 3D - const int padding = 20; - const bool horizontal = m_windowListLayout->direction() == QBoxLayout::LeftToRight; if (horizontal) { - count = qMin(count, screenWidth * 2 / SNAP_WIDTH); - const int h = SNAP_HEIGHT + MARGIN * 2; const int w = SNAP_WIDTH * count + MARGIN * 2 + SPACING * (count - 1); - setFixedHeight(h); - setFixedWidth(qMin(w, screenWidth - padding)); + m_windowListWidget->setFixedSize(w, h); + setFixedSize(qMin(w, screenWidth), h); } else { - count = qMin(count, screenWidth * 2 / SNAP_HEIGHT); - - const int w = SNAP_WIDTH + MARGIN * 2; const int h = SNAP_HEIGHT * count + MARGIN * 2 + SPACING * (count - 1); + const int w = SNAP_WIDTH + MARGIN * 2; - setFixedWidth(w); - setFixedHeight(qMin(h, screenHeight - padding)); + m_windowListWidget->setFixedSize(w, h); + setFixedSize(w, qMin(h, screenHeight)); } } else if (m_windowListLayout->count()) { // 2D - count = qMin(count, screenWidth / SNAP_HEIGHT_WITHOUT_COMPOSITE); const int h = SNAP_HEIGHT_WITHOUT_COMPOSITE * count + MARGIN * 2 + SPACING * (count - 1); - auto appSnapshot = static_cast(m_windowListLayout->itemAt(0)->widget()); - auto font = appSnapshot->layout()->itemAt(0)->widget()->font(); - QFontMetrics fontMetrics(font); - - // 获取 appitem title 的最大宽度 - int titleWidth = fontMetrics.boundingRect(appSnapshot->title()).width(); + int titleWidth = 0; for (int i = 0; i < m_windowListLayout->count(); i++) { - auto otherWidget = static_cast(m_windowListLayout->itemAt(i)->widget()); - titleWidth = qMax(titleWidth, fontMetrics.boundingRect(otherWidget->title()).width()); + auto snapshotWidget = static_cast(m_windowListLayout->itemAt(i)->widget()); + titleWidth = qMax(titleWidth, snapshotWidget->minimumWidth()); } - // 关闭按键的宽度和边缘间距的和,调整标题居中 - const int closeBtnMargin = 2 * (SNAP_CLOSE_BTN_WIDTH + SNAP_CLOSE_BTN_MARGIN); - if (titleWidth < SNAP_WIDTH - closeBtnMargin) - setFixedSize(titleWidth + closeBtnMargin, h); - else - setFixedSize(SNAP_WIDTH, h); - } + m_windowListWidget->setFixedSize(titleWidth, h); - //根据计算的数量,将相应的预览界面添加到布局并显示,其他的暂时不添加,减少界面刷新次数 - int i = 0; - for (AppSnapshot *snap : m_snapshots) { - if (i < count && m_windowListLayout->indexOf(snap) < 0 ) { - m_windowListLayout->addWidget(snap); + if (m_dockPos == Dock::Top || m_dockPos == Dock::Bottom) { + // 滚动区域高度 = 屏幕高度 - 任务栏高度 - 箭头高度 + setFixedSize(titleWidth, qMin(h, screenHeight - m_dockSize - 20)); + } else { + // 滚动区域高度 = 屏幕高度 + setFixedSize(titleWidth, qMin(h, screenHeight)); } - snap->setVisible(i < count); - i++; } } @@ -196,7 +259,6 @@ void PreviewContainer::appendSnapWidget(const WId wid) { //创建预览界面,默认不显示,等计算出显示数量后再加入布局并显示 AppSnapshot *snap = new AppSnapshot(wid); - snap->setVisible(false); connect(snap, &AppSnapshot::clicked, this, &PreviewContainer::onSnapshotClicked, Qt::QueuedConnection); connect(snap, &AppSnapshot::entered, this, &PreviewContainer::previewEntered, Qt::QueuedConnection); @@ -204,6 +266,7 @@ void PreviewContainer::appendSnapWidget(const WId wid) connect(snap, &AppSnapshot::requestCloseAppSnapshot, this, &PreviewContainer::onRequestCloseAppSnapshot); m_snapshots.insert(wid, snap); + m_windowListLayout->addWidget(snap); } void PreviewContainer::enterEvent(QEvent *e) @@ -249,6 +312,64 @@ void PreviewContainer::dragLeaveEvent(QDragLeaveEvent *e) m_mouseLeaveTimer->start(); } +bool PreviewContainer::eventFilter(QObject *watcher, QEvent *event) +{ + // 将鼠标滚轮事件转换成水平滚动 + if (watcher == m_windowListWidget && event->type() == QEvent::Wheel) { + QWheelEvent *wheelEvent = static_cast(event); + + if (m_windowListLayout->direction() == Qt::LeftToRight) { + const int delta = wheelEvent->delta(); + const int currValue = m_scrollArea->horizontalScrollBar()->value(); + + if (currValue - delta <= 0) { + m_scrollArea->horizontalScrollBar()->setValue(0); + } else if (currValue - delta >= m_scrollArea->horizontalScrollBar()->maximum()) { + m_scrollArea->horizontalScrollBar()->setValue(m_scrollArea->horizontalScrollBar()->maximum()); + } else { + m_scrollArea->horizontalScrollBar()->setValue(currValue - delta); + } + + return true; + } + } + + // 在m_floatingPreview界面显示时,需要响应滚轮事件 + if (watcher == m_floatingPreview && event->type() == QEvent::Wheel) { + QWheelEvent *wheelEvent = static_cast(event); + + if (m_windowListLayout->direction() == Qt::LeftToRight) { + const int delta = wheelEvent->delta(); + const int currValue = m_scrollArea->horizontalScrollBar()->value(); + + if (currValue - delta <= 0) { + m_scrollArea->horizontalScrollBar()->setValue(0); + } else if (currValue - delta >= m_scrollArea->horizontalScrollBar()->maximum()) { + m_scrollArea->horizontalScrollBar()->setValue(m_scrollArea->horizontalScrollBar()->maximum()); + } else { + m_scrollArea->horizontalScrollBar()->setValue(currValue - delta); + } + + return true; + } else { + const int delta = wheelEvent->delta(); + const int currValue = m_scrollArea->verticalScrollBar()->value(); + + if (currValue - delta <= 0) { + m_scrollArea->verticalScrollBar()->setValue(0); + } else if (currValue - delta >= m_scrollArea->verticalScrollBar()->maximum()) { + m_scrollArea->verticalScrollBar()->setValue(m_scrollArea->verticalScrollBar()->maximum()); + } else { + m_scrollArea->verticalScrollBar()->setValue(currValue - delta); + } + + return true; + } + } + + return QWidget::eventFilter(watcher, event); +} + void PreviewContainer::onSnapshotClicked(const WId wid) { if (Utils::IS_WAYLAND_DISPLAY) { @@ -272,16 +393,13 @@ void PreviewContainer::previewEntered(const WId wid) if (!snap) { return; } - snap->setContentsMargins(100, 0, 100, 0); AppSnapshot *preSnap = m_floatingPreview->trackedWindow(); if (preSnap && preSnap != snap) { - preSnap->setContentsMargins(0, 0, 0, 0); preSnap->setWindowState(); } m_currentWId = wid; - m_floatingPreview->trackWindow(snap); if (m_waitForShowPreviewTimer->isActive()) { @@ -293,7 +411,15 @@ void PreviewContainer::previewEntered(const WId wid) void PreviewContainer::previewFloating() { - if (!m_waitForShowPreviewTimer->isActive()) { + if (!m_waitForShowPreviewTimer->isActive() && m_canPreview) { + // 将单个预览界面在滚动区域的坐标转换到当前界面坐标上 + if (m_floatingPreview->trackedWindow()) { + const QRect snapGeometry = m_floatingPreview->trackedWindow()->geometry(); + const QPoint topLeft = m_windowListWidget->mapTo(m_scrollArea, snapGeometry.topLeft()); + const QPoint bottomRight = m_windowListWidget->mapTo(m_scrollArea, snapGeometry.bottomRight()); + m_floatingPreview->setGeometry(QRect(topLeft, bottomRight)); + } + m_floatingPreview->setVisible(true); m_floatingPreview->raise(); diff --git a/frame/item/components/previewcontainer.h b/frame/item/components/previewcontainer.h index 11b8bd976..dffad2aec 100644 --- a/frame/item/components/previewcontainer.h +++ b/frame/item/components/previewcontainer.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "constants.h" #include "appsnapshot.h" @@ -45,6 +47,7 @@ public: public slots: void updateLayoutDirection(const Dock::Position dockPos); + void updateDockSize(const int size); void checkMouseLeave(); void prepareHide(); @@ -52,10 +55,11 @@ private: void adjustSize(bool composite); void appendSnapWidget(const WId wid); - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void dragEnterEvent(QDragEnterEvent *e); - void dragLeaveEvent(QDragLeaveEvent *e); + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void dragEnterEvent(QDragEnterEvent *e) override; + void dragLeaveEvent(QDragLeaveEvent *e) override; + bool eventFilter(QObject *watcher, QEvent *event) override; private slots: void onSnapshotClicked(const WId wid); @@ -65,11 +69,18 @@ private slots: private: bool m_needActivate; + bool m_canPreview; + int m_dockSize; + Dock::Position m_dockPos; QMap m_snapshots; FloatingPreview *m_floatingPreview; + QScrollArea * m_scrollArea; + QWidget *m_windowListWidget; QBoxLayout *m_windowListLayout; + QScrollerProperties m_sp; + QTimer *m_preparePreviewTimer; QTimer *m_mouseLeaveTimer; DWindowManagerHelper *m_wmHelper; QTimer *m_waitForShowPreviewTimer; diff --git a/frame/item/dockitem.cpp b/frame/item/dockitem.cpp index f5eecdbc9..fe78c2d64 100644 --- a/frame/item/dockitem.cpp +++ b/frame/item/dockitem.cpp @@ -14,6 +14,7 @@ #define ITEM_MAXSIZE 100 Position DockItem::DockPosition = Position::Top; +int DockItem::DockSize = 40; DisplayMode DockItem::DockDisplayMode = DisplayMode::Efficient; QPointer DockItem::PopupWindow(nullptr); @@ -77,6 +78,11 @@ void DockItem::setDockPosition(const Position side) DockPosition = side; } +void DockItem::setDockSize(const int size) +{ + DockSize = size; +} + void DockItem::setDockDisplayMode(const DisplayMode mode) { DockDisplayMode = mode; diff --git a/frame/item/dockitem.h b/frame/item/dockitem.h index 293dfe060..a41f9cd5c 100644 --- a/frame/item/dockitem.h +++ b/frame/item/dockitem.h @@ -36,6 +36,7 @@ public: ~DockItem() override; static void setDockPosition(const Position side); + static void setDockSize(const int size); static void setDockDisplayMode(const DisplayMode mode); inline virtual ItemType itemType() const {return App;} @@ -101,6 +102,7 @@ protected: QTimer *m_popupAdjustDelayTimer; static Position DockPosition; + static int DockSize; static DisplayMode DockDisplayMode; static QPointer PopupWindow; }; diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index de89c26d5..def4aaa00 100755 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -480,6 +480,7 @@ void MainWindow::resetDragWindow() m_multiScreenWorker->requestUpdateFrontendGeometry(); // 2.再更新任务栏位置,保证先1再2 m_multiScreenWorker->requestNotifyWindowManager(); m_multiScreenWorker->requestUpdateRegionMonitor(); // 界面发生变化,应更新监控区域 + DockItem::setDockSize(dockSize); // 更新预览界面2D模式时大小 if ((Top == m_multiScreenWorker->position()) || (Bottom == m_multiScreenWorker->position())) { m_dragWidget->setCursor(Qt::SizeVerCursor); diff --git a/tests/item/ut_appitem.cpp b/tests/item/ut_appitem.cpp index 4161fd731..ad7cefc7b 100644 --- a/tests/item/ut_appitem.cpp +++ b/tests/item/ut_appitem.cpp @@ -93,7 +93,6 @@ TEST_F(Test_AppItem, coverage_test) appItem->checkGSettingsControl(); appItem->showHoverTips(); appItem->popupTips(); - appItem->startDrag(); appItem->playSwingEffect(); appItem->invokedMenuItem("invalid", true); appItem->contextMenu();