Use Qt's High-DPI scaling on Windows (#4868)

This commit is contained in:
nerix
2024-05-12 13:59:14 +02:00
committed by GitHub
parent 8202cd0d99
commit febcf464fe
21 changed files with 459 additions and 320 deletions
+39 -15
View File
@@ -8,26 +8,44 @@
#include <QPainter>
#include <QScreen>
namespace chatterino {
namespace {
// returns a new resized image or the old one if the size didn't change
auto resizePixmap(const QPixmap &current, const QPixmap resized,
const QSize &size) -> QPixmap
QSizeF deviceIndependentSize(const QPixmap &pixmap)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 0)
return QSizeF(pixmap.width(), pixmap.height()) / pixmap.devicePixelRatio();
#else
return pixmap.deviceIndependentSize();
#endif
}
/**
* Resizes a pixmap to a desired size.
* Does nothing if the target pixmap is already sized correctly.
*
* @param target The target pixmap.
* @param source The unscaled pixmap.
* @param size The desired device independent size.
* @param dpr The device pixel ratio of the target area. The size of the target in pixels will be `size * dpr`.
*/
void resizePixmap(QPixmap &target, const QPixmap &source, const QSize &size,
qreal dpr)
{
if (deviceIndependentSize(target) == size)
{
if (resized.size() == size)
{
return resized;
}
else
{
return current.scaled(size, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
}
return;
}
QPixmap resized = source;
resized.setDevicePixelRatio(dpr);
target = resized.scaled(size * dpr, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
}
} // namespace
namespace chatterino {
Button::Button(BaseWidget *parent)
: BaseWidget(parent)
{
@@ -47,6 +65,12 @@ void Button::setMouseEffectColor(std::optional<QColor> color)
void Button::setPixmap(const QPixmap &_pixmap)
{
// Avoid updates if the pixmap didn't change
if (_pixmap.cacheKey() == this->pixmap_.cacheKey())
{
return;
}
this->pixmap_ = _pixmap;
this->resizedPixmap_ = {};
this->update();
@@ -158,8 +182,8 @@ void Button::paintButton(QPainter &painter)
QRect rect = this->rect();
this->resizedPixmap_ =
resizePixmap(this->pixmap_, this->resizedPixmap_, rect.size());
resizePixmap(this->resizedPixmap_, this->pixmap_, rect.size(),
this->devicePixelRatio());
int margin = this->height() < 22 * this->scale() ? 3 : 6;
+19 -10
View File
@@ -615,7 +615,7 @@ void ChannelView::scaleChangedEvent(float scale)
if (this->goToBottom_)
{
auto factor = this->qtFontScale();
auto factor = this->scale();
#ifdef Q_OS_MACOS
factor = scale * 80.F /
std::max<float>(
@@ -703,8 +703,10 @@ void ChannelView::layoutVisibleMessages(
{
const auto &message = messages[i];
redrawRequired |= message->layout(layoutWidth, this->scale(), flags,
this->bufferInvalidationQueued_);
redrawRequired |= message->layout(
layoutWidth, this->scale(),
this->scale() * static_cast<float>(this->devicePixelRatio()),
flags, this->bufferInvalidationQueued_);
y += message->getHeight();
}
@@ -738,7 +740,10 @@ void ChannelView::updateScrollbar(
{
auto *message = messages[i].get();
message->layout(layoutWidth, this->scale(), flags, false);
message->layout(
layoutWidth, this->scale(),
this->scale() * static_cast<float>(this->devicePixelRatio()), flags,
false);
h -= message->getHeight();
@@ -1720,9 +1725,11 @@ void ChannelView::wheelEvent(QWheelEvent *event)
}
else
{
snapshot[i - 1]->layout(this->getLayoutWidth(),
this->scale(), this->getFlags(),
false);
snapshot[i - 1]->layout(
this->getLayoutWidth(), this->scale(),
this->scale() *
static_cast<float>(this->devicePixelRatio()),
this->getFlags(), false);
scrollFactor = 1;
currentScrollLeft = snapshot[i - 1]->getHeight();
}
@@ -1755,9 +1762,11 @@ void ChannelView::wheelEvent(QWheelEvent *event)
}
else
{
snapshot[i + 1]->layout(this->getLayoutWidth(),
this->scale(), this->getFlags(),
false);
snapshot[i + 1]->layout(
this->getLayoutWidth(), this->scale(),
this->scale() *
static_cast<float>(this->devicePixelRatio()),
this->getFlags(), false);
scrollFactor = 1;
currentScrollLeft = snapshot[i + 1]->getHeight();
+4 -15
View File
@@ -27,15 +27,6 @@
namespace chatterino {
namespace {
qreal deviceDpi(QWidget *widget)
{
#ifdef Q_OS_WIN
return widget->devicePixelRatioF();
#else
return 1.0;
#endif
}
// Translates the given rectangle by an amount in the direction to appear like the tab is selected.
// For example, if location is Top, the rectangle will be translated in the negative Y direction,
// or "up" on the screen, by amount.
@@ -196,8 +187,8 @@ int NotebookTab::normalTabWidth()
float scale = this->scale();
int width;
auto metrics = getIApp()->getFonts()->getFontMetrics(
FontStyle::UiTabs, float(qreal(this->scale()) * deviceDpi(this)));
QFontMetrics metrics =
getIApp()->getFonts()->getFontMetrics(FontStyle::UiTabs, scale);
if (this->hasXButton())
{
@@ -439,11 +430,9 @@ void NotebookTab::paintEvent(QPaintEvent *)
QPainter painter(this);
float scale = this->scale();
auto div = std::max<float>(0.01f, this->logicalDpiX() * deviceDpi(this));
painter.setFont(
getIApp()->getFonts()->getFont(FontStyle::UiTabs, scale * 96.f / div));
painter.setFont(app->getFonts()->getFont(FontStyle::UiTabs, scale));
QFontMetrics metrics =
app->getFonts()->getFontMetrics(FontStyle::UiTabs, scale * 96.f / div);
app->getFonts()->getFontMetrics(FontStyle::UiTabs, scale);
int height = int(scale * NOTEBOOK_TAB_HEIGHT);