Skip to content

Commit ba895ea

Browse files
committed
Debugger: Fix some theming issues
1 parent 59289ec commit ba895ea

8 files changed

+187
-17
lines changed

pcsx2-qt/Debugger/DebuggerWindow.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
114114

115115
setMenuWidget(m_dock_manager->createMenuBar(menu_bar));
116116

117+
updateTheme();
118+
117119
Host::RunOnCPUThread([]() {
118120
R5900SymbolImporter.OnDebuggerOpened();
119121
});
@@ -193,7 +195,7 @@ void DebuggerWindow::setupFonts()
193195
m_font_size++;
194196

195197
updateFontActions();
196-
updateStyleSheets();
198+
updateTheme();
197199
saveFontSize();
198200
});
199201

@@ -205,20 +207,19 @@ void DebuggerWindow::setupFonts()
205207
m_font_size--;
206208

207209
updateFontActions();
208-
updateStyleSheets();
210+
updateTheme();
209211
saveFontSize();
210212
});
211213

212214
connect(m_ui.actionResetFontSize, &QAction::triggered, this, [this]() {
213215
m_font_size = DEFAULT_FONT_SIZE;
214216

215217
updateFontActions();
216-
updateStyleSheets();
218+
updateTheme();
217219
saveFontSize();
218220
});
219221

220222
updateFontActions();
221-
updateStyleSheets();
222223
}
223224

224225
void DebuggerWindow::updateFontActions()
@@ -239,7 +240,7 @@ int DebuggerWindow::fontSize()
239240
return m_font_size;
240241
}
241242

242-
void DebuggerWindow::updateStyleSheets()
243+
void DebuggerWindow::updateTheme()
243244
{
244245
// TODO: Migrate away from stylesheets to improve performance.
245246
if (m_font_size != DEFAULT_FONT_SIZE)
@@ -252,7 +253,7 @@ void DebuggerWindow::updateStyleSheets()
252253
setStyleSheet(QString());
253254
}
254255

255-
dockManager().updateStyleSheets();
256+
dockManager().updateTheme();
256257
}
257258

258259
void DebuggerWindow::saveWindowGeometry()

pcsx2-qt/Debugger/DebuggerWindow.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class DebuggerWindow : public KDDockWidgets::QtWidgets::MainWindow
3131
void updateFontActions();
3232
void saveFontSize();
3333
int fontSize();
34-
void updateStyleSheets();
34+
void updateTheme();
3535

3636
void saveWindowGeometry();
3737
void restoreWindowGeometry();

pcsx2-qt/Debugger/Docking/DockManager.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <QtCore/QTimer>
2626
#include <QtCore/QtTranslation>
2727
#include <QtWidgets/QMessageBox>
28+
#include <QtWidgets/QProxyStyle>
29+
#include <QtWidgets/QStyleFactory>
2830

2931
DockManager::DockManager(QObject* parent)
3032
: QObject(parent)
@@ -757,11 +759,23 @@ void DockManager::switchToDebuggerWidget(DebuggerWidget* widget)
757759
}
758760
}
759761

760-
void DockManager::updateStyleSheets()
762+
void DockManager::updateTheme()
761763
{
764+
if (m_menu_bar)
765+
m_menu_bar->updateTheme();
766+
762767
for (DockLayout& layout : m_layouts)
763768
for (const auto& [unique_name, widget] : layout.debuggerWidgets())
764769
widget->updateStyleSheet();
770+
771+
// KDDockWidgets::QtWidgets::TabBar sets its own style to a subclass of
772+
// QProxyStyle in its constructor, so we need to update that here.
773+
for (KDDockWidgets::Core::Group* group : KDDockWidgets::DockRegistry::self()->groups())
774+
{
775+
auto tab_bar = static_cast<KDDockWidgets::QtWidgets::TabBar*>(group->tabBar()->view());
776+
if (QProxyStyle* style = qobject_cast<QProxyStyle*>(tab_bar->style()))
777+
style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
778+
}
765779
}
766780

767781
bool DockManager::isLayoutLocked()

pcsx2-qt/Debugger/Docking/DockManager.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class DockManager : public QObject
8989
void setPrimaryDebuggerWidget(DebuggerWidget* widget, bool is_primary);
9090
void switchToDebuggerWidget(DebuggerWidget* widget);
9191

92-
void updateStyleSheets();
92+
void updateTheme();
9393

9494
bool isLayoutLocked();
9595
void setLayoutLockedAndSaveSetting(bool locked);

pcsx2-qt/Debugger/Docking/DockMenuBar.cpp

+114-7
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,45 @@
33

44
#include "DockMenuBar.h"
55

6+
#include <QtCore/QTimer>
67
#include <QtGui/QPainter>
78
#include <QtGui/QPaintEvent>
89
#include <QtWidgets/QBoxLayout>
10+
#include <QtWidgets/QStyleFactory>
911
#include <QtWidgets/QStyleOption>
1012

13+
static const int OUTER_MENU_MARGIN = 2;
14+
static const int INNER_MENU_MARGIN = 4;
15+
1116
DockMenuBar::DockMenuBar(QWidget* original_menu_bar, QWidget* parent)
1217
: QWidget(parent)
18+
, m_original_menu_bar(original_menu_bar)
1319
{
20+
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
21+
1422
QHBoxLayout* layout = new QHBoxLayout;
15-
layout->setContentsMargins(0, 2, 2, 0);
23+
layout->setContentsMargins(0, OUTER_MENU_MARGIN, OUTER_MENU_MARGIN, 0);
1624
setLayout(layout);
1725

1826
QWidget* menu_wrapper = new QWidget;
1927
menu_wrapper->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
2028
layout->addWidget(menu_wrapper);
2129

2230
QHBoxLayout* menu_layout = new QHBoxLayout;
23-
menu_layout->setContentsMargins(0, 4, 0, 4);
31+
menu_layout->setContentsMargins(0, INNER_MENU_MARGIN, 0, INNER_MENU_MARGIN);
2432
menu_wrapper->setLayout(menu_layout);
2533

2634
menu_layout->addWidget(original_menu_bar);
2735

2836
m_layout_switcher = new QTabBar;
2937
m_layout_switcher->setContentsMargins(0, 0, 0, 0);
30-
m_layout_switcher->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
38+
m_layout_switcher->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
3139
m_layout_switcher->setContextMenuPolicy(Qt::CustomContextMenu);
40+
m_layout_switcher->setDrawBase(false);
41+
m_layout_switcher->setExpanding(false);
3242
m_layout_switcher->setMovable(true);
3343
layout->addWidget(m_layout_switcher);
3444

35-
QWidget* spacer = new QWidget;
36-
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
37-
layout->addWidget(spacer);
38-
3945
connect(m_layout_switcher, &QTabBar::tabMoved, this, [this](int from, int to) {
4046
DockLayout::Index from_index = static_cast<DockLayout::Index>(from);
4147
DockLayout::Index to_index = static_cast<DockLayout::Index>(to);
@@ -59,6 +65,26 @@ DockMenuBar::DockMenuBar(QWidget* original_menu_bar, QWidget* parent)
5965
emit lockButtonToggled(checked);
6066
});
6167
layout->addWidget(m_layout_locked_toggle);
68+
69+
updateTheme();
70+
}
71+
72+
void DockMenuBar::updateTheme()
73+
{
74+
bool needs_new_style = false;
75+
76+
if (!m_style)
77+
{
78+
m_style = new DockLayoutSwitcherStyle(m_layout_switcher);
79+
m_layout_switcher->setStyle(m_style);
80+
81+
needs_new_style = true;
82+
}
83+
84+
if (needs_new_style || m_style->baseStyle()->name() != qApp->style()->name())
85+
m_style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
86+
87+
m_layout_locked_toggle->setStyleSheet("color: palette(text)");
6288
}
6389

6490
void DockMenuBar::updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts)
@@ -166,6 +192,32 @@ void DockMenuBar::stopBlink()
166192
}
167193
}
168194

195+
int DockMenuBar::innerHeight() const
196+
{
197+
return m_original_menu_bar->sizeHint().height() + INNER_MENU_MARGIN * 2;
198+
}
199+
200+
QSize DockMenuBar::sizeHint() const
201+
{
202+
return QSize(m_original_menu_bar->sizeHint().width(), innerHeight() + OUTER_MENU_MARGIN);
203+
}
204+
205+
void DockMenuBar::paintEvent(QPaintEvent* event)
206+
{
207+
QPainter painter(this);
208+
209+
// This fixes the background colour of the menu bar when using the WIndows
210+
// classic theme.
211+
QStyleOptionMenuItem menu_option;
212+
menu_option.palette = palette();
213+
menu_option.state = QStyle::State_None;
214+
menu_option.menuItemType = QStyleOptionMenuItem::EmptyArea;
215+
menu_option.checkType = QStyleOptionMenuItem::NotCheckable;
216+
menu_option.rect = rect();
217+
menu_option.menuRect = rect();
218+
style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menu_option, &painter, this);
219+
}
220+
169221
void DockMenuBar::tabChanged(int index)
170222
{
171223
// Prevent recursion.
@@ -182,3 +234,58 @@ void DockMenuBar::tabChanged(int index)
182234
emit newButtonClicked();
183235
}
184236
}
237+
238+
// *****************************************************************************
239+
240+
DockLayoutSwitcherStyle::DockLayoutSwitcherStyle(QObject* parent)
241+
: QProxyStyle(nullptr)
242+
{
243+
setParent(parent);
244+
}
245+
246+
void DockLayoutSwitcherStyle::drawControl(
247+
ControlElement element,
248+
const QStyleOption* option,
249+
QPainter* painter,
250+
const QWidget* widget) const
251+
{
252+
QProxyStyle::drawControl(element, option, painter, widget);
253+
254+
// Draw a slick-looking highlight under the currently selected tab.
255+
if (element == CE_TabBarTab && baseStyle()->name() == "fusion")
256+
{
257+
const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option);
258+
if (tab && (tab->state & State_Selected))
259+
{
260+
painter->setPen(tab->palette.highlight().color());
261+
painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight());
262+
}
263+
}
264+
}
265+
266+
QSize DockLayoutSwitcherStyle::sizeFromContents(
267+
QStyle::ContentsType type, const QStyleOption* option, const QSize& contents_size, const QWidget* widget) const
268+
{
269+
QSize size = QProxyStyle::sizeFromContents(type, option, contents_size, widget);
270+
271+
DockMenuBar* menu_bar = qobject_cast<DockMenuBar*>(widget->parent());
272+
if (!menu_bar)
273+
return size;
274+
275+
// Adjust the size of the layout switcher tabs depending on the theme.
276+
if (type == CT_TabBarTab)
277+
{
278+
if (baseStyle()->name() == "fusion" || baseStyle()->name() == "windowsvista")
279+
{
280+
// Make sure the tab extends to the bottom of the widget.
281+
size.setHeight(menu_bar->innerHeight() - option->rect.top());
282+
}
283+
else if (baseStyle()->name() == "windows11")
284+
{
285+
// Make sure the tab is centred vertically.
286+
size.setHeight(menu_bar->innerHeight() - option->rect.top() * 2);
287+
}
288+
}
289+
290+
return size;
291+
}

pcsx2-qt/Debugger/Docking/DockMenuBar.h

+39
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
#include "Debugger/Docking/DockLayout.h"
77

88
#include <QtWidgets/QMenuBar>
9+
#include <QtWidgets/QProxyStyle>
910
#include <QtWidgets/QPushButton>
1011
#include <QtWidgets/QTabBar>
1112
#include <QtWidgets/QWidget>
1213

14+
class DockLayoutSwitcherStyle;
15+
16+
// The widget that replaces the normal menu bar. This contains the original menu
17+
// bar, the layout switcher and the layout locked/unlocked toggle button.
1318
class DockMenuBar : public QWidget
1419
{
1520
Q_OBJECT
@@ -19,6 +24,8 @@ class DockMenuBar : public QWidget
1924

2025
void updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts);
2126

27+
void updateTheme();
28+
2229
// Notify the menu bar that a new layout has been selected.
2330
void onCurrentLayoutChanged(DockLayout::Index current_index);
2431

@@ -29,6 +36,10 @@ class DockMenuBar : public QWidget
2936
void updateBlink();
3037
void stopBlink();
3138

39+
int innerHeight() const;
40+
41+
QSize sizeHint() const override;
42+
3243
Q_SIGNALS:
3344
void currentLayoutChanged(DockLayout::Index layout_index);
3445
void newButtonClicked();
@@ -37,9 +48,13 @@ class DockMenuBar : public QWidget
3748

3849
void layoutSwitcherContextMenuRequested(const QPoint& pos, QTabBar* layout_switcher);
3950

51+
protected:
52+
void paintEvent(QPaintEvent* event) override;
53+
4054
private:
4155
void tabChanged(int index);
4256

57+
QWidget* m_original_menu_bar;
4358

4459
QTabBar* m_layout_switcher;
4560
QMetaObject::Connection m_tab_connection;
@@ -53,4 +68,28 @@ class DockMenuBar : public QWidget
5368

5469
QPushButton* m_layout_locked_toggle;
5570
bool m_ignore_lock_state_changed = false;
71+
72+
DockLayoutSwitcherStyle* m_style = nullptr;
73+
};
74+
75+
// Highlight the selected tab with an underline, and improve the appearance of
76+
// the layout switcher when the Windows Vista or Windows 11 styles are used.
77+
class DockLayoutSwitcherStyle : public QProxyStyle
78+
{
79+
Q_OBJECT
80+
81+
public:
82+
DockLayoutSwitcherStyle(QObject* parent = nullptr);
83+
84+
void drawControl(
85+
ControlElement element,
86+
const QStyleOption* option,
87+
QPainter* painter,
88+
const QWidget* widget = nullptr) const override;
89+
90+
QSize sizeFromContents(
91+
QStyle::ContentsType type,
92+
const QStyleOption* option,
93+
const QSize& contents_size,
94+
const QWidget* widget = nullptr) const override;
5695
};

pcsx2-qt/Debugger/Docking/DockViews.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <QtWidgets/QInputDialog>
2121
#include <QtWidgets/QMessageBox>
2222
#include <QtWidgets/QMenu>
23+
#include <QtWidgets/QStyleFactory>
2324

2425
KDDockWidgets::Core::View* DockViewFactory::createDockWidget(
2526
const QString& unique_name,
@@ -143,6 +144,14 @@ DockTabBar::DockTabBar(KDDockWidgets::Core::TabBar* controller, QWidget* parent)
143144
{
144145
setContextMenuPolicy(Qt::CustomContextMenu);
145146
connect(this, &DockTabBar::customContextMenuRequested, this, &DockTabBar::openContextMenu);
147+
148+
// The constructor of KDDockWidgets::QtWidgets::TabBar makes a QProxyStyle
149+
// that ends up taking ownerhsip of the style for the entire application!
150+
if (QProxyStyle* proxy_style = qobject_cast<QProxyStyle*>(style()))
151+
{
152+
proxy_style->baseStyle()->setParent(qApp);
153+
proxy_style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
154+
}
146155
}
147156

148157
void DockTabBar::openContextMenu(QPoint pos)

pcsx2-qt/MainWindow.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,7 @@ void MainWindow::updateTheme()
17811781
reloadThemeSpecificImages();
17821782

17831783
if (g_debugger_window)
1784-
g_debugger_window->updateStyleSheets();
1784+
g_debugger_window->updateTheme();
17851785
}
17861786

17871787
void MainWindow::reloadThemeSpecificImages()

0 commit comments

Comments
 (0)