test: wayland环境下dde-dock测试

dde-dock代码里存在X相关的硬编码。
为了在wayland环境下能够显示dde-dock且不影响其基本功能,故先将相关代码屏蔽。

Log: 适配dde-dock在wayland环境下显示
Influence: wayland适配
Change-Id: I9d579841b1e371f2ccea81351ffdfdc8eddfc070
This commit is contained in:
范朋程 2021-11-05 21:29:32 +08:00
parent c8bdbd8cb1
commit 0d1f12dc1b
16 changed files with 198 additions and 22 deletions

3
debian/control vendored
View File

@ -26,7 +26,8 @@ Build-Depends: debhelper (>= 8.0.0),
libgtest-dev,
libgmock-dev,
qttools5-dev,
dde-control-center-dev
dde-control-center-dev,
libxcursor-dev
Standards-Version: 3.9.8
Homepage: http://www.deepin.org/

View File

@ -22,7 +22,7 @@ find_package(Qt5Svg REQUIRED)
find_package(DtkWidget REQUIRED)
find_package(DtkCMake REQUIRED)
pkg_check_modules(XCB_EWMH REQUIRED xcb-ewmh x11)
pkg_check_modules(XCB_EWMH REQUIRED xcb-ewmh x11 xcursor)
pkg_check_modules(DFrameworkDBus REQUIRED dframeworkdbus)
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
pkg_check_modules(DtkGUI REQUIRED dtkgui)

View File

@ -20,6 +20,12 @@
*/
#include "appdrag.h"
#include "utils.h"
#include <QGSettings>
#include <QDebug>
#include <X11/Xcursor/Xcursor.h>
AppDrag::AppDrag(QObject *dragSource)
: QDrag(dragSource)
@ -27,6 +33,9 @@ AppDrag::AppDrag(QObject *dragSource)
{
// delete by itself
m_appDragWidget->setVisible(false);
if (Utils::IS_WAYLAND_DISPLAY)
setDragMoveCursor();
}
AppDrag::~AppDrag() {
@ -69,3 +78,22 @@ AppDragWidget *AppDrag::appDragWidget()
{
return m_appDragWidget;
}
void AppDrag::setDragMoveCursor()
{
QString theme = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-name", "bloom").toString();
int cursorSize = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-size", 24).toInt();
const char* cursorName = "dnd-move";
XcursorImages *images = XcursorLibraryLoadImages(cursorName, theme.toStdString().c_str(), cursorSize);
if (!images || !(images->images[0])) {
qWarning() << "loadCursorFalied, theme =" << theme << ", cursorName=" << cursorName;
return;
}
const int imgW = images->images[0]->width;
const int imgH = images->images[0]->height;
QImage img((const uchar*)images->images[0]->pixels, imgW, imgH, QImage::Format_ARGB32);
QPixmap pixmap = QPixmap::fromImage(img);
delete images;
setDragCursor(pixmap, Qt::MoveAction);
}

View File

@ -42,6 +42,9 @@ public:
AppDragWidget *appDragWidget();
private:
void setDragMoveCursor();
private:
QPointer<AppDragWidget> m_appDragWidget;
};

View File

@ -20,12 +20,16 @@
*/
#include "previewcontainer.h"
#include "imageutil.h"
#include "utils.h"
#include <QDesktopWidget>
#include <QScreen>
#include <QApplication>
#include <QDragEnterEvent>
#include <QDesktopWidget>
#include <QCursor>
#include <QGSettings>
#define SPACING 0
#define MARGIN 0
@ -211,8 +215,29 @@ void PreviewContainer::appendSnapWidget(const WId wid)
snap->fetchSnapshot();
}
void PreviewContainer::updatePreviewCursor()
{
static QCursor *lastArrowCursor = nullptr;
static QString lastCursorTheme;
int lastCursorSize = 0;
QString theme = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-name", "bloom").toString();
int cursorSize = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-size", 24).toInt();
if (theme != lastCursorTheme || cursorSize != lastCursorSize) {
QCursor *cursor = ImageUtil::loadQCursorFromX11Cursor(theme.toStdString().c_str(), "left_ptr", cursorSize);
lastCursorTheme = theme;
lastCursorSize = cursorSize;
setCursor(*cursor);
if (lastArrowCursor)
delete lastArrowCursor;
lastArrowCursor = cursor;
}
}
void PreviewContainer::enterEvent(QEvent *e)
{
if (Utils::IS_WAYLAND_DISPLAY)
updatePreviewCursor();
QWidget::enterEvent(e);
m_needActivate = false;

View File

@ -69,6 +69,7 @@ public slots:
private:
void adjustSize(const bool composite);
void appendSnapWidget(const WId wid);
void updatePreviewCursor();
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);

View File

@ -20,6 +20,7 @@
*/
#include "dockpopupwindow.h"
#include "imageutil.h"
#include "utils.h"
#include <QScreen>
@ -27,6 +28,8 @@
#include <QDesktopWidget>
#include <QAccessible>
#include <QAccessibleEvent>
#include <QCursor>
#include <QGSettings>
DWIDGET_USE_NAMESPACE
@ -111,6 +114,8 @@ void DockPopupWindow::hide()
void DockPopupWindow::showEvent(QShowEvent *e)
{
DArrowRectangle::showEvent(e);
if (Utils::IS_WAYLAND_DISPLAY)
updatePopupWindowCursor();
QTimer::singleShot(1, this, &DockPopupWindow::ensureRaised);
}
@ -118,10 +123,31 @@ void DockPopupWindow::showEvent(QShowEvent *e)
void DockPopupWindow::enterEvent(QEvent *e)
{
DArrowRectangle::enterEvent(e);
if (Utils::IS_WAYLAND_DISPLAY)
updatePopupWindowCursor();
QTimer::singleShot(1, this, &DockPopupWindow::ensureRaised);
}
void DockPopupWindow::updatePopupWindowCursor()
{
static QCursor *lastArrowCursor = nullptr;
static QString lastCursorTheme;
int lastCursorSize = 0;
QString theme = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-name", "bloom").toString();
int cursorSize = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-size", 24).toInt();
if (theme != lastCursorTheme || cursorSize != lastCursorSize) {
QCursor *cursor = ImageUtil::loadQCursorFromX11Cursor(theme.toStdString().c_str(), "left_ptr", cursorSize);
lastCursorTheme = theme;
lastCursorSize = cursorSize;
setCursor(*cursor);
if (lastArrowCursor)
delete lastArrowCursor;
lastArrowCursor = cursor;
}
}
bool DockPopupWindow::eventFilter(QObject *o, QEvent *e)
{
if (o != getContent() || e->type() != QEvent::Resize)

View File

@ -63,6 +63,7 @@ private slots:
void onGlobMouseRelease(const QPoint &mousePos, const int flag);
void compositeChanged();
void ensureRaised();
void updatePopupWindowCursor();
private:
bool m_model;

View File

@ -23,6 +23,11 @@
#include <QIcon>
#include <QPainter>
#include <QCursor>
#include <QGSettings>
#include <QDebug>
#include <X11/Xcursor/Xcursor.h>
const QPixmap ImageUtil::loadSvg(const QString &iconName, const QString &localPath, const int size, const qreal ratio)
{
@ -57,3 +62,22 @@ const QPixmap ImageUtil::loadSvg(const QString &iconName, const QSize size, cons
}
return QPixmap();
}
QCursor* ImageUtil::loadQCursorFromX11Cursor(const char* theme, const char* cursorName, int cursorSize)
{
if (!theme || !cursorName || cursorSize <= 0)
return nullptr;
XcursorImages *images = XcursorLibraryLoadImages(cursorName, theme, cursorSize);
if (!images || !(images->images[0])) {
qWarning() << "loadCursorFalied, theme =" << theme << ", cursorName=" << cursorName;
return nullptr;
}
const int imgW = images->images[0]->width;
const int imgH = images->images[0]->height;
QImage img((const uchar*)images->images[0]->pixels, imgW, imgH, QImage::Format_ARGB32);
QPixmap pixmap = QPixmap::fromImage(img);
QCursor *cursor = new QCursor(pixmap, images->images[0]->xhot, images->images[0]->yhot);
delete images;
return cursor;
}

View File

@ -27,11 +27,14 @@
#include <QSvgRenderer>
#include <QApplication>
class QCursor;
class ImageUtil
{
public:
static const QPixmap loadSvg(const QString &iconName, const QString &localPath, const int size, const qreal ratio);
static const QPixmap loadSvg(const QString &iconName, const QSize size, const qreal ratio = qApp->devicePixelRatio());
static QCursor* loadQCursorFromX11Cursor(const char* theme, const char* cursorName, int cursorSize);
};
#endif // IMAGEUTIL_H

View File

@ -720,7 +720,7 @@ void MultiScreenWorker::onRequestNotifyWindowManager()
return;
}
XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
//XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
return;
}
@ -779,10 +779,10 @@ void MultiScreenWorker::onRequestNotifyWindowManager()
return;
}
XcbMisc::instance()->set_strut_partial(static_cast<xcb_window_t>(parent()->winId()), orientation,
static_cast<uint>(strut + WINDOWMARGIN * ratio), // 设置窗口与屏幕边缘距离,需要乘缩放
static_cast<uint>(strutStart), // 设置任务栏起点坐标上下为x左右为y
static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y
// XcbMisc::instance()->set_strut_partial(static_cast<xcb_window_t>(parent()->winId()), orientation,
// static_cast<uint>(strut + WINDOWMARGIN * ratio), // 设置窗口与屏幕边缘距离,需要乘缩放
// static_cast<uint>(strutStart), // 设置任务栏起点坐标上下为x左右为y
// static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y
}
void MultiScreenWorker::onRequestUpdatePosition(const Position &fromPos, const Position &toPos)
@ -1176,7 +1176,7 @@ void MultiScreenWorker::changeDockPosition(QString fromScreen, QString toScreen,
qWarning() << "QX11Info::display() is " << display;
} else {
// 先清除原先的窗管任务栏区域
XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
//XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
}
// 隐藏后需要通知界面更新布局方向

View File

@ -30,6 +30,7 @@
#include "touchsignalmanager.h"
#include "utils.h"
#include "desktop_widget.h"
#include "imageutil.h"
#include <QDrag>
#include <QTimer>
@ -711,6 +712,14 @@ bool MainPanelControl::eventFilter(QObject *watched, QEvent *event)
return QWidget::eventFilter(watched, event);
}
void MainPanelControl::enterEvent(QEvent *event)
{
if (Utils::IS_WAYLAND_DISPLAY)
updatePanelCursor();
QWidget::enterEvent(event);
}
void MainPanelControl::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton) {
@ -1293,3 +1302,23 @@ bool MainPanelControl::appIsOnDock(const QString &appDesktop)
{
return DockItemManager::instance()->appIsOnDock(appDesktop);
}
// TODO: 多处使用类似方法,可尝试提取公共函数
void MainPanelControl::updatePanelCursor()
{
static QCursor *lastArrowCursor = nullptr;
static QString lastCursorTheme;
int lastCursorSize = 0;
QString theme = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-name", "bloom").toString();
int cursorSize = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-size", 24).toInt();
if (theme != lastCursorTheme || cursorSize != lastCursorSize) {
QCursor *cursor = ImageUtil::loadQCursorFromX11Cursor(theme.toStdString().c_str(), "left_ptr", cursorSize);
lastCursorTheme = theme;
lastCursorSize = cursorSize;
setCursor(*cursor);
if (lastArrowCursor)
delete lastArrowCursor;
lastArrowCursor = cursor;
}
}

View File

@ -85,16 +85,18 @@ private:
void resizeDesktopWidget();
bool checkNeedShowDesktop();
bool appIsOnDock(const QString &appDesktop);
protected:
void dragMoveEvent(QDragMoveEvent *e) override;
void dragEnterEvent(QDragEnterEvent *e) override;
void dragLeaveEvent(QDragLeaveEvent *e) override;
void dropEvent(QDropEvent *) override;
bool eventFilter(QObject *watched, QEvent *event) override;
void enterEvent(QEvent *event) override;
void mousePressEvent(QMouseEvent *e) override;
void resizeEvent(QResizeEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void updatePanelCursor();
private:
QBoxLayout *m_mainPanelLayout;

View File

@ -23,7 +23,6 @@
#include "mainwindow.h"
#include "mainpanelcontrol.h"
#include "dockitemmanager.h"
#include "utils.h"
#include "menuworker.h"
#include <DStyle>
@ -96,15 +95,18 @@ MainWindow::MainWindow(QWidget *parent)
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_X11DoNotAcceptFocus);
Qt::WindowFlags flags = Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Window;
//1 确保这两行代码的先后顺序,否则会导致任务栏界面不再置顶
setWindowFlags(Qt::WindowDoesNotAcceptFocus);
setWindowFlags(windowFlags() | flags | Qt::WindowDoesNotAcceptFocus);
const auto display = QX11Info::display();
if (!display) {
qWarning() << "QX11Info::display() is " << display;
} else {
//2 确保这两行代码的先后顺序,否则会导致任务栏界面不再置顶
XcbMisc::instance()->set_window_type(xcb_window_t(this->winId()), XcbMisc::Dock);
if (DGuiApplicationHelper::isXWindowPlatform()) {
const auto display = QX11Info::display();
if (!display) {
qWarning() << "QX11Info::display() is " << display;
} else {
//2 确保这两行代码的先后顺序,否则会导致任务栏界面不再置顶
XcbMisc::instance()->set_window_type(xcb_window_t(this->winId()), XcbMisc::Dock);
}
}
setMouseTracking(true);
@ -132,10 +134,12 @@ MainWindow::MainWindow(QWidget *parent)
m_dragWidget->setMouseTracking(true);
m_dragWidget->setFocusPolicy(Qt::NoFocus);
if ((Top == m_multiScreenWorker->position()) || (Bottom == m_multiScreenWorker->position())) {
m_dragWidget->setCursor(Qt::SizeVerCursor);
} else {
m_dragWidget->setCursor(Qt::SizeHorCursor);
if (!Utils::IS_WAYLAND_DISPLAY) {
if ((Top == m_multiScreenWorker->position()) || (Bottom == m_multiScreenWorker->position())) {
m_dragWidget->setCursor(Qt::SizeVerCursor);
} else {
m_dragWidget->setCursor(Qt::SizeHorCursor);
}
}
}

View File

@ -28,6 +28,8 @@
#include "mainpanelcontrol.h"
#include "multiscreenworker.h"
#include "touchsignalmanager.h"
#include "imageutil.h"
#include "utils.h"
#include <DPlatformWindowHandle>
#include <DWindowManagerHelper>
@ -114,6 +116,9 @@ private:
void enterEvent(QEvent *) override
{
if (Utils::IS_WAYLAND_DISPLAY)
updateCursor();
QApplication::setOverrideCursor(cursor());
}
@ -121,6 +126,30 @@ private:
{
QApplication::setOverrideCursor(Qt::ArrowCursor);
}
void updateCursor()
{
QString theme = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-name", "bloom").toString();
int cursorSize = Utils::SettingValue("com.deepin.xsettings", "/com/deepin/xsettings/", "gtk-cursor-theme-size", 24).toInt();
Position position = static_cast<Dock::Position>(qApp->property("position").toInt());
static QCursor *lastCursor = nullptr;
static QString lastTheme;
static int lastPosition = -1;
static int lastCursorSize = -1;
if (theme != lastTheme || position != lastPosition || cursorSize != lastCursorSize) {
lastTheme = theme;
lastPosition = position;
lastCursorSize = cursorSize;
const char* cursorName = (position == Bottom || position == Top) ? "v_double_arrow" : "h_double_arrow";
QCursor *newCursor = ImageUtil::loadQCursorFromX11Cursor(theme.toStdString().c_str(), cursorName, cursorSize);
setCursor(*newCursor);
if (lastCursor)
delete lastCursor;
lastCursor = newCursor;
}
}
};
class MainWindow : public DBlurEffectWidget

View File

@ -54,7 +54,7 @@ find_package(GMock REQUIRED)
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
pkg_check_modules(DFrameworkDBus REQUIRED dframeworkdbus)
pkg_check_modules(XCB_EWMH REQUIRED xcb-ewmh x11)
pkg_check_modules(XCB_EWMH REQUIRED xcb-ewmh x11 xcursor)
#
add_executable(${BIN_NAME}