diff -Nru dtkgui-5.4.15/debian/changelog dtkgui-5.5.17.1/debian/changelog --- dtkgui-5.4.15/debian/changelog 2021-09-17 10:37:52.000000000 +0000 +++ dtkgui-5.5.17.1/debian/changelog 2021-09-18 08:40:40.000000000 +0000 @@ -1,3 +1,9 @@ +dtkgui (5.5.17.1) impish; urgency=medium + + * New upstream release. + + -- Arun Kumar Pariyar Sat, 18 Sep 2021 14:25:40 +0545 + dtkgui (5.4.15-1) impish; urgency=medium * New upstream release. diff -Nru dtkgui-5.4.15/debian/control dtkgui-5.5.17.1/debian/control --- dtkgui-5.4.15/debian/control 2021-09-17 10:37:52.000000000 +0000 +++ dtkgui-5.5.17.1/debian/control 2021-09-18 08:40:40.000000000 +0000 @@ -7,7 +7,8 @@ Hu Feng , Clay Stan Build-Depends: debhelper-compat (= 13), - libdtkcore-dev (>= 5.4.10~), + libdtkcore-dev (>= 5.5~), + libgmock-dev, libgtest-dev, librsvg2-dev, pkg-config, diff -Nru dtkgui-5.4.15/debian/watch dtkgui-5.5.17.1/debian/watch --- dtkgui-5.4.15/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/debian/watch 2021-09-18 08:37:49.000000000 +0000 @@ -0,0 +1,4 @@ +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%dtkgui-$1.tar.gz%" \ + https://github.com/linuxdeepin/dtkgui/tags \ + (?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate diff -Nru dtkgui-5.4.15/examples/test-taskbar/main.cpp dtkgui-5.5.17.1/examples/test-taskbar/main.cpp --- dtkgui-5.4.15/examples/test-taskbar/main.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/examples/test-taskbar/main.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -1,3 +1,6 @@ +#include +#include + #include #include @@ -29,5 +32,10 @@ QFile::remove(desktopFile.fileName()); }); + //控制中心修改字体大小可以看到打印输出 + QObject::connect(DGuiApplicationHelper::instance()->fontManager(), &DFontManager::fontChanged, [] { + qDebug() << DGuiApplicationHelper::instance()->fontManager()->baseFont(); + }); + return a.exec(); } diff -Nru dtkgui-5.4.15/.gitignore dtkgui-5.5.17.1/.gitignore --- dtkgui-5.4.15/.gitignore 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/.gitignore 2021-07-02 03:37:24.000000000 +0000 @@ -46,4 +46,4 @@ cmake DtkGuis dtkgui_config.h -qt_lib_dtkgui.pri +qt_lib_dtkgui*.pri diff -Nru dtkgui-5.4.15/rpm/dtkgui.spec dtkgui-5.5.17.1/rpm/dtkgui.spec --- dtkgui-5.4.15/rpm/dtkgui.spec 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/rpm/dtkgui.spec 2021-07-02 03:37:24.000000000 +0000 @@ -1,5 +1,5 @@ Name: dtkgui -Version: 5.2.2.18 +Version: 5.4.0 Release: 1%{?dist} Summary: Deepin dtkgui License: LGPLv3+ @@ -21,6 +21,7 @@ BuildRequires: qt5-qtbase-private-devel %{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}} %endif +BuildRequires: make %description Dtkgui is the GUI module for DDE look and feel. diff -Nru dtkgui-5.4.15/src/kernel/dguiapplicationhelper.cpp dtkgui-5.5.17.1/src/kernel/dguiapplicationhelper.cpp --- dtkgui-5.4.15/src/kernel/dguiapplicationhelper.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dguiapplicationhelper.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -21,6 +21,7 @@ #include "dguiapplicationhelper.h" #include "private/dguiapplicationhelper_p.h" #include "dplatformhandle.h" +#include #include #include @@ -35,6 +36,9 @@ #include #include +#include +#include +#include #ifdef Q_OS_LINUX #include @@ -282,12 +286,45 @@ Q_GLOBAL_STATIC(QLocalServer, _d_singleServer) static quint8 _d_singleServerVersion = 1; +Q_GLOBAL_STATIC(DFontManager, _globalFM) #define WINDOW_THEME_KEY "_d_platform_theme" -bool DGuiApplicationHelperPrivate::useInactiveColor = true; -bool DGuiApplicationHelperPrivate::compositingColor = false; +class _DGuiApplicationHelper +{ +public: +#define INVALID_HELPER reinterpret_cast(1) + inline DGuiApplicationHelper *helper() + { + // 临时存储一个无效的指针值, 用于此处条件变量的竞争 + if (m_helper.testAndSetRelaxed(nullptr, INVALID_HELPER)) { + m_helper.store(creator()); + m_helper.load()->initialize(); + } + + return m_helper.load(); + } + + inline void clear() + { + if (m_helper != INVALID_HELPER) + delete m_helper.fetchAndStoreRelaxed(nullptr); + } + + static DGuiApplicationHelper *defaultCreator() + { + return new DGuiApplicationHelper(); + } + + QAtomicPointer m_helper; + static DGuiApplicationHelper::HelperCreator creator; +}; + +DGuiApplicationHelper::HelperCreator _DGuiApplicationHelper::creator = _DGuiApplicationHelper::defaultCreator; +Q_GLOBAL_STATIC(_DGuiApplicationHelper, _globalHelper) + int DGuiApplicationHelperPrivate::waitTime = 3000; +DGuiApplicationHelper::Attributes DGuiApplicationHelperPrivate::attributes = DGuiApplicationHelper::UseInactiveColorGroup; DGuiApplicationHelperPrivate::DGuiApplicationHelperPrivate(DGuiApplicationHelper *qq) : DObjectPrivate(qq) @@ -300,13 +337,16 @@ D_Q(DGuiApplicationHelper); systemTheme = new DPlatformTheme(0, q); - // 初始时先将appTheme指定为systtemTheme,在后面合适的地方再初始化appTheme + // 直接对应到系统级别的主题, 不再对外提供为某个单独程序设置主题的接口. + // 程序设置自身主题相关的东西皆可通过 setPaletteType 和 setApplicationPalette 实现. appTheme = systemTheme; if (qGuiApp) { initApplication(qGuiApp); } else { - qAddPreRoutine(staticInitApplication); + // 确保qAddPreRoutine只会被调用一次 + static auto _ = [] {qAddPreRoutine(staticInitApplication); return true;}(); + Q_UNUSED(_) } } @@ -314,73 +354,67 @@ { D_Q(DGuiApplicationHelper); + // 跟随application销毁 + qAddPostRoutine(staticCleanApplication); + q->connect(app, &QGuiApplication::paletteChanged, q, [q, this, app] { - if (themeType == DGuiApplicationHelper::UnknownType) + // 如果用户没有自定义颜色类型, 则应该通知程序的颜色类型发送变化 + if (Q_LIKELY(!isCustomPalette())) { Q_EMIT q->themeTypeChanged(q->toColorType(app->palette())); + Q_EMIT q->applicationPaletteChanged(); + } else { + qWarning() << "DGuiApplicationHelper: Don't use QGuiApplication::setPalette on DTK application."; + } }); + // 转发程序自己变化的信号 + q->connect(app, &QGuiApplication::fontChanged, q, &DGuiApplicationHelper::fontChanged); - app->connect(systemTheme, &DPlatformTheme::themeNameChanged, app, [this, app] { - if (appTheme == systemTheme) - return; - - appTheme->setFallbackProperty(false); - const QByteArray &theme_name = appTheme->themeName(); - appTheme->setFallbackProperty(true); - - if (!theme_name.isEmpty()) - notifyAppThemeChanged(app); - }); - app->connect(systemTheme, &DPlatformTheme::activeColorChanged, app, [this, app] { - if (appTheme == systemTheme) - return; - - appTheme->setFallbackProperty(false); - const QColor &active_color = appTheme->activeColor(); - appTheme->setFallbackProperty(true); - - if (!active_color.isValid()) - notifyAppThemeChanged(app, true); - }); - app->connect(systemTheme, &DPlatformTheme::paletteChanged, app, [this, app] { - if (appTheme == systemTheme) - return; - - if (!appTheme->isValid()) - notifyAppThemeChanged(app); - }); - - if (QGuiApplicationPrivate::is_app_running) { + if (Q_UNLIKELY(!appTheme)) { // 此时说明appTheme可能已经被初始化为了systemtheme + if (QGuiApplicationPrivate::is_app_running) { + _q_initApplicationTheme(); + } else { + // 延后初始化数据,因为在调用 clientLeader 前必须要保证QGuiApplication已经完全构造完成 + q->metaObject()->invokeMethod(q, "_q_initApplicationTheme", Qt::QueuedConnection, Q_ARG(bool, true)); + } + } else if (appTheme == systemTheme) { + // 此时appTheme等价于systemTheme, 可以直接信号链接 _q_initApplicationTheme(); - } else { - // 延后初始化数据,因为在调用 clientLeader 前必须要保证QGuiApplication已经完全构造完成 - q->metaObject()->invokeMethod(q, "_q_initApplicationTheme", Qt::QueuedConnection, Q_ARG(bool, true)); } } void DGuiApplicationHelperPrivate::staticInitApplication() { - if (DGuiApplicationHelper *helper = DGuiApplicationHelper::instance()) { - helper->d_func()->initApplication(qGuiApp); + if (!_globalHelper.exists()) + return; + + if (DGuiApplicationHelper *helper = _globalHelper->m_helper.load()) { + // systemTheme未创建时说明DGuiApplicationHelper还未初始化 + if (helper->d_func()->systemTheme) + helper->d_func()->initApplication(qGuiApp); } } -DPlatformTheme *DGuiApplicationHelperPrivate::initWindow(QWindow *window) const +void DGuiApplicationHelperPrivate::staticCleanApplication() { - // 如果appTheme还未初始化,应当先初始化appTheme - if (appTheme == systemTheme) { - // 此时QGuiApplication必须是已经初始化完成的状态 - Q_ASSERT(QGuiApplicationPrivate::is_app_running); - // 初始程序级别的主题对象 - const_cast(this)->_q_initApplicationTheme(true); - } + if (_globalHelper.exists()) + _globalHelper->clear(); +} - DPlatformTheme *theme = new DPlatformTheme(window->winId(), appTheme); +DPlatformTheme *DGuiApplicationHelperPrivate::initWindow(QWindow *window) const +{ + DPlatformTheme *theme = new DPlatformTheme(window->winId(), q_func()->applicationTheme()); window->setProperty(WINDOW_THEME_KEY, QVariant::fromValue(theme)); theme->setParent(window); // 跟随窗口销毁 - auto onWindowThemeChanged = [theme, window] { - qGuiApp->postEvent(window, new QEvent(QEvent::ThemeChange)); + auto onWindowThemeChanged = [window, theme, this] { + // 如果程序自定义了调色板, 则没有必要再关心窗口自身平台主题的变化 + // 需要注意的是, 这里的信号和事件可能会与 notifyAppThemeChanged 中的重复 + // 但是不能因此而移除这里的通知, 当窗口自身所对应的平台主题发生变化时, 这里 + // 的通知机制就有了用武之地. + if (Q_LIKELY(!isCustomPalette())) { + qGuiApp->postEvent(window, new QEvent(QEvent::ThemeChange)); + } }; window->connect(theme, &DPlatformTheme::themeNameChanged, window, onWindowThemeChanged); @@ -392,65 +426,52 @@ void DGuiApplicationHelperPrivate::_q_initApplicationTheme(bool notifyChange) { - if (appTheme && appTheme != systemTheme) - return; + if (!appTheme) { + // DPlatfromHandle::windowLeader依赖platformIntegration + Q_ASSERT(QGuiApplicationPrivate::platformIntegration()); + appTheme = new DPlatformTheme(DPlatformHandle::windowLeader(), systemTheme); + } - appTheme = new DPlatformTheme(DPlatformHandle::windowLeader(), systemTheme); QGuiApplication *app = qGuiApp; - auto onAppThemeChanged = std::bind(&DGuiApplicationHelperPrivate::notifyAppThemeChanged, this, app, false); + auto onAppThemeChanged = [this] { + // 只有当程序未自定义调色板时才需要关心DPlatformTheme中themeName和palette的改变 + if (!isCustomPalette()) + notifyAppThemeChanged(); + }; + // 监听与程序主题相关的改变 QObject::connect(appTheme, &DPlatformTheme::themeNameChanged, app, onAppThemeChanged); - QObject::connect(appTheme, &DPlatformTheme::activeColorChanged, app, onAppThemeChanged); QObject::connect(appTheme, &DPlatformTheme::paletteChanged, app, onAppThemeChanged); + QObject::connect(appTheme, &DPlatformTheme::activeColorChanged, app, [this] { + if (!appPalette) + notifyAppThemeChanged(); + }); // appTheme在此之前可能由systemTheme所代替被使用,此时在创建appTheme // 并初始化之后,应当发送信号通知程序主题的改变 if (notifyChange && appTheme->isValid()) { - notifyAppThemeChanged(app); + notifyAppThemeChanged(); } } -void DGuiApplicationHelperPrivate::notifyAppThemeChanged(QGuiApplication *app, bool ignorePaletteType) +void DGuiApplicationHelperPrivate::notifyAppThemeChanged() { D_Q(DGuiApplicationHelper); - if (app->testAttribute(Qt::AA_SetPalette) - || (!ignorePaletteType && paletteType != DGuiApplicationHelper::UnknownType)) { - return; - } - QWindowSystemInterfacePrivate::ThemeChangeEvent event(nullptr); + // 此事件会促使QGuiApplication重新从QPlatformTheme中获取系统级别的QPalette. + // 而在deepin平台下, 系统级别的QPalette来源自 \a applicationPalette() QGuiApplicationPrivate::processThemeChanged(&event); - Q_EMIT q->themeTypeChanged(q->toColorType(app->palette())); + // 通知主题类型发生变化, 此处可能存在误报的行为, 不过不应该对此做额外的约束 + // 此信号的行为应当等价于 applicationPaletteChanged + Q_EMIT q->themeTypeChanged(q->themeType()); + // 通知调色板对象的改变 + Q_EMIT q->applicationPaletteChanged(); } -class _DGuiApplicationHelper +bool DGuiApplicationHelperPrivate::isCustomPalette() const { -public: - _DGuiApplicationHelper() - : helper(nullptr) - { - } - - ~_DGuiApplicationHelper() - { - if (helper) { - helper->deleteLater(); - helper = nullptr; - } - } - - static DGuiApplicationHelper *defaultCreator() - { - return new DGuiApplicationHelper(); - } - - DGuiApplicationHelper *helper; - static DGuiApplicationHelper::HelperCreator creator; -}; - -DGuiApplicationHelper::HelperCreator _DGuiApplicationHelper::creator = _DGuiApplicationHelper::defaultCreator; -Q_GLOBAL_STATIC(_DGuiApplicationHelper, _globalHelper) - + return appPalette || paletteType != DGuiApplicationHelper::UnknownType; +} /*! * \~chinese \class DGuiApplicationHelper @@ -472,6 +493,37 @@ * \~chinese 深色主题 */ +/*! + * + * \~chinese \enum DGuiApplicationHelper::Attribute + * \~chinese DGuiApplicationHelper::Attribute 定义了功能属性 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::UseInactiveColorGroup + * \~chinese 如果开启,当窗口处于Inactive状态时就会使用QPalette::Inactive的颜色,否则窗口将没有任何颜色变化。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::ColorCompositing + * \~chinese 是否采用半透明样式的调色板。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::ReadOnlyLimit + * \~chinese 区分只读枚举。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::IsDeepinPlatformTheme + * \~chinese 获取当前是否使用deepin的platformtheme插件,platformtheme插件可以为Qt程序提供特定的控件样式,默认使用chameleon主题。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::IsDPlatformDXcb + * \~chinese 获取当前使用的是不是dtk的xcb窗口插件,dxcb插件提供了窗口圆角和阴影功能。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::IsXWindowPlatform + * \~chinese 获取当前是否运行在X11环境中。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::IsTableEnvironment + * \~chinese 获取当前是否运行在deepin平板环境中,检测XDG_CURRENT_DESKTOP环境变量是不是tablet结尾。 + * + * \~chinese \var DGuiApplicationHelper:Attribute DGuiApplicationHelper::IsDeepinEnvironment + * \~chinese 获取当前是否运行在deepin桌面环境中,检测XDG_CURRENT_DESKTOP环境变量是不是deepin。 + * + */ + DGuiApplicationHelper::DGuiApplicationHelper() : QObject(nullptr) , DObject(*new DGuiApplicationHelperPrivate(this)) @@ -498,9 +550,8 @@ _DGuiApplicationHelper::creator = creator; - if (_globalHelper.exists() && _globalHelper->helper) { - _globalHelper->helper->deleteLater(); - _globalHelper->helper = nullptr; + if (_globalHelper.exists()) { + _globalHelper->clear(); } } @@ -516,29 +567,12 @@ */ DGuiApplicationHelper *DGuiApplicationHelper::instance() { - // 单例模式,延迟创建DGuiApplicationHelper - if (nullptr == _globalHelper->helper) { - _globalHelper->helper = _DGuiApplicationHelper::creator(); - _globalHelper->helper->initialize(); - // 当QApplication析构时,同时析构DGuiApplicationHelper - QObject::connect(qApp, &QObject::destroyed, [](){ - if (_globalHelper->helper) { - _globalHelper->helper->deleteLater(); - _globalHelper->helper = nullptr; - } - }); - } - - return _globalHelper->helper; + return _globalHelper->helper(); } DGuiApplicationHelper::~DGuiApplicationHelper() { - D_D(DGuiApplicationHelper); - - if (d->appPalette) { - delete d->appPalette; - } + _globalHelper->m_helper = nullptr; } /*! @@ -691,9 +725,10 @@ { static const DPalette *light_palette = nullptr, *dark_palette = nullptr; static const DPalette *alpha_light_palette = nullptr, *alpha_dark_palette = nullptr; + const bool allowCompositingColor = DGuiApplicationHelper::testAttribute(ColorCompositing); if (type == LightType) { - if (Q_UNLIKELY(DGuiApplicationHelperPrivate::compositingColor)) { + if (Q_UNLIKELY(allowCompositingColor)) { if (Q_LIKELY(alpha_light_palette)) { return *alpha_light_palette; } @@ -703,7 +738,7 @@ return *light_palette; } } else if (type == DarkType) { - if (Q_UNLIKELY(DGuiApplicationHelperPrivate::compositingColor)) { + if (Q_UNLIKELY(allowCompositingColor)) { if (Q_LIKELY(alpha_dark_palette)) { return *alpha_dark_palette; } @@ -722,7 +757,7 @@ if (type == DarkType) { pa = new DPalette(); - if (DGuiApplicationHelperPrivate::compositingColor) + if (allowCompositingColor) alpha_dark_palette = pa; else dark_palette = pa; @@ -732,7 +767,7 @@ } else { pa = new DPalette(); - if (DGuiApplicationHelperPrivate::compositingColor) + if (allowCompositingColor) alpha_light_palette = pa; else light_palette = pa; @@ -753,7 +788,7 @@ } #endif // 处理半透明色 - if (DGuiApplicationHelperPrivate::compositingColor) { + if (allowCompositingColor) { switch (role) { case QPalette::Window: color = type == LightType ? adjustColor(color, 0, 0, 0, 0, 0, 0, -20) : adjustColor(color, 0, 0, -10, 0, 0, 0, -20); @@ -789,7 +824,7 @@ QColor color = dcolor_list[i]; // 处理半透明色 - if (DGuiApplicationHelperPrivate::compositingColor) { + if (allowCompositingColor) { switch (role) { case DPalette::ItemBackground: color = adjustColor(color, 0, 0, 100, 0, 0, 0, type == LightType ? -80 : -90); @@ -842,7 +877,7 @@ base.setColor(QPalette::Disabled, role, DGuiApplicationHelper::adjustColor(color, 0, 0, 0, 0, 0, 0, -60)); } - if (DGuiApplicationHelperPrivate::useInactiveColor) + if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::Attribute::UseInactiveColorGroup)) base.setColor(QPalette::Inactive, role, DGuiApplicationHelper::blendColor(color, inactive_mask_color)); else base.setColor(QPalette::Inactive, role, color); @@ -874,10 +909,17 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::generatePaletteColor 获取调色板颜色 - * \~chinese \param base调色板 - * \~chinese \param role背景颜色 - * \~chinese \param type主题枚举值 + * \~chinese \brief DGuiApplicationHelper::generatePaletteColor + * \~chinese 加工调色板的颜色. 一般我们只会为调色板的 \a QPalette::Normal 组设置颜色值, 但是 + * \~chinese 控件中也需要使用其他组的颜色, 此函数使用一些固定规则为 \a base 填充 \a QPalette::Disabled + * \~chinese 和 \a QPalette::Inactive 分组的颜色. 不同的颜色类型会使用不同的加工规则, 如果为 \a LightType + * \~chinese 类型, 则将颜色的alpha通道调整为 0.6 后作为 \a QPalette::Disabled 类的颜色使用, 调整为 0.4 后 + * \~chinese 作为 \a QPalette::Inactive 类的颜色使用. 如果为 \a DarkType 类型, 则将颜色的alpha通道调整为 + * \~chinese 0.7 后作为 \a QPalette::Disabled 类的颜色使用, 调整为 0.6 后作为 \a QPalette::Inactive + * \~chinese 类的颜色使用. + * \~chinese \param base 被加工的调色板 + * \~chinese \param role 加工的项 + * \~chinese \param type 加工时所使用的颜色类型, 如果值为 UnknownType 将使用 \a toColorType 获取颜色类型 */ void DGuiApplicationHelper::generatePaletteColor(DPalette &base, DPalette::ColorType role, DGuiApplicationHelper::ColorType type) { @@ -885,9 +927,11 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::generatePalette 根据主题的枚举值获取调色板数据 - * \~chinese \param base调色板 - * \~chinese \param type主题的枚举值 + * \~chinese \brief DGuiApplicationHelper::generatePalette + * \~chinese 加工调色板的颜色. 同 \a generatePaletteColor, 将直接调用 \a generatePaletteColor 加工 + * \~chinese 所有类型的调色板颜色. + * \~chinese \param base 被加工的调色板 + * \~chinese \param type 加工时所使用的颜色类型, 如果值为 UnknownType 将使用 \a toColorType 获取颜色类型 */ void DGuiApplicationHelper::generatePalette(DPalette &base, ColorType type) { @@ -908,9 +952,14 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::fetchPalette取出主题的调色板 - * \~chinese \param theme主题信息 - * \~chinese \return 调色板信息 + * \~chinese \brief DGuiApplicationHelper::fetchPalette 获取调色板数据. + * \~chinese 首先根据 DPlatformTheme::themeName 获取主题的颜色类型, 如果名称以 + * \~chinese "dark" 结尾则认为其颜色类型为 \a DarkType, 否则为 \a LightType. + * \~chinese 如果主题名称为空, 将使用其父主题的名称( \a DPlatformTheme::fallbackProperty ). + * \~chinese 根据颜色类型将使用 \a standardPalette 获取基础调色板数据, 在此基础上 + * \~chinese 从 \a DPlatformTheme::fetchPalette 获取最终的调色板. + * \~chinese \param theme 平台主题对象 + * \~chinese \return 调色板数据 */ DPalette DGuiApplicationHelper::fetchPalette(const DPlatformTheme *theme) { @@ -950,7 +999,7 @@ */ void DGuiApplicationHelper::setUseInactiveColorGroup(bool on) { - DGuiApplicationHelperPrivate::useInactiveColor = on; + DGuiApplicationHelper::setAttribute(Attribute::UseInactiveColorGroup, on); } /*! @@ -959,19 +1008,29 @@ */ void DGuiApplicationHelper::setColorCompositingEnabled(bool on) { - DGuiApplicationHelperPrivate::compositingColor = on; + DGuiApplicationHelper::setAttribute(Attribute::ColorCompositing, on); } bool DGuiApplicationHelper::isXWindowPlatform() { - static bool isX = qGuiApp->platformName() == "xcb" || qGuiApp->platformName() == "dxcb"; + return DGuiApplicationHelper::testAttribute(Attribute::IsXWindowPlatform); +} - return isX; +/*! + * \~chinese \brief isTabletEnvironment 用于判断当前桌面环境是否是平板电脑环境 + * \~chinese \return true 是平板电脑环境 false不是平板电脑环境 + */ +bool DGuiApplicationHelper::isTabletEnvironment() +{ + return DGuiApplicationHelper::testAttribute(Attribute::IsTableEnvironment); } /*! - * \~chinese \brief DGuiApplicationHelper::systemTheme返回系统主题 - * \~chinese \return 系统主题 + * \~chinese \brief DGuiApplicationHelper::systemTheme + * \~chinese 返回系统级别的主题, 优先级低于 \a applicationTheme + * \~chinese \return 平台主题对象 + * \~chinese \sa applicationTheme + * \~chinese \sa windowTheme */ DPlatformTheme *DGuiApplicationHelper::systemTheme() const { @@ -981,20 +1040,33 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::applicationTheme返回应用主题对象 - * \~chinese \return 应用主题 + * \~chinese \brief DGuiApplicationHelper::applicationTheme + * \~chinese 同 systemTheme + * \~chinese \return 平台主题对象 + * \~chinese \sa systemTheme + * \~chinese \sa windowTheme */ DPlatformTheme *DGuiApplicationHelper::applicationTheme() const { D_DC(DGuiApplicationHelper); + // 如果appTheme还未初始化,应当先初始化appTheme + if (Q_UNLIKELY(!d->appTheme)) { + // 初始程序级别的主题对象 + const_cast(d)->_q_initApplicationTheme(false); + } + return d->appTheme; } /*! - * \~chinese \brief DGuiApplicationHelper::windowTheme返回 QWindow 主题对象 - * \~chinese \param windowQWindow 对象 - * \~chinese \return QWindow主题 + * \~chinese \brief DGuiApplicationHelper::windowTheme + * \~chinese 返回窗口级别的主题, 优先级高于 \a windowTheme 和 \a systemTheme + * \~chinese \param window 主题对象对应的窗口 + * \~chinese \return 平台主题对象 + * \~chinese \sa applicationTheme + * \~chinese \sa windowTheme + * \~chinese \warning 已废弃, 不再对外暴露为特定窗口设置主题的接口 */ DPlatformTheme *DGuiApplicationHelper::windowTheme(QWindow *window) const { @@ -1012,6 +1084,16 @@ /*! * \~chinese \brief DGuiApplicationHelper::applicationPalette返回应用程序调色板 + * \~chinese 如果使用 \a setApplicationPalette 设置过一个有效的调色板, 将直接返回保存的调色板. 否则 + * \~chinese 先计算调色板的ColorType, 再使用这个颜色类型通过 \a standardPalette 获取标准调色板. 计算 + * \~chinese ColorType的数据来源按优先级从高到低排列有以下几种方式: + * \~chinese 1. 如果使用 \a setThemeType 设置过一个有效的颜色类型, 将直接使用 \a themeType 的值. + * \~chinese 2. 如果为QGuiApplication设置过调色板(表现为 QGuiApplication::testAttribute(Qt::AA_SetPalette) + * \~chinese 为true), 则将使用 QGuiApplication::palette 通过 \a toColorType 获取颜色类型. + * \~chinese 3. 将根据 \a applicationTheme 的 DPlatformTheme::themeName 计算颜色类型. + * \~chinese 如果ColorType来源自第2种方式, 则会直接使用 QGuiApplication::palette 覆盖标准调色板中的 + * \~chinese QPalette 部分, 且程序不会再跟随系统的活动色自动更新调色板. + * \~chinese \warning 不应该在DTK程序中使用QGuiApplication/QApplication::setPalette * \~chinese \return 应用程序调色板 */ DPalette DGuiApplicationHelper::applicationPalette() const @@ -1022,67 +1104,107 @@ return *d->appPalette; } - ColorType type = UnknownType; + ColorType type = d->paletteType; + bool aa_setPalette = qGuiApp && qGuiApp->testAttribute(Qt::AA_SetPalette); + // 此时appTheme可能还未初始化, 因此先使用systemTheme, 待appTheme初始化之后会 + // 通知程序调色板发生改变 + auto theme = Q_LIKELY(d->appTheme) ? d->appTheme : d->systemTheme; - // 如果应用程序自己设置过palette,则以这个palette为基础获取DPalette - if (qGuiApp && qGuiApp->testAttribute(Qt::AA_SetPalette)) { - type = toColorType(qGuiApp->palette()); - } else { - type = d->paletteType; + if (type == UnknownType) { + if (aa_setPalette) { + type = toColorType(qGuiApp->palette()); + } else { + // 如果程序未自定义调色板, 则直接从平台主题中获取调色板数据 + return fetchPalette(theme); + } } - // 如果自定义了palette的类型,则直接返回对应的标准DPalette - if (type != UnknownType) { - DPalette pa = standardPalette(type); - const QColor &active_color = d->appTheme->activeColor(); + // 如果程序自定义了palette的类型,将忽略 appTheme 中设置的调色板数据. + DPalette pa = standardPalette(type); + + if (aa_setPalette) { + // 如果程序通过QGuiApplication::setPalette自定义了调色板, 则应当尊重程序的选择 + // 覆盖DPalette中的的QPalette数据 + pa.QPalette::operator =(qGuiApp->palette()); + } else { + const QColor &active_color = theme->activeColor(); if (active_color.isValid()) { // 应用Active Color pa.setColor(QPalette::Normal, QPalette::Highlight, active_color); generatePaletteColor(pa, QPalette::Highlight, type); } - - return pa; } - return fetchPalette(d->appTheme); + return pa; } /*! - * \~chinese \brief DGuiApplicationHelper::setApplicationPalette设置应用程序调色板 - * \~chinese \param palette调色板 + * \~chinese \brief DGuiApplicationHelper::setApplicationPalette + * \~chinese 自定义应用程序调色板, 如果没有为 QGuiApplication 设置过 QPalette, 则 + * \~chinese 将触发 \a QGuiApplication::palette 的更新. 如果仅需要控制程序使用亮色还是暗色的 + * \~chinese 调色板, 请使用 setThemeType. + * \~chinese \note 主动设置调色板的操作会导致程序不再使用 DPlatformTheme 中调色板相关的数据, 也 + * \~chinese 包括窗口级别的 \a windowTheme 所对应的 DPlatformTheme, 届时设置 DPlatformTheme + * \~chinese 的 themeName 和所有与 palette 相关的属性都不再生效. + * \~chinese \warning 使用此方式设置的调色板将不会自动跟随活动色的变化 + * \~chinese \warning 如果使用过QGuiApplication::setPalette, 此方式可能不会生效 + * \~chinese \param palette 要设置的调色板 */ void DGuiApplicationHelper::setApplicationPalette(const DPalette &palette) { D_D(DGuiApplicationHelper); + if (qGuiApp && qGuiApp->testAttribute(Qt::AA_SetPalette)) { + qWarning() << "DGuiApplicationHelper: Plase check 'QGuiApplication::setPalette', Don't use it on DTK application."; + } + if (d->appPalette) { if (palette.resolve()) { *d->appPalette = palette; } else { - delete d->appPalette; + d->appPalette.reset(); } } else if (palette.resolve()) { - d->appPalette = new DPalette(palette); + d->appPalette.reset(new DPalette(palette)); } else { return; } - d->notifyAppThemeChanged(qGuiApp, true); + // 通知QGuiApplication更新自身的palette和font + d->notifyAppThemeChanged(); } /*! * \~chinese \brief DGuiApplicationHelper::windowPalette + * \~chinese 返回窗口所对应的调色板数据, 同 \a applicationPalette, 如果程序中自定义了 + * \~chinese 调色板, 则直接使用 \a applicationPalette. 自定义调色板的三种方式如下: + * \~chinese 1. 通过 \a setApplicationPalette 固定调色板 + * \~chinese 2. 通过 \a setThemeType 固定调色板的类型 + * \~chinese 3. 通过 \a QGuiApplication::setPalette 固定调色板, 需要注意此方法不可逆. + * \~chinese 否则将基于窗口所对应的 \a DPlatformTheme 获取调色板(\sa fetchPalette). * \~chinese \param window * \~chinese \return 调色板 + * \~chinese \sa windowTheme + * \~chinese \sa fetchPalette + * \~chinese \sa standardPalette + * \~chinese \sa generatePalette + * \~chinese \sa applicationPalette + * \~chinese \warning 使用时要同时关注 \a paletteChanged, 收到此信号后可能需要重新获取窗口的调色板 + * \~chinese \warning 已废弃, 不再对外暴露控制窗口级别调色板的接口 */ DPalette DGuiApplicationHelper::windowPalette(QWindow *window) const { D_DC(DGuiApplicationHelper); + // 如果程序自定义了调色版, 则不再关心窗口对应的平台主题上的设置 + if (Q_UNLIKELY(d->isCustomPalette())) { + return applicationPalette(); + } + DPlatformTheme *theme = windowTheme(window); - if (!theme) { + if (Q_UNLIKELY(!theme)) { return applicationPalette(); } @@ -1090,11 +1212,27 @@ } /*! + * \~chinese \brief DGuiApplicationHelper::fontManager + * \~chinese 程序中唯一的DFontManager对象, 会根据程序的fontChanged信号 + * \~chinese 更新 DFontManager::baseFontPixelSize + * \~chinese \warning 请不要尝试更改它的 baseFontPixelSize 属性 + */ +const DFontManager *DGuiApplicationHelper::fontManager() const +{ + // 为对象初始化信号链接 + if (!_globalFM.exists()) { + connect(this, &DGuiApplicationHelper::fontChanged, _globalFM, &DFontManager::setBaseFont); + } + + return _globalFM; +} + +/*! * \~chinese \brief DGuiApplicationHelper::toColorType 获取颜色的明亮度,将其转换为主题类型的枚举值。 * \~chinese 转换的策略为:先将颜色转换为rgb格式,再根据 Y = 0.299R + 0.587G + 0.114B 的公式 * \~chinese 计算出颜色的亮度,亮度大于 191 时认为其为浅色,否则认为其为深色。 * \~chinese \param color 需要转换为主题的类型的颜色 - * \~chinese \return 主题类型的枚举值 + * \~chinese \return 颜色类型的枚举值 */ DGuiApplicationHelper::ColorType DGuiApplicationHelper::toColorType(const QColor &color) { @@ -1113,10 +1251,11 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::toColorType获取颜色的明亮度,将其转换为主题类型的枚举值。 - * \~chinese \row 返回调色板背景颜色 + * \~chinese \brief DGuiApplicationHelper::toColorType + * \~chinese 使用 QPalette::background 获取颜色的明亮度,将其转换为主题类型的枚举值。 + * \~chinese \row 返回调色板的颜色类型 * \~chinese \param palette调色板 - * \~chinese \return 主题类型的枚举值 + * \~chinese \return 颜色类型的枚举值 */ DGuiApplicationHelper::ColorType DGuiApplicationHelper::toColorType(const QPalette &palette) { @@ -1124,30 +1263,34 @@ } /*! - * \~chinese \brief DGuiApplicationHelper::themeType主题类型 - * \~chinese \row Dpalette::ColorType 针对某一个控件 - * \~chinese \row DGuiApplicationHelper::ColorType 针对整个程序 - * \~chinese \return 主题类型的枚举值 + * \~chinese \brief DGuiApplicationHelper::themeType + * \~chinese \row 返回程序的主题类型, 当themeType为UnknownType时, 将自动根据 + * \~chinese GuiApplication::palette的QPalette::background颜色计算主题 + * \~chinese 类型, 否则与 \a paletteType 的值一致. 程序中应当使用此值作为 + * \~chinese 暗色/亮色主题类型的判断. + * \~chinese \return 主题的颜色类型 + * \~chinese \sa toColorType */ DGuiApplicationHelper::ColorType DGuiApplicationHelper::themeType() const { D_DC(DGuiApplicationHelper); - if (d->themeType != UnknownType) { - return d->themeType; + if (d->paletteType != UnknownType) { + return d->paletteType; } - return qGuiApp ? toColorType(qGuiApp->palette()) : d->themeType; + return toColorType(qGuiApp->palette()); } /*! * \~chinese \brief DGuiApplicationHelper::paletteType - * \~chinese \return 主题类型的枚举值 + * \~chinese 返回当前已设置的调色板类型,如果未调用过 setPaletteType, 默认为 UnknownType. + * \~chinese \warning 与 themetype 不同,此值与程序当前的 QPalette 没有关系。 + * \~chinese \sa DGuiApplicationHelper::themeType */ DGuiApplicationHelper::ColorType DGuiApplicationHelper::paletteType() const { D_DC(DGuiApplicationHelper); - return d->paletteType; } @@ -1245,8 +1388,8 @@ qInfo() << "New instance: pid=" << pid << "arguments=" << arguments; // 通知新进程的信息 - if (_globalHelper.exists()) - Q_EMIT _globalHelper->helper->newProcessInstance(pid, arguments); + if (_globalHelper.exists() && _globalHelper->m_helper.load()) + Q_EMIT _globalHelper->m_helper.load()->newProcessInstance(pid, arguments); }); instance->flush(); //发送数据给新的实例 @@ -1277,23 +1420,55 @@ DGuiApplicationHelperPrivate::waitTime = interval; } +void DGuiApplicationHelper::setAttribute(DGuiApplicationHelper::Attribute attribute, bool enable) +{ + if (attribute < Attribute::ReadOnlyLimit) { + DGuiApplicationHelperPrivate::attributes.setFlag(attribute, enable); + } else { + qWarning() << "You are setting for the read-only option."; + return; + } +} + +bool DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::Attribute attribute) +{ + switch (attribute) { + case IsXWindowPlatform: + return qGuiApp->platformName() == QByteArrayLiteral("xcb") + || qGuiApp->platformName() == QByteArrayLiteral("dxcb"); + case IsDXcbPlatform: + return DPlatformHandle::isDXcbPlatform(); + case IsTableEnvironment: + return QGuiApplicationPrivate::instance()->platformIntegration()->services()->desktopEnvironment().toLower().endsWith("tablet"); + case IsDeepinPlatformTheme: + if (!QGuiApplicationPrivate::platform_name) { + return false; + } + return QString(typeid(*QGuiApplicationPrivate::platform_theme).name()).contains("QDeepinTheme"); + case IsDeepinEnvironment: + return QGuiApplicationPrivate::instance()->platformIntegration()->services()->desktopEnvironment().toLower().contains("deepin"); + default: + return DGuiApplicationHelperPrivate::attributes.testFlag(attribute); + } +} + /*! - * \~chinese \brief DGuiApplicationHelper::setThemeType设置主题类型 - * \~chinese \param themeType主题类型的枚举值 + * \~chinese \brief DGuiApplicationHelper::setThemeType + * \~chinese 同 setPaletteType, 已废弃,请不要再使用。 */ void DGuiApplicationHelper::setThemeType(DGuiApplicationHelper::ColorType themeType) { - D_D(DGuiApplicationHelper); - - if (d->themeType == themeType) - return; - - d->themeType = themeType; - Q_EMIT themeTypeChanged(themeType); + setPaletteType(themeType); } /*! - * \~chinese \brief DGuiApplicationHelper::setPaletteType设置调色板类型 + * \~chinese \brief DGuiApplicationHelper::setPaletteType 设置程序所应用的调色板类型。 + * \~chinese 将固定程序的调色板类型, 此行为可能导致 applicationPalette 变化, 前提是未使用 + * \~chinese \a setApplicationPalette 固定过程序的调色板, 此方法不影响程序的调色板跟随 + * \~chinese 活动色改变, 可用于控制程序使用亮色还是暗色调色板. + * \~chinese \note 主动设置调色板颜色类型的操作会导致程序不再使用 DPlatformTheme 中调色板相关的数据, 也 + * \~chinese 包括窗口级别的 \a windowTheme 所对应的 DPlatformTheme, 届时设置 DPlatformTheme + * \~chinese 的 themeName 和所有与 palette 相关的属性都不再生效. * \~chinese \param paletteType主题类型的枚举值 */ void DGuiApplicationHelper::setPaletteType(DGuiApplicationHelper::ColorType paletteType) @@ -1303,8 +1478,14 @@ if (d->paletteType == paletteType) return; + if (qGuiApp && qGuiApp->testAttribute(Qt::AA_SetPalette)) { + qWarning() << "DGuiApplicationHelper: Plase check 'QGuiApplication::setPalette', Don't use it on DTK application."; + } + d->paletteType = paletteType; - d->notifyAppThemeChanged(qGuiApp, true); + // 如果未固定调色板, 则paletteType的变化可能会导致调色板改变, 应当通知程序更新数据 + if (!d->appPalette) + d->notifyAppThemeChanged(); Q_EMIT paletteTypeChanged(paletteType); } diff -Nru dtkgui-5.4.15/src/kernel/dguiapplicationhelper.h dtkgui-5.5.17.1/src/kernel/dguiapplicationhelper.h --- dtkgui-5.4.15/src/kernel/dguiapplicationhelper.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dguiapplicationhelper.h 2021-07-02 03:37:24.000000000 +0000 @@ -31,13 +31,14 @@ DGUI_BEGIN_NAMESPACE class DPlatformTheme; +class DFontManager; class DGuiApplicationHelperPrivate; class DGuiApplicationHelper : public QObject, public DCORE_NAMESPACE::DObject { Q_OBJECT D_DECLARE_PRIVATE(DGuiApplicationHelper) - Q_PROPERTY(ColorType themeType READ themeType WRITE setThemeType NOTIFY themeTypeChanged) + Q_PROPERTY(ColorType themeType READ themeType NOTIFY themeTypeChanged) Q_PROPERTY(ColorType paletteType READ paletteType WRITE setPaletteType NOTIFY paletteTypeChanged) public: @@ -46,15 +47,32 @@ LightType, DarkType }; + Q_ENUM(ColorType) enum SingleScope { UserScope, GroupScope, WorldScope }; + Q_ENUM(SingleScope) + + enum Attribute { + UseInactiveColorGroup = 1 << 0, + ColorCompositing = 1 << 1, + + /* readonly flag */ + ReadOnlyLimit = 1 << 22, + IsDeepinPlatformTheme = ReadOnlyLimit << 0, + IsDXcbPlatform = ReadOnlyLimit << 1, + IsXWindowPlatform = ReadOnlyLimit << 2, + IsTableEnvironment = ReadOnlyLimit << 3, + IsDeepinEnvironment = ReadOnlyLimit << 4, + }; + Q_ENUM(Attribute) + Q_DECLARE_FLAGS(Attributes, Attribute) typedef DGuiApplicationHelper *(*HelperCreator)(); - static void registerInstanceCreator(HelperCreator creator); + D_DECL_DEPRECATED static void registerInstanceCreator(HelperCreator creator); static DGuiApplicationHelper *instance(); ~DGuiApplicationHelper(); @@ -66,22 +84,26 @@ static void generatePaletteColor(DPalette &base, DPalette::ColorType role, ColorType type); static void generatePalette(DPalette &base, ColorType type = UnknownType); static DPalette fetchPalette(const DPlatformTheme *theme); - static void setUseInactiveColorGroup(bool on); - static void setColorCompositingEnabled(bool on); + Q_DECL_DEPRECATED_X("Use UseInactiveColorGroup enum with setAttribute.") static void setUseInactiveColorGroup(bool on); + Q_DECL_DEPRECATED_X("Use ColorCompositing enum with setAttribute.") static void setColorCompositingEnabled(bool on); static bool isXWindowPlatform(); + static bool isTabletEnvironment(); + static void setAttribute(Attribute attribute, bool enable); + static bool testAttribute(Attribute attribute); DPlatformTheme *systemTheme() const; DPlatformTheme *applicationTheme() const; - DPlatformTheme *windowTheme(QWindow *window) const; + D_DECL_DEPRECATED DPlatformTheme *windowTheme(QWindow *window) const; DPalette applicationPalette() const; void setApplicationPalette(const DPalette &palette); - DPalette windowPalette(QWindow *window) const; + D_DECL_DEPRECATED DPalette windowPalette(QWindow *window) const; + + const DFontManager *fontManager() const; static ColorType toColorType(const QColor &color); static ColorType toColorType(const QPalette &palette); ColorType themeType() const; - ColorType paletteType() const; static bool setSingleInstance(const QString &key, SingleScope singleScope = UserScope); @@ -89,13 +111,15 @@ D_DECL_DEPRECATED static void setSingelInstanceInterval(int interval = 3000); public Q_SLOTS: - void setThemeType(ColorType themeType); + D_DECL_DEPRECATED_X("Plase use setPaletteType") void setThemeType(ColorType themeType); void setPaletteType(ColorType paletteType); Q_SIGNALS: void themeTypeChanged(ColorType themeType); void paletteTypeChanged(ColorType paletteType); void newProcessInstance(qint64 pid, const QStringList &arguments); + void fontChanged(const QFont &font); + void applicationPaletteChanged(); protected: explicit DGuiApplicationHelper(); diff -Nru dtkgui-5.4.15/src/kernel/dnativesettings.cpp dtkgui-5.5.17.1/src/kernel/dnativesettings.cpp --- dtkgui-5.4.15/src/kernel/dnativesettings.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dnativesettings.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -87,6 +87,10 @@ { D_DC(DNativeSettings); + // 避免进入死循环 + if (!d->valid) + return QVariant(); + return property(name.constData()); } @@ -94,6 +98,10 @@ { D_D(DNativeSettings); + // 避免进入死循环 + if (!d->valid) + return; + setProperty(name.constData(), value); } diff -Nru dtkgui-5.4.15/src/kernel/dpalette.h dtkgui-5.5.17.1/src/kernel/dpalette.h --- dtkgui-5.4.15/src/kernel/dpalette.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dpalette.h 2021-07-02 03:37:24.000000000 +0000 @@ -31,6 +31,7 @@ class DPalettePrivate; class DPalette : public QPalette { + Q_GADGET public: enum ColorType { NoType, @@ -47,6 +48,7 @@ ObviousBackground, //明显的背景色 NColorTypes }; + Q_ENUM(ColorType) DPalette(); DPalette(const QPalette &palette); diff -Nru dtkgui-5.4.15/src/kernel/dplatformhandle.cpp dtkgui-5.5.17.1/src/kernel/dplatformhandle.cpp --- dtkgui-5.4.15/src/kernel/dplatformhandle.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dplatformhandle.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -54,12 +54,14 @@ DEFINE_CONST_CHAR(enableBlurWindow); DEFINE_CONST_CHAR(windowBlurAreas); DEFINE_CONST_CHAR(windowBlurPaths); +DEFINE_CONST_CHAR(windowWallpaperParas); DEFINE_CONST_CHAR(autoInputMaskByClipPath); // functions DEFINE_CONST_CHAR(setWmBlurWindowBackgroundArea); DEFINE_CONST_CHAR(setWmBlurWindowBackgroundPathList); DEFINE_CONST_CHAR(setWmBlurWindowBackgroundMaskImage); +DEFINE_CONST_CHAR(setWmWallpaperParameter); DEFINE_CONST_CHAR(setWindowProperty); DEFINE_CONST_CHAR(pluginVersion); DEFINE_CONST_CHAR(disableOverrideCursor); @@ -844,6 +846,90 @@ } /*! + * \~chinese \brief DWindowHandle::setWindowWallpaperParaByWM + * \~chinese 设置窗口背景壁纸,示例: + * \~chinese \code + * QWindow w; + * QRect area; + * WallpaperScaleMode sMode + * WallpaperFillMode fMode + * + * area.setRect(50, 50, 200, 200); + * bMode = WallpaperScaleFlag::FollowWindow | WallpaperFillFlag::PreserveAspectCrop; + * + * DWindowHandle::setWindowWallpaperParaByWM(&w, area, bMode); + * + * QSurfaceFormat format = w.format(); + * format.setAlphaBufferSize(8); + * + * w.setFormat(format); + * w.resize(300, 300); + * w.show(); + * + * \endcode + * \~chinese \param window 目标窗口对象 + * \~chinese \param area 壁纸区域,此区域范围内的窗口背景将填充为用户设置的当前工作区窗口壁纸 + * \~Chinese \param sMode 控制壁纸缩放是随屏幕还是随窗口 + * \~Chinese \param fMode 控制壁纸是缩放还是裁剪 + * \~chinese \return 如果设置成功则返回 true,否则返回 false + * \~chinese \note 对于需要显示opengl壁纸特效的窗口,需要将其 QSurfaceFormat 的 alpha 通道设置为8 + * \~chinese \note 需要在window handle有效之后调用否则3d下失效 + * \~chinese \note 调用此接口设置窗口背景壁纸区域后将覆盖之前所设置的区域 + * \~chinese \note 此功能依赖于窗口管理器的实现,目前仅支持 kwin 窗口管理器 + * \~chinese \sa DBlurEffectWidget + * \~chinese \sa QSurfaceFormat::setAlphaBufferSize + * \~chinese \sa QWindow::setFormat + * \~chinese \sa DWindowManagerHelper::hasBlurWindow + * \~chinese \sa DWindowHandle::setWindowBlurAreaByWM(QWindow *, const QList &) + */ +bool DPlatformHandle::setWindowWallpaperParaByWM(QWindow *window, const QRect &area, WallpaperScaleMode sMode, WallpaperFillMode fMode) +{ + if (!window) { + return false; + } + + QFunctionPointer setWmWallpaperParameter = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + setWmWallpaperParameter = qApp->platformFunction(_setWmWallpaperParameter); +#endif + + if (!setWmWallpaperParameter) { + qWarning("setWindowWallpaperParaByWM is not support"); + + return false; + } + + QSurfaceFormat format = window->format(); + + format.setAlphaBufferSize(8); + window->setFormat(format); + + quint32 bMode = sMode | fMode; + + // 激活 backing store + window->setProperty("_d_dxcb_wallpaper", QVariant::fromValue(QPair(area, bMode))); + + if (!window->handle()) { + return true; + } else { + qWarning() << "because the window handle has been created, so 2D mode will have no effect"; + } + + const qreal device_ratio = window->devicePixelRatio(); + if (qFuzzyCompare(device_ratio, 1.0) || !area.isValid()) { + return reinterpret_cast(setWmWallpaperParameter)(window->winId(), area, bMode); + } + + QRect new_area(area.x() * device_ratio, + area.y() * device_ratio, + area.width() * device_ratio, + area.height() * device_ratio); + + return reinterpret_cast(setWmWallpaperParameter)(window->winId(), new_area, bMode); +} + +/*! * \~chinese \brief DWindowHandle::connectWindowManagerChangedSignal * \~chinese 将窗口管理器变化的信号链接到 object 对象的 slot 槽,建议使用 DWindowManager::windowManagerChanged * \~chinese \param object diff -Nru dtkgui-5.4.15/src/kernel/dplatformhandle.h dtkgui-5.5.17.1/src/kernel/dplatformhandle.h --- dtkgui-5.4.15/src/kernel/dplatformhandle.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dplatformhandle.h 2021-07-02 03:37:24.000000000 +0000 @@ -79,8 +79,19 @@ qint32 yRaduis = 0; }; + enum WallpaperScaleMode { + FollowScreen = 0x00000000, + FollowWindow = 0x00010000 + }; + + enum WallpaperFillMode { + PreserveAspectCrop = 0x00000000, + PreserveAspectFit = 0x00000001 + }; + static bool setWindowBlurAreaByWM(QWindow *window, const QVector &area); static bool setWindowBlurAreaByWM(QWindow *window, const QList &paths); + static bool setWindowWallpaperParaByWM(QWindow *window, const QRect &area, WallpaperScaleMode sMode, WallpaperFillMode fMode); static bool connectWindowManagerChangedSignal(QObject *object, std::function slot); static bool connectHasBlurWindowChanged(QObject *object, std::function slot); diff -Nru dtkgui-5.4.15/src/kernel/dplatformtheme.cpp dtkgui-5.5.17.1/src/kernel/dplatformtheme.cpp --- dtkgui-5.4.15/src/kernel/dplatformtheme.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dplatformtheme.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -30,6 +30,8 @@ DGUI_BEGIN_NAMESPACE +// "/deepin/palette" 为调色板属性的存储位置 +// 在x11平台下,将使用_DEEPIN_PALETTE作为存储调色板数据的窗口属性 DPlatformThemePrivate::DPlatformThemePrivate(Dtk::Gui::DPlatformTheme *qq) : DNativeSettingsPrivate(qq, QByteArrayLiteral("/deepin/palette")) { @@ -40,6 +42,11 @@ { D_Q(DPlatformTheme); + // 转发属性变化的信号,此信号来源可能为parent theme或“非调色板”的属性变化。 + // 使用队列的形式转发,避免多次发出同样的信号 + q->staticMetaObject.invokeMethod(q, "propertyChanged", Qt::QueuedConnection, + Q_ARG(const QByteArray&, name), Q_ARG(const QVariant&, value)); + if (QByteArrayLiteral("Gtk/FontName") == name) { Q_EMIT q->gtkFontNameChanged(value.toByteArray()); return; @@ -87,7 +94,7 @@ const QMetaProperty &p = mo->property(index); bool is_parent_signal = q->sender() != theme; - // 当自己属性有效时应该忽略父对象属性的信号 + // 当自己的属性有效时应该忽略父主题的属性变化信号,优先以自身的属性值为准。 if (is_parent_signal && p.read(q).isValid()) { return; } diff -Nru dtkgui-5.4.15/src/kernel/dregionmonitor.h dtkgui-5.5.17.1/src/kernel/dregionmonitor.h --- dtkgui-5.4.15/src/kernel/dregionmonitor.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dregionmonitor.h 2021-07-02 03:37:24.000000000 +0000 @@ -28,7 +28,7 @@ Q_DECLARE_FLAGS(RegisterdFlags, RegisterdFlag) enum WatchedFlags { - Button_Left = 1, + Button_Left = 1, Button_Middle, Button_Right, Wheel_Up, @@ -75,7 +75,7 @@ Q_PRIVATE_SLOT(d_func(), void _q_KeyRelease(const QString &, const int, const int, const QString &)) }; -Q_DECLARE_OPERATORS_FOR_FLAGS(DRegionMonitor::RegisterdFlags); +Q_DECLARE_OPERATORS_FOR_FLAGS (DRegionMonitor::RegisterdFlags); DGUI_END_NAMESPACE diff -Nru dtkgui-5.4.15/src/kernel/dwindowmanagerhelper.cpp dtkgui-5.5.17.1/src/kernel/dwindowmanagerhelper.cpp --- dtkgui-5.4.15/src/kernel/dwindowmanagerhelper.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dwindowmanagerhelper.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -41,11 +42,13 @@ DEFINE_CONST_CHAR(hasBlurWindow); DEFINE_CONST_CHAR(hasComposite); DEFINE_CONST_CHAR(hasNoTitlebar); +DEFINE_CONST_CHAR(hasWallpaperEffect); DEFINE_CONST_CHAR(windowManagerName); DEFINE_CONST_CHAR(connectWindowManagerChangedSignal); DEFINE_CONST_CHAR(connectHasBlurWindowChanged); DEFINE_CONST_CHAR(connectHasCompositeChanged); DEFINE_CONST_CHAR(connectHasNoTitlebarChanged); +DEFINE_CONST_CHAR(connectHasWallpaperEffectChanged); DEFINE_CONST_CHAR(getCurrentWorkspaceWindows); DEFINE_CONST_CHAR(getWindows); DEFINE_CONST_CHAR(windowFromPoint); @@ -56,6 +59,7 @@ DEFINE_CONST_CHAR(getMWMDecorations); DEFINE_CONST_CHAR(connectWindowMotifWMHintsChanged); DEFINE_CONST_CHAR(popupSystemWindowMenu); +DEFINE_CONST_CHAR(setWMClassName); static bool connectWindowManagerChangedSignal(QObject *object, std::function slot) { @@ -101,6 +105,17 @@ return connectHasNoTitlebarChanged && reinterpret_cast)>(connectHasNoTitlebarChanged)(object, slot); } +static bool connectHasWallpaperEffectChanged(QObject *object, std::function slot) +{ + QFunctionPointer connectHasWallpaperEffectChanged = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + connectHasWallpaperEffectChanged = qApp->platformFunction(_connectHasWallpaperEffectChanged); +#endif + + return connectHasWallpaperEffectChanged && reinterpret_cast)>(connectHasWallpaperEffectChanged)(object, slot); +} + static bool connectWindowListChanged(QObject *object, std::function slot) { QFunctionPointer connectWindowListChanged = Q_NULLPTR; @@ -171,6 +186,14 @@ */ /*! + * \~chinese \property DWindowManagerHelper::hasWallpaperEffect + * \~chinese \brief 窗口管理器是否支持窗口背景特效绘制。如果支持,则 绘制背景到透明窗口 + * \~chinese 会使用此方法开启特效窗口壁纸背景绘制。 + * \~chinese \note 只读 + * \~chinese \sa DPlatformWindowHandle::hasWallpaperEffectChanged + */ + +/*! * \~chinese \enum DWindowManagerHelper::MotifFunction * \~chinese MotifFunction::MotifFunction 窗口管理器对窗口所能控制的行为 * @@ -296,6 +319,8 @@ * \~chinese \brief 信号会在 hasComposite 属性的值改变时被发送 * \~chinese \fn DWindowManagerHelper::hasNoTitlebarChanged * \~chinese \brief 信号会在 hasNoTitlebar 属性的值改变时被发送 + * \~chinese \fn DWindowManagerHelper::hasWallpaperEffectChanged + * \~chinese \brief 信号会在 hasWallpaperEffect 属性的值改变时被发送 * \~chinese \fn DWindowManagerHelper::windowListChanged * \~chinese \brief 信号会在当前环境本地窗口列表变化时被发送。包含打开新窗口、关闭窗口、改变窗口的 * \~chinese 层叠顺序 @@ -464,6 +489,32 @@ } /*! + * \~chinese \brief DWindowManagerHelper::setWmWindowTypes + * \~chinese 直接设置窗口管理器层级提供的窗口类型,如DesktopType和DockType类型也被 + * \~chinese 桌面环境需要,但是Qt自身并没有提供对应的设置接口 + * \~chinese \param window + * \~chinese \param types + */ +void DWindowManagerHelper::setWmWindowTypes(QWindow *window, WmWindowTypes types) +{ + const int _types = static_cast(types); + QXcbWindowFunctions::setWmWindowType(window, static_cast(_types)); +} + +/*! + * \~chinese \brief DWindowManagerHelper::setWmClassName + * \~chinese 设置x11环境上默认使用的wm class name,主要是在窗口创建时用于设置WM_CLASS窗口属性 + * \~chinese \param name + * \~chinese \note 如果值为空,Qt将在下次使用此值时根据程序名称再次初始化此值 + * \~chinese \sa QCoreApplication::applicationName + */ +void DWindowManagerHelper::setWmClassName(const QByteArray &name) +{ + typedef void (*SetWmNameType)(const QByteArray&); + return QPlatformHeaderHelper::callPlatformFunction(_setWMClassName, name); +} + +/*! * \~chinese \brief DWindowManagerHelper::popupSystemWindowMenu * \~chinese 显示窗口管理器对窗口的菜单,和有边框的窗口在标题栏上点击鼠标右键弹出的菜单内容一致。 * \~chinese 在 DMainWindow 的标题栏上点击鼠标右键会调用此函数打开系统菜单: @@ -543,6 +594,21 @@ } /*! + * \~chinese \brief DWindowManagerHelper::hasWallpaperEffect + * \~chinese \return 如果窗口管理器当前支持背景图片特效绘制返回 true,否则返回 false + */ +bool DWindowManagerHelper::hasWallpaperEffect() const +{ + QFunctionPointer hasWallpaperEffect = Q_NULLPTR; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + hasWallpaperEffect = qApp->platformFunction(_hasWallpaperEffect); +#endif + + return hasWallpaperEffect && reinterpret_cast(hasWallpaperEffect)(); +} + +/*! * \~chinese \brief DWindowManagerHelper::windowManagerNameString * \~chinese \return 返回窗口管理器名称。在X11平台上,此值为窗口管理器对应窗口的 _NET_WM_NAME * \~chinese 的值 @@ -704,6 +770,9 @@ connectHasNoTitlebarChanged(this, [this] { Q_EMIT hasNoTitlebarChanged(); }); + connectHasWallpaperEffectChanged(this, [this] { + Q_EMIT hasWallpaperEffectChanged(); + }); connectWindowListChanged(this, [this] { Q_EMIT windowListChanged(); }); diff -Nru dtkgui-5.4.15/src/kernel/dwindowmanagerhelper.h dtkgui-5.5.17.1/src/kernel/dwindowmanagerhelper.h --- dtkgui-5.4.15/src/kernel/dwindowmanagerhelper.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/kernel/dwindowmanagerhelper.h 2021-07-02 03:37:24.000000000 +0000 @@ -38,6 +38,7 @@ Q_PROPERTY(bool hasBlurWindow READ hasBlurWindow NOTIFY hasBlurWindowChanged) Q_PROPERTY(bool hasComposite READ hasComposite NOTIFY hasCompositeChanged) Q_PROPERTY(bool hasNoTitlebar READ hasNoTitlebar NOTIFY hasNoTitlebarChanged) + Q_PROPERTY(bool hasWallpaperEffect READ hasWallpaperEffect NOTIFY hasWallpaperEffectChanged) public: enum MotifFunction { @@ -68,6 +69,28 @@ }; Q_ENUM(WMName) + enum WmWindowType { + UnknowWindowType = 0x000000, + NormalType = 0x000001, + DesktopType = 0x000002, + DockType = 0x000004, + ToolbarType = 0x000008, + MenuType = 0x000010, + UtilityType = 0x000020, + SplashType = 0x000040, + DialogType = 0x000080, + DropDownMenuType = 0x000100, + PopupMenuType = 0x000200, + TooltipType = 0x000400, + NotificationType = 0x000800, + ComboType = 0x001000, + DndType = 0x002000, + KdeOverrideType = 0x004000 + }; + Q_ENUM(WmWindowType) + Q_DECLARE_FLAGS(WmWindowTypes, WmWindowType) + Q_FLAG(WmWindowTypes) + ~DWindowManagerHelper(); static DWindowManagerHelper *instance(); @@ -78,12 +101,15 @@ static void setMotifDecorations(const QWindow *window, MotifDecorations hints); static MotifDecorations setMotifDecorations(const QWindow *window, MotifDecorations hints, bool on); static MotifDecorations getMotifDecorations(const QWindow *window); + static void setWmWindowTypes(QWindow *window, WmWindowTypes types); + static void setWmClassName(const QByteArray &name); static void popupSystemWindowMenu(const QWindow *window); bool hasBlurWindow() const; bool hasComposite() const; bool hasNoTitlebar() const; + bool hasWallpaperEffect() const; QString windowManagerNameString() const; WMName windowManagerName() const; @@ -97,6 +123,7 @@ void hasBlurWindowChanged(); void hasCompositeChanged(); void hasNoTitlebarChanged(); + void hasWallpaperEffectChanged(); void windowListChanged(); void windowMotifWMHintsChanged(quint32 winId); @@ -111,5 +138,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(DTK_GUI_NAMESPACE::DWindowManagerHelper::MotifFunctions) Q_DECLARE_OPERATORS_FOR_FLAGS(DTK_GUI_NAMESPACE::DWindowManagerHelper::MotifDecorations) +Q_DECLARE_OPERATORS_FOR_FLAGS(DTK_GUI_NAMESPACE::DWindowManagerHelper::WmWindowTypes) #endif // DWINDOWMANAGERHELPER_H diff -Nru dtkgui-5.4.15/src/private/dfontmanager_p.h dtkgui-5.5.17.1/src/private/dfontmanager_p.h --- dtkgui-5.4.15/src/private/dfontmanager_p.h 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/src/private/dfontmanager_p.h 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2020 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFONTSIZEMANAGER_P_H +#define DFONTSIZEMANAGER_P_H + +#include +#include + +#include "dfontmanager.h" + +DGUI_BEGIN_NAMESPACE + +class DFontManagerPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate +{ +public: + DFontManagerPrivate(DFontManager *qq); + + int fontPixelSize[DFontManager::NSizeTypes] = {40, 30, 24, 20, 17, 14, 13, 12, 11, 10}; + int baseFontSizeType = DFontManager::T6; + // 字号的差值 + int fontPixelSizeDiff = 0; + QFont baseFont; + +private: + D_DECLARE_PUBLIC(DFontManager) +}; + +DGUI_END_NAMESPACE + +#endif // DFONTSIZEMANAGER_P_H diff -Nru dtkgui-5.4.15/src/private/dguiapplicationhelper_p.h dtkgui-5.5.17.1/src/private/dguiapplicationhelper_p.h --- dtkgui-5.4.15/src/private/dguiapplicationhelper_p.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/private/dguiapplicationhelper_p.h 2021-07-02 03:37:24.000000000 +0000 @@ -41,24 +41,28 @@ void init(); void initApplication(QGuiApplication *app); static void staticInitApplication(); + static void staticCleanApplication(); DPlatformTheme *initWindow(QWindow *window) const; void _q_initApplicationTheme(bool notifyChange = false); - void notifyAppThemeChanged(QGuiApplication *app, bool ignorePaletteType = false); + void notifyAppThemeChanged(); + // 返回程序是否自定义了调色板 + inline bool isCustomPalette() const; - DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::UnknownType; DGuiApplicationHelper::ColorType paletteType = DGuiApplicationHelper::UnknownType; // 系统级别的主题设置 DPlatformTheme *systemTheme; - // 应用程序级别的主题设置 - DPlatformTheme *appTheme = nullptr; - DPalette *appPalette = nullptr; - static bool useInactiveColor; - // 是否采用半透明样式的调色板 - static bool compositingColor; + QScopedPointer appPalette; // 获取QLocalSever消息的等待时间 static int waitTime; + static DGuiApplicationHelper::Attributes attributes; + +private: + // 应用程序级别的主题设置 + DPlatformTheme *appTheme = nullptr; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(DGuiApplicationHelper::Attributes) + DGUI_END_NAMESPACE #endif // DGUIAPPLICATIONHELPER_P_H diff -Nru dtkgui-5.4.15/src/private/dplatformtheme_p.h dtkgui-5.5.17.1/src/private/dplatformtheme_p.h --- dtkgui-5.4.15/src/private/dplatformtheme_p.h 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/private/dplatformtheme_p.h 2021-07-02 03:37:24.000000000 +0000 @@ -32,15 +32,23 @@ D_DECLARE_PUBLIC(DPlatformTheme) DPlatformThemePrivate(DPlatformTheme *qq); + // 接收parent主题或非调色板DNativeSettings对象(theme对象)的属性变化通知 + // 调色板相关的属性变化与此无关 void _q_onThemePropertyChanged(const QByteArray &name, const QVariant &value); void onQtColorChanged(QPalette::ColorRole role, const QColor &color); void onDtkColorChanged(DPalette::ColorType type, const QColor &color); void notifyPaletteChanged(); + // 父主题,可以从其继承除调色板之外的所有窗口设置 DPlatformTheme *parent = nullptr; + // 用于控制是否fallback到父主题中获取属性 bool fallbackProperty = true; + // 默认时,DPlatformTheme会从/deepin/palette域下获取调色板相关的属性值 + // 此处的DNativeSettings用于获取除调色板之外的属性设置 DNativeSettings *theme; + // 缓存的调色板数据 DPalette *palette = nullptr; + // 减少调色板changed信号的通知频率 QTimer *notifyPaletteChangeTimer = nullptr; }; diff -Nru dtkgui-5.4.15/src/private/private.pri dtkgui-5.5.17.1/src/private/private.pri --- dtkgui-5.4.15/src/private/private.pri 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/private/private.pri 2021-07-02 03:37:24.000000000 +0000 @@ -5,4 +5,5 @@ $$PWD/dfiledragcommon_p.h \ $$PWD/dfiledragserver_p.h \ $$PWD/dregionmonitor_p.h \ - $$PWD/dtaskbarcontrol_p.h + $$PWD/dtaskbarcontrol_p.h \ + $$PWD/dfontmanager_p.h diff -Nru dtkgui-5.4.15/src/src.pro dtkgui-5.5.17.1/src/src.pro --- dtkgui-5.4.15/src/src.pro 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/src.pro 2021-07-02 03:37:24.000000000 +0000 @@ -39,6 +39,7 @@ $$PWD/filedrag/DFileDragClient \ $$PWD/filedrag/DFileDragServer \ $$PWD/util/*.h \ + $$PWD/util/DFontManager \ $$PWD/util/DSvgRenderer \ $$PWD/util/DTaskbarControl \ $$PWD/util/DThumbnailProvider @@ -54,3 +55,11 @@ load(dtk_cmake) load(dtk_module) + +# 支持上游一包多依赖 +load(dtk_multiversion) +# 5.5 5.6可通过重复调用此函数,来增加对更多版本的支持 +dtkBuildMultiVersion(5.5) + +# INSTALL变量增加多版本下的配置文件 +load(dtk_install_multiversion) diff -Nru dtkgui-5.4.15/src/util/dthumbnailprovider.cpp dtkgui-5.5.17.1/src/util/dthumbnailprovider.cpp --- dtkgui-5.4.15/src/util/dthumbnailprovider.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/util/dthumbnailprovider.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -48,6 +48,7 @@ return QCryptographicHash::hash(data, QCryptographicHash::Md5).toHex(); } +#ifndef UT_DThumbnailProviderPrivate class DThumbnailProviderPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate { public: @@ -82,6 +83,7 @@ D_DECLARE_PUBLIC(DThumbnailProvider) }; +#endif QSet DThumbnailProviderPrivate::hasThumbnailMimeHash; diff -Nru dtkgui-5.4.15/src/util/util.pri dtkgui-5.5.17.1/src/util/util.pri --- dtkgui-5.4.15/src/util/util.pri 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/src/util/util.pri 2021-07-02 03:37:24.000000000 +0000 @@ -1,10 +1,12 @@ HEADERS += \ + $$PWD/dfontmanager.h \ $$PWD/dsvgrenderer.h \ $$PWD/dtaskbarcontrol.h \ $$PWD/dthumbnailprovider.h SOURCES += \ + $$PWD/dfontmanager.cpp \ $$PWD/dsvgrenderer.cpp \ $$PWD/dtaskbarcontrol.cpp \ $$PWD/dthumbnailprovider.cpp diff -Nru dtkgui-5.4.15/tests/images/logo_icon.svg dtkgui-5.5.17.1/tests/images/logo_icon.svg --- dtkgui-5.4.15/tests/images/logo_icon.svg 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/images/logo_icon.svg 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,23 @@ + + + logo icon + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -Nru dtkgui-5.4.15/tests/main.cpp dtkgui-5.5.17.1/tests/main.cpp --- dtkgui-5.4.15/tests/main.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/main.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -1,14 +1,46 @@ -#include +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "test.h" -#include +#include #include +#ifdef QT_DEBUG +#include +#endif + int main(int argc, char *argv[]) { // gerrit编译时没有显示器,需要指定环境变量 - qputenv("QT_QPA_PLATFORM", "offscreen"); + if (!qEnvironmentVariableIsSet("DISPLAY")) + qputenv("QT_QPA_PLATFORM", "offscreen"); - QGuiApplication app(argc, argv); + QApplication app(argc, argv); ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int ret = RUN_ALL_TESTS(); + +#ifdef QT_DEBUG + __sanitizer_set_report_path("asan.log"); +#endif + + return ret; } diff -Nru dtkgui-5.4.15/tests/res.qrc dtkgui-5.5.17.1/tests/res.qrc --- dtkgui-5.4.15/tests/res.qrc 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/res.qrc 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,5 @@ + + + images/logo_icon.svg + + diff -Nru dtkgui-5.4.15/tests/src/ut_dfontmanager.cpp dtkgui-5.5.17.1/tests/src/ut_dfontmanager.cpp --- dtkgui-5.4.15/tests/src/ut_dfontmanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dfontmanager.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" +#include "dfontmanager.h" + +#include + +DGUI_USE_NAMESPACE + +TEST(ut_DFontManager, StaticFunction) +{ + enum { FontSize = 18 }; + + QFont tF = DFontManager::get(FontSize, qApp->font()); + ASSERT_EQ(tF.pixelSize(), FontSize); + ASSERT_EQ(DFontManager::fontPixelSize(tF), FontSize); + + tF.setPointSizeF(FontSize); + ASSERT_TRUE(DFontManager::fontPixelSize(tF) > 0); +} + +class TDFontManager : public DTestWithParam +{ +protected: + void SetUp(); + void TearDown(); + + DFontManager *manager; +}; + +INSTANTIATE_TEST_CASE_P(DFontManager, TDFontManager, testing::Range(int(DFontManager::T1), int(DFontManager::NSizeTypes))); + +void TDFontManager::SetUp() +{ + manager = new DFontManager; +} + +void TDFontManager::TearDown() +{ + delete manager; +} + +TEST_P(TDFontManager, testGetFont) +{ + int param = GetParam(); + + QFont font = manager->get(DFontManager::SizeType(param), qApp->font()); + ASSERT_EQ(font.pixelSize(), manager->fontPixelSize(DFontManager::SizeType(param))); + + manager->setBaseFont(qApp->font()); + ASSERT_EQ(manager->baseFont(), qApp->font()); + + font = manager->get(DFontManager::SizeType(param)); + ASSERT_EQ(font.pixelSize(), manager->fontPixelSize(DFontManager::SizeType(param))); + + manager->resetBaseFont(); + ASSERT_NE(manager->baseFont(), qApp->font()); + + manager->setFontPixelSize(DFontManager::SizeType(param), param); + ASSERT_EQ(manager->fontPixelSize(DFontManager::SizeType(param)), param); +} + +TEST_F(TDFontManager, testFontSize) +{ + manager->setBaseFont(qApp->font()); + + ASSERT_EQ(manager->t1().pixelSize(), manager->fontPixelSize(DFontManager::T1)); + ASSERT_EQ(manager->t2().pixelSize(), manager->fontPixelSize(DFontManager::T2)); + ASSERT_EQ(manager->t3().pixelSize(), manager->fontPixelSize(DFontManager::T3)); + ASSERT_EQ(manager->t4().pixelSize(), manager->fontPixelSize(DFontManager::T4)); + ASSERT_EQ(manager->t5().pixelSize(), manager->fontPixelSize(DFontManager::T5)); + ASSERT_EQ(manager->t6().pixelSize(), manager->fontPixelSize(DFontManager::T6)); + ASSERT_EQ(manager->t7().pixelSize(), manager->fontPixelSize(DFontManager::T7)); + ASSERT_EQ(manager->t8().pixelSize(), manager->fontPixelSize(DFontManager::T8)); + ASSERT_EQ(manager->t9().pixelSize(), manager->fontPixelSize(DFontManager::T9)); + ASSERT_EQ(manager->t10().pixelSize(), manager->fontPixelSize(DFontManager::T10)); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dforeignwindow.cpp dtkgui-5.5.17.1/tests/src/ut_dforeignwindow.cpp --- dtkgui-5.4.15/tests/src/ut_dforeignwindow.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dforeignwindow.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -1,12 +1,36 @@ -#include +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" #include "dforeignwindow.h" #include +#include #include DGUI_BEGIN_NAMESPACE -class TDForeignWindow : public testing::Test +#define WmClass "_d_WmClass" +#define ProcessId "_d_ProcessId" + +class TDForeignWindow : public DTest { protected: virtual void SetUp() @@ -19,7 +43,6 @@ } virtual void TearDown() { - qDeleteAll(foreignWindows); foreignWindows.clear(); } @@ -38,4 +61,20 @@ ASSERT_NE(foreignWindow->pid(), 0); } +TEST_F(TDForeignWindow, event) +{ + QDynamicPropertyChangeEvent wmevent(WmClass); + QDynamicPropertyChangeEvent pidevent(ProcessId); + + for (auto foreignWindow : qAsConst(foreignWindows)) { + QSignalSpy wmspy(foreignWindow, SIGNAL(wmClassChanged())); + ASSERT_TRUE(foreignWindow->event(&wmevent)); + ASSERT_EQ(wmspy.count(), 1); + + QSignalSpy pidspy(foreignWindow, SIGNAL(pidChanged())); + ASSERT_TRUE(foreignWindow->event(&pidevent)); + ASSERT_EQ(pidspy.count(), 1); + } +} + DGUI_END_NAMESPACE diff -Nru dtkgui-5.4.15/tests/src/ut_dguiapplicationhelper.cpp dtkgui-5.5.17.1/tests/src/ut_dguiapplicationhelper.cpp --- dtkgui-5.4.15/tests/src/ut_dguiapplicationhelper.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dguiapplicationhelper.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -1,16 +1,38 @@ -#include +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" #include "dguiapplicationhelper.h" +#include "dguiapplicationhelper_p.h" #include DGUI_BEGIN_NAMESPACE -class TDGuiApplicationHelper : public testing::Test +class TDGuiApplicationHelper : public DTest { protected: virtual void SetUp() { helper = DGuiApplicationHelper::instance(); + helper_d = helper->d_func(); /* read write */ readWriteDatas << DGuiApplicationHelper::Attribute::UseInactiveColorGroup @@ -25,10 +47,55 @@ } DGuiApplicationHelper *helper = nullptr; + DGuiApplicationHelperPrivate *helper_d = nullptr; QList readWriteDatas; QList readOnlyDatas; }; +TEST_F(TDGuiApplicationHelper, testFunction) +{ + QColor testColor(Qt::red); + QColor adjustedColor = helper->adjustColor(testColor, 0, 0, 0, 0, 0, 0, -20); + ASSERT_NE(testColor, adjustedColor); + ASSERT_TRUE(adjustedColor.isValid()); + + QColor disBlendColor = Qt::black; + QColor blendedColor = helper->blendColor(testColor, disBlendColor); + ASSERT_NE(testColor, blendedColor); + ASSERT_TRUE(blendedColor.isValid()); + + DPalette tPalette; + helper->generatePaletteColor(tPalette, QPalette::Window, DGuiApplicationHelper::ColorType::LightType); + ASSERT_EQ(tPalette.brush(QPalette::Disabled, QPalette::Window), tPalette.brush(QPalette::Normal, QPalette::Window)); + + tPalette.setColor(DPalette::Background, Qt::black); + helper->generatePaletteColor(tPalette, QPalette::Highlight, DGuiApplicationHelper::ColorType::DarkType); + ASSERT_TRUE(tPalette.highlight().color().isValid()); + + // 初始化调色板为默认值 + helper->generatePalette(tPalette); + + ASSERT_EQ(helper->isXWindowPlatform(), DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsXWindowPlatform)); + ASSERT_EQ(helper->isTabletEnvironment(), DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsTableEnvironment)); + + ASSERT_TRUE(helper->applicationTheme()); + ASSERT_TRUE(helper->systemTheme()); + ASSERT_NE(helper->applicationPalette(), tPalette); + qGuiApp->setAttribute(Qt::AA_SetPalette, false); + helper->setPaletteType(DGuiApplicationHelper::DarkType); + ASSERT_NE(helper->applicationPalette(), tPalette); + + helper->setApplicationPalette(tPalette); + ASSERT_EQ(helper->applicationPalette(), tPalette); + + ASSERT_TRUE(helper->fontManager()); + ASSERT_EQ(helper->toColorType(QColor(Qt::white)), DGuiApplicationHelper::LightType); + ASSERT_EQ(helper->toColorType(QColor(Qt::black)), DGuiApplicationHelper::DarkType); + ASSERT_EQ(helper->themeType(), DGuiApplicationHelper::DarkType); + ASSERT_EQ(helper->paletteType(), DGuiApplicationHelper::DarkType); + ASSERT_TRUE(helper->setSingleInstance("dtkgui-ut")); +} + TEST_F(TDGuiApplicationHelper, AttributeReadWrite) { QMap oldData; diff -Nru dtkgui-5.4.15/tests/src/ut_dpalette.cpp dtkgui-5.5.17.1/tests/src/ut_dpalette.cpp --- dtkgui-5.4.15/tests/src/ut_dpalette.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dpalette.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include +#include +#include + +#include "test.h" +#include "dpalette.h" + +DGUI_USE_NAMESPACE + +class TDPalette : public DTestWithParam +{ +protected: + void SetUp(); + void testAttribute(int cgCount, int ctCount); + + DPalette palette; +}; + +INSTANTIATE_TEST_CASE_P(DPalette, TDPalette, ::testing::Range(0, 12)); + +void TDPalette::SetUp() +{ + DGuiApplicationHelper::instance()->generatePalette(palette, DGuiApplicationHelper::LightType); +} + +TEST_P(TDPalette, testFunction) +{ + // 测试属性设置和属性获取函数能够正常调用且返回正确数值 + enum {ColorGroupCount = 6}; + + int ctGroup = GetParam(); + for (int i = 0; i < ColorGroupCount; ++i) { + QColor color = palette.color(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup)); + ASSERT_TRUE(color.isValid()); + + QBrush brush = palette.brush(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup)); + ASSERT_TRUE(brush.color().isValid()); + + color = palette.color(DPalette::ColorType(ctGroup)); + ASSERT_TRUE(color.isValid()); + + palette.setColor(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup), Qt::black); + color = palette.color(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup)); + ASSERT_EQ(color, Qt::black); + + palette.setBrush(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup), QBrush(Qt::blue)); + brush = palette.brush(DPalette::ColorGroup(i), DPalette::ColorType(ctGroup)); + ASSERT_EQ(brush.color(), Qt::blue); + } + + palette.setColor(DPalette::ColorType(ctGroup), Qt::white); + QColor color = palette.color(DPalette::ColorType(ctGroup)); + ASSERT_EQ(color, Qt::white); + + palette.setBrush(DPalette::ColorType(ctGroup), QBrush(Qt::blue)); + QBrush brush = palette.brush(DPalette::ColorType(ctGroup)); + ASSERT_EQ(brush.color(), Qt::blue); +} + +TEST_F(TDPalette, testColorFunction) +{ + // 测试默认的调色板颜色有效 + QBrush brush = palette.itemBackground(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.textTiele(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.textTips(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.textWarning(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.textLively(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.lightLively(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.darkLively(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.frameBorder(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.placeholderText(); + ASSERT_TRUE(brush.color().isValid()); + + brush = palette.frameShadowBorder(); + ASSERT_TRUE(brush.color().isValid()); + +#ifndef QT_NO_DATASTREAM + QByteArray inArray; + QDataStream in(&inArray, QIODevice::WriteOnly); + // in.setVersion(QDataStream::Qt_5_11); + + // 直接调用左移运算符会出现二异性 先直接执行一次生成结果 + in << static_cast(palette); + for (int i = 0; i < DPalette::NColorGroups; ++i) { + for (int j = 0; j < DPalette::NColorTypes; ++j) { + in << palette.brush(DPalette::ColorGroup(i), DPalette::ColorType(j)); + } + } + + ASSERT_FALSE(inArray.isEmpty()); + + DPalette tp; + QDataStream out(&inArray, QIODevice::ReadOnly); + out >> tp; + + ASSERT_EQ(palette, tp); +#endif + +#ifndef QT_NO_DEBUG_STREAM + QByteArray debugData; + QBuffer debugBuffer(&debugData); + ASSERT_TRUE(debugBuffer.open(QIODevice::WriteOnly)); + QDebug(&debugBuffer) << palette; + debugBuffer.close(); + + EXPECT_FALSE(debugData.isEmpty()); +#endif +} diff -Nru dtkgui-5.4.15/tests/src/ut_dplatformhandle.cpp dtkgui-5.5.17.1/tests/src/ut_dplatformhandle.cpp --- dtkgui-5.4.15/tests/src/ut_dplatformhandle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dplatformhandle.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include + +#include "dplatformhandle.h" + +#define DXCB_PLUGIN_KEY "dxcb" +#define DXCB_PLUGIN_SYMBOLIC_PROPERTY "_d_isDxcb" +#define SETWMWALLPAPERPARAMETER "_d_setWmWallpaperParameter" +#define CLIENTLEADER "_d_clientLeader" +#define WINDOWRADIUS "_d_windowRadius" +#define BORDERWIDTH "_d_borderWidth" +#define BORDRCOLOR "_d_borderColor" +#define SHADOWRADIUS "_d_shadowRadius" +#define SHADOWOFFSET "_d_shadowOffset" +#define SHADOWCOLOR "_d_shadowColor" +#define CLIPPATH "_d_clipPath" +#define FRAMEMASK "_d_frameMask" +#define FRAMEMARGINS "_d_frameMargins" +#define TRANSLUCENTBACKGROUND "_d_translucentBackground" +#define ENABLESYSTEMRESIZE "_d_enableSystemResize" +#define ENABLESYSTEMMOVE "_d_enableSystemMove" +#define ENABLEBLURWINDOW "_d_enableBlurWindow" +#define AUTOINPUTMASKBYCLIPPATH "_d_autoINPUTMASKBYCLIPPATH" +#define REALWINDOWID "_d_real_content_window" + +DGUI_USE_NAMESPACE + +class TDPlatformHandle : public testing::Test +{ +protected: + void SetUp(); + void TearDown(); + + QWidget *widget; + DPlatformHandle *pHandle; +}; + +void TDPlatformHandle::SetUp() +{ + widget = new QWidget; + widget->show(); + ASSERT_TRUE(QTest::qWaitForWindowExposed(widget)); + + if (QWindow *wHandle = widget->windowHandle()) { + pHandle = new DPlatformHandle(wHandle); + ASSERT_TRUE(pHandle); + } +} + +void TDPlatformHandle::TearDown() +{ + delete widget; + delete pHandle; +} + +TEST_F(TDPlatformHandle, testFunction) +{ + if (!pHandle || qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + EXPECT_FALSE(DPlatformHandle::pluginVersion().isEmpty()); + EXPECT_EQ(DPlatformHandle::isDXcbPlatform(), (qApp->platformName() == DXCB_PLUGIN_KEY || qApp->property(DXCB_PLUGIN_SYMBOLIC_PROPERTY).toBool())); + (DPlatformHandle::enableDXcbForWindow(widget->windowHandle())); + (DPlatformHandle::enableDXcbForWindow(widget->windowHandle(), true)); + + qInfo() << "TDPlatformHandle(isEnabledDXcb):" << DPlatformHandle::isEnabledDXcb(widget->windowHandle()); + + EXPECT_TRUE(DPlatformHandle::setEnabledNoTitlebarForWindow(widget->windowHandle(), true)); + EXPECT_TRUE(DPlatformHandle::setEnabledNoTitlebarForWindow(widget->windowHandle(), false)); + + QVector wmAreaVector; + wmAreaVector << dMakeWMBlurArea(0, 0, 20, 20, 4, 4); + + EXPECT_TRUE(pHandle->setWindowBlurAreaByWM(widget->windowHandle(), wmAreaVector)); + + QPainterPath pPath; + pPath.addRect({0, 0, 20, 20}); + + EXPECT_TRUE(pHandle->setWindowBlurAreaByWM(widget->windowHandle(), {pPath})); + EXPECT_TRUE(pHandle->setWindowBlurAreaByWM(wmAreaVector)); + EXPECT_TRUE(pHandle->setWindowBlurAreaByWM({pPath})); + + if (qApp->platformFunction(SETWMWALLPAPERPARAMETER)) { + EXPECT_TRUE(pHandle->setWindowWallpaperParaByWM(widget->windowHandle(), {0, 0, 20, 20}, DPlatformHandle::FollowScreen, DPlatformHandle::PreserveAspectFit)); + } else { + EXPECT_FALSE(pHandle->setWindowWallpaperParaByWM(widget->windowHandle(), {0, 0, 20, 20}, DPlatformHandle::FollowScreen, DPlatformHandle::PreserveAspectFit)); + } + + + if (qApp->platformFunction(CLIENTLEADER)) { + ASSERT_TRUE(DPlatformHandle::windowLeader()); + } else { + ASSERT_FALSE(DPlatformHandle::windowLeader()); + } + + DPlatformHandle::setDisableWindowOverrideCursor(widget->windowHandle(), true); + QVariant windowRadius = widget->windowHandle()->property(WINDOWRADIUS); + + if (windowRadius.isValid() && windowRadius.canConvert(QVariant::Int)) { + ASSERT_EQ(pHandle->windowRadius(), windowRadius.toInt()); + } + + QVariant borderWidth = widget->windowHandle()->property(BORDERWIDTH); + + if (borderWidth.isValid() && borderWidth.canConvert(QVariant::Int)) { + ASSERT_EQ(pHandle->borderWidth(), borderWidth.toInt()); + } else { + ASSERT_EQ(pHandle->borderWidth(), 0); + } + + QVariant borderColor = widget->windowHandle()->property(BORDRCOLOR); + + if (borderColor.isValid() && borderColor.canConvert(QVariant::Color)) { + ASSERT_EQ(pHandle->borderColor(), borderColor.value()); + } else { + ASSERT_FALSE(pHandle->borderColor().isValid()); + } + + QVariant shadowRadius = widget->windowHandle()->property(SHADOWRADIUS); + + if (shadowRadius.isValid() && shadowRadius.canConvert(QVariant::Int)) { + ASSERT_EQ(pHandle->shadowRadius(), shadowRadius.toInt()); + } else { + ASSERT_FALSE(pHandle->borderColor().isValid()); + } + + QVariant shadowOffset = widget->windowHandle()->property(SHADOWOFFSET); + + if (shadowOffset.isValid() && shadowOffset.canConvert(QVariant::Point)) { + ASSERT_EQ(pHandle->shadowOffset(), shadowOffset.value()); + } else { + ASSERT_TRUE(pHandle->shadowOffset().isNull()); + } + + QVariant shadowColor = widget->windowHandle()->property(SHADOWCOLOR); + + if (shadowColor.isValid() && shadowColor.canConvert(QVariant::Color)) { + ASSERT_EQ(pHandle->shadowColor(), shadowColor.value()); + } else { + ASSERT_FALSE(pHandle->shadowColor().isValid()); + } + + QVariant clipPath = widget->windowHandle()->property(CLIPPATH); + + if (clipPath.isValid() && !clipPath.value().isEmpty()) { + ASSERT_EQ(pHandle->clipPath(), clipPath.value()); + } else { + ASSERT_TRUE(pHandle->clipPath().isEmpty()); + } + + QVariant frameMask = widget->windowHandle()->property(FRAMEMASK); + + if (frameMask.isValid() && frameMask.canConvert(QVariant::Region)) { + ASSERT_EQ(pHandle->frameMask(), frameMask.value()); + } else { + ASSERT_TRUE(pHandle->frameMask().isEmpty()); + } + + QVariant frameMargins = widget->windowHandle()->property(FRAMEMARGINS); + + if (frameMargins.isValid() && !frameMargins.value().isNull()) { + ASSERT_EQ(pHandle->frameMargins(), frameMargins.value()); + } else { + ASSERT_TRUE(pHandle->frameMargins().isNull()); + } + + QVariant translucentBackground = widget->windowHandle()->property(TRANSLUCENTBACKGROUND); + if (translucentBackground.isValid() && translucentBackground.canConvert(QVariant::Bool)) { + ASSERT_EQ(pHandle->translucentBackground(), translucentBackground.toBool()); + } else { + ASSERT_FALSE(pHandle->translucentBackground()); + } + + QVariant enableSystemResize = widget->windowHandle()->property(ENABLESYSTEMRESIZE); + if (enableSystemResize.isValid() && enableSystemResize.canConvert(QVariant::Bool)) { + ASSERT_EQ(pHandle->enableSystemResize(), enableSystemResize.toBool()); + } else { + ASSERT_FALSE(pHandle->enableSystemResize()); + } + + QVariant enableSystemMove = widget->windowHandle()->property(ENABLESYSTEMMOVE); + if (enableSystemMove.isValid() && enableSystemMove.canConvert(QVariant::Bool)) { + ASSERT_EQ(pHandle->enableSystemMove(), enableSystemMove.toBool()); + } else { + ASSERT_FALSE(pHandle->enableSystemMove()); + } + + QVariant enableBlurWindow = widget->windowHandle()->property(ENABLEBLURWINDOW); + if (enableBlurWindow.isValid() && enableBlurWindow.canConvert(QVariant::Bool)) { + ASSERT_EQ(pHandle->enableBlurWindow(), enableBlurWindow.toBool()); + } else { + ASSERT_FALSE(pHandle->enableBlurWindow()); + } + + QVariant autoInputMaskByClipPath = widget->windowHandle()->property(AUTOINPUTMASKBYCLIPPATH); + if (autoInputMaskByClipPath.isValid() && autoInputMaskByClipPath.canConvert(QVariant::Bool)) { + ASSERT_EQ(pHandle->autoInputMaskByClipPath(), autoInputMaskByClipPath.toBool()); + } else { + ASSERT_FALSE(pHandle->autoInputMaskByClipPath()); + } + + QVariant realWindowId = widget->windowHandle()->property(REALWINDOWID); + if (enableBlurWindow.isValid() && enableBlurWindow.value() != 0) { + ASSERT_EQ(pHandle->realWindowId(), enableBlurWindow.value()); + } else { + ASSERT_FALSE(pHandle->realWindowId()); + } +} + +TEST_F(TDPlatformHandle, testSlots) +{ + enum { TESTBORDERWIDTH = 4, TESTOFFSET = 6, TESTRADIUS = 8 }; + if (pHandle) { + pHandle->setWindowRadius(TESTRADIUS); + ASSERT_EQ(pHandle->windowRadius(), TESTRADIUS); + + pHandle->setBorderWidth(TESTBORDERWIDTH); + ASSERT_EQ(pHandle->borderWidth(), TESTBORDERWIDTH); + + pHandle->setBorderColor(Qt::black); + ASSERT_EQ(pHandle->borderColor(), Qt::black); + + pHandle->setShadowRadius(TESTRADIUS); + ASSERT_EQ(pHandle->shadowRadius(), TESTRADIUS); + + pHandle->setShadowOffset({TESTOFFSET, TESTOFFSET}); + ASSERT_EQ(pHandle->shadowOffset(), QPoint(TESTOFFSET, TESTOFFSET)); + + pHandle->setShadowColor(Qt::blue); + ASSERT_EQ(pHandle->shadowColor(), Qt::blue); + + QPainterPath pPath; + pPath.addRect({0, 0, 20, 20}); + + pHandle->setClipPath(pPath); + ASSERT_EQ(pHandle->clipPath(), pPath); + + pHandle->setFrameMask(QRegion(0, 0, 10, 10)); + ASSERT_EQ(pHandle->frameMask(), QRegion(0, 0, 10, 10)); + + pHandle->setTranslucentBackground(true); + ASSERT_TRUE(pHandle->translucentBackground()); + + pHandle->setEnableSystemResize(true); + ASSERT_TRUE(pHandle->enableSystemResize()); + + pHandle->setEnableSystemMove(true); + ASSERT_TRUE(pHandle->enableSystemMove()); + + pHandle->setEnableBlurWindow(true); + ASSERT_TRUE(pHandle->enableBlurWindow()); + + pHandle->setAutoInputMaskByClipPath(true); + ASSERT_TRUE(pHandle->autoInputMaskByClipPath()); + } +} + +TEST_F(TDPlatformHandle, wmAreaDebug) +{ + DPlatformHandle::WMBlurArea area = dMakeWMBlurArea(0, 0, 20, 20); + + QByteArray data; + QBuffer buf(&data); + ASSERT_TRUE(buf.open(QIODevice::WriteOnly)); + + QDebug tDebug(&buf); + tDebug << area; + buf.close(); + ASSERT_FALSE(data.isEmpty()); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dplatformtheme.cpp dtkgui-5.5.17.1/tests/src/ut_dplatformtheme.cpp --- dtkgui-5.4.15/tests/src/ut_dplatformtheme.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dplatformtheme.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include +#include +#include + +#include "dguiapplicationhelper.h" +#include "dplatformtheme.h" +#include "dplatformtheme_p.h" + +DGUI_USE_NAMESPACE + +class TDPlatformTheme : public testing::Test +{ +protected: + void SetUp(); + void TearDown(); + + QWidget *widget; + DPlatformTheme *theme; + DPlatformThemePrivate *theme_d; +}; + +void TDPlatformTheme::SetUp() +{ + widget = new QWidget; + widget->show(); + ASSERT_TRUE(QTest::qWaitForWindowExposed(widget)); + + theme = new DPlatformTheme(widget->windowHandle()->winId(), widget); + theme_d = theme->d_func(); +} + +void TDPlatformTheme::TearDown() +{ + delete widget; +} + +TEST_F(TDPlatformTheme, testFunction) +{ + ASSERT_TRUE(theme_d->theme); + ASSERT_EQ(theme->parentTheme(), theme_d->parent); + ASSERT_FALSE(theme->isValid()); + + DPalette tPalette = theme->palette(); + ASSERT_EQ(theme->fetchPalette(tPalette), tPalette); +} + +#define TEST_THEME_NAME(TYPE) \ + QByteArrayLiteral("Test_Name_About_").append(TYPE) + +#define ASSERT_EQ_BY_VALUE(SetFunc,Func,Param) \ + theme->SetFunc(Param); \ + ASSERT_EQ(theme->Func(),Param); \ + +#define ASSERT_EQ_COLOR(SetFunc,Func,Param) \ + ASSERT_EQ_BY_VALUE(SetFunc,Func,Param); \ + +#define ASSERT_EQ_BY_NAME(SetFunc,Func,Param) \ + theme->SetFunc(TEST_THEME_NAME(Param)); \ + ASSERT_EQ(theme->Func(),TEST_THEME_NAME(Param)); + +TEST_F(TDPlatformTheme, testSetFunction) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + enum { TEST_COLOR = Qt::blue, TEST_DATA = 50 }; + + ASSERT_EQ_BY_VALUE(setCursorBlinkTime, cursorBlinkTime, TEST_DATA); + ASSERT_EQ_BY_VALUE(setCursorBlinkTimeout, cursorBlinkTimeout, TEST_DATA); + ASSERT_EQ_BY_VALUE(setCursorBlink, cursorBlink, true) + ASSERT_EQ_BY_VALUE(setDoubleClickDistance, doubleClickDistance, TEST_DATA); + ASSERT_EQ_BY_VALUE(setDoubleClickTime, doubleClickTime, TEST_DATA) + ASSERT_EQ_BY_VALUE(setDndDragThreshold, dndDragThreshold, TEST_DATA); + ASSERT_EQ_BY_NAME(setThemeName, themeName, "Theme"); + ASSERT_EQ_BY_NAME(setIconThemeName, iconThemeName, "Icon"); + ASSERT_EQ_BY_NAME(setSoundThemeName, soundThemeName, "Sound"); + ASSERT_EQ_BY_NAME(setFontName, fontName, "Font"); + ASSERT_EQ_BY_NAME(setMonoFontName, monoFontName, "MonoFont"); + ASSERT_EQ_BY_NAME(setGtkFontName, gtkFontName, "GtkFont"); + ASSERT_EQ_BY_VALUE(setFontPointSize, fontPointSize, TEST_DATA); + ASSERT_EQ_BY_VALUE(setActiveColor, activeColor, TEST_COLOR); + ASSERT_EQ_COLOR(setWindow, window, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setWindowText, windowText, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setBase, base, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setAlternateBase, alternateBase, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setToolTipBase, toolTipBase, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setToolTipText, toolTipText, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setText, text, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setButton, button, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setButtonText, buttonText, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setBrightText, brightText, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setLight, light, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setMidlight, midlight, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setDark, dark, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setMid, mid, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setShadow, shadow, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setHighlight, highlight, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setLink, link, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setLinkVisited, linkVisited, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setItemBackground, itemBackground, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setTextTitle, textTitle, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setTextTips, textTips, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setTextWarning, textWarning, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setTextLively, textLively, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setLightLively, lightLively, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setDarkLively, darkLively, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setFrameBorder, frameBorder, TEST_COLOR); + ASSERT_EQ_BY_VALUE(setWindowRadius, windowRadius, TEST_DATA / 10); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dregionmonitor.cpp dtkgui-5.5.17.1/tests/src/ut_dregionmonitor.cpp --- dtkgui-5.4.15/tests/src/ut_dregionmonitor.cpp 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dregionmonitor.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -1,11 +1,34 @@ -#include +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" #include "dregionmonitor.h" +#include "private/dregionmonitor_p.h" #include +#include +#include DGUI_BEGIN_NAMESPACE -class TDRegionMonitor : public testing::Test +class TDRegionMonitor : public DTest { protected: virtual void SetUp() @@ -21,27 +44,42 @@ TEST_F(TDRegionMonitor, registerRegion) { - // regionMonitor->registerRegion(); - // ASSERT_TRUE(regionMonitor->registered()); + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + regionMonitor->registerRegion(); + ASSERT_TRUE(regionMonitor->registered()); } TEST_F(TDRegionMonitor, registered) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_FALSE(regionMonitor->registered()); } TEST_F(TDRegionMonitor, watchedRegion) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_EQ(regionMonitor->watchedRegion(), QRegion()); } TEST_F(TDRegionMonitor, coordinateType) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_EQ(regionMonitor->coordinateType(), DRegionMonitor::ScaleRatio); } TEST_F(TDRegionMonitor, registerRegionArg) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_EQ(regionMonitor->watchedRegion(), QRegion()); QRegion r(0, 0, 600, 400); regionMonitor->registerRegion(r); @@ -50,14 +88,20 @@ TEST_F(TDRegionMonitor, unregisterRegion) { - // regionMonitor->registerRegion(); - // ASSERT_TRUE(regionMonitor->registered()); - // regionMonitor->unregisterRegion(); - // ASSERT_FALSE(regionMonitor->registered()); + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + regionMonitor->registerRegion(); + ASSERT_TRUE(regionMonitor->registered()); + regionMonitor->unregisterRegion(); + ASSERT_FALSE(regionMonitor->registered()); } TEST_F(TDRegionMonitor, setWatchedRegion) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_EQ(regionMonitor->watchedRegion(), QRegion()); QRegion r(0, 0, 600, 400); regionMonitor->setWatchedRegion(r); @@ -66,9 +110,91 @@ TEST_F(TDRegionMonitor, setCoordinateType) { + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + ASSERT_EQ(regionMonitor->coordinateType(), DRegionMonitor::ScaleRatio); regionMonitor->setCoordinateType(DRegionMonitor::Original); ASSERT_EQ(regionMonitor->coordinateType(), DRegionMonitor::Original); } +TEST_F(TDRegionMonitor, registerFlags) +{ +#ifndef QT_NO_DEBUG_STREAM + enum { TestRegionFlag = (DRegionMonitor::Motion | DRegionMonitor::Button) }; + + regionMonitor->setRegisterFlags(DRegionMonitor::RegisterdFlag(TestRegionFlag)); + ASSERT_EQ(regionMonitor->registerFlags(), TestRegionFlag); +#endif +} + +TEST_F(TDRegionMonitor, privateFunctions) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + DRegionMonitorPrivate *region_d = regionMonitor->d_func(); + ASSERT_TRUE(region_d); + + regionMonitor->registerRegion(); + ASSERT_TRUE(region_d->registered()); + + region_d->registerMonitorRegion(); + ASSERT_FALSE(region_d->registerKey.isEmpty()); + + region_d->watchedRegion = {0, 0, 30, 30}; + region_d->registerMonitorRegion(); + ASSERT_FALSE(region_d->registerKey.isEmpty()); + + region_d->unregisterMonitorRegion(); + ASSERT_TRUE(region_d->registerKey.isEmpty()); + + enum { TestFlag = 1 | 2, TestPos = 20 }; + const QString testKey = "Key_Enter"; + + QSignalSpy btnPressSpy(regionMonitor, SIGNAL(buttonPress(const QPoint &, const int))); + region_d->_q_ButtonPress(TestFlag, TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(btnPressSpy.count(), 1); + auto pressArguments = btnPressSpy.takeFirst(); + ASSERT_EQ(pressArguments.at(0).toPoint(), region_d->deviceScaledCoordinate({TestPos, TestPos}, qApp->devicePixelRatio())); + ASSERT_EQ(pressArguments.at(1).toInt(), TestFlag); + + QSignalSpy btnreleaseSpy(regionMonitor, SIGNAL(buttonRelease(const QPoint &, const int))); + region_d->_q_ButtonRelease(TestFlag, TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(btnreleaseSpy.count(), 1); + auto releaseArguments = btnreleaseSpy.takeFirst(); + ASSERT_EQ(releaseArguments.at(0).toPoint(), region_d->deviceScaledCoordinate({TestPos, TestPos}, qApp->devicePixelRatio())); + ASSERT_EQ(releaseArguments.at(1).toInt(), TestFlag); + + QSignalSpy cursorMoveSpy(regionMonitor, SIGNAL(cursorMove(const QPoint &))); + region_d->_q_CursorMove(TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(cursorMoveSpy.count(), 1); + auto curMoveArguments = cursorMoveSpy.takeFirst(); + ASSERT_EQ(curMoveArguments.at(0).toPoint(), region_d->deviceScaledCoordinate({TestPos, TestPos}, qApp->devicePixelRatio())); + + QSignalSpy cursorEnterSpy(regionMonitor, SIGNAL(cursorEnter(const QPoint &))); + region_d->_q_CursorEnter(TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(cursorEnterSpy.count(), 1); + auto curEnterArguments = cursorEnterSpy.takeFirst(); + ASSERT_EQ(curEnterArguments.at(0).toPoint(), region_d->deviceScaledCoordinate({TestPos, TestPos}, qApp->devicePixelRatio())); + + QSignalSpy cursorLeaveSpy(regionMonitor, SIGNAL(cursorLeave(const QPoint &))); + region_d->_q_CursorLeave(TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(cursorLeaveSpy.count(), 1); + auto curLeaveArguments = cursorLeaveSpy.takeFirst(); + ASSERT_EQ(curLeaveArguments.at(0).toPoint(), region_d->deviceScaledCoordinate({TestPos, TestPos}, qApp->devicePixelRatio())); + + QSignalSpy keyPressSpy(regionMonitor, SIGNAL(keyPress(const QString &))); + region_d->_q_KeyPress(testKey, TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(keyPressSpy.count(), 1); + auto keyPressArguments = keyPressSpy.takeFirst(); + ASSERT_EQ(keyPressArguments.at(0).toString(), testKey); + + QSignalSpy keyReleaseSpy(regionMonitor, SIGNAL(keyRelease(const QString &))); + region_d->_q_KeyRelease(testKey, TestPos, TestPos, region_d->registerKey); + ASSERT_EQ(keyReleaseSpy.count(), 1); + auto keyReleaseArguments = keyReleaseSpy.takeFirst(); + ASSERT_EQ(keyReleaseArguments.at(0).toString(), testKey); +} + DGUI_END_NAMESPACE diff -Nru dtkgui-5.4.15/tests/src/ut_dsvgrenderer.cpp dtkgui-5.5.17.1/tests/src/ut_dsvgrenderer.cpp --- dtkgui-5.4.15/tests/src/ut_dsvgrenderer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dsvgrenderer.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "dsvgrenderer.h" +#include "test.h" +#include +#include +#include +#include +#include + +DGUI_USE_NAMESPACE + +TEST(ut_DSvgRenderer, testInit) +{ + DSvgRenderer svg_1; + DSvgRenderer svg_2(QStringLiteral(":/images/logo_icon.svg")); + + ASSERT_FALSE(svg_1.isValid()); + ASSERT_TRUE(svg_2.isValid()); + + QFile file(":/images/logo_icon.svg"); + if (!file.open(QFile::ReadOnly)) + return; + + QByteArray data = file.readAll(); + DSvgRenderer svg_3(data); + ASSERT_TRUE(svg_3.isValid()); +} + +class TDSvgRenderer : public DTest +{ +protected: + void SetUp(); + void TearDown(); + + DSvgRenderer *renderer; + bool canLoad; +}; + +void TDSvgRenderer::SetUp() +{ + QLibrary rsvg("rsvg-2", "2"); + + if (!rsvg.isLoaded()) { + canLoad = rsvg.load(); + if (canLoad) { + rsvg.unload(); + } + } + + renderer = new DSvgRenderer; +} + +void TDSvgRenderer::TearDown() +{ + delete renderer; +} + +TEST_F(TDSvgRenderer, testLoad) +{ + if (!canLoad) + return; + + ASSERT_TRUE(renderer->load(QStringLiteral(":/images/logo_icon.svg"))); + ASSERT_TRUE(renderer->isValid()); + ASSERT_FALSE(renderer->defaultSize().isEmpty()); + ASSERT_FALSE(renderer->viewBox().isEmpty()); + ASSERT_FALSE(renderer->viewBoxF().isEmpty()); +} + +static bool testPixmapHasData(const QPixmap &pixmap) +{ + QImage image = pixmap.toImage(); + + image.reinterpretAsFormat(QImage::Format_RGB32); + const QRgb *bits = reinterpret_cast(image.constBits()); + const QRgb *end = bits + image.byteCount() / sizeof(QRgb); + return !std::all_of(bits, end, [](QRgb r) { return r == QColor(Qt::green).rgb(); }); +} + +#define TestRenderID QStringLiteral("#tittlebar") +#define TestRenderID_NotExist QStringLiteral("#TestRsvg_notexist") + +TEST_F(TDSvgRenderer, testRender) +{ + if (!canLoad) + return; + + enum { TestPixmapSize = 16 }; + + ASSERT_TRUE(renderer->load(QString(":/images/logo_icon.svg"))); + QPixmap tPixmap(QSize(TestPixmapSize, TestPixmapSize)); + tPixmap.fill(Qt::green); + QPainter tPainter(&tPixmap); + + renderer->render(&tPainter); + ASSERT_TRUE(testPixmapHasData(tPixmap)); + tPixmap.fill(Qt::green); + ASSERT_FALSE(testPixmapHasData(tPixmap)); + + renderer->render(&tPainter, TestRenderID); + ASSERT_TRUE(testPixmapHasData(tPixmap)); + tPixmap.fill(Qt::green); + ASSERT_FALSE(testPixmapHasData(tPixmap)); + ASSERT_TRUE(renderer->elementExists(TestRenderID)); + ASSERT_FALSE(renderer->elementExists(TestRenderID_NotExist)); + ASSERT_FALSE(renderer->boundsOnElement(TestRenderID).isEmpty()); + ASSERT_TRUE(renderer->boundsOnElement(TestRenderID_NotExist).isEmpty()); + + renderer->render(&tPainter, {0, 0, TestPixmapSize, TestPixmapSize}); + ASSERT_TRUE(testPixmapHasData(tPixmap)); + tPixmap.fill(Qt::green); + ASSERT_FALSE(testPixmapHasData(tPixmap)); + + ASSERT_FALSE(renderer->toImage({TestPixmapSize, TestPixmapSize}).isNull()); + ASSERT_FALSE(renderer->toImage({TestPixmapSize, TestPixmapSize}, TestRenderID).isNull()); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dtaskbarcontrol.cpp dtkgui-5.5.17.1/tests/src/ut_dtaskbarcontrol.cpp --- dtkgui-5.4.15/tests/src/ut_dtaskbarcontrol.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dtaskbarcontrol.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" +#include "dtaskbarcontrol.h" + +#include +#include + +DGUI_USE_NAMESPACE + +// 由于需要发送dbus接口 使用打桩类进行 +class MockDTaskbarControl : public DTaskbarControl +{ +public: + using DTaskbarControl::DTaskbarControl; + MOCK_METHOD1(sendMessage, void(const QVariantMap &)); +}; + +class TDTaskbarControl : public DTest +{ +protected: + void SetUp(); + void TearDown(); + + MockDTaskbarControl *control; +}; + +void TDTaskbarControl::SetUp() +{ + control = new MockDTaskbarControl; +} + +void TDTaskbarControl::TearDown() +{ + delete control; +} + +TEST_F(TDTaskbarControl, testFunction) +{ + enum { ProgressTestValue = 1 }; + EXPECT_CALL(*control, sendMessage(testing::_)).Times(testing::AtLeast(1)); + + QSignalSpy valueChangedSpy(control, SIGNAL(progressChanged(double))); + control->setProgress(true, ProgressTestValue); + ASSERT_EQ(valueChangedSpy.count(), 1); + + QSignalSpy visibleChangedSpy(control, SIGNAL(progressVisibleChanged(bool))); + control->setProgress(false, ProgressTestValue); + ASSERT_EQ(visibleChangedSpy.count(), 1); + + QSignalSpy counterChangedSpy(control, SIGNAL(counterChanged(int))); + control->setCounter(true, 1); + ASSERT_EQ(control->counter(), 1); + ASSERT_EQ(counterChangedSpy.count(), 1); + + QSignalSpy counterVisibleSpy(control, SIGNAL(counterVisibleChanged(bool))); + control->setCounter(false, 1); + ASSERT_EQ(counterVisibleSpy.count(), 1); + + control->setUrgency(true); + control->setCounterVisible(true); + ASSERT_EQ(control->counterVisible(), true); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dthumbnailprovider.cpp dtkgui-5.5.17.1/tests/src/ut_dthumbnailprovider.cpp --- dtkgui-5.4.15/tests/src/ut_dthumbnailprovider.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dthumbnailprovider.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" +#include "dthumbnailprovider.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DGUI_BEGIN_NAMESPACE +#ifndef UT_DThumbnailProviderPrivate +#define UT_DThumbnailProviderPrivate +class DThumbnailProviderPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate +{ +public: + DThumbnailProviderPrivate(DThumbnailProvider *qq); + + void init(); + + QString sizeToFilePath(DThumbnailProvider::Size size) const; + + QString errorString; + // MAX + qint64 defaultSizeLimit = INT64_MAX; + QHash sizeLimitHash; + QMimeDatabase mimeDatabase; + + static QSet hasThumbnailMimeHash; + + struct ProduceInfo + { + QFileInfo fileInfo; + DThumbnailProvider::Size size; + DThumbnailProvider::CallBack callback; + }; + + QQueue produceQueue; + QSet> discardedProduceInfos; + + bool running = true; + + QWaitCondition waitCondition; + QReadWriteLock dataReadWriteLock; + + D_DECLARE_PUBLIC(DThumbnailProvider) +}; +#endif +DGUI_END_NAMESPACE + +DGUI_USE_NAMESPACE + +class TDThumbnailProvider : public DTest +{ +protected: + void SetUp(); + void TearDown(); + + DThumbnailProvider *provider; + DThumbnailProviderPrivate *provider_d; +}; + +void TDThumbnailProvider::SetUp() +{ + provider = DThumbnailProvider::instance(); + provider_d = provider->d_func(); +} + +void TDThumbnailProvider::TearDown() +{ + // gtest会释放静态部分数据 导致双重释放程序崩溃这里手动将数据清空防止崩溃事情发生 + provider_d->hasThumbnailMimeHash.clear(); +} + +#define TESTRES_PATH ":/images/logo_icon.svg" +#define TESTRES_PATH_1 "no_exist" + +TEST_F(TDThumbnailProvider, TestCreate) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + QFileInfo fi(TESTRES_PATH); + QSignalSpy finishedSpy(provider, SIGNAL(createThumbnailFinished(const QString &, const QString &))); + QString ret = provider->createThumbnail(fi, DThumbnailProvider::Normal); + ASSERT_FALSE(ret.isEmpty()); + ASSERT_EQ(finishedSpy.count(), 1); + ASSERT_FALSE(provider->thumbnailFilePath(fi, DThumbnailProvider::Normal).isEmpty()); + + QFileInfo fi_notexisted(TESTRES_PATH_1); + QSignalSpy failedSpy(provider, SIGNAL(createThumbnailFailed(const QString &))); + ret = provider->createThumbnail(fi_notexisted, DThumbnailProvider::Normal); + ASSERT_TRUE(ret.isEmpty()); + ASSERT_EQ(finishedSpy.count(), 1); + ASSERT_FALSE(provider->errorString().isEmpty()); + ASSERT_TRUE(provider->thumbnailFilePath(fi_notexisted, DThumbnailProvider::Normal).isEmpty()); +} + +TEST_F(TDThumbnailProvider, testAttribute) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + ASSERT_TRUE(provider->hasThumbnail(QFileInfo(TESTRES_PATH))); + + enum { TEST_DEFALUTSIZELIMIT = 25 }; + provider->setDefaultSizeLimit(TEST_DEFALUTSIZELIMIT); + ASSERT_EQ(provider->defaultSizeLimit(), TEST_DEFALUTSIZELIMIT); + + QMimeDatabase base; + auto type = base.mimeTypeForFile(TESTRES_PATH); + provider->setSizeLimit(type, TEST_DEFALUTSIZELIMIT); + ASSERT_EQ(provider->sizeLimit(type), TEST_DEFALUTSIZELIMIT); +} + +void testCallBack(const QString &) +{ + return; +} + +TEST_F(TDThumbnailProvider, TestProducrQueue) +{ + provider_d->running = true; + provider->appendToProduceQueue(QFileInfo(TESTRES_PATH), DThumbnailProvider::Small); + provider->appendToProduceQueue(QFileInfo(TESTRES_PATH), DThumbnailProvider::Large, &testCallBack); + ASSERT_FALSE(provider_d->produceQueue.isEmpty()); + + provider->removeInProduceQueue(QFileInfo(TESTRES_PATH), DThumbnailProvider::Small); + ASSERT_FALSE(provider_d->discardedProduceInfos.isEmpty()); + provider_d->running = false; +} diff -Nru dtkgui-5.4.15/tests/src/ut_dwindowgroupleader.cpp dtkgui-5.5.17.1/tests/src/ut_dwindowgroupleader.cpp --- dtkgui-5.4.15/tests/src/ut_dwindowgroupleader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dwindowgroupleader.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" +#include "dwindowgroupleader.h" +#include + +#include +#include + +DGUI_USE_NAMESPACE + + +class TDWindowGroupLeader : public DTest +{ +protected: + void SetUp(); + void TearDown(); + + DWindowGroupLeader *groupLeader; + QWidget *tWidget_1; + QWidget *tWidget_2; +}; + +void TDWindowGroupLeader::SetUp() +{ + groupLeader = new DWindowGroupLeader; + tWidget_1 = new QWidget; + tWidget_2 = new QWidget; + + tWidget_1->show(); + tWidget_2->show(); + ASSERT_TRUE(QTest::qWaitForWindowExposed(tWidget_1)); + ASSERT_TRUE(QTest::qWaitForWindowExposed(tWidget_2)); +} + +void TDWindowGroupLeader::TearDown() +{ + delete groupLeader; + delete tWidget_1; + delete tWidget_2; +} + +TEST_F(TDWindowGroupLeader, testFunctions) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + // 测试多种情况添加window时数据是否正常 + groupLeader->addWindow(tWidget_1->windowHandle()); + groupLeader->addWindow(tWidget_2->windowHandle()); + + ASSERT_TRUE(groupLeader->groupLeaderId() != 0); + ASSERT_TRUE(groupLeader->clientLeaderId() != 0); + + groupLeader->removeWindow(tWidget_1->windowHandle()); + + ASSERT_TRUE(groupLeader->groupLeaderId() != 0); + ASSERT_TRUE(groupLeader->clientLeaderId() != 0); + + groupLeader->addWindow(tWidget_2->windowHandle()); + ASSERT_TRUE(groupLeader->groupLeaderId() != 0); + ASSERT_TRUE(groupLeader->clientLeaderId() != 0); +} diff -Nru dtkgui-5.4.15/tests/src/ut_dwindowmanagerhelper.cpp dtkgui-5.5.17.1/tests/src/ut_dwindowmanagerhelper.cpp --- dtkgui-5.4.15/tests/src/ut_dwindowmanagerhelper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/src/ut_dwindowmanagerhelper.cpp 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "test.h" +#include + +#include "dwindowmanagerhelper.h" +#include "dforeignwindow.h" + +DGUI_USE_NAMESPACE + +class TDWindowMangerHelper : public DTest +{ +protected: + void SetUp(); + + DWindowManagerHelper *wm_helper; +}; + +void TDWindowMangerHelper::SetUp() +{ + wm_helper = DWindowManagerHelper::instance(); +} + +TEST_F(TDWindowMangerHelper, testStaticFunction) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + QWidget *w = new QWidget; + w->show(); + ASSERT_TRUE(QTest::qWaitForWindowExposed(w)); + enum { TestMotifFunction = DWindowManagerHelper::FUNC_RESIZE | DWindowManagerHelper::FUNC_MOVE, TestAllMotifFunction = DWindowManagerHelper::FUNC_ALL}; + enum { TestDecorations = DWindowManagerHelper::DECOR_BORDER | DWindowManagerHelper::DECOR_RESIZEH, TestAllDecorations = DWindowManagerHelper::DECOR_ALL }; + + // 测试静态函数测试是否正常 + DWindowManagerHelper::setMotifFunctions(w->windowHandle(), DWindowManagerHelper::MotifFunctions(TestMotifFunction)); + DWindowManagerHelper::MotifFunctions mFuncs = DWindowManagerHelper::getMotifFunctions(w->windowHandle()); + ASSERT_EQ(mFuncs, TestMotifFunction); + + mFuncs = DWindowManagerHelper::setMotifFunctions(w->windowHandle(), DWindowManagerHelper::MotifFunctions(TestAllMotifFunction), true); + ASSERT_EQ(mFuncs, TestAllMotifFunction); + + DWindowManagerHelper::setMotifDecorations(w->windowHandle(), DWindowManagerHelper::MotifDecorations(TestDecorations)); + DWindowManagerHelper::MotifDecorations mDecos = DWindowManagerHelper::getMotifDecorations(w->windowHandle()); + ASSERT_EQ(mDecos, TestDecorations); + + mDecos = DWindowManagerHelper::setMotifDecorations(w->windowHandle(), DWindowManagerHelper::MotifDecorations(TestAllDecorations), true); + ASSERT_EQ(mDecos, TestAllDecorations); + + // 没有崩溃则测试成功 + enum { TestWindowType = DWindowManagerHelper::DesktopType | DWindowManagerHelper::MenuType }; + DWindowManagerHelper::setWmWindowTypes(w->windowHandle(), DWindowManagerHelper::WmWindowTypes(TestWindowType)); + DWindowManagerHelper::setWmClassName(QByteArrayLiteral("TestWmClass")); + DWindowManagerHelper::popupSystemWindowMenu(w->windowHandle()); + + delete w; +} + +TEST_F(TDWindowMangerHelper, testFunctions) +{ + if (qgetenv("QT_QPA_PLATFORM").contains("offscreen")) + return; + + ASSERT_TRUE(wm_helper->hasBlurWindow()); + ASSERT_TRUE(wm_helper->hasComposite()); + ASSERT_TRUE(wm_helper->hasNoTitlebar()); + ASSERT_TRUE(wm_helper->hasWallpaperEffect()); + ASSERT_FALSE(wm_helper->windowManagerNameString().isEmpty()); + if (wm_helper->windowManagerNameString().contains(QStringLiteral("DeepinGala"))) { + ASSERT_EQ(wm_helper->windowManagerName(), DWindowManagerHelper::DeepinWM); + } else if (wm_helper->windowManagerNameString().contains(QStringLiteral("KWin"))) { + ASSERT_EQ(wm_helper->windowManagerName(), DWindowManagerHelper::KWinWM); + } else { + ASSERT_EQ(wm_helper->windowManagerName(), DWindowManagerHelper::OtherWM); + } + + ASSERT_FALSE(wm_helper->allWindowIdList().isEmpty()); + ASSERT_FALSE(wm_helper->currentWorkspaceWindowIdList().isEmpty()); + ASSERT_FALSE(wm_helper->currentWorkspaceWindows().isEmpty()); + ASSERT_TRUE(wm_helper->windowFromPoint(wm_helper->currentWorkspaceWindows().first()->position())); +} diff -Nru dtkgui-5.4.15/tests/test.h dtkgui-5.5.17.1/tests/test.h --- dtkgui-5.4.15/tests/test.h 1970-01-01 00:00:00.000000000 +0000 +++ dtkgui-5.5.17.1/tests/test.h 2021-07-02 03:37:24.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Chen Bin + * + * Maintainer: Chen Bin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#ifndef TEST_H +#define TEST_H + +#include + +class DTest : public ::testing::Test +{ +}; + +template +class DTestWithParam : public ::testing::TestWithParam +{ +}; +#endif // TEST_H diff -Nru dtkgui-5.4.15/tests/test-recoverage.sh dtkgui-5.5.17.1/tests/test-recoverage.sh --- dtkgui-5.4.15/tests/test-recoverage.sh 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/test-recoverage.sh 2021-07-02 03:37:24.000000000 +0000 @@ -7,17 +7,16 @@ rm -rf $BUILD_DIR mkdir $BUILD_DIR cd $BUILD_DIR -qmake .. -make +qmake .. CONFIG+=debug +make -j$(nproc) cd ../tests/ rm -rf $BUILD_DIR mkdir $BUILD_DIR cd $BUILD_DIR - qmake .. CONFIG+=debug export ASAN_OPTIONS=halt_on_error=0 -TESTARGS="--gtest_output=xml:dde_test_report_dtkgui.xml" make check -j$(nproc) +make check -j$(nproc) lcov -d ./ -c -o coverage_all.info #lcov --extract coverage_all.info $EXTRACT_ARGS --output-file coverage.info @@ -25,5 +24,7 @@ cd .. genhtml -o $REPORT_DIR $BUILD_DIR/coverage.info +mv ./build/asan.log* ./build/asan_dtkgui.log + #rm -rf $BUILD_DIR #rm -rf ../$BUILD_DIR diff -Nru dtkgui-5.4.15/tests/tests.pro dtkgui-5.5.17.1/tests/tests.pro --- dtkgui-5.4.15/tests/tests.pro 2021-07-08 09:40:12.000000000 +0000 +++ dtkgui-5.5.17.1/tests/tests.pro 2021-07-02 03:37:24.000000000 +0000 @@ -1,10 +1,10 @@ TEMPLATE = app -QT += dtkcore gui gui-private dbus network -CONFIG += thread testcase no_testcase_installs +QT += dtkcore gui gui-private dbus network testlib widgets +CONFIG += thread CONFIG -= app_bundle -QMAKE_CXXFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -O0 -QMAKE_LFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -O0 +load(dtk_testcase) +LIBS += -lgmock INCLUDEPATH += \ $$PWD/../src/ \ @@ -14,6 +14,16 @@ $$OUT_PWD/../src \ $$PWD/../src/private +QMAKE_CXXFLAGS += -fno-access-control +QMAKE_LFLAGS += -fno-access-control + +CONFIG(debug, debug|release) { +LIBS += -lgtest -lgmock +QMAKE_CXXFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -fsanitize=address -fsanitize-recover=address -O2 +QMAKE_LFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -fsanitize=address -fsanitize-recover=address -O2 +QMAKE_CXX += -g -fprofile-arcs -ftest-coverage -fsanitize=address -fsanitize-recover=address -O2 +} + # 指定moc文件生成目录和src一样 MOC_DIR=$$OUT_PWD/../src @@ -34,8 +44,24 @@ DBUS_INTERFACES += dbus_monitor } +HEADERS += \ + test.h + SOURCES += \ main.cpp \ - #src/ut_dguiapplicationhelper.cpp \ + src/ut_dguiapplicationhelper.cpp \ src/ut_dregionmonitor.cpp \ - src/ut_dforeignwindow.cpp + src/ut_dforeignwindow.cpp \ + src/ut_dpalette.cpp \ + src/ut_dplatformhandle.cpp \ + src/ut_dplatformtheme.cpp \ + src/ut_dwindowmanagerhelper.cpp \ + src/ut_dwindowgroupleader.cpp \ + src/ut_dfontmanager.cpp \ + src/ut_dsvgrenderer.cpp \ + src/ut_dtaskbarcontrol.cpp \ + src/ut_dthumbnailprovider.cpp + +RESOURCES += \ + res.qrc +