mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 21:07:02 +08:00
[5.14.1] UI adjustments
* OS native check of screen resolution (Qt free, experimental) * changed rounding * use string for scale factor so we can use fractions as 2/3 * utility functions to clean numbers, parse fractions It looks like: * my WIN10 scaling is 250% * obviously swift rounds that to 3 (device ratio) * now using FLOOR policy down-rounding to 2 * rational: scaling up (scale factor) is better as down-scaling as the factors would be clearer * 2->3 1.5, but 3->2 means 0.66667
This commit is contained in:
committed by
Mat Sutcliffe
parent
52de67a72f
commit
8f4c4a249c
@@ -25,6 +25,9 @@ else {
|
||||
QMAKE_CXXFLAGS += -idirafter $$EXTERNALSROOT/common/include/qwt
|
||||
}
|
||||
|
||||
# needed for "ShellScalingApi.h" only
|
||||
# win32 { LIBS *= -lSHCore }
|
||||
|
||||
DEPENDPATH += . ..
|
||||
|
||||
PRECOMPILED_HEADER = pch/pch.h
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QtGlobal>
|
||||
#include <QWhatsThis>
|
||||
#include <Qt>
|
||||
|
||||
using namespace BlackConfig;
|
||||
using namespace BlackMisc;
|
||||
@@ -351,21 +352,27 @@ namespace BlackGui
|
||||
CApplication::exit(retcode);
|
||||
}
|
||||
|
||||
void CGuiApplication::highDpiScreenSupport(double scaleFactor)
|
||||
void CGuiApplication::highDpiScreenSupport(const QString &scaleFactor)
|
||||
{
|
||||
// https://lists.qt-project.org/pipermail/development/2019-September/037434.html
|
||||
if (scaleFactor < 0)
|
||||
// QSize s = CGuiUtility::physicalScreenSizeOs();
|
||||
QString sf = scaleFactor.trimmed().isEmpty() ? defaultScaleFactorString() : scaleFactor;
|
||||
if (sf.contains('/'))
|
||||
{
|
||||
// qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1"); // until 5.14
|
||||
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); // HiDPI pixmaps
|
||||
const QString sf = QString::number(scaleFactor, 'f', 2);
|
||||
qputenv("QT_SCALE_FACTOR", sf.toLatin1());
|
||||
const double sfd = parseFraction(scaleFactor, -1);
|
||||
sf = sfd < 0 ? "1.0" : QString::number(sfd, 'f', 8);
|
||||
}
|
||||
|
||||
sf = cleanNumber(sf);
|
||||
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); // HiDPI pixmaps
|
||||
|
||||
// qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
|
||||
|
||||
const QByteArray sfa = sf.toLatin1();
|
||||
qputenv("QT_SCALE_FACTOR", sfa);
|
||||
}
|
||||
|
||||
bool CGuiApplication::isUsingHighDpiScreenSupport()
|
||||
@@ -375,7 +382,7 @@ namespace BlackGui
|
||||
|
||||
QScreen *CGuiApplication::currentScreen()
|
||||
{
|
||||
QWidget *w = CGuiApplication::mainApplicationWidget();
|
||||
const QWidget *w = CGuiApplication::mainApplicationWidget();
|
||||
const int s = QApplication::desktop()->screenNumber(w);
|
||||
if (s < QGuiApplication::screens().size()) { return QGuiApplication::screens()[s]; }
|
||||
return QGuiApplication::primaryScreen();
|
||||
@@ -552,6 +559,37 @@ namespace BlackGui
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
QString CGuiApplication::scaleFactor(int argc, char *argv[])
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (qstrcmp(argv[i], "--scale") == 0 || qstrcmp(argv[i], "-scale") == 0)
|
||||
{
|
||||
if (i + 1 >= argc) { return QString(); } // no value
|
||||
const QString factor(argv[i + 1]);
|
||||
return factor.trimmed();
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString CGuiApplication::defaultScaleFactorString()
|
||||
{
|
||||
if (!CBuildConfig::isRunningOnWindowsNtPlatform()) { return "1.0"; }
|
||||
|
||||
// On windows
|
||||
// Qt 5.14.1 default is device ratio 3
|
||||
// Qt 5.14.0 default device ratio was 2
|
||||
|
||||
// 2/3 (0.66667) => device ratio 3
|
||||
// 0.75 => device ratio 2.25
|
||||
// 0.8 => device ratio 2.4
|
||||
// 1.00 => device ratio 3
|
||||
|
||||
// currently NOT used
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
bool CGuiApplication::cmdLineErrorMessage(const QString &errorMessage, bool retry) const
|
||||
{
|
||||
const QString helpText(beautifyHelpMessage(m_parser.helpText()));
|
||||
|
||||
@@ -284,7 +284,7 @@ namespace BlackGui
|
||||
|
||||
//! Support for high DPI screens
|
||||
//! \note Needs to be at the beginning of main
|
||||
static void highDpiScreenSupport(double scaleFactor = -1);
|
||||
static void highDpiScreenSupport(const QString &scaleFactor = {});
|
||||
|
||||
//! Uses the high DPI support?
|
||||
static bool isUsingHighDpiScreenSupport();
|
||||
@@ -300,8 +300,15 @@ namespace BlackGui
|
||||
static void modalWindowToFront();
|
||||
|
||||
//! Parse scale factor if any
|
||||
//! \deprecated using scaleFactor now
|
||||
static double parseScaleFactor(int argc, char *argv[]);
|
||||
|
||||
//! Get the scale factor
|
||||
static QString scaleFactor(int argc, char *argv[]);
|
||||
|
||||
//! Get a default scale factor
|
||||
static QString defaultScaleFactorString();
|
||||
|
||||
signals:
|
||||
//! Style sheet changed
|
||||
void styleSheetsChanged();
|
||||
|
||||
@@ -43,6 +43,14 @@
|
||||
#include <QPropertyAnimation>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
// for the screen size
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "wtypes.h"
|
||||
#include "ShellScalingApi.h"
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
using namespace BlackMisc;
|
||||
|
||||
namespace BlackGui
|
||||
@@ -114,6 +122,79 @@ namespace BlackGui
|
||||
return QApplication::desktop()->screenGeometry(QApplication::desktop()).size();
|
||||
}
|
||||
|
||||
QSizeF CGuiUtility::physicalScreenSize(QWidget *currentWidget)
|
||||
{
|
||||
QScreen *s = QGuiApplication::screens().front();
|
||||
if (currentWidget)
|
||||
{
|
||||
const int sn = QApplication::desktop()->screenNumber(currentWidget);
|
||||
s = QGuiApplication::screens().at(sn);
|
||||
}
|
||||
|
||||
if (!s) { return QSizeF(); }
|
||||
const QSizeF ps1 = s->physicalSize();
|
||||
return ps1;
|
||||
}
|
||||
|
||||
namespace Private
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
QSize windowsGetDesktopResolution()
|
||||
{
|
||||
/**
|
||||
// https://stackoverflow.com/questions/8690619/how-to-get-screen-resolution-in-c
|
||||
RECT desktop;
|
||||
// Get a handle to the desktop window
|
||||
const HWND hDesktop = GetDesktopWindow();
|
||||
// Get the size of screen to the variable desktop
|
||||
GetWindowRect(hDesktop, &desktop);
|
||||
// The top left corner will have coordinates (0,0)
|
||||
// and the bottom right corner will have coordinates
|
||||
// (horizontal, vertical)
|
||||
const int horizontal = desktop.right;
|
||||
const int vertical = desktop.bottom;
|
||||
return QSize(vertical, horizontal);
|
||||
**/
|
||||
|
||||
// https://stackoverflow.com/questions/2156212/how-to-get-the-monitor-screen-resolution-from-a-hwnd
|
||||
const HWND hDesktop = GetDesktopWindow();
|
||||
HMONITOR monitor = MonitorFromWindow(hDesktop, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO info;
|
||||
info.cbSize = sizeof(MONITORINFO);
|
||||
GetMonitorInfo(monitor, &info);
|
||||
|
||||
/**
|
||||
DEVICE_SCALE_FACTOR pScale;
|
||||
GetScaleFactorForMonitor(monitor, &pScale);
|
||||
**/
|
||||
|
||||
const int monitor_width = info.rcMonitor.right - info.rcMonitor.left;
|
||||
const int monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;
|
||||
return QSize(monitor_height, monitor_width);
|
||||
|
||||
/**
|
||||
// https://stackoverflow.com/a/50205813/356726
|
||||
const int width = static_cast<int>(GetSystemMetrics(SM_CXSCREEN));
|
||||
const int height = static_cast<int>(GetSystemMetrics(SM_CYSCREEN));
|
||||
return QSize(width, height);
|
||||
**/
|
||||
}
|
||||
#endif
|
||||
} // namespace Private
|
||||
|
||||
QSize CGuiUtility::physicalScreenSizeOs()
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return Private::windowsGetDesktopResolution();
|
||||
#elif defined(Q_OS_MAC)
|
||||
return QSize();
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return QSize();
|
||||
#else
|
||||
return QSize();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CGuiUtility::isMainWindowFrameless()
|
||||
{
|
||||
const CEnableForFramelessWindow *mw = CGuiUtility::mainFramelessEnabledWindow();
|
||||
@@ -122,8 +203,15 @@ namespace BlackGui
|
||||
|
||||
QString CGuiUtility::screenInformation(const QString &separator)
|
||||
{
|
||||
const QSize ps = physicalScreenSizeOs();
|
||||
QString i = u"Number of screens: " % QString::number(QGuiApplication::screens().size()) % separator %
|
||||
u"Primary screen: " % QGuiApplication::primaryScreen()->name();
|
||||
u"Primary screen: " % QGuiApplication::primaryScreen()->name() % separator %
|
||||
u"QT_AUTO_SCREEN_SCALE_FACTOR: " % qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR") % separator %
|
||||
u"QT_SCALE_FACTOR: " % qgetenv("QT_SCALE_FACTOR") % separator %
|
||||
u"QT_ENABLE_HIGHDPI_SCALING: " % qgetenv("QT_ENABLE_HIGHDPI_SCALING") % separator %
|
||||
u"QT_SCALE_FACTOR_ROUNDING_POLICY: " % qgetenv("QT_SCALE_FACTOR_ROUNDING_POLICY") % separator %
|
||||
u"QT_SCREEN_SCALE_FACTORS: " % qgetenv("QT_SCREEN_SCALE_FACTORS") % separator %
|
||||
u"OS screen res." % QString::number(ps.width()) % u"/" % QString::number(ps.height()) % separator;
|
||||
|
||||
for (const QScreen *screen : QGuiApplication::screens())
|
||||
{
|
||||
@@ -509,7 +597,7 @@ namespace BlackGui
|
||||
else
|
||||
{
|
||||
flags &= ~Qt::WindowStaysOnBottomHint;
|
||||
flags |= Qt::WindowStaysOnTopHint;
|
||||
flags |= Qt::WindowStaysOnTopHint;
|
||||
}
|
||||
widget->setWindowFlags(flags);
|
||||
widget->show(); // without that the window sometimes just disappears
|
||||
@@ -523,7 +611,7 @@ namespace BlackGui
|
||||
if (onTop)
|
||||
{
|
||||
flags &= ~Qt::WindowStaysOnBottomHint;
|
||||
flags |= Qt::WindowStaysOnTopHint;
|
||||
flags |= Qt::WindowStaysOnTopHint;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -66,6 +66,14 @@ namespace BlackGui
|
||||
//! \remark might be scaled depending on CGuiUtility::mainApplicationWidgetPixelRatio
|
||||
static QSize desktopSize();
|
||||
|
||||
//! Pysical screen resolution
|
||||
//! \remark unscaled
|
||||
static QSizeF physicalScreenSize(QWidget *currentWidget = nullptr);
|
||||
|
||||
//! Qt independent implementation
|
||||
//! \remark allows to return values before QGuiApplication is initialized
|
||||
static QSize physicalScreenSizeOs();
|
||||
|
||||
//! Is main window frameless?
|
||||
static bool isMainWindowFrameless();
|
||||
|
||||
|
||||
@@ -491,6 +491,64 @@ namespace BlackMisc
|
||||
return (c % 2) == 0;
|
||||
}
|
||||
|
||||
double parseFraction(const QString &fraction, double failDefault)
|
||||
{
|
||||
if (fraction.isEmpty()) { return failDefault; }
|
||||
bool ok;
|
||||
|
||||
double r = failDefault;
|
||||
if (fraction.contains('/'))
|
||||
{
|
||||
const QStringList parts = fraction.split('/');
|
||||
if (parts.size() != 2) { return failDefault; }
|
||||
const double c = parts.front().trimmed().toDouble(&ok);
|
||||
if (!ok) { return failDefault; }
|
||||
|
||||
const double d = parts.last().trimmed().toDouble(&ok);
|
||||
if (!ok) { return failDefault; }
|
||||
if (qFuzzyCompare(0.0, d)) { return failDefault; }
|
||||
r = c / d;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = fraction.trimmed().toDouble(&ok);
|
||||
if (!ok) { return failDefault; }
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
QString cleanNumber(const QString &number)
|
||||
{
|
||||
QString n = number.trimmed();
|
||||
if (n.isEmpty()) { return QString(); }
|
||||
|
||||
int dp = n.indexOf('.');
|
||||
if (dp < 0) { dp = n.indexOf(','); }
|
||||
|
||||
// clean all trailing stuff
|
||||
while (dp >= 0 && !n.isEmpty())
|
||||
{
|
||||
const QChar l = n.at(n.size() - 1);
|
||||
if (l == '0')
|
||||
{
|
||||
n.chop(1);
|
||||
continue;
|
||||
}
|
||||
else if (l == '.' || l == ',')
|
||||
{
|
||||
n.chop(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while (n.startsWith("00"))
|
||||
{
|
||||
n.remove(0, 1);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
} // ns
|
||||
|
||||
//! \endcond
|
||||
|
||||
@@ -308,6 +308,12 @@ namespace BlackMisc
|
||||
//! Contains any string of the list?
|
||||
BLACKMISC_EXPORT bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs);
|
||||
|
||||
//! Parse a fraction like 2/3
|
||||
BLACKMISC_EXPORT double parseFraction(const QString &fraction, double failDefault = std::numeric_limits<double>::quiet_NaN());
|
||||
|
||||
//! Remove leading 0, trailing 0, " ", and "." from a number
|
||||
BLACKMISC_EXPORT QString cleanNumber(const QString &number);
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
/*!
|
||||
|
||||
@@ -27,7 +27,7 @@ using namespace BlackGui;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//! [SwiftApplicationDemo]
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::parseScaleFactor(argc, argv));
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::scaleFactor(argc, argv));
|
||||
QApplication qa(argc, argv);
|
||||
Q_UNUSED(qa) // init of qa is required, but qa not used
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ using namespace BlackGui;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::parseScaleFactor(argc, argv));
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::scaleFactor(argc, argv));
|
||||
QApplication qa(argc, argv);
|
||||
Q_UNUSED(qa);
|
||||
Q_UNUSED(qa)
|
||||
|
||||
CCrashHandler::instance()->init();
|
||||
CGuiApplication a(CApplicationInfo::swiftMappingTool(), CApplicationInfo::MappingTool, CIcons::swiftDatabase48());
|
||||
|
||||
@@ -24,7 +24,7 @@ using namespace BlackCore;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//! [SwiftApplicationDemo]
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::parseScaleFactor(argc, argv));
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::scaleFactor(argc, argv));
|
||||
QApplication qa(argc, argv);
|
||||
Q_UNUSED(qa) // application init needed
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ void SwiftGuiStd::init()
|
||||
sGui->initMainApplicationWidget(this);
|
||||
|
||||
// experimental: avoid mic flickering
|
||||
if (CBuildConfig::isLocalDeveloperDebugBuild()) { BlackSound::occupyAudioInputDevice(); }
|
||||
// disabled for 5.14.1
|
||||
// if (CBuildConfig::isLocalDeveloperDebugBuild()) { BlackSound::occupyAudioInputDevice(); }
|
||||
|
||||
// log messages
|
||||
m_logSubscriber.changeSubscription(CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityInfo));
|
||||
|
||||
@@ -29,7 +29,7 @@ using namespace BlackCore::Db;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//! [SwiftApplicationDemo]
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::parseScaleFactor(argc, argv));
|
||||
CGuiApplication::highDpiScreenSupport(CGuiApplication::scaleFactor(argc, argv));
|
||||
QApplication qa(argc, argv); // needed
|
||||
Q_UNUSED(qa)
|
||||
CGuiApplication a(CApplicationInfo::swiftLauncher(), CApplicationInfo::Laucher, CIcons::swiftLauncher1024());
|
||||
|
||||
@@ -483,7 +483,7 @@ void CSwiftLauncher::startButtonPressed()
|
||||
{
|
||||
const QObject *sender = QObject::sender();
|
||||
const qreal scaleFactor = ui->comp_Scale->getScaleFactor();
|
||||
CGuiApplication::highDpiScreenSupport(scaleFactor);
|
||||
CGuiApplication::highDpiScreenSupport(QString::number(scaleFactor, 'f', 4));
|
||||
|
||||
const Qt::KeyboardModifiers km = QGuiApplication::queryKeyboardModifiers();
|
||||
const bool shift = km.testFlag(Qt::ShiftModifier);
|
||||
|
||||
Reference in New Issue
Block a user