!41 自定义标题栏发送请求给窗口管理器弹出右键菜单

From: @liubuguiii 
Reviewed-by: @tangjie02 
Signed-off-by: @tangjie02
This commit is contained in:
openeuler-ci-bot 2024-01-22 10:00:11 +00:00 committed by Gitee
commit 81f67f2829
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 612 additions and 2 deletions

View File

@ -0,0 +1,606 @@
From c91b9ab12c19ea19171c63569064dc1a0e1c33bf Mon Sep 17 00:00:00 2001
From: liuxinhao <liuxinhao@kylinsec.com.cn>
Date: Mon, 22 Jan 2024 17:31:18 +0800
Subject: [PATCH] feat(KiranTitlebarWindow): Customize title bar to send
requests to the window manager and pop up a right-click menu
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 自定义标题栏发送请求给窗口管理器弹出右键菜单
Closes #24920
---
src/public/xlib-helper.cpp | 140 ++++++++++++++----
src/public/xlib-helper.h | 17 ++-
.../kiran-titlebar-window-private.cpp | 131 ++++++++--------
3 files changed, 189 insertions(+), 99 deletions(-)
diff --git a/src/public/xlib-helper.cpp b/src/public/xlib-helper.cpp
index c25ffda..8047430 100644
--- a/src/public/xlib-helper.cpp
+++ b/src/public/xlib-helper.cpp
@@ -1,27 +1,28 @@
/**
- * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
* kiranwidgets-qt5 is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- *
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
* Author: liuxinhao <liuxinhao@kylinos.com.cn>
*/
-
+
#include "xlib-helper.h"
-#include <X11/Xlib.h>
#include <X11/Xatom.h>
-#include <unistd.h>
+#include <X11/Xlib.h>
#include <memory.h>
+#include <unistd.h>
+#include <QMap>
using namespace Kiran;
-bool sendWMMoveResizeEvent(Display* display,EwmhMoveResizeDirection direction,quint64 xid,int x,int y)
+bool sendWMMoveResizeEvent(Display* display, EwmhMoveResizeDirection direction, quint64 xid, int x, int y)
{
Atom netMoveResize = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
XEvent xEvent;
@@ -46,18 +47,19 @@ bool sendWMMoveResizeEvent(Display* display,EwmhMoveResizeDirection direction,qu
return sendEvRes;
}
-bool XLibHelper::sendWMMoveEvent(Display *display, quint64 xid, int x, int y)
+bool XLibHelper::sendWMMoveEvent(Display* display, quint64 xid, int x, int y)
{
- return sendWMMoveResizeEvent(display,WM_MOVERESIZE_MOVE,xid,x,y);
+ return sendWMMoveResizeEvent(display, WM_MOVERESIZE_MOVE, xid, x, y);
}
-bool XLibHelper::sendResizeEvent(Display *display,
+bool XLibHelper::sendResizeEvent(Display* display,
CursorPositionEnums postion,
quint64 xid,
int x, int y)
{
EwmhMoveResizeDirection direction = WM_MOVERESIZE_CANCEL;
- switch (postion) {
+ switch (postion)
+ {
case CursorPosition_LeftTop:
direction = WM_MOVERESIZE_SIZE_TOPLEFT;
break;
@@ -83,10 +85,10 @@ bool XLibHelper::sendResizeEvent(Display *display,
direction = WM_MOVERESIZE_SIZE_RIGHT;
break;
}
- return sendWMMoveResizeEvent(display,direction,xid,x,y);
+ return sendWMMoveResizeEvent(display, direction, xid, x, y);
}
-int XLibHelper::SetShadowWidth(Display *xdisplay,
+int XLibHelper::SetShadowWidth(Display* xdisplay,
quint64 xid,
int left,
int right,
@@ -103,19 +105,103 @@ int XLibHelper::SetShadowWidth(Display *xdisplay,
frames[2] = top;
frames[3] = bottom;
int s = XChangeProperty(xdisplay,
- xid,
- atom,
- XA_CARDINAL,
- 32,
- PropModeReplace,
- (unsigned char *)frames,
- 4);
+ xid,
+ atom,
+ XA_CARDINAL,
+ 32,
+ PropModeReplace,
+ (unsigned char*)frames,
+ 4);
XFlush(xdisplay);
return s;
}
-bool XLibHelper::cancelWMMove(Display* display,quint64 xid,int x, int y)
+bool XLibHelper::cancelWMMove(Display* display, quint64 xid, int x, int y)
+{
+ return sendWMMoveResizeEvent(display, WM_MOVERESIZE_CANCEL, xid, x, y);
+}
+
+void reloadNetSupportedAtoms(Display* xdisplay, QMap<QString, Atom>& atomsMap)
+{
+ atomsMap.clear();
+
+ // get _NET_SUPPORTED atom
+ Atom netSupportedAtom = XInternAtom(xdisplay, "_NET_SUPPORTED", 1);
+ if (netSupportedAtom == None)
+ {
+ return;
+ }
+
+ // get _NET_SUPPORTED atom value from root window
+ Window rootWindow = QX11Info::appRootWindow(QX11Info::appScreen());
+ Atom type;
+ int format;
+ unsigned long after;
+ unsigned long natoms;
+ Atom* atoms;
+ XGetWindowProperty(xdisplay, rootWindow, netSupportedAtom, 0, LONG_MAX, False, XA_ATOM, &type, &format, &natoms, &after, (unsigned char**)&atoms);
+ if (type != XA_ATOM || atoms == nullptr)
+ {
+ return;
+ }
+
+ // cache root window _NET_SUPPORTED property
+ for (int i = 0; i < natoms; i++)
+ {
+ char* atomName = XGetAtomName(xdisplay, atoms[i]);
+ atomsMap.insert(atomName, atoms[i]);
+
+ XFree(atomName);
+ }
+
+ XFree(atoms);
+}
+
+bool checkNetWmHintSupported(Display* xdisplay, const char* atomName)
{
- return sendWMMoveResizeEvent(display,WM_MOVERESIZE_CANCEL,xid,x,y);
+ static QMap<QString, Atom> supportedAtomMap;
+
+ if (supportedAtomMap.isEmpty())
+ {
+ reloadNetSupportedAtoms(xdisplay, supportedAtomMap);
+ }
+
+ if (supportedAtomMap.contains(atomName))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// _GTK_SHOW_WINDOW_MENU支持情况
+// marco >= 1.20支持
+// kwin >= 5.26支持
+#define ATOM_WINDOW_SHOW_WINDOW_MENU "_GTK_SHOW_WINDOW_MENU"
+bool XLibHelper::showWindowMenuRequest(Display* xdisplay, quint64 xid, int root_x, int root_y)
+{
+ if (!checkNetWmHintSupported(xdisplay, ATOM_WINDOW_SHOW_WINDOW_MENU))
+ {
+ return false;
+ }
+
+ Atom showWindowMenuAtom = XInternAtom(xdisplay, ATOM_WINDOW_SHOW_WINDOW_MENU, 1);
+
+ XEvent xEvent;
+ memset(&xEvent, 0, sizeof(XEvent));
+ xEvent.xclient.type = ClientMessage;
+ xEvent.xclient.message_type = showWindowMenuAtom;
+ xEvent.xclient.display = xdisplay;
+ xEvent.xclient.window = xid;
+ xEvent.xclient.format = 32;
+ xEvent.xclient.data.l[0] = 0; /*GTK device ID(unused)*/
+ xEvent.xclient.data.l[1] = root_x; /* X coordinate relative to root */
+ xEvent.xclient.data.l[2] = root_y; /* Y coordinate relative to root */
+
+ XSendEvent(xdisplay, QX11Info::appRootWindow(QX11Info::appScreen()),
+ False, SubstructureNotifyMask | SubstructureRedirectMask,
+ &xEvent);
+ XFlush(xdisplay);
+ return true;
}
\ No newline at end of file
diff --git a/src/public/xlib-helper.h b/src/public/xlib-helper.h
index 65842c2..2ec879c 100644
--- a/src/public/xlib-helper.h
+++ b/src/public/xlib-helper.h
@@ -1,14 +1,14 @@
/**
- * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
* kiranwidgets-qt5 is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- *
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
* Author: liuxinhao <liuxinhao@kylinos.com.cn>
*/
@@ -24,6 +24,7 @@ namespace XLibHelper {
bool sendWMMoveEvent(Display* display,quint64 xid,int x,int y);
bool sendResizeEvent(Display* display,Kiran::CursorPositionEnums postion,quint64 xid,int x,int y);
int SetShadowWidth(Display *xdisplay,quint64 xid,int left,int right,int top,int bottom);
+ bool showWindowMenuRequest(Display *xdisplay,quint64 xid,int root_x,int root_y);
}
#endif // XLIBHELPER_H
diff --git a/src/widgets/kiran-titlebar-window/kiran-titlebar-window-private.cpp b/src/widgets/kiran-titlebar-window/kiran-titlebar-window-private.cpp
index 8252d97..43cd51a 100644
--- a/src/widgets/kiran-titlebar-window/kiran-titlebar-window-private.cpp
+++ b/src/widgets/kiran-titlebar-window/kiran-titlebar-window-private.cpp
@@ -1,14 +1,14 @@
/**
- * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
* kiranwidgets-qt5 is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- *
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
* Author: liuxinhao <liuxinhao@kylinos.com.cn>
*/
@@ -30,21 +30,20 @@
#include <QFontDatabase>
#include <QGraphicsDropShadowEffect>
#include <QMouseEvent>
+#include <QPainter>
+#include <QPainterPath>
#include <QScreen>
#include <QStyle>
#include <QTimer>
#include <QToolButton>
#include <QWindow>
-#include <QPainter>
-#include <QPainterPath>
-
-const int KiranTitlebarWindowPrivate::radius = 8;
+const int KiranTitlebarWindowPrivate::radius = 8;
-const int KiranTitlebarWindowPrivate::shadowWidth = 15;
-const int KiranTitlebarWindowPrivate::shadowRadius = 15;
-const QColor KiranTitlebarWindowPrivate::shadowActiveColor = QColor(0,0,0,150);
-const QColor KiranTitlebarWindowPrivate::shadowInactiveColor = QColor(0,0,0,75);
+const int KiranTitlebarWindowPrivate::shadowWidth = 15;
+const int KiranTitlebarWindowPrivate::shadowRadius = 15;
+const QColor KiranTitlebarWindowPrivate::shadowActiveColor = QColor(0, 0, 0, 150);
+const QColor KiranTitlebarWindowPrivate::shadowInactiveColor = QColor(0, 0, 0, 75);
extern void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
@@ -76,8 +75,8 @@ KiranTitlebarWindowPrivate::~KiranTitlebarWindowPrivate()
void KiranTitlebarWindowPrivate::init()
{
- //app调色盘改变可以认为主题风格产生变化需重新拿取图标更新
- connect(qApp, &QApplication::paletteChanged, this,&KiranTitlebarWindowPrivate::updateTitlebarButtonIcon);
+ // app调色盘改变可以认为主题风格产生变化需重新拿取图标更新
+ connect(qApp, &QApplication::paletteChanged, this, &KiranTitlebarWindowPrivate::updateTitlebarButtonIcon);
initOtherWidget();
@@ -88,8 +87,8 @@ void KiranTitlebarWindowPrivate::init()
/// 初始化阴影边框
m_isCompositingManagerRunning = QX11Info::isCompositingManagerRunning();
-
- if( m_isCompositingManagerRunning )
+
+ if (m_isCompositingManagerRunning)
{
m_layout->setMargin(shadowWidth);
}
@@ -212,7 +211,7 @@ void KiranTitlebarWindowPrivate::handlerMouseButtonPressEvent(QMouseEvent *ev)
qDebug() << "titlebar frame contains:" << m_titlebarWidget->frameGeometry().contains(ev->pos());
#endif
- if (m_titlebarWidget->frameGeometry().contains(m_titlebarWidget->mapFrom(q_ptr,ev->pos())))
+ if (m_titlebarWidget->frameGeometry().contains(m_titlebarWidget->mapFrom(q_ptr, ev->pos())))
{
m_titlebarIsPressed = true;
}
@@ -227,11 +226,18 @@ void KiranTitlebarWindowPrivate::handlerMouseButtonReleaseEvent(QMouseEvent *ev)
m_titlebarIsPressed = false;
}
}
+ else if (ev->button() == Qt::RightButton)
+ {
+ QPoint pos = QCursor::pos();
+ XLibHelper::showWindowMenuRequest(QX11Info::display(),
+ q_func()->winId(),
+ pos.x(), pos.y());
+ }
}
void KiranTitlebarWindowPrivate::handlerMouseMoveEvent(QMouseEvent *ev)
{
- ///判断是否点击标题栏区域
+ /// 判断是否点击标题栏区域
if (m_titlebarIsPressed)
{
QPoint pos = QCursor::pos();
@@ -240,7 +246,7 @@ void KiranTitlebarWindowPrivate::handlerMouseMoveEvent(QMouseEvent *ev)
q_func()->winId(),
pos.x(),
pos.y());
- ///NOTE:在此之后获取不到MouseRelease事件,需复位按钮按压
+ /// NOTE:在此之后获取不到MouseRelease事件,需复位按钮按压
m_titlebarIsPressed = false;
return;
}
@@ -268,13 +274,13 @@ void KiranTitlebarWindowPrivate::handlerMouseDoubleClickEvent(QMouseEvent *ev)
void KiranTitlebarWindowPrivate::initOtherWidget()
{
- ///主布局
+ /// 主布局
m_layout = new QVBoxLayout(q_ptr);
m_layout->setObjectName("KiranTitlebarMainLayout");
m_layout->setMargin(0);
m_layout->setSpacing(0);
- ///背景
+ /// 背景
m_frame = new FramelessBackgroundFrame(q_ptr);
m_frame->setRadius(radius);
m_frame->setAttribute(Qt::WA_Hover);
@@ -285,7 +291,7 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_frameLayout->setMargin(0);
m_frameLayout->setSpacing(0);
- ///标题栏
+ /// 标题栏
m_titlebarColorBlock = new KiranColorBlock(m_frame);
m_titlebarColorBlock->setDrawBackground(false);
m_titlebarColorBlock->setRoundedCorner(KiranColorBlock::CornersTop);
@@ -306,8 +312,8 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_titleBarLayout->setSpacing(0);
m_titleBarLayout->setObjectName("KiranTitlebarLayout");
- ///标题栏居左部分
- //标题栏图标
+ /// 标题栏居左部分
+ // 标题栏图标
m_titleIcon = new QLabel(m_titlebarWidget);
m_titleIcon->setObjectName("KiranTitlebarIcon");
m_titleIcon->setAccessibleName("WindowTitlebarIcon");
@@ -315,7 +321,7 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_titleBarLayout->setTitleBarIconLabel(m_titleIcon);
m_titleBarLayout->setTitleBarIconMargin(QMargins(12, 0, 0, 0));
- //标题
+ // 标题
m_title = new QLabel(m_titlebarWidget);
m_title->setFont(QFontDatabase::systemFont(QFontDatabase::TitleFont));
m_title->setObjectName("KiranTitlebarTitle");
@@ -325,8 +331,8 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_title->installEventFilter(this);
m_titleBarLayout->setTitleBarTitleLabel(m_title);
- ///标题栏居中部分
- //自定义控件区域
+ /// 标题栏居中部分
+ // 自定义控件区域
m_titlebarCenterWidget = new QWidget(m_titlebarWidget);
m_titlebarCenterWidget->setObjectName("KiranTitlebarCenterWidget");
m_titlebarCenterWidget->setAccessibleName("WindowTitlebarCenterWidget");
@@ -337,7 +343,7 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_customLayout->setSpacing(0);
m_customLayout->setObjectName("KiranTitlebarCustomLayout");
- ///标题栏居右部分
+ /// 标题栏居右部分
m_titlebarRirghtWidget = new QWidget(m_titlebarWidget);
m_titlebarRirghtWidget->setObjectName("KiranTitlebarRightWidget");
m_titlebarRirghtWidget->setAccessibleName("WindowTitlebarRightWidget");
@@ -348,11 +354,11 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
titlebarRightlayout->setSpacing(0);
titlebarRightlayout->setMargin(0);
- //占位
+ // 占位
QSpacerItem *spacerItem = new QSpacerItem(0, 20, QSizePolicy::Expanding);
titlebarRightlayout->addItem(spacerItem);
- //最小化
+ // 最小化
m_btnMin = new QPushButton(m_titlebarWidget);
m_btnMin->setObjectName("KiranTitlebarMinButton");
m_btnMin->setAccessibleName("WindowTitlebarMinimizeButton");
@@ -363,11 +369,10 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
connect(m_btnMin, &QPushButton::clicked, [this](bool checked)
{
Q_UNUSED(checked);
- q_ptr->showMinimized();
- });
+ q_ptr->showMinimized(); });
titlebarRightlayout->addWidget(m_btnMin, 0, Qt::AlignVCenter);
- //最大化
+ // 最大化
m_btnMax = new QPushButton(m_titlebarWidget);
m_btnMax->setObjectName("KiranTitlebarMaxButton");
m_btnMax->setAccessibleName("WindowTitlebarMaximizeButton");
@@ -385,11 +390,10 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
else
{
q_ptr->showMaximized();
- }
- });
+ } });
titlebarRightlayout->addWidget(m_btnMax, 0, Qt::AlignVCenter);
- //关闭
+ // 关闭
m_btnClose = new QPushButton(m_titlebarWidget);
m_btnClose->setObjectName("KiranTitlebarCloseButton");
m_btnClose->setAccessibleName("WindowTitlebarCloseButton");
@@ -400,13 +404,12 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
connect(m_btnClose, &QPushButton::clicked, [this](bool checked)
{
Q_UNUSED(checked);
- q_ptr->close();
- });
+ q_ptr->close(); });
titlebarRightlayout->addWidget(m_btnClose, 0, Qt::AlignVCenter);
setButtonHints(m_buttonHints);
- ///分割线
+ /// 分割线
m_tittlebarSpliteLine = new QFrame(m_frame);
m_tittlebarSpliteLine->setFixedHeight(1);
m_frameLayout->addWidget(m_tittlebarSpliteLine);
@@ -414,7 +417,7 @@ void KiranTitlebarWindowPrivate::initOtherWidget()
m_tittlebarSpliteLine->setFrameShape(QFrame::HLine);
m_tittlebarSpliteLine->setFrameShadow(QFrame::Sunken);
- ///内容窗口包装
+ /// 内容窗口包装
m_windowContentWidgetWrapper = new QWidget(m_frame);
m_windowContentWidgetWrapper->setObjectName("KiranTitlebarContentWrapper");
m_frameLayout->addWidget(m_windowContentWidgetWrapper);
@@ -461,47 +464,47 @@ CursorPositionEnums KiranTitlebarWindowPrivate::getCursorPosition(QPoint pos)
void KiranTitlebarWindowPrivate::ensureShadowPixmapUpdated()
{
- if( !m_isCompositingManagerRunning )
+ if (!m_isCompositingManagerRunning)
{
return;
}
-
+
bool isActiveWindow = q_ptr->isActiveWindow();
auto windowSize = q_ptr->size();
auto windowRect = q_ptr->rect();
- if( ( isActiveWindow && (m_shadowActivePix.size() == windowSize) ) ||
- ( !isActiveWindow && (m_shadowPix.size() == windowSize) ) )
+ if ((isActiveWindow && (m_shadowActivePix.size() == windowSize)) ||
+ (!isActiveWindow && (m_shadowPix.size() == windowSize)))
{
- //不需更新
+ // 不需更新
return;
}
qDebug() << "update shadow pixmap..." << isActiveWindow << windowSize;
- QPainterPath innerPath,outerPath;
- innerPath.addRoundedRect(windowRect.adjusted(shadowWidth,shadowWidth,-shadowWidth,-shadowWidth),radius,radius);
- outerPath.addRoundedRect(windowRect,radius,radius);
+ QPainterPath innerPath, outerPath;
+ innerPath.addRoundedRect(windowRect.adjusted(shadowWidth, shadowWidth, -shadowWidth, -shadowWidth), radius, radius);
+ outerPath.addRoundedRect(windowRect, radius, radius);
- QImage img(windowSize,QImage::Format_ARGB32_Premultiplied);
+ QImage img(windowSize, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter imgPainter(&img);
imgPainter.setCompositionMode(QPainter::CompositionMode_Source);
- imgPainter.fillPath(innerPath,QBrush(Qt::white));
+ imgPainter.fillPath(innerPath, QBrush(Qt::white));
imgPainter.end();
- QImage blurredImg(img.size(),img.format());
+ QImage blurredImg(img.size(), img.format());
blurredImg.fill(0);
QPainter blurPainter(&blurredImg);
- qt_blurImage(&blurPainter,img,shadowRadius,false,true);
+ qt_blurImage(&blurPainter, img, shadowRadius, false, true);
blurPainter.end();
img = std::move(blurredImg);
imgPainter.begin(&img);
imgPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
- imgPainter.fillRect(img.rect(),isActiveWindow?shadowActiveColor:shadowInactiveColor);
+ imgPainter.fillRect(img.rect(), isActiveWindow ? shadowActiveColor : shadowInactiveColor);
imgPainter.end();
QPixmap pixmap(img.size());
@@ -513,10 +516,10 @@ void KiranTitlebarWindowPrivate::ensureShadowPixmapUpdated()
QPainter outputPainter(&pixmap);
outputPainter.setClipPath(clipPath);
- outputPainter.drawImage(img.rect(),img);
+ outputPainter.drawImage(img.rect(), img);
outputPainter.end();
- if( isActiveWindow )
+ if (isActiveWindow)
{
m_shadowActivePix = pixmap;
}
@@ -532,7 +535,7 @@ void KiranTitlebarWindowPrivate::updateTitleFont(QFont font)
bool KiranTitlebarWindowPrivate::eventFilter(QObject *obj, QEvent *event)
{
- //NOTE:用户标题栏暂时需要使用窗口管理器单独设置的字体,不和程序字体通用
+ // NOTE:用户标题栏暂时需要使用窗口管理器单独设置的字体,不和程序字体通用
if (obj == m_title && event->type() == QEvent::ApplicationFontChange)
{
return true;
@@ -546,9 +549,9 @@ bool KiranTitlebarWindowPrivate::eventFilter(QObject *obj, QEvent *event)
case QEvent::ShowToParent:
// 若在初始化时 createWinId 再调用下列方法设置属性,设置属性成功,但窗口管理器未能成功识别
// 在接近显示时进行处理设置_GTK_FRAME_EXTENTS属性
- if( m_isCompositingManagerRunning )
+ if (m_isCompositingManagerRunning)
{
- int scaledShadowWidth = q_ptr->devicePixelRatio()*shadowWidth;
+ int scaledShadowWidth = q_ptr->devicePixelRatio() * shadowWidth;
XLibHelper::SetShadowWidth(QX11Info::display(), q_ptr->winId(), scaledShadowWidth, scaledShadowWidth, scaledShadowWidth, scaledShadowWidth);
}
break;
@@ -576,8 +579,8 @@ bool KiranTitlebarWindowPrivate::eventFilter(QObject *obj, QEvent *event)
case QEvent::StyleChange:
updateTitlebarButtonIcon();
break;
- case QEvent::WindowStateChange:
- if( q_ptr->windowState() == Qt::WindowMaximized )
+ case QEvent::WindowStateChange:
+ if (q_ptr->windowState() == Qt::WindowMaximized)
{
m_frame->setRadius(0);
}
--
2.33.0

View File

@ -1,6 +1,6 @@
Name: kiran-widgets-qt5
Version: 2.4.2
Release: 2%{?dist}
Release: 3%{?dist}
Summary: Encapsulated QT Widget
Summary(zh_CN): 封装的Qt小部件
@ -8,6 +8,7 @@ License: MulanPSL-2.0
Source0: %{name}-%{version}.tar.gz
Patch0000: 0000-fix-KiranPasswordEdit-default-password-input-does-no.patch
Patch0001: 0001-feat-KiranTitlebarWindow-Customize-title-bar-to-send.patch
BuildRequires: cmake >= 3.5
BuildRequires: gcc-c++
@ -78,6 +79,9 @@ make %{?_smp_mflags}
rm -rf %{buildroot}
%changelog
* Mon Jan 22 2024 liuxinhao <liuxinhao@kylinsec.com.cn> - 2.4.2-3
- KYOS-F: Customize title bar send requests to window manager and pop up a right-click menu(#24920)
* Thu Jan 18 2024 liuxinhao <liuxinhao@kylinsec.com.cn> - 2.4.2-2.kb1
- KYOS-B: default password input does not provide clear text display function(#25230)
@ -216,4 +220,4 @@ rm -rf %{buildroot}
- KYOS-F: Suitable for high DPI
* Fri Sep 25 2020 liuxinhao <liuxinhao@kylinos.com.cn> - 2.0.0+alpha1
- first build
- first build