Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support TreeLand window personalization mode #252

Merged
merged 10 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions archlinux/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pkgdesc='Deepin Toolkit, gui module for DDE look and feel'
arch=('x86_64' 'aarch64')
url="https://github.com/linuxdeepin/dtkgui"
license=('LGPL3')
depends=('dtkcore-git' 'dtkcommon-git' 'qt5-svg' 'libqtxdg' 'freeimage' 'librsvg')
depends=('dtkcore-git' 'dtkcommon-git' 'qt5-svg' 'libqtxdg' 'freeimage' 'librsvg' 'qt5-wayland')
# INFO: you can disable freeimage not to support RAW images
# Then set DTK_DISABLE_EX_IMAGE_FORMAT=OFF
makedepends=('git' 'qt5-tools' 'gtest' 'gmock' 'ninja' 'cmake' 'doxygen')
makedepends=('git' 'qt5-tools' 'gtest' 'gmock' 'ninja' 'cmake' 'doxygen' 'extra-cmake-modules')
conflicts=('dtkgui')
provides=('dtkgui')
groups=('deepin-git')
Expand Down
5 changes: 3 additions & 2 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ Source: dtkgui
Section: libdevel
Priority: optional
Maintainer: Deepin Packages Builder <[email protected]>
Build-Depends: debhelper-compat (= 12), pkg-config,
Build-Depends: debhelper-compat (= 12), pkg-config,
qtbase5-private-dev, qtbase5-dev-tools, doxygen, graphviz, qttools5-dev,
libdtkcore-dev, librsvg2-dev, libfreeimage-dev, libraw-dev, libgtest-dev, libgmock-dev,
libqt5xdg-dev, libqt5xdgiconloader-dev, cmake, qt5-image-formats-plugins
libqt5xdg-dev, libqt5xdgiconloader-dev, cmake, qt5-image-formats-plugins, libqt5waylandclient5-dev,
extra-cmake-modules, qtwayland5-dev-tools, qtwayland5-private-dev, libkf5wayland-dev
Standards-Version: 3.9.8

Package: libdtkgui5
Expand Down
38 changes: 38 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
if("${QT_VERSION_MAJOR}" STREQUAL "6")
find_package(Qt6 REQUIRED COMPONENTS Core Widgets WaylandClient)
else()
find_package(Qt5 REQUIRED COMPONENTS WaylandClient XkbCommonSupport)
endif()

add_library(${LIB_NAME} SHARED)

include(dbus/dbus.cmake)
Expand All @@ -6,6 +12,30 @@ include(kernel/kernel.cmake)
include(private/private.cmake)
include(util/util.cmake)

if("${QT_VERSION_MAJOR}" STREQUAL "6")
qt6_generate_wayland_protocol_client_sources(${LIB_NAME} FILES
${CMAKE_CURRENT_SOURCE_DIR}/wayland/protocol/treeland-personalization-manager-v1.xml
)
else()
# ECM setup
include(FeatureSummary)
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${ECM_MODULE_PATH}")
find_package(QtWaylandScanner)
ecm_add_qtwayland_client_protocol(${LIB_NAME}
PROTOCOL ${CMAKE_CURRENT_SOURCE_DIR}/wayland/protocol/treeland-personalization-manager-v1.xml
BASENAME treeland-personalization-manager-v1
)
target_sources(${LIB_NAME} PRIVATE
${CLIENT_LIB_SRCS}
)
endif()

include(wayland/wayland.cmake)
target_sources(${LIB_NAME} PRIVATE
${wayland_SRC}
)

target_sources(${LIB_NAME} PRIVATE
${dbus_SRC}
${filedrag_SRC}
Expand Down Expand Up @@ -34,7 +64,15 @@ PRIVATE
Qt${QT_VERSION_MAJOR}::GuiPrivate
Qt${QT_VERSION_MAJOR}::CorePrivate
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::WaylandClientPrivate
)

if("${QT_VERSION_MAJOR}" STREQUAL "5")
target_link_libraries(${LIB_NAME}
PRIVATE
Qt${QT_VERSION_MAJOR}::XkbCommonSupportPrivate
)
endif()

if(DTK_DISABLE_LIBRSVG)
find_package(Qt${QT_VERSION_MAJOR}Svg REQUIRED)
Expand Down
105 changes: 75 additions & 30 deletions src/kernel/dplatformhandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "dplatformhandle.h"
#include "dplatformtheme.h"
#include "dwindowmanagerhelper.h"
#include "wayland/dcontextshellwindow.h"
#include <private/qwaylandwindow_p.h>

#include <QWindow>
#include <QGuiApplication>
Expand Down Expand Up @@ -194,12 +196,12 @@ static void setWindowProperty(QWindow *window, const char *name, const QVariant
QWidget w;
QPainterPath path;
QFont font;

font.setPixelSize(100);
path.addText(0, 150, font, "deepin");

DPlatformHandle handle(&w);

handle.setClipPath(path);
w.resize(400, 200);
w.show();
Expand All @@ -217,7 +219,7 @@ static void setWindowProperty(QWindow *window, const char *name, const QVariant
\code
QWidget w;
DPlatformHandle handle(&w);

// 为何更好的观察效果,此处将阴影改为蓝色
handle.setShadowColor(Qt::blue);
w.resize(400, 200);
Expand Down Expand Up @@ -449,26 +451,26 @@ bool DPlatformHandle::isDXcbPlatform()
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
</pre>
\endraw

但是,如果窗口管理器自身支持隐藏窗口标题栏,则此方法将优先调用 enableNoTitlebarForWindow 实现同样的效果。

例子:
\code
QWidget w1;

w1.setWindowTitle("使用系统边框的窗口");
w1.show();

DMainWindow w2;
QWidget w3;

w2.titlebar()->setTitle("使用DTK风格边框带标题栏的窗口");
w3.setWindowTitle("使用DTK风格边框没有标题栏的窗口");
w2.show();

DPlatformHandle::enableDXcbForWindow(&w3);
w3.show(); // 因为这个窗口没有标题栏,所以不会显示窗口标题

\endcode
\image dtk_and_system_window.jpeg
开启了dxcb的窗口,在窗口外边缘10像素的范围按下鼠标左键可以触发改变窗口大小的行为,
Expand All @@ -482,7 +484,7 @@ bool DPlatformHandle::isDXcbPlatform()
{
public:
explicit Window() {

}

protected:
Expand All @@ -497,10 +499,10 @@ bool DPlatformHandle::isDXcbPlatform()
w.show();
\endcode
将无法使用鼠标移动窗口w

窗口管理器(如X11平台上的Window Manager)是否支持混成会影响dxcb插件对窗口添加的默认装饰。
\note 在 Deepin 桌面环境中,打开窗口特效则支持混成,关闭窗口特效则不支持混成

支持混成:
\image enable_composite.png
不支持混成:
Expand Down Expand Up @@ -607,6 +609,7 @@ static void initWindowRadius(QWindow *window)
}

class Q_DECL_HIDDEN CreatorWindowEventFile : public QObject {
bool m_windowMoving = false;
public:
CreatorWindowEventFile(QObject *par= nullptr): QObject(par){}

Expand All @@ -620,6 +623,36 @@ class Q_DECL_HIDDEN CreatorWindowEventFile : public QObject {
}
}

if (auto *w = qobject_cast<QWindow *>(watched)) {
if(DContextShellWindow *window = DContextShellWindow::get(qobject_cast<QWindow *>(watched))) {
bool is_mouse_move = event->type() == QEvent::MouseMove && static_cast<QMouseEvent*>(event)->buttons() == Qt::LeftButton;

if (event->type() == QEvent::MouseButtonRelease) {
m_windowMoving = false;
}

// workaround for kwin: Qt receives no release event when kwin finishes MOVE operation,
// which makes app hang in windowMoving state. when a press happens, there's no sense of
// keeping the moving state, we can just reset ti back to normal.
if (event->type() == QEvent::MouseButtonPress) {
m_windowMoving = false;
}

// FIXME: We need to check whether the event is accepted.
// Only when the upper control does not accept the event,
// the window should be moved through the window.
// But every event here has been accepted. I don't know what happened.
if (is_mouse_move && w->geometry().contains(static_cast<QMouseEvent*>(event)->globalPos())) {
if (!m_windowMoving && window->noTitlebar()) {
m_windowMoving = true;

event->accept();
static_cast<QtWaylandClient::QWaylandWindow *>(w->handle())->startSystemMove();
}
}
}
}

return QObject::eventFilter(watched, event);
}
};
Expand All @@ -641,9 +674,21 @@ bool DPlatformHandle::setEnabledNoTitlebarForWindow(QWindow *window, bool enable
auto isDWaylandPlatform = [] {
return qApp->platformName() == "dwayland" || qApp->property("_d_isDwayland").toBool();
};
if (!(isDXcbPlatform() || isDWaylandPlatform()))
auto isTreeLand = [] {
return qEnvironmentVariable("DDE_CURRENT_COMPOSITOR") == "TreeLand";
};
if (!(isDXcbPlatform() || isDWaylandPlatform() || isTreeLand()))
return false;

if (window && isTreeLand()) {
DContextShellWindow *contextWindow = DContextShellWindow::get(window);
if (contextWindow->noTitlebar() == enable)
return true;
contextWindow->setNoTitlebar(enable);
window->installEventFilter(new CreatorWindowEventFile(window));
return true;
}

if (isEnabledNoTitlebar(window) == enable)
return true;

Expand Down Expand Up @@ -714,24 +759,24 @@ inline DPlatformHandle::WMBlurArea operator *(const DPlatformHandle::WMBlurArea
QWindow w;
QVector<DPlatformHandle::WMBlurArea> area_list;
DPlatformHandle::WMBlurArea area;

area.x = 50;
area.y = 50;
area.width = 200;
area.height = 200;
area.xRadius = 10;
area.yRaduis = 10;
area_list.append(area);

DPlatformHandle::setWindowBlurAreaByWM(&w, area_list);

QSurfaceFormat format = w.format();
format.setAlphaBufferSize(8);

w.setFormat(format);
w.resize(300, 300);
w.show();

\endcode
\image blur_window_demo1.png
\a window 目标窗口对象
Expand Down Expand Up @@ -823,21 +868,21 @@ inline QPainterPath operator *(const QPainterPath &path, qreal scale)
QList<QPainterPath> path_list;
QPainterPath path;
QFont font;

font.setPixelSize(100);
font.setBold(true);
path.addText(0, 150, font, "deepin");
path_list.append(path);

DPlatformHandle::setWindowBlurAreaByWM(&w, path_list);

QSurfaceFormat format = w.format();
format.setAlphaBufferSize(8);

w.setFormat(format);
w.resize(300, 300);
w.show();

\endcode
\image blur_window_demo2.png
\a window 目标窗口对象
Expand Down Expand Up @@ -911,19 +956,19 @@ bool DPlatformHandle::setWindowBlurAreaByWM(QWindow *window, const QList<QPainte
QRect area;
WallpaperScaleMode sMode
WallpaperFillMode fMode

area.setRect(50, 50, 200, 200);
bMode = WallpaperScaleFlag::FollowWindow | WallpaperFillFlag::PreserveAspectCrop;

DPlatformHandle::setWindowWallpaperParaByWM(&w, area, bMode);

QSurfaceFormat format = w.format();
format.setAlphaBufferSize(8);

w.setFormat(format);
w.resize(300, 300);
w.show();

\endcode
\a window 目标窗口对象
\a area 壁纸区域,此区域范围内的窗口背景将填充为用户设置的当前工作区窗口壁纸
Expand Down
Loading
Loading