From a346ba1be0ab61eecd5064767ad0f723db7636dd Mon Sep 17 00:00:00 2001 From: Yuki Date: Mon, 27 Apr 2026 13:39:02 +0800 Subject: [PATCH 1/9] init --- TeXmacs/misc/themes/liii-night.css | 8 ++------ TeXmacs/misc/themes/liii.css | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 9a1d0e04c8..2e7d19a0ef 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -358,10 +358,7 @@ QTMTabPage { color: #FFFFFF; background-color: transparent; border: 1px solid transparent; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-radius: 10px; } QTMTabPage:hover { @@ -373,8 +370,7 @@ QTMTabPage:checked { background-color: #333333; border: 1px solid #4c4c4c; border-bottom: none; - border-top-left-radius: 10px; - border-top-right-radius: 10px; + border-radius: 10px; color: #FFFFFF; } diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 202063396e..c468bca980 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -348,10 +348,7 @@ QTMTabPage { color: #000000; background-color: transparent; border: 1px solid transparent; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-radius: 10px; } QTMTabPage:hover { @@ -363,8 +360,7 @@ QTMTabPage:checked { background-color: #FFFFFF; border: 1px solid #CFCFCF; border-bottom: none; - border-top-left-radius: 10px; - border-top-right-radius: 10px; + border-radius: 10px; } QTMTabPage QToolButton#tabpage-close-button { From 8e32641b9b451a58875bd9489a76fed62b429aca Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 11:43:54 +0800 Subject: [PATCH 2/9] wip --- TeXmacs/misc/themes/liii-night.css | 28 ---------------- TeXmacs/misc/themes/liii.css | 28 ---------------- src/Plugins/Qt/QTMTabPage.cpp | 52 ++++++++++++++++-------------- src/Plugins/Qt/qt_tm_widget.cpp | 25 ++------------ 4 files changed, 30 insertions(+), 103 deletions(-) diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 2e7d19a0ef..1e0a8db9a2 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -354,11 +354,9 @@ QDockWidget::title { ****************************************************************************/ /* Tab Page 基础样式 */ QTMTabPage { - padding: 8px 12px; color: #FFFFFF; background-color: transparent; border: 1px solid transparent; - border-radius: 10px; } QTMTabPage:hover { @@ -370,7 +368,6 @@ QTMTabPage:checked { background-color: #333333; border: 1px solid #4c4c4c; border-bottom: none; - border-radius: 10px; color: #FFFFFF; } @@ -378,23 +375,9 @@ QTMTabPage QToolButton#tabpage-close-button { background-color: transparent; border: none; padding: 0; - margin-left: 6px; - border-radius: 4px; - min-width: 20px; - min-height: 20px; - max-width: 20px; - max-height: 20px; color: #ffffff; } -QTMTabPage QToolButton#tabpage-close-button[platform="mac"] { - min-width: 16px; - min-height: 16px; - max-width: 16px; - max-height: 16px; - font-size: 12pt; -} - QTMTabPage QToolButton#tabpage-close-button:hover { background-color: #E81123; color: #FFFFFF; @@ -409,17 +392,6 @@ QTMTabPageContainer QToolButton#add-tab-button { border: none; color: #FFFFFF; font-weight: bold; - border-radius: 6px; - padding: 0; - font-size: 12pt; -} - -QTMTabPageContainer QToolButton#add-tab-button[platform="mac"] { - min-width: 20px; - min-height: 20px; - max-width: 20px; - max-height: 20px; - font-size: 11pt; } QTMTabPageContainer QToolButton#add-tab-button:hover { diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index c468bca980..0608165ec6 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -344,11 +344,9 @@ QDockWidget::title { ****************************************************************************/ /* Tab Page 基础样式 */ QTMTabPage { - padding: 8px 12px; color: #000000; background-color: transparent; border: 1px solid transparent; - border-radius: 10px; } QTMTabPage:hover { @@ -360,27 +358,12 @@ QTMTabPage:checked { background-color: #FFFFFF; border: 1px solid #CFCFCF; border-bottom: none; - border-radius: 10px; } QTMTabPage QToolButton#tabpage-close-button { background-color: transparent; border: none; padding: 0; - margin-left: 6px; - border-radius: 4px; - min-width: 20px; - min-height: 20px; - max-width: 20px; - max-height: 20px; -} - -QTMTabPage QToolButton#tabpage-close-button[platform="mac"] { - min-width: 16px; - min-height: 16px; - max-width: 16px; - max-height: 16px; - font-size: 12pt; } QTMTabPage QToolButton#tabpage-close-button:hover { @@ -397,17 +380,6 @@ QTMTabPageContainer QToolButton#add-tab-button { border: none; color: #2c2c2c; font-weight: bold; - border-radius: 6px; - padding: 0; - font-size: 12pt; -} - -QTMTabPageContainer QToolButton#add-tab-button[platform="mac"] { - min-width: 20px; - min-height: 20px; - max-width: 20px; - max-height: 20px; - font-size: 11pt; } QTMTabPageContainer QToolButton#add-tab-button:hover { diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index d28bb84730..9c4956b28c 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -19,7 +19,7 @@ // Base tab widths constexpr int MAX_TAB_PAGE_WIDTH_BASE = 150; constexpr int MIN_TAB_PAGE_WIDTH_BASE = 25; -constexpr int STARTUP_TAB_MAX_WIDTH_BASE= 100; +constexpr int STARTUP_TAB_MAX_WIDTH_BASE= 90; // The horizontal padding for tab container (in pixels). #ifdef Q_OS_MAC @@ -28,15 +28,9 @@ const int TAB_CONTAINER_PADDING= 75; const int TAB_CONTAINER_PADDING= 0; #endif -#ifdef Q_OS_MAC -constexpr int TAB_CONTENT_VERTICAL_OFFSET = 4.5; -constexpr int ADD_TAB_BUTTON_VERTICAL_OFFSET= 4; -constexpr int TAB_RIGHT_EXTRA_GAP = 0; -#else constexpr int TAB_CONTENT_VERTICAL_OFFSET = 0; constexpr int ADD_TAB_BUTTON_VERTICAL_OFFSET= 0; constexpr int TAB_RIGHT_EXTRA_GAP = 66; -#endif // DPI scaling utility functions (使用 DpiUtils) static double @@ -61,31 +55,19 @@ getScaledStartupTabMaxWidth () { static int getScaledSystemBarHeight () { -#ifdef Q_OS_MAC - constexpr int baseHeight= 22; -#else constexpr int baseHeight= 36; -#endif return int (baseHeight * getDPIScaleFactor ()); } static int getScaledSystemButtonHeight () { -#ifdef Q_OS_MAC - constexpr int baseHeight= 15; -#else constexpr int baseHeight= 24; -#endif return int (baseHeight * getDPIScaleFactor ()); } static QSize getScaledTabCloseButtonSize () { -#ifdef Q_OS_MAC - constexpr int baseSize= 12; -#else constexpr int baseSize= 20; -#endif int side= qMax (baseSize, int (baseSize * getDPIScaleFactor ())); return QSize (side, side); } @@ -143,6 +125,14 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, setDefaultAction (p_title); setFocusPolicy (Qt::NoFocus); initializeCloseButton (); + int padY= DpiUtils::scaled (8); + int padX= DpiUtils::scaled (12); + int radius= DpiUtils::scaled (10); + setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") + .arg (padY) + .arg (padX) + .arg (radius)); + DpiUtils::applyScaledFont (this, 14); m_closeBtn->setDefaultAction (p_closeBtn); connect (m_closeBtn, &QToolButton::clicked, this, [=] () { g_mostRecentlyClosedTab= m_viewUrl; }); @@ -151,6 +141,14 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { setFocusPolicy (Qt::NoFocus); initializeCloseButton (); + int padY= DpiUtils::scaled (8); + int padX= DpiUtils::scaled (12); + int radius= DpiUtils::scaled (10); + setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") + .arg (padY) + .arg (padX) + .arg (radius)); + DpiUtils::applyScaledFont (this, 14); } void @@ -158,13 +156,16 @@ QTMTabPage::initializeCloseButton () { m_closeBtn= new QToolButton (this); m_closeBtn->setObjectName ("tabpage-close-button"); m_closeBtn->setFocusPolicy (Qt::NoFocus); -#ifdef Q_OS_MAC - m_closeBtn->setProperty ("platform", "mac"); -#endif const QSize closeBtnSize= getScaledTabCloseButtonSize (); m_closeBtn->setFixedSize (closeBtnSize); const int closeIconSide= qMax (closeBtnSize.width () - 4, 8); m_closeBtn->setIconSize (QSize (closeIconSide, closeIconSide)); + int marginLeft= DpiUtils::scaled (6); + int btnRadius= DpiUtils::scaled (4); + m_closeBtn->setStyleSheet ( + QString ("margin-left: %1px; border-radius: %2px;") + .arg (marginLeft) + .arg (btnRadius)); updateCloseButtonVisibility (); } @@ -335,9 +336,10 @@ QTMTabPageContainer::QTMTabPageContainer (QWidget* p_parent) m_addTabButton->setMinimumSize (addButtonSide, addButtonSide); m_addTabButton->setFixedSize (addButtonSide, addButtonSide); m_addTabButton->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); -#ifdef Q_OS_MAC - m_addTabButton->setProperty ("platform", "mac"); -#endif + int addBtnRadius= DpiUtils::scaled (6); + m_addTabButton->setStyleSheet ( + QString ("border-radius: %1px; padding: 0px;").arg (addBtnRadius)); + DpiUtils::applyScaledFont (m_addTabButton, 16); connect (m_addTabButton, &QToolButton::clicked, this, &QTMTabPageContainer::onAddTabClicked); m_addTabButton->hide (); diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index f2f8cfc559..968487fe91 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -229,8 +229,7 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) int titleBarHeight= int (32 * scale); int buttonWidth = int (46 * scale); int buttonHeight = int (32 * scale); - int iconBaseSize = int (12 * scale); - int macosiconSize = int (20 * scale); + int iconBaseSize = DpiUtils::scaled (12); #if defined(Q_OS_MAC) // 无边框布局(macOS)- 只显示登录按钮 @@ -348,11 +347,7 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) loginButton->setFocusPolicy (Qt::NoFocus); loginButton->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); loginButton->setFixedSize (buttonWidth, buttonHeight); -#if defined(Q_OS_MAC) - loginButton->setIconSize (QSize (macosiconSize, macosiconSize)); -#else loginButton->setIconSize (QSize (iconBaseSize, iconBaseSize)); -#endif loginButton->setIconNormal (QIcon (":/window-bar/login.svg")); loginButton->setObjectName ("login-button"); loginButton->setProperty ("system-button", true); @@ -590,12 +585,8 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) // NOTICE: setFixedHeight must be after setIconSize // TODO: the size of the toolbar should be calculated dynamically { - double scale = retina_scale; - int h = (int) floor (36 * scale + 0.5); + int h = DpiUtils::scaled (36); int tabRowHeight= h; -#ifdef Q_OS_MAC - tabRowHeight= (int) floor (30 * scale + 0.5); -#endif // 工具栏高度相等 mainToolBar->setFixedHeight (h); @@ -2045,12 +2036,7 @@ qt_tm_widget_rep::setupLoginDialog (QWK::LoginDialog* loginDialog) { infoLayout->setSpacing (4); // 登出按钮 - 登录成功后显示(使用图标) - const double logoutScale= DpiUtils::scaleFactor (); -#if defined(Q_OS_MAC) - const int logoutIconSize= int (30 * logoutScale); -#else - const int logoutIconSize= int (20 * logoutScale); -#endif + const int logoutIconSize= DpiUtils::scaled (20); logoutButton= new QPushButton (); logoutButton->setObjectName ("logout-button"); logoutButton->setIcon (QIcon (":/window-bar/logout.svg")); @@ -2491,13 +2477,8 @@ qt_tm_widget_rep::updateLoginButtonState (bool isLoggedIn, if (!isLoggedIn) { label= qt_translate ("Not logged in"); } -#if defined(Q_OS_MAC) - loginButton->setIconSize ( - QSize (DpiUtils::scaled (20), DpiUtils::scaled (20))); -#else loginButton->setIconSize ( QSize (DpiUtils::scaled (12), DpiUtils::scaled (12))); -#endif // 已登录时不设置文字,只显示图标 QFontMetrics metrics (loginButton->font ()); From 80d287c6db3dee713ee0757ecc707820f343d189 Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 12:54:34 +0800 Subject: [PATCH 3/9] wip --- src/Plugins/Qt/qt_tm_widget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index 968487fe91..e0b846c59e 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -229,14 +229,14 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) int titleBarHeight= int (32 * scale); int buttonWidth = int (46 * scale); int buttonHeight = int (32 * scale); - int iconBaseSize = DpiUtils::scaled (12); + int iconBaseSize = int (12 * scale); #if defined(Q_OS_MAC) // 无边框布局(macOS)- 只显示登录按钮 Q_INIT_RESOURCE (styles); QWK::WindowBar* windowBar= nullptr; windowAgent = nullptr; - setupWindowBar (windowBar, windowAgent, /*minHeight*/ 20, + setupWindowBar (windowBar, windowAgent, /*minHeight*/ titleBarHeight, /*setSafeArea*/ true); #elif defined(Q_OS_WIN) || defined(Q_OS_LINUX) // 无边框布局(Windows / Linux),并使用 /styles 资源中的图标 From bcdc7ed2c5edad4d7238a144e2de85082d6b11cb Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 13:58:10 +0800 Subject: [PATCH 4/9] wip --- TeXmacs/misc/images/images.qrc | 6 +++ TeXmacs/misc/images/tabpage/add-white.svg | 1 + TeXmacs/misc/images/tabpage/add.svg | 1 + TeXmacs/misc/images/tabpage/close-white.svg | 1 + TeXmacs/misc/images/tabpage/close.svg | 1 + TeXmacs/misc/themes/liii-night.css | 20 ++++---- TeXmacs/misc/themes/liii.css | 19 ++++---- TeXmacs/progs/texmacs/menus/tabpage-menu.scm | 2 +- src/Plugins/Qt/QTMTabPage.cpp | 51 ++++++++------------ src/Plugins/Qt/QTMTabPage.hpp | 9 ++-- src/Plugins/Qt/qt_tm_widget.cpp | 6 +-- 11 files changed, 58 insertions(+), 59 deletions(-) create mode 100644 TeXmacs/misc/images/tabpage/add-white.svg create mode 100644 TeXmacs/misc/images/tabpage/add.svg create mode 100644 TeXmacs/misc/images/tabpage/close-white.svg create mode 100644 TeXmacs/misc/images/tabpage/close.svg diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index a6e2005f9b..8275fcccb2 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -5,6 +5,9 @@ ocr-button/right-align.svg ocr-button/ocr.svg + tabpage/add.svg + tabpage/close.svg + ocr-button/left-align-white.svg @@ -12,6 +15,9 @@ ocr-button/right-align-white.svg ocr-button/ocr-white.svg + tabpage/add-white.svg + tabpage/close-white.svg + tutorial/ocr-tutorial.gif tutorial/magic-paste-tutorial.gif diff --git a/TeXmacs/misc/images/tabpage/add-white.svg b/TeXmacs/misc/images/tabpage/add-white.svg new file mode 100644 index 0000000000..601b5477cb --- /dev/null +++ b/TeXmacs/misc/images/tabpage/add-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TeXmacs/misc/images/tabpage/add.svg b/TeXmacs/misc/images/tabpage/add.svg new file mode 100644 index 0000000000..d4b340345e --- /dev/null +++ b/TeXmacs/misc/images/tabpage/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TeXmacs/misc/images/tabpage/close-white.svg b/TeXmacs/misc/images/tabpage/close-white.svg new file mode 100644 index 0000000000..03a88d0a22 --- /dev/null +++ b/TeXmacs/misc/images/tabpage/close-white.svg @@ -0,0 +1 @@ + diff --git a/TeXmacs/misc/images/tabpage/close.svg b/TeXmacs/misc/images/tabpage/close.svg new file mode 100644 index 0000000000..e3182e3e6b --- /dev/null +++ b/TeXmacs/misc/images/tabpage/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 1e0a8db9a2..20bba9714a 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -371,34 +371,32 @@ QTMTabPage:checked { color: #FFFFFF; } -QTMTabPage QToolButton#tabpage-close-button { +QTMTabPage QPushButton#tabpage-close-button { background-color: transparent; border: none; - padding: 0; - color: #ffffff; + qproperty-iconNormal: url(":/tabpage/close-white.svg"); + qproperty-iconHovered: url(":/tabpage/close-white.svg"); } -QTMTabPage QToolButton#tabpage-close-button:hover { +QTMTabPage QPushButton#tabpage-close-button:hover { background-color: #E81123; - color: #FFFFFF; } -QTMTabPage QToolButton#tabpage-close-button:pressed { +QTMTabPage QPushButton#tabpage-close-button:pressed { background-color: #C50F1F; } -QTMTabPageContainer QToolButton#add-tab-button { +QTMTabPageContainer QPushButton#add-tab-button { background-color: transparent; border: none; - color: #FFFFFF; - font-weight: bold; + qproperty-iconNormal: url(":/tabpage/add-white.svg"); } -QTMTabPageContainer QToolButton#add-tab-button:hover { +QTMTabPageContainer QPushButton#add-tab-button:hover { background-color: rgba(255, 255, 255, 0.06); } -QTMTabPageContainer QToolButton#add-tab-button:pressed { +QTMTabPageContainer QPushButton#add-tab-button:pressed { background-color: rgba(255, 255, 255, 0.10); } diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 0608165ec6..38fb498c30 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -360,33 +360,32 @@ QTMTabPage:checked { border-bottom: none; } -QTMTabPage QToolButton#tabpage-close-button { +QTMTabPage QPushButton#tabpage-close-button { background-color: transparent; border: none; - padding: 0; + qproperty-iconNormal: url(":/tabpage/close.svg"); + qproperty-iconHovered: url(":/tabpage/close-white.svg"); } -QTMTabPage QToolButton#tabpage-close-button:hover { +QTMTabPage QPushButton#tabpage-close-button:hover { background-color: #E81123; - color: #FFFFFF; } -QTMTabPage QToolButton#tabpage-close-button:pressed { +QTMTabPage QPushButton#tabpage-close-button:pressed { background-color: #C50F1F; } -QTMTabPageContainer QToolButton#add-tab-button { +QTMTabPageContainer QPushButton#add-tab-button { background-color: transparent; border: none; - color: #2c2c2c; - font-weight: bold; + qproperty-iconNormal: url(":/tabpage/add.svg"); } -QTMTabPageContainer QToolButton#add-tab-button:hover { +QTMTabPageContainer QPushButton#add-tab-button:hover { background-color: rgba(0, 0, 0, 0.08); } -QTMTabPageContainer QToolButton#add-tab-button:pressed { +QTMTabPageContainer QPushButton#add-tab-button:pressed { background-color: rgba(0, 0, 0, 0.12); } diff --git a/TeXmacs/progs/texmacs/menus/tabpage-menu.scm b/TeXmacs/progs/texmacs/menus/tabpage-menu.scm index 8900dc546f..9546de6880 100644 --- a/TeXmacs/progs/texmacs/menus/tabpage-menu.scm +++ b/TeXmacs/progs/texmacs/menus/tabpage-menu.scm @@ -45,6 +45,6 @@ ((balloon (eval `(verbatim ,tab-title)) (eval `(verbatim ,doc-path))) (window-set-view view-win view #t)) ;; #t stansd for focus - ((balloon "✕" "Close") (safely-kill-tabpage-by-url view-win view buf)) + ((balloon "" "Close") (safely-kill-tabpage-by-url view-win view buf)) (eval active?) )))) diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 9c4956b28c..79002308e3 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -65,13 +65,6 @@ getScaledSystemButtonHeight () { return int (baseHeight * getDPIScaleFactor ()); } -static QSize -getScaledTabCloseButtonSize () { - constexpr int baseSize= 20; - int side= qMax (baseSize, int (baseSize * getDPIScaleFactor ())); - return QSize (side, side); -} - /** * What is g_mostRecentlyClosedTab used for? When we close an ACTIVE(!) tab * (let's denote it as T), the tab bar is refreshed twice, meaning that @@ -124,25 +117,22 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, p_title->setChecked (p_isActive); setDefaultAction (p_title); setFocusPolicy (Qt::NoFocus); - initializeCloseButton (); - int padY= DpiUtils::scaled (8); - int padX= DpiUtils::scaled (12); + initializeCloseButton (p_closeBtn); + int padY = DpiUtils::scaled (8); + int padX = DpiUtils::scaled (12); int radius= DpiUtils::scaled (10); setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") .arg (padY) .arg (padX) .arg (radius)); DpiUtils::applyScaledFont (this, 14); - m_closeBtn->setDefaultAction (p_closeBtn); - connect (m_closeBtn, &QToolButton::clicked, this, - [=] () { g_mostRecentlyClosedTab= m_viewUrl; }); } QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { setFocusPolicy (Qt::NoFocus); initializeCloseButton (); - int padY= DpiUtils::scaled (8); - int padX= DpiUtils::scaled (12); + int padY = DpiUtils::scaled (8); + int padX = DpiUtils::scaled (12); int radius= DpiUtils::scaled (10); setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") .arg (padY) @@ -152,20 +142,23 @@ QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { } void -QTMTabPage::initializeCloseButton () { - m_closeBtn= new QToolButton (this); +QTMTabPage::initializeCloseButton (QAction* closeAction) { + m_closeBtn= new QWK::WindowButton (this); m_closeBtn->setObjectName ("tabpage-close-button"); m_closeBtn->setFocusPolicy (Qt::NoFocus); - const QSize closeBtnSize= getScaledTabCloseButtonSize (); - m_closeBtn->setFixedSize (closeBtnSize); - const int closeIconSide= qMax (closeBtnSize.width () - 4, 8); - m_closeBtn->setIconSize (QSize (closeIconSide, closeIconSide)); - int marginLeft= DpiUtils::scaled (6); - int btnRadius= DpiUtils::scaled (4); + int closeBtnSize= getScaledSystemButtonHeight (); + m_closeBtn->setMinimumSize (closeBtnSize, closeBtnSize); + m_closeBtn->setFixedSize (closeBtnSize, closeBtnSize); + m_closeBtn->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + int closeBtnRadius= DpiUtils::scaled (6); m_closeBtn->setStyleSheet ( - QString ("margin-left: %1px; border-radius: %2px;") - .arg (marginLeft) - .arg (btnRadius)); + QString ("border-radius: %1px; padding: 0px;").arg (closeBtnRadius)); + if (closeAction) { + connect (m_closeBtn, &QPushButton::clicked, this, [=] () { + g_mostRecentlyClosedTab= m_viewUrl; + closeAction->trigger (); + }); + } updateCloseButtonVisibility (); } @@ -329,9 +322,8 @@ QTMTabPageContainer::QTMTabPageContainer (QWidget* p_parent) dummyTabPage->hide (); // 创建新增标签页按钮 - m_addTabButton= new QToolButton (this); + m_addTabButton= new QWK::WindowButton (this); m_addTabButton->setObjectName ("add-tab-button"); - m_addTabButton->setText ("+"); int addButtonSide= getScaledSystemButtonHeight (); m_addTabButton->setMinimumSize (addButtonSide, addButtonSide); m_addTabButton->setFixedSize (addButtonSide, addButtonSide); @@ -339,8 +331,7 @@ QTMTabPageContainer::QTMTabPageContainer (QWidget* p_parent) int addBtnRadius= DpiUtils::scaled (6); m_addTabButton->setStyleSheet ( QString ("border-radius: %1px; padding: 0px;").arg (addBtnRadius)); - DpiUtils::applyScaledFont (m_addTabButton, 16); - connect (m_addTabButton, &QToolButton::clicked, this, + connect (m_addTabButton, &QPushButton::clicked, this, &QTMTabPageContainer::onAddTabClicked); m_addTabButton->hide (); diff --git a/src/Plugins/Qt/QTMTabPage.hpp b/src/Plugins/Qt/QTMTabPage.hpp index 76c6f5186a..5f682d3b64 100644 --- a/src/Plugins/Qt/QTMTabPage.hpp +++ b/src/Plugins/Qt/QTMTabPage.hpp @@ -11,6 +11,7 @@ #ifndef QTMTABPAGE_HPP #define QTMTABPAGE_HPP +#include "windowbutton.hpp" #include #include #include @@ -29,8 +30,8 @@ */ class QTMTabPage : public QToolButton { Q_OBJECT - QToolButton* m_closeBtn; - QPoint m_dragStartPos; + QWK::WindowButton* m_closeBtn; + QPoint m_dragStartPos; public: const url m_viewUrl; @@ -54,7 +55,7 @@ public slots: private: void updateCloseButtonVisibility (); - void initializeCloseButton (); + void initializeCloseButton (QAction* closeAction= nullptr); }; /*! QTMTabPageAction is used as a carrier of QTMTabPage widget. @@ -86,7 +87,7 @@ class QTMTabPageContainer : public QWidget { int m_width= 0; bool dragging; QPoint dragPosition; - QToolButton* m_addTabButton; + QWK::WindowButton* m_addTabButton; public: QTMTabPage* dummyTabPage; diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index e0b846c59e..14c30c7341 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -585,8 +585,8 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) // NOTICE: setFixedHeight must be after setIconSize // TODO: the size of the toolbar should be calculated dynamically { - int h = DpiUtils::scaled (36); - int tabRowHeight= h; + int h = DpiUtils::scaled (36); + int tabRowHeight= h; // 工具栏高度相等 mainToolBar->setFixedHeight (h); @@ -2037,7 +2037,7 @@ qt_tm_widget_rep::setupLoginDialog (QWK::LoginDialog* loginDialog) { // 登出按钮 - 登录成功后显示(使用图标) const int logoutIconSize= DpiUtils::scaled (20); - logoutButton= new QPushButton (); + logoutButton = new QPushButton (); logoutButton->setObjectName ("logout-button"); logoutButton->setIcon (QIcon (":/window-bar/logout.svg")); logoutButton->setToolTip (qt_translate ("Logout")); From 760f366287d771df1d2cf417d19d1caede95994d Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 14:28:21 +0800 Subject: [PATCH 5/9] =?UTF-8?q?wip=E3=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/themes/liii-night.css | 1 - TeXmacs/misc/themes/liii.css | 1 - src/Plugins/Qt/QTMTabPage.cpp | 35 ++++++++++-------------------- src/Plugins/Qt/QTMTabPage.hpp | 1 + src/Plugins/Qt/qt_tm_widget.cpp | 2 +- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 20bba9714a..2d893d8dc9 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -367,7 +367,6 @@ QTMTabPage:hover { QTMTabPage:checked { background-color: #333333; border: 1px solid #4c4c4c; - border-bottom: none; color: #FFFFFF; } diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 38fb498c30..f6a4bce6a7 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -357,7 +357,6 @@ QTMTabPage:hover { QTMTabPage:checked { background-color: #FFFFFF; border: 1px solid #CFCFCF; - border-bottom: none; } QTMTabPage QPushButton#tabpage-close-button { diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 79002308e3..1d88ed2d99 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -3,6 +3,7 @@ * MODULE : QTMTabPage.cpp * DESCRIPTION: QT Texmacs tab page classes * COPYRIGHT : (C) 2024 Zhenjun Guo + * 2026 Yifan Lu ******************************************************************************* * This software falls under the GNU general public license version 3 or later. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE @@ -53,12 +54,6 @@ getScaledStartupTabMaxWidth () { return DpiUtils::scaled (STARTUP_TAB_MAX_WIDTH_BASE); } -static int -getScaledSystemBarHeight () { - constexpr int baseHeight= 36; - return int (baseHeight * getDPIScaleFactor ()); -} - static int getScaledSystemButtonHeight () { constexpr int baseHeight= 24; @@ -118,26 +113,20 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, setDefaultAction (p_title); setFocusPolicy (Qt::NoFocus); initializeCloseButton (p_closeBtn); - int padY = DpiUtils::scaled (8); - int padX = DpiUtils::scaled (12); + int pad = DpiUtils::scaled (8); int radius= DpiUtils::scaled (10); - setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") - .arg (padY) - .arg (padX) - .arg (radius)); + setStyleSheet ( + QString ("padding: %1px; border-radius: %3px;").arg (pad).arg (radius)); DpiUtils::applyScaledFont (this, 14); } QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { setFocusPolicy (Qt::NoFocus); initializeCloseButton (); - int padY = DpiUtils::scaled (8); - int padX = DpiUtils::scaled (12); + int pad = DpiUtils::scaled (8); int radius= DpiUtils::scaled (10); - setStyleSheet (QString ("padding: %1px %2px; border-radius: %3px;") - .arg (padY) - .arg (padX) - .arg (radius)); + setStyleSheet ( + QString ("padding: %1px; border-radius: %3px;").arg (pad).arg (radius)); DpiUtils::applyScaledFont (this, 14); } @@ -189,7 +178,7 @@ QTMTabPage::paintEvent (QPaintEvent*) { } int fontBoxH = fm.height (); - int centeredTop= (getScaledSystemBarHeight () - fontBoxH) / 2; + int centeredTop= (height () - fontBoxH) / 2; centeredTop+= TAB_CONTENT_VERTICAL_OFFSET; #ifdef Q_OS_WIN // Windows 上字体度量与控件背景的边距叠加,通常需要轻微上移 1px 以达到光学居中 @@ -213,7 +202,7 @@ QTMTabPage::resizeEvent (QResizeEvent* e) { int w= m_closeBtn->width (); int h= m_closeBtn->height (); int x= e->size ().width () - w - 12; - int y= (getScaledSystemBarHeight () - h) / 2; + int y= (height () - h) / 2; y+= TAB_CONTENT_VERTICAL_OFFSET; m_closeBtn->setGeometry (x, y, w, h); @@ -482,7 +471,7 @@ QTMTabPageContainer::arrangeTabPages () { int addButtonHeight= m_addTabButton->height (); int buttonX = accumWidth; // 调整按钮垂直位置,与系统按钮对齐 - int buttonY= (getScaledSystemBarHeight () - addButtonHeight) / 2; + int buttonY= (m_rowHeight - addButtonHeight) / 2; buttonY+= ADD_TAB_BUTTON_VERTICAL_OFFSET; m_addTabButton->setGeometry (buttonX, buttonY, addButtonWidth, addButtonHeight); @@ -496,7 +485,7 @@ QTMTabPageContainer::arrangeTabPages () { void QTMTabPageContainer::adjustHeight (int p_rowCount) { int h= m_rowHeight * (p_rowCount + 1); - setFixedHeight (h - 2); + setFixedHeight (h); } void @@ -697,7 +686,7 @@ QTMTabPageBar::resizeEvent (QResizeEvent* e) { // 确保容器使用全部可用宽度减去左边的留出的拖拽句柄空间 int availableWidth= size.width () - 7; if (availableWidth > 0 && m_container) { - m_container->setGeometry (7, 0, availableWidth, size.height () - 2); + m_container->setGeometry (7, 0, availableWidth, size.height ()); } } diff --git a/src/Plugins/Qt/QTMTabPage.hpp b/src/Plugins/Qt/QTMTabPage.hpp index 5f682d3b64..98183327c4 100644 --- a/src/Plugins/Qt/QTMTabPage.hpp +++ b/src/Plugins/Qt/QTMTabPage.hpp @@ -3,6 +3,7 @@ * MODULE : QTMTabPage.hpp * DESCRIPTION: QT Texmacs tab page classes * COPYRIGHT : (C) 2024 Zhenjun Guo + * 2026 Yifan Lu ******************************************************************************* * This software falls under the GNU general public license version 3 or later. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index 14c30c7341..56be08b34f 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -585,7 +585,7 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) // NOTICE: setFixedHeight must be after setIconSize // TODO: the size of the toolbar should be calculated dynamically { - int h = DpiUtils::scaled (36); + int h = DpiUtils::scaled (32); int tabRowHeight= h; // 工具栏高度相等 From 0ffa4b4130f95a9b2dba1822548308ab7b39bae4 Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 15:20:40 +0800 Subject: [PATCH 6/9] wip --- src/Plugins/Qt/QTMTabPage.cpp | 21 ++++++++++++++------- src/Plugins/Qt/qt_tm_widget.cpp | 10 +++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 1d88ed2d99..503e41c079 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -32,6 +32,8 @@ const int TAB_CONTAINER_PADDING= 0; constexpr int TAB_CONTENT_VERTICAL_OFFSET = 0; constexpr int ADD_TAB_BUTTON_VERTICAL_OFFSET= 0; constexpr int TAB_RIGHT_EXTRA_GAP = 66; +constexpr int ADD_BUTTON_SIZE = 20; +constexpr int CLOSE_BUTTON_SIZE = 18; // DPI scaling utility functions (使用 DpiUtils) static double @@ -55,9 +57,13 @@ getScaledStartupTabMaxWidth () { } static int -getScaledSystemButtonHeight () { - constexpr int baseHeight= 24; - return int (baseHeight * getDPIScaleFactor ()); +getScaledAddButtonHeight () { + return DpiUtils::scaled (ADD_BUTTON_SIZE); +} + +static int +getScaledCloseButtonHeight () { + return DpiUtils::scaled (CLOSE_BUTTON_SIZE); } /** @@ -135,7 +141,7 @@ QTMTabPage::initializeCloseButton (QAction* closeAction) { m_closeBtn= new QWK::WindowButton (this); m_closeBtn->setObjectName ("tabpage-close-button"); m_closeBtn->setFocusPolicy (Qt::NoFocus); - int closeBtnSize= getScaledSystemButtonHeight (); + int closeBtnSize= getScaledCloseButtonHeight (); m_closeBtn->setMinimumSize (closeBtnSize, closeBtnSize); m_closeBtn->setFixedSize (closeBtnSize, closeBtnSize); m_closeBtn->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); @@ -280,7 +286,8 @@ QTMTabPage::leaveEvent (QEvent* e) { void QTMTabPage::updateCloseButtonVisibility () { - bool shouldShow= !is_startup_tab_view (m_viewUrl); + bool shouldShow= + !is_startup_tab_view (m_viewUrl) && (underMouse () || isChecked ()); bool wasVisible= m_closeBtn->isVisible (); m_closeBtn->setVisible (shouldShow); @@ -313,7 +320,7 @@ QTMTabPageContainer::QTMTabPageContainer (QWidget* p_parent) // 创建新增标签页按钮 m_addTabButton= new QWK::WindowButton (this); m_addTabButton->setObjectName ("add-tab-button"); - int addButtonSide= getScaledSystemButtonHeight (); + int addButtonSide= getScaledAddButtonHeight (); m_addTabButton->setMinimumSize (addButtonSide, addButtonSide); m_addTabButton->setFixedSize (addButtonSide, addButtonSide); m_addTabButton->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); @@ -394,7 +401,7 @@ QTMTabPageContainer::arrangeTabPages () { parentWidget () ? parentWidget ()->width () : this->width (); // 动态计算右侧预留空间,防止标签页覆盖系统按钮 double scale = getDPIScaleFactor (); - int buttonWidth= int (46 * scale); // 按钮宽度 + int buttonWidth= int (60 * scale); // 按钮宽度 int buttonCount= 5; // pin, min, max, close,login #ifdef Q_OS_MAC buttonCount= 1; // macOS 仅保留 login diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index 56be08b34f..8543e2fc59 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -226,10 +226,10 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) }; double scale = DpiUtils::scaleFactor (); - int titleBarHeight= int (32 * scale); - int buttonWidth = int (46 * scale); - int buttonHeight = int (32 * scale); - int iconBaseSize = int (12 * scale); + int titleBarHeight= int (42 * scale); + int buttonWidth = int (60 * scale); + int buttonHeight = int (42 * scale); + int iconBaseSize = int (16 * scale); #if defined(Q_OS_MAC) // 无边框布局(macOS)- 只显示登录按钮 @@ -585,7 +585,7 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) // NOTICE: setFixedHeight must be after setIconSize // TODO: the size of the toolbar should be calculated dynamically { - int h = DpiUtils::scaled (32); + int h = DpiUtils::scaled (42); int tabRowHeight= h; // 工具栏高度相等 From ff29c904a271b8c9e37cd2d267e0833898a96105 Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 15:36:07 +0800 Subject: [PATCH 7/9] wip --- src/Plugins/Qt/QTMTabPage.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 503e41c079..7498cc0109 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -18,9 +18,13 @@ #include // Base tab widths -constexpr int MAX_TAB_PAGE_WIDTH_BASE = 150; -constexpr int MIN_TAB_PAGE_WIDTH_BASE = 25; +constexpr int MAX_TAB_PAGE_WIDTH_BASE= 150; +constexpr int MIN_TAB_PAGE_WIDTH_BASE= 25; +#ifdef IS_COMMUNITY +constexpr int STARTUP_TAB_MAX_WIDTH_BASE= 120; +#else constexpr int STARTUP_TAB_MAX_WIDTH_BASE= 90; +#endif // The horizontal padding for tab container (in pixels). #ifdef Q_OS_MAC @@ -183,23 +187,18 @@ QTMTabPage::paintEvent (QPaintEvent*) { rightPadding = width () - leftPadding - availableWidth; } - int fontBoxH = fm.height (); - int centeredTop= (height () - fontBoxH) / 2; - centeredTop+= TAB_CONTENT_VERTICAL_OFFSET; -#ifdef Q_OS_WIN - // Windows 上字体度量与控件背景的边距叠加,通常需要轻微上移 1px 以达到光学居中 - const int opticalAdjust= -1; -#else - const int opticalAdjust= 0; -#endif - centeredTop+= opticalAdjust; - - QRect textRect (leftPadding, qMax (0, centeredTop), availableWidth, fontBoxH); - // 使用省略号来处理过长的文字 QString elidedText= fm.elidedText (text (), Qt::ElideRight, availableWidth); - p.drawItemText (textRect, Qt::AlignLeft | Qt::AlignVCenter, palette (), + bool isStartup= is_startup_tab_view (m_viewUrl); + int textAlign= isStartup ? Qt::AlignCenter : Qt::AlignLeft; + + QRect textRect (leftPadding, 0, availableWidth, height ()); + if (isStartup) { + textRect= QRect (0, 0, width (), height ()); + } + + p.drawItemText (textRect, textAlign | Qt::AlignVCenter, palette (), isEnabled (), elidedText, QPalette::ButtonText); } From 6e7153afb6e76fd67ca826640a98048fe8fcf164 Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 15:48:41 +0800 Subject: [PATCH 8/9] wip --- src/Plugins/Qt/QTMTabPage.cpp | 4 ++-- src/Plugins/Qt/qt_tm_widget.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 7498cc0109..4eeb2cfd99 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -126,7 +126,7 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, int pad = DpiUtils::scaled (8); int radius= DpiUtils::scaled (10); setStyleSheet ( - QString ("padding: %1px; border-radius: %3px;").arg (pad).arg (radius)); + QString ("padding: %1px; border-radius: %2px;").arg (pad).arg (radius)); DpiUtils::applyScaledFont (this, 14); } @@ -136,7 +136,7 @@ QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { int pad = DpiUtils::scaled (8); int radius= DpiUtils::scaled (10); setStyleSheet ( - QString ("padding: %1px; border-radius: %3px;").arg (pad).arg (radius)); + QString ("padding: %1px; border-radius: %2px;").arg (pad).arg (radius)); DpiUtils::applyScaledFont (this, 14); } diff --git a/src/Plugins/Qt/qt_tm_widget.cpp b/src/Plugins/Qt/qt_tm_widget.cpp index 8543e2fc59..395ce46f02 100644 --- a/src/Plugins/Qt/qt_tm_widget.cpp +++ b/src/Plugins/Qt/qt_tm_widget.cpp @@ -585,8 +585,8 @@ qt_tm_widget_rep::qt_tm_widget_rep (int mask, command _quit) // NOTICE: setFixedHeight must be after setIconSize // TODO: the size of the toolbar should be calculated dynamically { - int h = DpiUtils::scaled (42); - int tabRowHeight= h; + int h = DpiUtils::scaled (32); + int tabRowHeight= DpiUtils::scaled (38); // 工具栏高度相等 mainToolBar->setFixedHeight (h); From 19786b020ace1f81193eb7e80a0e51e6c6f233c7 Mon Sep 17 00:00:00 2001 From: Yuki Date: Tue, 28 Apr 2026 17:38:18 +0800 Subject: [PATCH 9/9] devel --- devel/222_75.md | 78 +++++++++++++++++++++++++++++++++++ src/Plugins/Qt/QTMTabPage.cpp | 20 ++++----- src/Plugins/Qt/QTMTabPage.hpp | 6 +-- 3 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 devel/222_75.md diff --git a/devel/222_75.md b/devel/222_75.md new file mode 100644 index 0000000000..954261afd1 --- /dev/null +++ b/devel/222_75.md @@ -0,0 +1,78 @@ +# 222_75 TabPage UI 重构:统一跨平台样式并引入 SVG 图标 + +## 如何测试 + +1. 编译:`xmake b stem` +2. 启动 Mogan,确认标签页栏(TabPage Bar)视觉正常。 +3. 确认关闭按钮和添加按钮显示为 SVG 图标(`×` 和 `+`),而非文字或原生按钮。 +4. 确认关闭按钮仅在鼠标 Hover 或标签处于选中状态时显示,移出后隐藏。 +5. 确认启动页(Startup Tab)标签文字居中对齐。 +6. 分别验证亮色/暗色主题下图标颜色正常(亮色主题关闭按钮 hover 变红,暗色主题图标为白色)。 +7. 验证标签页拖拽排序功能正常。 +8. 分别测试 macOS / Windows / Linux 下的标签页高度和按钮尺寸一致性。 + +## 2026/04/28 实现说明 + +### What + +对 TabPage 组件进行全面 UI 重构,将关闭按钮和添加按钮从 `QToolButton` 迁移到 `QWK::WindowButton`,引入 SVG 图标资源,并彻底移除 macOS / Windows / Linux 三平台硬编码差异,实现跨平台样式统一。 + +#### 修改文件 + +**src/Plugins/Qt/QTMTabPage.cpp / hpp** +- 关闭按钮 `m_closeBtn` 和添加按钮 `m_addTabButton` 类型从 `QToolButton*` 改为 `QWK::WindowButton*`。 +- 移除全部 `#ifdef Q_OS_MAC` 分支:包括 `TAB_CONTENT_VERTICAL_OFFSET`、`getScaledSystemBarHeight`、`getScaledSystemButtonHeight`、`getScaledTabCloseButtonSize` 等。 +- DPI 缩放统一使用 `DpiUtils::scaled()`,新增 `getScaledAddButtonHeight()` / `getScaledCloseButtonHeight()` 替代旧函数。 +- 新增 `ADD_BUTTON_SIZE = 20`、`CLOSE_BUTTON_SIZE = 18` 常量。 +- `STARTUP_TAB_MAX_WIDTH_BASE` 区分社区版(`IS_COMMUNITY`)和商业版:120 / 90。 +- 关闭按钮连接逻辑改为 `QPointer` 保护,防止 action 被释放后悬空触发。 +- `paintEvent` 中启动页标签文字改为 `Qt::AlignCenter`,普通标签保持 `Qt::AlignLeft`。 +- `updateCloseButtonVisibility` 增加条件:仅在 `underMouse() || isChecked()` 时显示关闭按钮。 +- 默认构造函数不再调用 `initializeCloseButton()`(`dummyTabPage` 不需要关闭按钮),并在所有访问 `m_closeBtn` 处补充空指针检查。 +- `m_closeBtn` 成员添加 `= nullptr` 默认初始化。 +- `enterEvent` 补充 `override` 关键字。 +- 移除未使用的全局变量 `g_hiddentTabIndex`。 +- `QTMTabPageContainer` 析构函数移除冗余的 `delete m_addTabButton`。 +- `arrangeTabPages` 中 `addButtonWidth` 语义修正:`height()` → `width()`。 + +**src/Plugins/Qt/qt_tm_widget.cpp** +- 标题栏高度统一为 `42 * scale`(macOS 原特殊值 20 移除)。 +- 系统按钮尺寸统一为 `60 * scale` 宽、`42 * scale` 高(移除 macOS 特殊逻辑)。 +- 图标基础尺寸统一为 `16 * scale`(macOS 原特殊值 20 移除)。 +- 工具栏高度统一为 `DpiUtils::scaled(32)`,tab row 高度统一为 `DpiUtils::scaled(38)`(移除 macOS 特殊值 30)。 +- 登录按钮图标尺寸统一为 `12`(macOS 原特殊值 20 移除)。 +- 登出按钮图标尺寸统一为 `20`(macOS 原特殊值 30 移除)。 + +**TeXmacs/misc/themes/liii.css / liii-night.css** +- `QTMTabPage` 移除硬编码 `padding`、`border-radius` 和 `border-bottom: none`,改为由 C++ 动态计算。 +- 关闭按钮和添加按钮选择器从 `QToolButton` 改为 `QPushButton`。 +- 移除全部 `[platform="mac"]` 规则。 +- 关闭按钮通过 `qproperty-iconNormal` / `qproperty-iconHovered` 设置图标(亮色:`close.svg` / `close-white.svg`;暗色:`close-white.svg`)。 +- 添加按钮通过 `qproperty-iconNormal` 设置图标(亮色:`add.svg`;暗色:`add-white.svg`)。 +- 移除关闭按钮的 `min-width`、`max-width`、`margin-left` 等硬编码尺寸。 +- 移除添加按钮的 `font-weight: bold`、`font-size`、`color` 等文字样式。 + +**TeXmacs/misc/images/images.qrc** +- 新增 4 个 SVG 资源文件:`tabpage/add.svg`、`tabpage/close.svg`、`tabpage/add-white.svg`、`tabpage/close-white.svg`。 + +**TeXmacs/misc/images/tabpage/*.svg** +- 新增 4 个 SVG 图标文件,基于 48×48 viewBox,提供亮色/暗色两版。 + +**TeXmacs/progs/texmacs/menus/tabpage-menu.scm** +- 关闭按钮文字从 `"✕"` 改为 `""`(空字符串),因为图标已由 CSS/C++ 接管。 + +### Why + +1. **跨平台统一**:旧代码中 macOS 拥有大量独立分支(标题栏高度、按钮尺寸、字体大小等),维护成本高且视觉不一致。统一后三平台代码完全一致。 +2. **图标化**:关闭按钮和添加按钮从纯文字(`✕`、`+`)升级为 SVG 图标,视觉更现代,且支持亮色/暗色主题自动切换。 +3. **样式解耦**:将 `padding`、`border-radius` 等从 CSS 硬编码移至 C++ 动态计算(通过 `DpiUtils::scaled()`),确保高 DPI 下尺寸正确。 +4. **交互优化**:关闭按钮仅在需要时显示(hover/选中),减少标签页视觉噪音,更接近现代浏览器标签页体验。 +5. **安全性**:`QPointer` 防护避免 action 生命周期问题;空指针检查使 `dummyTabPage` 不初始化关闭按钮的逻辑更安全。 + +### How + +- 引入 `QWK::WindowButton`(已存在于项目中,用于系统标题栏按钮)替代 `QToolButton`,复用其 `iconNormal` / `iconHovered` 属性支持。 +- 新增 `tabpage/` SVG 资源目录,通过 `.qrc` 编译进二进制。 +- CSS 中通过 `qproperty-*` 语法将图标路径与按钮绑定。 +- 全面替换 `int (base * getDPIScaleFactor())` 为 `DpiUtils::scaled(base)`,消除浮点截断误差。 +- 移除 `dummyTabPage` 的关闭按钮初始化,并在所有 `m_closeBtn` 访问点做空指针守卫。 diff --git a/src/Plugins/Qt/QTMTabPage.cpp b/src/Plugins/Qt/QTMTabPage.cpp index 4eeb2cfd99..1bf7bb39ce 100644 --- a/src/Plugins/Qt/QTMTabPage.cpp +++ b/src/Plugins/Qt/QTMTabPage.cpp @@ -86,7 +86,6 @@ getScaledCloseButtonHeight () { */ int g_tabWidth = -1; int g_pointingIndex = -1; -int g_hiddentTabIndex = -1; url g_mostRecentlyClosedTab = url_none (); url g_mostRecentlyDraggedTab= url_none (); QTMTabPageContainer* g_mostRecentlyDraggedBar= nullptr; @@ -132,7 +131,6 @@ QTMTabPage::QTMTabPage (url p_url, QAction* p_title, QAction* p_closeBtn, QTMTabPage::QTMTabPage () : m_viewUrl (url_none ()) { setFocusPolicy (Qt::NoFocus); - initializeCloseButton (); int pad = DpiUtils::scaled (8); int radius= DpiUtils::scaled (10); setStyleSheet ( @@ -153,9 +151,11 @@ QTMTabPage::initializeCloseButton (QAction* closeAction) { m_closeBtn->setStyleSheet ( QString ("border-radius: %1px; padding: 0px;").arg (closeBtnRadius)); if (closeAction) { + QPointer safeAction (closeAction); connect (m_closeBtn, &QPushButton::clicked, this, [=] () { + if (!safeAction) return; g_mostRecentlyClosedTab= m_viewUrl; - closeAction->trigger (); + safeAction->trigger (); }); } updateCloseButtonVisibility (); @@ -176,7 +176,7 @@ QTMTabPage::paintEvent (QPaintEvent*) { // 计算可用的文字绘制区域,需要排除关闭按钮的空间 int leftPadding = 10; - int rightPadding = m_closeBtn->isVisible () + int rightPadding = (m_closeBtn && m_closeBtn->isVisible ()) ? m_closeBtn->width () + 12 : 12; // 如果关闭按钮可见,留出更多空间 int availableWidth= width () - leftPadding - rightPadding; @@ -204,6 +204,7 @@ QTMTabPage::paintEvent (QPaintEvent*) { void QTMTabPage::resizeEvent (QResizeEvent* e) { + if (!m_closeBtn) return; int w= m_closeBtn->width (); int h= m_closeBtn->height (); int x= e->size ().width () - w - 12; @@ -285,6 +286,7 @@ QTMTabPage::leaveEvent (QEvent* e) { void QTMTabPage::updateCloseButtonVisibility () { + if (!m_closeBtn) return; bool shouldShow= !is_startup_tab_view (m_viewUrl) && (underMouse () || isChecked ()); bool wasVisible= m_closeBtn->isVisible (); @@ -338,13 +340,7 @@ QTMTabPageContainer::QTMTabPageContainer (QWidget* p_parent) setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred); } -QTMTabPageContainer::~QTMTabPageContainer () { - removeAllTabPages (); - if (m_addTabButton) { - delete m_addTabButton; - m_addTabButton= nullptr; - } -} +QTMTabPageContainer::~QTMTabPageContainer () { removeAllTabPages (); } void QTMTabPageContainer::replaceTabPages (QList* p_src) { @@ -473,7 +469,7 @@ QTMTabPageContainer::arrangeTabPages () { // 设置新增标签页按钮的位置 if (m_addTabButton) { // 将按钮放在最后一个标签页的后面 - int addButtonWidth = m_addTabButton->height (); + int addButtonWidth = m_addTabButton->width (); int addButtonHeight= m_addTabButton->height (); int buttonX = accumWidth; // 调整按钮垂直位置,与系统按钮对齐 diff --git a/src/Plugins/Qt/QTMTabPage.hpp b/src/Plugins/Qt/QTMTabPage.hpp index 98183327c4..64a61c88cf 100644 --- a/src/Plugins/Qt/QTMTabPage.hpp +++ b/src/Plugins/Qt/QTMTabPage.hpp @@ -31,7 +31,7 @@ */ class QTMTabPage : public QToolButton { Q_OBJECT - QWK::WindowButton* m_closeBtn; + QWK::WindowButton* m_closeBtn= nullptr; QPoint m_dragStartPos; public: @@ -50,8 +50,7 @@ public slots: virtual void resizeEvent (QResizeEvent* e) override; virtual void mousePressEvent (QMouseEvent* e) override; virtual void mouseMoveEvent (QMouseEvent* e) override; - virtual void - enterEvent (QEnterEvent* e); // 为了防止和QEvent冲突,不要override + virtual void enterEvent (QEnterEvent* e) override; virtual void leaveEvent (QEvent* e) override; private: @@ -145,7 +144,6 @@ class QTMTabPageBar : public QToolBar { // Global variables for tab page management extern int g_tabWidth; extern int g_pointingIndex; -extern int g_hiddentTabIndex; extern url g_mostRecentlyClosedTab; extern url g_mostRecentlyDraggedTab; extern QTMTabPageContainer* g_mostRecentlyDraggedBar;