dde-dock/frame/util/dockpopupwindow.cpp
zyz e16944a99f fix: 修复触控屏下手指多次点击任务栏声音图标声音列表显示一片空白
修复触控屏下手指多次点击任务栏声音图标声音列表显示一片空白。原因:触摸屏上手指点动图标,会先触发leaveEvent,导致content页面隐藏,显示的时候PopupWindow仍然显示。手指快速点触向上滑动图标,会稳定复现此现象。

Log: 修复触控屏下手指多次点击任务栏声音图标声音列表显示一片空白
Bug: https://pms.uniontech.com/bug-view-127803.html
Influence: 任务栏点击图标显示列表功能。
Change-Id: I82b5ce7ccf61c20dcc1006617b35a77fdd6e8214
2022-06-22 12:41:35 +08:00

204 lines
5.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dockpopupwindow.h"
#include "imageutil.h"
#include "utils.h"
#include <QScreen>
#include <QApplication>
#include <QDesktopWidget>
#include <QAccessible>
#include <QAccessibleEvent>
#include <QCursor>
#include <QGSettings>
DWIDGET_USE_NAMESPACE
DockPopupWindow::DockPopupWindow(QWidget *parent)
: DArrowRectangle(ArrowBottom, parent),
m_model(false),
m_regionInter(new DRegionMonitor(this)),
m_enableMouseRelease(true)
{
setMargin(0);
m_wmHelper = DWindowManagerHelper::instance();
compositeChanged();
setWindowFlags(Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus);
if (Utils::IS_WAYLAND_DISPLAY) {
setAttribute(Qt::WA_NativeWindow);
windowHandle()->setProperty("_d_dwayland_window-type", "override");
} else {
setAttribute(Qt::WA_InputMethodEnabled, false);
}
connect(m_wmHelper, &DWindowManagerHelper::hasCompositeChanged, this, &DockPopupWindow::compositeChanged);
connect(m_regionInter, &DRegionMonitor::buttonRelease, this, &DockPopupWindow::onGlobMouseRelease);
}
DockPopupWindow::~DockPopupWindow()
{
}
bool DockPopupWindow::model() const
{
return isVisible() && m_model;
}
void DockPopupWindow::setContent(QWidget *content)
{
QWidget *lastWidget = getContent();
if (lastWidget)
lastWidget->removeEventFilter(this);
content->installEventFilter(this);
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
if (!content->objectName().trimmed().isEmpty())
setAccessibleName(content->objectName() + "-popup");
DArrowRectangle::setContent(content);
}
void DockPopupWindow::show(const QPoint &pos, const bool model)
{
m_model = model;
m_lastPoint = pos;
show(pos.x(), pos.y());
if (m_regionInter->registered()) {
m_regionInter->unregisterRegion();
}
if (m_model) {
m_regionInter->registerRegion();
}
blockButtonRelease();
}
void DockPopupWindow::show(const int x, const int y)
{
m_lastPoint = QPoint(x, y);
blockButtonRelease();
DArrowRectangle::show(x, y);
}
void DockPopupWindow::blockButtonRelease()
{
// 短暂的不处理鼠标release事件防止出现刚显示又被隐藏的情况
m_enableMouseRelease = false;
QTimer::singleShot(10, this, [this] {
m_enableMouseRelease = true;
});
}
void DockPopupWindow::hide()
{
if (m_regionInter->registered())
m_regionInter->unregisterRegion();
DArrowRectangle::hide();
}
void DockPopupWindow::showEvent(QShowEvent *e)
{
DArrowRectangle::showEvent(e);
if (Utils::IS_WAYLAND_DISPLAY) {
Utils::updateCursor(this);
}
QTimer::singleShot(1, this, &DockPopupWindow::ensureRaised);
}
void DockPopupWindow::enterEvent(QEvent *e)
{
DArrowRectangle::enterEvent(e);
if (Utils::IS_WAYLAND_DISPLAY) {
Utils::updateCursor(this);
}
QTimer::singleShot(1, this, &DockPopupWindow::ensureRaised);
}
bool DockPopupWindow::eventFilter(QObject *o, QEvent *e)
{
if (o != getContent() || e->type() != QEvent::Resize)
return false;
// FIXME: ensure position move after global mouse release event
if (isVisible())
{
QTimer::singleShot(10, this, [=] {
// NOTE(sbw): double check is necessary, in this time, the popup maybe already hided.
if (isVisible())
show(m_lastPoint, m_model);
});
}
return false;
}
void DockPopupWindow::onGlobMouseRelease(const QPoint &mousePos, const int flag)
{
Q_ASSERT(m_model);
if (!m_enableMouseRelease)
return;
if (!((flag == DRegionMonitor::WatchedFlags::Button_Left) ||
(flag == DRegionMonitor::WatchedFlags::Button_Right))) {
return;
}
const QRect rect = QRect(pos(), size());
if (rect.contains(mousePos))
return;
emit accept();
m_regionInter->unregisterRegion();
}
void DockPopupWindow::compositeChanged()
{
if (m_wmHelper->hasComposite())
setBorderColor(QColor(255, 255, 255, 255 * 0.05));
else
setBorderColor(QColor("#2C3238"));
}
void DockPopupWindow::ensureRaised()
{
if (isVisible()) {
QWidget *content = getContent();
if (!content || !content->isVisible()) {
this->setVisible(false);
} else {
raise();
}
}
}