-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.cpp
More file actions
178 lines (154 loc) · 7.15 KB
/
Copy pathmain.cpp
File metadata and controls
178 lines (154 loc) · 7.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTranslator>
#include <QDir>
#include <QIcon>
#include <QPixmap>
#include <QDebug>
#include <QFont>
#include <QSurfaceFormat>
#include <QSettings>
#include "src/FanController.h"
#include "src/SystemStatsMonitor.h"
#include "src/AuraController.h"
#include "src/FanCurveController.h"
#include <stdio.h>
// Security Fix: Custom Message Handler
// Protects against Information Disclosure by suppressing debug logs in Release builds
void secureMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// Suppress noisy font warnings that cause false alarms
if (msg.contains("OpenType support missing")) {
return; // These are harmless Qt font rendering hints, not errors
}
// In Release builds (when QT_DEBUG is NOT defined), suppress Debug and Info messages
// This prevents leaking system paths, arguments, and hardware details to stdout
#ifndef QT_DEBUG
if (type == QtDebugMsg || type == QtInfoMsg) {
return;
}
#endif
// Default formatting for allowed messages
QByteArray localMsg = msg.toLocal8Bit();
const char *file = context.file ? context.file : "";
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s\n", localMsg.constData());
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s\n", localMsg.constData());
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s\n", localMsg.constData());
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u)\n", localMsg.constData(), file, context.line);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u)\n", localMsg.constData(), file, context.line);
abort();
}
}
int main(int argc, char *argv[])
{
// Performance: Force hardware OpenGL rendering (prevents software fallback)
qputenv("QSG_RENDER_LOOP", "basic"); // Use basic render loop for stability
qputenv("QT_QUICK_BACKEND", ""); // Use default (OpenGL) not software
// Fix: Suppress ALL session DBus access for a root process.
//
// Root cause of warnings:
// Qt6 tries to connect to org.freedesktop.portal.Settings (color scheme),
// org.freedesktop.portal.Background (app ID), and QSettings DBus backend.
// Previous fix forwarded the user's session bus — but the bus security
// policy REJECTS root connections, producing "NoReply" hangs (worse than
// the original "FileNotFound" error, because "NoReply" blocks for a timeout).
//
// Correct approach:
// Unset DBUS_SESSION_BUS_ADDRESS entirely. Qt then fails instantly
// with "no socket" rather than hanging for a reply that never comes.
// Combine with QT_NO_XDG_DESKTOP_PORTAL (already set) and
// an empty QT_QPA_PLATFORMTHEME to prevent all portal probes.
qunsetenv("DBUS_SESSION_BUS_ADDRESS");
qputenv("QT_NO_XDG_DESKTOP_PORTAL", "1");
qputenv("QT_QPA_PLATFORMTHEME", ""); // Disable GTK theme → no portal probes
// Use IniFormat so QSettings writes to ~/.config/AsusTuf/FanControl.ini
// instead of attempting org.freedesktop.portal.Settings DBus calls.
QSettings::setDefaultFormat(QSettings::IniFormat);
// Install Security Handler
qInstallMessageHandler(secureMessageHandler);
// Performance: Set OpenGL surface format before app creation
QSurfaceFormat format;
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
format.setSwapInterval(1); // VSync on
QSurfaceFormat::setDefaultFormat(format);
QGuiApplication app(argc, argv);
// Fix: Set fonts with proper multi-script support (Tamil, Hindi, Arabic, etc.)
// Using font families that include all script variants reduces fallback lag
QFont defaultFont;
defaultFont.setFamilies({"Noto Sans", "Noto Sans Tamil", "Noto Sans Tamil UI",
"Noto Sans Devanagari", "Noto Sans Arabic", "Noto Color Emoji"});
defaultFont.setPointSize(10);
defaultFont.setStyleHint(QFont::SansSerif);
app.setFont(defaultFont);
// Fix: Set Identity for consistent QSettings location
app.setOrganizationName("AsusTuf");
app.setApplicationName("FanControl");
// Fix: Provide the .desktop file basename as the stable App ID.
// Qt uses this to form a unique DBus name. Without it, Qt guesses
// an ID from the binary name, which can collide across sessions
// if the portal is somehow attempted (e.g., on future non-root runs).
app.setDesktopFileName("asus-tuf-fan-control");
// i18n Fix: Load Translations
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
qInfo() << "System Locale:" << QLocale::system().name();
qInfo() << "UI Languages:" << uiLanguages;
// DEBUG: List available resources
QDir resDir(":/translations");
qInfo() << "Available Translations in binary:" << resDir.entryList();
for (const QString &locale : uiLanguages) {
// Try precise match first
QString baseName = "AsusTufFanControl_" + QLocale(locale).name();
qInfo() << "Attempting to load translation:" << baseName;
if (translator.load(":/translations/" + baseName) || translator.load(":/translations/" + baseName + ".qm")) {
qInfo() << "Successfully loaded:" << baseName;
app.installTranslator(&translator);
break;
} else {
// Try fallback to just the language code (e.g. "es" from "es_ES")
QString langCode = QLocale(locale).name().split('_').first();
if (langCode != QLocale(locale).name()) {
QString fallbackName = "AsusTufFanControl_" + langCode;
qInfo() << "Attempting fallback:" << fallbackName;
if (translator.load(":/translations/" + fallbackName) || translator.load(":/translations/" + fallbackName + ".qm")) {
qInfo() << "Successfully loaded fallback:" << fallbackName;
app.installTranslator(&translator);
break;
}
}
}
}
// --- DEBUG CHECK ---
QPixmap testLoad(":/ui/app_icon.png");
if (testLoad.isNull()) {
qCritical() << "ERROR: Image failed to load! Check file path and re-run cmake.";
} else {
qInfo() << "SUCCESS: Image loaded. Size:" << testLoad.size();
app.setWindowIcon(QIcon(testLoad));
}
// -------------------
qmlRegisterType<FanController>("AsusTufFanControl", 1, 0, "FanController");
qmlRegisterType<SystemStatsMonitor>("AsusTufFanControl", 1, 0, "SystemStatsMonitor");
qmlRegisterType<AuraController>("AsusTufFanControl", 1, 0, "AuraController");
qmlRegisterType<FanCurveController>("AsusTufFanControl", 1, 0, "FanCurveController");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/ui/Main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}