Skip to content

Commit

Permalink
Merge pull request #3960 from daschuer/Q_SCALE_FACTOR
Browse files Browse the repository at this point in the history
Q scale factor from preferences
  • Loading branch information
uklotzde authored Sep 14, 2021
2 parents 5b8a7a5 + 46182d1 commit ac51d27
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 128 deletions.
38 changes: 38 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QThread>
#include <QtDebug>

#include "config.h"
#include "coreservices.h"
#include "errordialoghandler.h"
#include "mixxxapplication.h"
Expand All @@ -22,6 +23,10 @@ namespace {
constexpr int kFatalErrorOnStartupExitCode = 1;
constexpr int kParseCmdlineArgsErrorExitCode = 2;

constexpr char kScaleFactorEnvVar[] = "QT_SCALE_FACTOR";
const QString kConfigGroup = QStringLiteral("[Config]");
const QString kScaleFactorKey = QStringLiteral("ScaleFactor");

int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) {
const auto pCoreServices = std::make_shared<mixxx::CoreServices>(args, pApp);

Expand Down Expand Up @@ -59,6 +64,37 @@ int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) {
return exitCode;
}

void adjustScaleFactor(CmdlineArgs* pArgs) {
if (qEnvironmentVariableIsSet(kScaleFactorEnvVar)) {
bool ok;
const double f = qgetenv(kScaleFactorEnvVar).toDouble(&ok);
if (ok && f > 0) {
// The environment variable overrides the preferences option
qDebug() << "Using" << kScaleFactorEnvVar << f;
pArgs->setScaleFactor(f);
return;
}
}
// We cannot use SettingsManager, because it depends on MixxxApplication
// but the scale factor is read during it's constructor.
// QHighDpiScaling can not be used afterwards because it is private.
// This means the following code may fail after down/upgrade ... a one time issue.

// Read and parse the config file from the settings path
auto config = ConfigObject<ConfigValue>(
QDir(pArgs->getSettingsPath()).filePath(MIXXX_SETTINGS_FILE),
QString(),
QString());
QString strScaleFactor = config.getValue(
ConfigKey(kConfigGroup, kScaleFactorKey));
double scaleFactor = strScaleFactor.toDouble();
if (scaleFactor > 0) {
qDebug() << "Using preferences ScaleFactor" << scaleFactor;
qputenv(kScaleFactorEnvVar, strScaleFactor.toLocal8Bit());
pArgs->setScaleFactor(scaleFactor);
}
}

} // anonymous namespace

int main(int argc, char * argv[]) {
Expand Down Expand Up @@ -110,6 +146,8 @@ int main(int argc, char * argv[]) {
Sandbox::checkSandboxed();
#endif

adjustScaleFactor(&args);

MixxxApplication app(argc, argv);

#ifdef __APPLE__
Expand Down
16 changes: 13 additions & 3 deletions src/preferences/configobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,19 @@ ConfigValueKbd::ConfigValueKbd(const QKeySequence& keys)
QTextStream(&value) << m_keys.toString();
}

template <class ValueType> ConfigObject<ValueType>::ConfigObject(const QString& file)
: m_resourcePath(computeResourcePath()),
m_settingsPath(computeSettingsPath(file)) {
template<class ValueType>
ConfigObject<ValueType>::ConfigObject(const QString& file)
: ConfigObject(file, computeResourcePath(), computeSettingsPath(file)) {
reopen(file);
}

template<class ValueType>
ConfigObject<ValueType>::ConfigObject(
const QString& file,
const QString& resourcePath,
const QString& settingsPath)
: m_resourcePath(resourcePath),
m_settingsPath(settingsPath) {
reopen(file);
}

Expand Down
1 change: 1 addition & 0 deletions src/preferences/configobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ inline bool operator!=(const ConfigValueKbd& lhs, const ConfigValueKbd& rhs) {
template <class ValueType> class ConfigObject {
public:
ConfigObject(const QString& file);
ConfigObject(const QString& file, const QString& resourcePath, const QString& settingsPath);
ConfigObject(const QDomNode& node);
~ConfigObject();

Expand Down
109 changes: 48 additions & 61 deletions src/preferences/dialog/dlgprefinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
using mixxx::skin::SkinManifest;
using mixxx::skin::SkinPointer;

namespace {

const QString kConfigGroup = QStringLiteral("[Config]");
const QString kControlsGroup = QStringLiteral("[Controls]");
const QString kScaleFactorKey = QStringLiteral("ScaleFactor");
const QString kStartInFullscreenKey = QStringLiteral("StartInFullscreen");
const QString kSchemeKey = QStringLiteral("Scheme");
const QString kResizableSkinKey = QStringLiteral("ResizableSkin");
const QString kLocaleKey = QStringLiteral("Locale");
const QString kTooltipsKey = QStringLiteral("Tooltips");

} // namespace

DlgPrefInterface::DlgPrefInterface(
QWidget* parent,
std::shared_ptr<mixxx::ScreensaverManager> pScreensaverManager,
Expand All @@ -34,9 +47,8 @@ DlgPrefInterface::DlgPrefInterface(
m_pScreensaverManager(pScreensaverManager),
m_pSkinLoader(pSkinLoader),
m_pSkin(pSkinLoader->getConfiguredSkin()),
m_dScaleFactorAuto(1.0),
m_bUseAutoScaleFactor(false),
m_dScaleFactor(1.0),
m_minScaleFactor(1.0),
m_dDevicePixelRatio(1.0),
m_bStartWithFullScreen(false),
m_bRebootMixxxView(false) {
Expand All @@ -45,6 +57,16 @@ DlgPrefInterface::DlgPrefInterface(
// get the pixel ratio to display a crisp skin preview when Mixxx is scaled
m_dDevicePixelRatio = getDevicePixelRatioF(this);

// Calculate the minimum scale factor that leads to a device pixel ratio of 1.0
// m_dDevicePixelRatio must not drop below 1.0 because this creates an
// unusable GUI with visual artefacts
double initialScaleFactor = CmdlineArgs::Instance().getScaleFactor();
if (initialScaleFactor <= 0) {
initialScaleFactor = 1.0;
}
double unscaledDevicePixelRatio = m_dDevicePixelRatio / initialScaleFactor;
m_minScaleFactor = 1 / unscaledDevicePixelRatio;

VERIFY_OR_DEBUG_ASSERT(m_pSkin != nullptr) {
qWarning() << "Skipping creation of DlgPrefInterface because there is no skin available.";
return;
Expand Down Expand Up @@ -149,13 +171,9 @@ DlgPrefInterface::DlgPrefInterface(
this,
&DlgPrefInterface::slotSetScheme);

checkBoxScaleFactorAuto->hide();
spinBoxScaleFactor->hide();
labelScaleFactor->hide();

// Start in fullscreen mode
checkBoxStartFullScreen->setChecked(m_pConfig->getValueString(
ConfigKey("[Config]", "StartInFullscreen")).toInt()==1);
checkBoxStartFullScreen->setChecked(
m_pConfig->getValue(ConfigKey(kConfigGroup, kStartInFullscreenKey), 0) == 1);

// Screensaver mode
comboBoxScreensaver->clear();
Expand Down Expand Up @@ -211,7 +229,7 @@ void DlgPrefInterface::slotUpdateSchemes() {
m_colorScheme = QString();
} else {
ComboBoxSchemeconf->setEnabled(true);
QString configScheme = m_pConfig->getValueString(ConfigKey("[Config]", "Scheme"));
QString configScheme = m_pConfig->getValue(ConfigKey(kConfigGroup, kSchemeKey));
bool foundConfigScheme = false;
for (int i = 0; i < schlist.size(); i++) {
ComboBoxSchemeconf->addItem(schlist[i]);
Expand All @@ -234,7 +252,7 @@ void DlgPrefInterface::slotUpdateSchemes() {

void DlgPrefInterface::slotUpdate() {
const QString skinNameOnUpdate =
m_pConfig->getValueString(ConfigKey("[Config]", "ResizableSkin"));
m_pConfig->getValue(ConfigKey(kConfigGroup, kResizableSkinKey));
const SkinPointer pSkinOnUpdate = m_skins[skinNameOnUpdate];
if (pSkinOnUpdate != nullptr && pSkinOnUpdate->isValid()) {
m_skinNameOnUpdate = pSkinOnUpdate->name();
Expand All @@ -245,19 +263,18 @@ void DlgPrefInterface::slotUpdate() {
slotUpdateSchemes();
m_bRebootMixxxView = false;

m_localeOnUpdate = m_pConfig->getValueString(ConfigKey("[Config]", "Locale"));
m_localeOnUpdate = m_pConfig->getValue(ConfigKey(kConfigGroup, kLocaleKey));
ComboBoxLocale->setCurrentIndex(ComboBoxLocale->findData(m_localeOnUpdate));

checkBoxScaleFactorAuto->setChecked(m_pConfig->getValue(
ConfigKey("[Config]", "ScaleFactorAuto"), m_bUseAutoScaleFactor));

// The spinbox shows a percentage but Mixxx stores a multiplication factor
// with 1.00 as no scaling, so multiply the stored value by 100.
spinBoxScaleFactor->setValue(m_pConfig->getValue(
ConfigKey("[Config]", "ScaleFactor"), m_dScaleFactor) * 100);
double configScaleFactor = m_pConfig->getValue(
ConfigKey(kConfigGroup, kScaleFactorKey), m_dScaleFactor);
spinBoxScaleFactor->setValue(configScaleFactor * 100);
spinBoxScaleFactor->setMinimum(m_minScaleFactor * 100);

checkBoxStartFullScreen->setChecked(m_pConfig->getValue(
ConfigKey("[Config]", "StartInFullscreen"), m_bStartWithFullScreen));
ConfigKey(kConfigGroup, kStartInFullscreenKey), m_bStartWithFullScreen));

loadTooltipPreferenceFromConfig();

Expand All @@ -276,9 +293,6 @@ void DlgPrefInterface::slotResetToDefaults() {
// Default to normal size widgets
// The spinbox shows a percentage with 100% as no scaling.
spinBoxScaleFactor->setValue(100);
if (m_dScaleFactorAuto > 0) {
checkBoxScaleFactorAuto->setChecked(true);
}

// Don't start in full screen.
checkBoxStartFullScreen->setChecked(false);
Expand All @@ -291,29 +305,6 @@ void DlgPrefInterface::slotResetToDefaults() {
radioButtonTooltipsLibraryAndSkin->setChecked(true);
}

void DlgPrefInterface::slotSetScaleFactor(double newValue) {
// The spinbox shows a percentage, but Mixxx stores a multiplication factor
// with 1.00 as no change.
newValue /= 100.0;
if (m_dScaleFactor != newValue) {
m_dScaleFactor = newValue;
m_bRebootMixxxView = true;
}
}

void DlgPrefInterface::slotSetScaleFactorAuto(bool newValue) {
if (newValue) {
if (!m_bUseAutoScaleFactor) {
m_bRebootMixxxView = true;
}
} else {
slotSetScaleFactor(newValue);
}

m_bUseAutoScaleFactor = newValue;
spinBoxScaleFactor->setEnabled(!newValue);
}

void DlgPrefInterface::slotSetTooltips() {
m_tooltipMode = mixxx::TooltipsPreference::TOOLTIPS_ON;
if (radioButtonTooltipsOff->isChecked()) {
Expand All @@ -325,9 +316,10 @@ void DlgPrefInterface::slotSetTooltips() {

void DlgPrefInterface::notifyRebootNecessary() {
// make the fact that you have to restart mixxx more obvious
QMessageBox::information(
this, tr("Information"),
tr("Mixxx must be restarted before the new locale setting will take effect."));
QMessageBox::information(this,
tr("Information"),
tr("Mixxx must be restarted before the new locale or scaling "
"settings will take effect."));
}

void DlgPrefInterface::slotSetScheme(int) {
Expand Down Expand Up @@ -389,26 +381,20 @@ void DlgPrefInterface::slotSetSkin(int) {
}

void DlgPrefInterface::slotApply() {
m_pConfig->set(ConfigKey("[Config]", "ResizableSkin"), m_pSkin->name());
m_pConfig->set(ConfigKey("[Config]", "Scheme"), m_colorScheme);
m_pConfig->set(ConfigKey(kConfigGroup, kResizableSkinKey), m_pSkin->name());
m_pConfig->set(ConfigKey(kConfigGroup, kSchemeKey), m_colorScheme);

QString locale = ComboBoxLocale->itemData(
ComboBoxLocale->currentIndex()).toString();
m_pConfig->set(ConfigKey("[Config]", "Locale"), locale);
m_pConfig->set(ConfigKey(kConfigGroup, kLocaleKey), locale);

m_pConfig->setValue(
ConfigKey("[Config]", "ScaleFactorAuto"), m_bUseAutoScaleFactor);
if (m_bUseAutoScaleFactor) {
m_pConfig->setValue(
ConfigKey("[Config]", "ScaleFactor"), m_dScaleFactorAuto);
} else {
m_pConfig->setValue(ConfigKey("[Config]", "ScaleFactor"), m_dScaleFactor);
}
double scaleFactor = spinBoxScaleFactor->value() / 100;
m_pConfig->setValue(ConfigKey(kConfigGroup, kScaleFactorKey), scaleFactor);

m_pConfig->set(ConfigKey("[Config]", "StartInFullscreen"),
m_pConfig->set(ConfigKey(kConfigGroup, kStartInFullscreenKey),
ConfigValue(checkBoxStartFullScreen->isChecked()));

m_pConfig->set(ConfigKey("[Controls]", "Tooltips"),
m_pConfig->set(ConfigKey(kControlsGroup, kTooltipsKey),
ConfigValue(static_cast<int>(m_tooltipMode)));
emit tooltipModeChanged(m_tooltipMode);

Expand All @@ -421,10 +407,11 @@ void DlgPrefInterface::slotApply() {
static_cast<mixxx::ScreenSaverPreference>(screensaverComboBoxState));
}

if (locale != m_localeOnUpdate) {
if (locale != m_localeOnUpdate || scaleFactor != m_dScaleFactor) {
notifyRebootNecessary();
// hack to prevent showing the notification when pressing "Okay" after "Apply"
m_localeOnUpdate = locale;
m_dScaleFactor = scaleFactor;
}

if (m_bRebootMixxxView) {
Expand All @@ -437,7 +424,7 @@ void DlgPrefInterface::slotApply() {

void DlgPrefInterface::loadTooltipPreferenceFromConfig() {
const auto tooltipMode = static_cast<mixxx::TooltipsPreference>(
m_pConfig->getValue(ConfigKey("[Controls]", "Tooltips"),
m_pConfig->getValue(ConfigKey(kControlsGroup, kTooltipsKey),
static_cast<int>(mixxx::TooltipsPreference::TOOLTIPS_ON)));
switch (tooltipMode) {
case mixxx::TooltipsPreference::TOOLTIPS_OFF:
Expand Down
5 changes: 1 addition & 4 deletions src/preferences/dialog/dlgprefinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg
void slotSetSkinDescription();
void slotSetSkinPreview();
void slotUpdateSchemes();
void slotSetScaleFactor(double newValue);
void slotSetScaleFactorAuto(bool checked);

signals:
void reloadUserInterface();
Expand Down Expand Up @@ -75,9 +73,8 @@ class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg
QString m_colorScheme;
QString m_localeOnUpdate;
mixxx::TooltipsPreference m_tooltipMode;
double m_dScaleFactorAuto;
bool m_bUseAutoScaleFactor;
double m_dScaleFactor;
double m_minScaleFactor;
double m_dDevicePixelRatio;
bool m_bStartWithFullScreen;
mixxx::ScreenSaverPreference m_screensaverMode;
Expand Down
Loading

0 comments on commit ac51d27

Please sign in to comment.