Qt: Use a lighter link color in dark mode.
Add ColorUtils::themeLinkBrush, which returns a readable link color in dark mode. Use it in place of existing ...palette().link() calls. Add ColorUtils::themeLinkStyle, which produces an HTML <style/> block that lightens the link foreground color in dark mode. Use this to style links in the about box and in elided labels. Catch ApplicationPaletteChange events where needed. Add dark theme / dark mode notes to the WSDG. Ping-Bug: 15511 Change-Id: I92925bd997f97b155491f55a8c818f03549bc7f4 Reviewed-on: https://code.wireshark.org/review/33704 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
parent
cbcb50e8af
commit
94f497f929
|
@ -223,7 +223,7 @@ code through the following steps:
|
|||
- push and commit on Gerrit
|
||||
- push ts on Transifex
|
||||
|
||||
===== Colors
|
||||
===== Colors And Themes
|
||||
|
||||
Qt provides a number of colors via the http://doc.qt.io/qt-5/qpalette.html[QPalette]
|
||||
class. Use this class when you need a standard color provided by the
|
||||
|
@ -236,6 +236,20 @@ I/O graphs, sequence diagrams, and RTP streams. Please use this palette
|
|||
(defined in `tango_colors.h` and the *ColorUtils* class) if *QPalette*
|
||||
doesn't meet your needs.
|
||||
|
||||
Wireshark supports dark themes (aka “dark mode”) on some platforms. We
|
||||
leverage Qt's dark theme support when possible, but have implemented our
|
||||
own support and workarounds in some cases. You can ensure that your code
|
||||
includes proper dark theme support by doing the following:
|
||||
|
||||
* You can use a macOS-style template icon by creating a monochrome SVG
|
||||
document with “.template” appended to the name, e.g.
|
||||
`image/stock_icons/24x24/edit-find.template.svg`.
|
||||
* Qt draws unvisited links *Qt::blue* no matter what. You can work
|
||||
around this by using `ColorUtils::themeLinkBrush()` and
|
||||
`ColorUtils::themeLinkStyle()`.
|
||||
* You can catch dark and light mode changes by handling
|
||||
`QEvent::ApplicationPaletteChange`.
|
||||
|
||||
==== Other Issues and Information
|
||||
|
||||
The main window has many QActions which are shared with child widgets. See
|
||||
|
|
|
@ -44,8 +44,10 @@
|
|||
|
||||
#include "extcap.h"
|
||||
|
||||
#include <ui/qt/utils/color_utils.h>
|
||||
#include <ui/qt/utils/qt_ui_utils.h>
|
||||
#include <ui/qt/utils/variant_pointer.h>
|
||||
|
||||
#include <ui/qt/models/astringlist_list_model.h>
|
||||
#include <ui/qt/models/url_link_delegate.h>
|
||||
|
||||
|
@ -268,14 +270,6 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
|||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
QFile f_license;
|
||||
QString message;
|
||||
|
||||
QString vcs_version_info_str = get_ws_vcs_version_info();
|
||||
QString copyright_info_str = get_copyright_info();
|
||||
QString comp_info_str = gstring_free_to_qbytearray(get_compiled_version_info(get_wireshark_qt_compiled_info,
|
||||
get_gui_compiled_info));
|
||||
QString runtime_info_str = gstring_free_to_qbytearray(get_runtime_version_info(get_wireshark_runtime_info));
|
||||
|
||||
|
||||
AuthorListModel * authorModel = new AuthorListModel(this);
|
||||
AStringListListSortFilterProxyModel * proxyAuthorModel = new AStringListListSortFilterProxyModel(this);
|
||||
|
@ -294,20 +288,10 @@ AboutDialog::AboutDialog(QWidget *parent) :
|
|||
connect(ui->searchAuthors, SIGNAL(textChanged(QString)), proxyAuthorModel, SLOT(setFilter(QString)));
|
||||
|
||||
/* Wireshark tab */
|
||||
|
||||
/* Construct the message string */
|
||||
message = "<p>Version " + html_escape(vcs_version_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(copyright_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(comp_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(runtime_info_str) + "</p>\n\n";
|
||||
message += "<p>Wireshark is Open Source Software released under the GNU General Public License.</p>\n\n";
|
||||
message += "<p>Check the man page and ";
|
||||
message += "<a href=https://www.wireshark.org>https://www.wireshark.org</a> ";
|
||||
message += "for more information.</p>\n\n";
|
||||
updateWiresharkText();
|
||||
|
||||
ui->pte_wireshark->setFrameStyle(QFrame::NoFrame);
|
||||
ui->pte_wireshark->viewport()->setAutoFillBackground(false);
|
||||
ui->pte_wireshark->setHtml(message);
|
||||
|
||||
/* Check if it is a dev release... (VERSION_MINOR is odd in dev release) */
|
||||
#if VERSION_MINOR & 1
|
||||
|
@ -397,6 +381,19 @@ AboutDialog::~AboutDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
bool AboutDialog::event(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::ApplicationPaletteChange:
|
||||
updateWiresharkText();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
return QDialog::event(event);
|
||||
}
|
||||
|
||||
void AboutDialog::showEvent(QShowEvent * event)
|
||||
{
|
||||
int one_em = fontMetrics().height();
|
||||
|
@ -429,6 +426,28 @@ void AboutDialog::showEvent(QShowEvent * event)
|
|||
QDialog::showEvent(event);
|
||||
}
|
||||
|
||||
void AboutDialog::updateWiresharkText()
|
||||
{
|
||||
QString vcs_version_info_str = get_ws_vcs_version_info();
|
||||
QString copyright_info_str = get_copyright_info();
|
||||
QString comp_info_str = gstring_free_to_qbytearray(get_compiled_version_info(get_wireshark_qt_compiled_info,
|
||||
get_gui_compiled_info));
|
||||
QString runtime_info_str = gstring_free_to_qbytearray(get_runtime_version_info(get_wireshark_runtime_info));
|
||||
|
||||
QString message = ColorUtils::themeLinkStyle();
|
||||
|
||||
/* Construct the message string */
|
||||
message += "<p>Version " + html_escape(vcs_version_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(copyright_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(comp_info_str) + "</p>\n\n";
|
||||
message += "<p>" + html_escape(runtime_info_str) + "</p>\n\n";
|
||||
message += "<p>Wireshark is Open Source Software released under the GNU General Public License.</p>\n\n";
|
||||
message += "<p>Check the man page and ";
|
||||
message += "<a href=https://www.wireshark.org>https://www.wireshark.org</a> ";
|
||||
message += "for more information.</p>\n\n";
|
||||
ui->pte_wireshark->setHtml(message);
|
||||
}
|
||||
|
||||
void AboutDialog::urlDoubleClicked(const QModelIndex &idx)
|
||||
{
|
||||
if (idx.column() != 1) {
|
||||
|
|
|
@ -87,9 +87,12 @@ public:
|
|||
~AboutDialog();
|
||||
|
||||
protected:
|
||||
virtual bool event(QEvent *event);
|
||||
virtual void showEvent(QShowEvent *);
|
||||
|
||||
private:
|
||||
void updateWiresharkText();
|
||||
|
||||
Ui::AboutDialog *ui;
|
||||
QString script_pattern;
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include <ui/qt/models/astringlist_list_model.h>
|
||||
|
||||
#include <ui/qt/utils/color_utils.h>
|
||||
|
||||
AStringListListModel::AStringListListModel(QObject * parent):
|
||||
QAbstractTableModel(parent)
|
||||
{}
|
||||
|
@ -187,7 +189,7 @@ QVariant AStringListListUrlProxyModel::data(const QModelIndex &index, int role)
|
|||
if ( result.canConvert(QVariant::Brush) )
|
||||
{
|
||||
QBrush selected = result.value<QBrush>();
|
||||
selected.setColor(QApplication::palette().link().color());
|
||||
selected.setColor(ColorUtils::themeLinkBrush().color());
|
||||
return selected;
|
||||
}
|
||||
} else if ( role == Qt::TextColorRole ) {
|
||||
|
|
|
@ -123,7 +123,7 @@ QVariant ProtoTreeModel::data(const QModelIndex &index, int role) const
|
|||
return ColorUtils::expert_color_foreground;
|
||||
}
|
||||
if (finfo.isLink()) {
|
||||
return QApplication::palette().link();
|
||||
return ColorUtils::themeLinkBrush();
|
||||
}
|
||||
if(finfo.headerInfo().type == FT_PROTOCOL) {
|
||||
return QApplication::palette().windowText();
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <QPainter>
|
||||
#include <QRegExp>
|
||||
|
||||
#include <ui/qt/utils/color_utils.h>
|
||||
|
||||
UrlLinkDelegate::UrlLinkDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent),
|
||||
re_col_(-1),
|
||||
|
@ -44,7 +46,7 @@ void UrlLinkDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
|
|||
initStyleOption(&opt, index);
|
||||
|
||||
opt.font.setUnderline(true);
|
||||
opt.palette.setColor(QPalette::Text, opt.palette.link().color());
|
||||
opt.palette.setColor(QPalette::Text, ColorUtils::themeLinkBrush().color());
|
||||
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
}
|
||||
|
|
|
@ -146,6 +146,37 @@ bool ColorUtils::themeIsDark()
|
|||
return wsApp->palette().windowText().color().lightness() > wsApp->palette().window().color().lightness();
|
||||
}
|
||||
|
||||
// As of 5.12.3, Qt always uses Qt::blue for the link color, which is
|
||||
// unreadable when using a dark theme. Changing the application palette
|
||||
// via ...Application::setPalette is problematic, since QGuiApplication
|
||||
// sets a flag (ApplicationPaletteExplicitlySet) which keeps us from
|
||||
// catching theme changes.
|
||||
//
|
||||
// themeLinkBrush and themeLinkStyle provide convenience routines for
|
||||
// fetching the link brush and style. We can remove them if Qt ever fixes
|
||||
// the link color.
|
||||
//
|
||||
// We could also override WiresharkApplication::palette, but keeping the
|
||||
// routines together here seemed to make more sense.
|
||||
QBrush ColorUtils::themeLinkBrush()
|
||||
{
|
||||
if (themeIsDark()) {
|
||||
return QBrush(tango_sky_blue_2);
|
||||
}
|
||||
return wsApp->palette().link();
|
||||
}
|
||||
|
||||
QString ColorUtils::themeLinkStyle()
|
||||
{
|
||||
QString link_style;
|
||||
|
||||
if (themeIsDark()) {
|
||||
link_style = QString("<style>a:link { color: %1; }</style>")
|
||||
.arg(themeLinkBrush().color().name());
|
||||
}
|
||||
return link_style;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines
|
||||
*
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
* @return true if we're running in dark mode, false otherwise.
|
||||
*/
|
||||
static bool themeIsDark();
|
||||
static QBrush themeLinkBrush();
|
||||
static QString themeLinkStyle();
|
||||
|
||||
signals:
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <ui/qt/widgets/elided_label.h>
|
||||
|
||||
#include <ui/qt/utils/color_utils.h>
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QResizeEvent>
|
||||
|
||||
|
@ -26,6 +28,19 @@ void ElidedLabel::setUrl(const QString &url)
|
|||
updateText();
|
||||
}
|
||||
|
||||
bool ElidedLabel::event(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::ApplicationPaletteChange:
|
||||
updateText();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
return QLabel::event(event);
|
||||
}
|
||||
|
||||
void ElidedLabel::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
updateText();
|
||||
|
@ -40,6 +55,7 @@ void ElidedLabel::updateText()
|
|||
QString label_text = small_text_ ? "<small><i>" : "<i>";
|
||||
|
||||
if (url_.length() > 0) {
|
||||
label_text.prepend(ColorUtils::themeLinkStyle());
|
||||
label_text.append(QString("<a href=\"%1\">%2</a>")
|
||||
.arg(url_)
|
||||
.arg(elided_text)
|
||||
|
|
|
@ -21,7 +21,8 @@ public:
|
|||
void setSmallText(bool small_text = true) { small_text_ = small_text; }
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
virtual bool event(QEvent *event);
|
||||
virtual void resizeEvent(QResizeEvent *);
|
||||
|
||||
private:
|
||||
bool small_text_;
|
||||
|
|
Loading…
Reference in New Issue