Fix HiDPI and improve session

pull/6/head
reionwong 4 years ago
parent bc8d003916
commit 01f815bebf

@ -7,7 +7,7 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(QT Core Gui Widgets Quick QuickControls2 DBus X11Extras LinguistTools) set(QT Core Gui Widgets Quick QuickControls2 DBus X11Extras LinguistTools)

@ -20,6 +20,7 @@
#include "application.h" #include "application.h"
#include "sessionadaptor.h" #include "sessionadaptor.h"
// Qt
#include <QDBusConnection> #include <QDBusConnection>
#include <QStandardPaths> #include <QStandardPaths>
#include <QSettings> #include <QSettings>
@ -27,6 +28,58 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QDBusConnectionInterface>
#include <QDBusServiceWatcher>
// STL
#include <optional>
std::optional<QStringList> getSystemdEnvironment()
{
QStringList list;
auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.systemd1"),
QStringLiteral("/org/freedesktop/systemd1"),
QStringLiteral("org.freedesktop.DBus.Properties"),
QStringLiteral("Get"));
msg << QStringLiteral("org.freedesktop.systemd1.Manager") << QStringLiteral("Environment");
auto reply = QDBusConnection::sessionBus().call(msg);
if (reply.type() == QDBusMessage::ErrorMessage) {
return std::nullopt;
}
// Make sure the returned type is correct.
auto arguments = reply.arguments();
if (arguments.isEmpty() || arguments[0].userType() != qMetaTypeId<QDBusVariant>()) {
return std::nullopt;
}
auto variant = qdbus_cast<QVariant>(arguments[0]);
if (variant.type() != QVariant::StringList) {
return std::nullopt;
}
return variant.toStringList();
}
bool isShellVariable(const QByteArray &name)
{
return name == "_" || name.startsWith("SHLVL");
}
bool isSessionVariable(const QByteArray &name)
{
// Check is variable is specific to session.
return name == "DISPLAY" || name == "XAUTHORITY" || //
name == "WAYLAND_DISPLAY" || name == "WAYLAND_SOCKET" || //
name.startsWith("XDG_");
}
void setEnvironmentVariable(const QByteArray &name, const QByteArray &value)
{
if (qgetenv(name) != value) {
qputenv(name, value);
}
}
Application::Application(int &argc, char **argv) Application::Application(int &argc, char **argv)
: QApplication(argc, argv) : QApplication(argc, argv)
, m_processManager(new ProcessManager) , m_processManager(new ProcessManager)
@ -38,15 +91,24 @@ Application::Application(int &argc, char **argv)
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Session"), this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Session"), this);
createConfigDirectory(); createConfigDirectory();
initEnvironments();
initLanguage(); initLanguage();
initScreenScaleFactors(); initScreenScaleFactors();
initFontDpi();
initEnvironments();
if (!syncDBusEnvironment()) { if (!syncDBusEnvironment()) {
// Startup error // Startup error
qDebug() << "Could not sync environment to dbus."; qDebug() << "Could not sync environment to dbus.";
qApp->exit(1);
} }
// We import systemd environment after we sync the dbus environment here.
// Otherwise it may leads to some unwanted order of applying environment
// variables (e.g. LANG and LC_*)
// ref plasma
importSystemdEnvrionment();
QTimer::singleShot(100, m_processManager, &ProcessManager::start); QTimer::singleShot(100, m_processManager, &ProcessManager::start);
} }
@ -75,7 +137,6 @@ void Application::initEnvironments()
qputenv("QT_QPA_PLATFORMTHEME", "cutefish"); qputenv("QT_QPA_PLATFORMTHEME", "cutefish");
qputenv("QT_PLATFORM_PLUGIN", "cutefish"); qputenv("QT_PLATFORM_PLUGIN", "cutefish");
qunsetenv("QT_AUTO_SCREEN_SCALE_FACTOR");
qunsetenv("QT_SCALE_FACTOR"); qunsetenv("QT_SCALE_FACTOR");
qunsetenv("QT_SCREEN_SCALE_FACTORS"); qunsetenv("QT_SCREEN_SCALE_FACTORS");
qunsetenv("QT_ENABLE_HIGHDPI_SCALING"); qunsetenv("QT_ENABLE_HIGHDPI_SCALING");
@ -83,6 +144,8 @@ void Application::initEnvironments()
qunsetenv("QT_FONT_DPI"); qunsetenv("QT_FONT_DPI");
qputenv("QT_SCALE_FACTOR_ROUNDING_POLICY", "PassThrough"); qputenv("QT_SCALE_FACTOR_ROUNDING_POLICY", "PassThrough");
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
// IM Config // IM Config
qputenv("GTK_IM_MODULE", "fcitx5"); qputenv("GTK_IM_MODULE", "fcitx5");
qputenv("QT4_IM_MODULE", "fcitx5"); qputenv("QT4_IM_MODULE", "fcitx5");
@ -91,6 +154,21 @@ void Application::initEnvironments()
qputenv("XMODIFIERS", "@im=fcitx"); qputenv("XMODIFIERS", "@im=fcitx");
} }
void Application::initFontDpi()
{
QSettings settings(QSettings::UserScope, "cutefishos", "theme");
int fontDpi = settings.value("forceFontDPI", 0).toReal();
// TODO port to c++?
const QByteArray input = "Xft.dpi: " + QByteArray::number(fontDpi);
QProcess p;
p.start(QStringLiteral("xrdb"), {QStringLiteral("-quiet"), QStringLiteral("-merge"), QStringLiteral("-nocpp")});
p.setProcessChannelMode(QProcess::ForwardedChannels);
p.write(input);
p.closeWriteChannel();
p.waitForFinished(-1);
}
void Application::initLanguage() void Application::initLanguage()
{ {
QSettings settings(QSettings::UserScope, "cutefishos", "language"); QSettings settings(QSettings::UserScope, "cutefishos", "language");
@ -125,16 +203,11 @@ void Application::initScreenScaleFactors()
qreal scaleFactor = settings.value("PixelRatio", 1.0).toReal(); qreal scaleFactor = settings.value("PixelRatio", 1.0).toReal();
qputenv("QT_SCREEN_SCALE_FACTORS", QByteArray::number(scaleFactor)); qputenv("QT_SCREEN_SCALE_FACTORS", QByteArray::number(scaleFactor));
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", QByteArray::number(1));
// GDK // for Gtk
if (!isInteger(scaleFactor)) { if (qFloor(scaleFactor) > 1) {
qunsetenv("GDK_SCALE");
qputenv("GDK_DPI_SCALE", QByteArray::number(scaleFactor));
} else {
qputenv("GDK_SCALE", QByteArray::number(scaleFactor, 'g', 0)); qputenv("GDK_SCALE", QByteArray::number(scaleFactor, 'g', 0));
// Intger scale does not adjust GDK_DPI_SCALE. qputenv("GDK_DPI_SCALE", QByteArray::number(1.0 / scaleFactor, 'g', 3));
// qputenv("GDK_DPI_SCALE", QByteArray::number(scaleFactor, 'g', 3));
} }
} }
@ -150,6 +223,31 @@ bool Application::syncDBusEnvironment()
return exitCode == 0; return exitCode == 0;
} }
// Import systemd user environment.
// Systemd read ~/.config/environment.d which applies to all systemd user unit.
// But it won't work if cutefishDE is not started by systemd.
void Application::importSystemdEnvrionment()
{
auto environment = getSystemdEnvironment();
if (!environment) {
return;
}
for (auto &envString : environment.value()) {
const auto env = envString.toLocal8Bit();
const int idx = env.indexOf('=');
if (Q_UNLIKELY(idx <= 0)) {
continue;
}
const auto name = env.left(idx);
if (isShellVariable(name) || isSessionVariable(name)) {
continue;
}
setEnvironmentVariable(name, env.mid(idx + 1));
}
}
void Application::createConfigDirectory() void Application::createConfigDirectory()
{ {
const QString configDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); const QString configDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);

@ -63,9 +63,11 @@ public slots:
private: private:
void initEnvironments(); void initEnvironments();
void initFontDpi();
void initLanguage(); void initLanguage();
void initScreenScaleFactors(); void initScreenScaleFactors();
bool syncDBusEnvironment(); bool syncDBusEnvironment();
void importSystemdEnvrionment();
void createConfigDirectory(); void createConfigDirectory();
int runSync(const QString &program, const QStringList &args, const QStringList &env = {}); int runSync(const QString &program, const QStringList &args, const QStringList &env = {});

@ -21,6 +21,7 @@
#include "themeadaptor.h" #include "themeadaptor.h"
#include <QDBusInterface> #include <QDBusInterface>
#include <QProcess>
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
@ -158,6 +159,30 @@ qreal ThemeManager::devicePixelRatio()
void ThemeManager::setDevicePixelRatio(qreal ratio) void ThemeManager::setDevicePixelRatio(qreal ratio)
{ {
m_settings->setValue(s_devicePixelRatio, ratio); m_settings->setValue(s_devicePixelRatio, ratio);
// Set font dpi
// ref kscreen.
if (qFuzzyCompare(ratio, 1.0)) {
// if dpi is the default (96) remove the entry rather than setting it
QProcess proc;
proc.start(QStringLiteral("xrdb"), {QStringLiteral("-quiet"), QStringLiteral("-remove"), QStringLiteral("-nocpp")});
if (proc.waitForStarted()) {
proc.write(QByteArray("Xft.dpi\n"));
proc.closeWriteChannel();
proc.waitForFinished();
}
m_settings->setValue("forceFontDPI", 0);
} else {
const int scaleDpi = qRound(ratio * 96.0);
QProcess proc;
proc.start(QStringLiteral("xrdb"), {QStringLiteral("-quiet"), QStringLiteral("-merge"), QStringLiteral("-nocpp")});
if (proc.waitForStarted()) {
proc.write(QByteArray("Xft.dpi: " + QString::number(scaleDpi).toLatin1()));
proc.closeWriteChannel();
proc.waitForFinished();
}
m_settings->setValue("forceFontDPI", scaleDpi);
}
} }
QString ThemeManager::wallpaper() QString ThemeManager::wallpaper()

Loading…
Cancel
Save