Skip to content

Commit f3ca82a

Browse files
committed
feat: session-aware driver install/update for Wayland and X11
1 parent 8a70298 commit f3ca82a

3 files changed

Lines changed: 350 additions & 44 deletions

File tree

src/backend/nvidia/installer.cpp

Lines changed: 199 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,93 @@
11
#include "installer.h"
2+
23
#include "system/commandrunner.h"
34

4-
NvidiaInstaller::NvidiaInstaller(QObject *parent) : QObject(parent) {}
5+
#include <QtGlobal>
6+
7+
NvidiaInstaller::NvidiaInstaller(QObject *parent) : QObject(parent) {
8+
refreshProprietaryAgreement();
9+
}
10+
11+
void NvidiaInstaller::setProprietaryAgreement(bool required,
12+
const QString &text) {
13+
if (m_proprietaryAgreementRequired == required &&
14+
m_proprietaryAgreementText == text) {
15+
return;
16+
}
17+
18+
m_proprietaryAgreementRequired = required;
19+
m_proprietaryAgreementText = text;
20+
emit proprietaryAgreementChanged();
21+
}
22+
23+
void NvidiaInstaller::refreshProprietaryAgreement() {
24+
CommandRunner runner;
25+
const auto info = runner.run(QStringLiteral("dnf"),
26+
{QStringLiteral("info"),
27+
QStringLiteral("akmod-nvidia")});
28+
29+
if (!info.success()) {
30+
setProprietaryAgreement(false, QString());
31+
return;
32+
}
33+
34+
QString licenseLine;
35+
const QStringList lines = info.stdout.split(QLatin1Char('\n'));
36+
for (const QString &line : lines) {
37+
if (line.startsWith(QStringLiteral("License"), Qt::CaseInsensitive)) {
38+
licenseLine = line;
39+
break;
40+
}
41+
}
42+
43+
const QString lowered = licenseLine.toLower();
44+
const bool requiresAgreement = lowered.contains(QStringLiteral("eula")) ||
45+
lowered.contains(QStringLiteral("proprietary")) ||
46+
lowered.contains(QStringLiteral("nvidia"));
47+
48+
if (requiresAgreement) {
49+
setProprietaryAgreement(
50+
true,
51+
QStringLiteral("Kapali kaynak NVIDIA surucusunu kurmadan once lisans "
52+
"kosullarini kabul etmeniz gerekir. Tespit edilen lisans: %1")
53+
.arg(licenseLine.isEmpty() ? QStringLiteral("Bilinmiyor")
54+
: licenseLine));
55+
return;
56+
}
57+
58+
setProprietaryAgreement(false, QString());
59+
}
60+
61+
void NvidiaInstaller::install() { installProprietary(false); }
62+
63+
void NvidiaInstaller::installProprietary(bool agreementAccepted) {
64+
refreshProprietaryAgreement();
65+
66+
if (m_proprietaryAgreementRequired && !agreementAccepted) {
67+
emit installFinished(
68+
false,
69+
QStringLiteral("Kurulumdan once lisans/sozlesme onayi gereklidir."));
70+
return;
71+
}
572

6-
void NvidiaInstaller::install() {
773
CommandRunner runner;
874

9-
// CommandRunner'dan gelen her satırı QML'e ilet
1075
connect(&runner, &CommandRunner::outputLine, this,
1176
&NvidiaInstaller::progressMessage);
1277

1378
emit progressMessage(QStringLiteral("RPM Fusion deposu kontrol ediliyor..."));
1479

1580
CommandRunner rpmRunner;
16-
const auto fedora = rpmRunner.run(QStringLiteral("rpm"),
17-
{QStringLiteral("-E"), QStringLiteral("%fedora")});
18-
const QString fedoraVersion = fedora.stdout.trimmed();
81+
const auto fedoraResult =
82+
rpmRunner.run(QStringLiteral("rpm"),
83+
{QStringLiteral("-E"), QStringLiteral("%fedora")});
1984

85+
const QString fedoraVersion = fedoraResult.stdout.trimmed();
2086
if (fedoraVersion.isEmpty()) {
2187
emit installFinished(false, QStringLiteral("Fedora surumu tespit edilemedi."));
2288
return;
2389
}
2490

25-
// Adım 1: RPM Fusion reposunu etkinleştir
2691
auto result = runner.runAsRoot(
2792
QStringLiteral("dnf"),
2893
{QStringLiteral("install"), QStringLiteral("-y"),
@@ -40,37 +105,85 @@ void NvidiaInstaller::install() {
40105
return;
41106
}
42107

43-
emit progressMessage(
44-
QStringLiteral("NVIDIA sürücüsü kuruluyor (akmod-nvidia)..."));
108+
emit progressMessage(QStringLiteral(
109+
"Kapali kaynak NVIDIA surucusu kuruluyor (akmod-nvidia)..."));
45110

46-
// Adım 2: akmod-nvidia kur
47111
result = runner.runAsRoot(QStringLiteral("dnf"),
48112
{QStringLiteral("install"), QStringLiteral("-y"),
49113
QStringLiteral("akmod-nvidia")});
50114

51115
if (!result.success()) {
52116
emit installFinished(false,
53-
QStringLiteral("Kurulum başarısız: ") + result.stderr);
117+
QStringLiteral("Kurulum basarisiz: ") + result.stderr);
54118
return;
55119
}
56120

57-
emit progressMessage(QStringLiteral(
58-
"Kernel modülü derleniyor (bu birkaç dakika sürebilir)..."));
59-
60-
// Adım 3: akmods ile modülü derle
121+
emit progressMessage(
122+
QStringLiteral("Kernel modulu derleniyor (akmods --force)..."));
61123
runner.runAsRoot(QStringLiteral("akmods"), {QStringLiteral("--force")});
62124

125+
const QString sessionType = detectSessionType();
126+
QString sessionError;
127+
if (!applySessionSpecificSetup(runner, sessionType, &sessionError)) {
128+
emit installFinished(false, sessionError);
129+
return;
130+
}
131+
132+
emit installFinished(
133+
true,
134+
QStringLiteral("Kapali kaynak NVIDIA surucusu basariyla kuruldu. "
135+
"Lutfen sistemi yeniden baslatin."));
136+
}
137+
138+
void NvidiaInstaller::installOpenSource() {
139+
CommandRunner runner;
140+
141+
connect(&runner, &CommandRunner::outputLine, this,
142+
&NvidiaInstaller::progressMessage);
143+
144+
emit progressMessage(
145+
QStringLiteral("Acik kaynak surucuye gecis baslatiliyor..."));
146+
147+
// Once kapali kaynak paketleri kaldir.
148+
auto result = runner.runAsRoot(
149+
QStringLiteral("dnf"),
150+
{QStringLiteral("remove"), QStringLiteral("-y"),
151+
QStringLiteral("akmod-nvidia"), QStringLiteral("xorg-x11-drv-nvidia*")});
152+
153+
if (!result.success()) {
154+
emit installFinished(false,
155+
QStringLiteral("Kapali kaynak paket kaldirma basarisiz: ") +
156+
result.stderr);
157+
return;
158+
}
159+
160+
// Nouveau ve temel Mesa paketlerini garanti altina al.
161+
result = runner.runAsRoot(
162+
QStringLiteral("dnf"),
163+
{QStringLiteral("install"), QStringLiteral("-y"),
164+
QStringLiteral("xorg-x11-drv-nouveau"),
165+
QStringLiteral("mesa-dri-drivers")});
166+
167+
if (!result.success()) {
168+
emit installFinished(false,
169+
QStringLiteral("Acik kaynak surucu kurulumu basarisiz: ") +
170+
result.stderr);
171+
return;
172+
}
173+
174+
runner.runAsRoot(QStringLiteral("dracut"), {QStringLiteral("--force")});
175+
63176
emit installFinished(true,
64-
QStringLiteral("NVIDIA sürücüsü başarıyla kuruldu. "
65-
"Lütfen sistemi yeniden başlatın."));
177+
QStringLiteral("Acik kaynak surucu (Nouveau) kuruldu. "
178+
"Lutfen sistemi yeniden baslatin."));
66179
}
67180

68181
void NvidiaInstaller::remove() {
69182
CommandRunner runner;
70183
connect(&runner, &CommandRunner::outputLine, this,
71184
&NvidiaInstaller::progressMessage);
72185

73-
emit progressMessage(QStringLiteral("NVIDIA sürücüsü kaldırılıyor..."));
186+
emit progressMessage(QStringLiteral("NVIDIA surucusu kaldiriliyor..."));
74187

75188
const auto result = runner.runAsRoot(
76189
QStringLiteral("dnf"),
@@ -79,8 +192,8 @@ void NvidiaInstaller::remove() {
79192

80193
emit removeFinished(result.success(),
81194
result.success()
82-
? QStringLiteral("Sürücü başarıyla kaldırıldı.")
83-
: QStringLiteral("Kaldırma başarısız: ") +
195+
? QStringLiteral("Surucu basariyla kaldirildi.")
196+
: QStringLiteral("Kaldirma basarisiz: ") +
84197
result.stderr);
85198
}
86199

@@ -90,16 +203,78 @@ void NvidiaInstaller::deepClean() {
90203
&NvidiaInstaller::progressMessage);
91204

92205
emit progressMessage(
93-
QStringLiteral("Eski sürücü kalıntıları temizleniyor..."));
206+
QStringLiteral("Eski surucu kalintilari temizleniyor..."));
94207

95-
// Tüm nvidia paketlerini kaldır
96208
runner.runAsRoot(QStringLiteral("dnf"),
97209
{QStringLiteral("remove"), QStringLiteral("-y"),
98210
QStringLiteral("*nvidia*"), QStringLiteral("*akmod*")});
99211

100-
// DNF cache temizle
101212
runner.runAsRoot(QStringLiteral("dnf"),
102213
{QStringLiteral("clean"), QStringLiteral("all")});
103214

104-
emit progressMessage(QStringLiteral("Temizlik tamamlandı."));
215+
emit progressMessage(QStringLiteral("Deep clean tamamlandi."));
216+
}
217+
218+
QString NvidiaInstaller::detectSessionType() const {
219+
const QString envType = qEnvironmentVariable("XDG_SESSION_TYPE").trimmed().toLower();
220+
if (!envType.isEmpty())
221+
return envType;
222+
223+
CommandRunner runner;
224+
const auto loginctl = runner.run(
225+
QStringLiteral("loginctl"),
226+
{QStringLiteral("show-session"), qEnvironmentVariable("XDG_SESSION_ID"),
227+
QStringLiteral("-p"), QStringLiteral("Type"), QStringLiteral("--value")});
228+
229+
if (loginctl.success()) {
230+
const QString type = loginctl.stdout.trimmed().toLower();
231+
if (!type.isEmpty())
232+
return type;
233+
}
234+
235+
return QStringLiteral("unknown");
236+
}
237+
238+
bool NvidiaInstaller::applySessionSpecificSetup(CommandRunner &runner,
239+
const QString &sessionType,
240+
QString *errorMessage) {
241+
if (sessionType == QStringLiteral("wayland")) {
242+
emit progressMessage(
243+
QStringLiteral("Wayland tespit edildi: nvidia-drm.modeset=1 ayari uygulaniyor..."));
244+
245+
const auto result = runner.runAsRoot(
246+
QStringLiteral("grubby"),
247+
{QStringLiteral("--update-kernel=ALL"),
248+
QStringLiteral("--args=nvidia-drm.modeset=1")});
249+
250+
if (!result.success()) {
251+
if (errorMessage) {
252+
*errorMessage = QStringLiteral(
253+
"Wayland icin kernel parametresi uygulanamadi: ") +
254+
result.stderr;
255+
}
256+
return false;
257+
}
258+
return true;
259+
}
260+
261+
if (sessionType == QStringLiteral("x11")) {
262+
emit progressMessage(
263+
QStringLiteral("X11 tespit edildi: X11 NVIDIA userspace paketleri kontrol ediliyor..."));
264+
265+
const auto result = runner.runAsRoot(
266+
QStringLiteral("dnf"),
267+
{QStringLiteral("install"), QStringLiteral("-y"),
268+
QStringLiteral("xorg-x11-drv-nvidia")});
269+
270+
if (!result.success()) {
271+
if (errorMessage) {
272+
*errorMessage =
273+
QStringLiteral("X11 NVIDIA paketi kurulurken hata: ") + result.stderr;
274+
}
275+
return false;
276+
}
277+
}
278+
279+
return true;
105280
}

src/backend/nvidia/installer.h

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,61 @@
33
#include <QObject>
44
#include <QString>
55

6+
class CommandRunner;
7+
68
// NvidiaInstaller: DNF üzerinden NVIDIA sürücü kurulum/kaldırma işlemleri.
79
// Tüm işlemler root gerektirir — polkit üzerinden yetki alınır.
8-
class NvidiaInstaller : public QObject
9-
{
10-
Q_OBJECT
10+
class NvidiaInstaller : public QObject {
11+
Q_OBJECT
12+
13+
Q_PROPERTY(bool proprietaryAgreementRequired READ proprietaryAgreementRequired
14+
NOTIFY proprietaryAgreementChanged)
15+
Q_PROPERTY(QString proprietaryAgreementText READ proprietaryAgreementText
16+
NOTIFY proprietaryAgreementChanged)
1117

1218
public:
13-
explicit NvidiaInstaller(QObject *parent = nullptr);
19+
explicit NvidiaInstaller(QObject *parent = nullptr);
20+
21+
bool proprietaryAgreementRequired() const {
22+
return m_proprietaryAgreementRequired;
23+
}
24+
QString proprietaryAgreementText() const { return m_proprietaryAgreementText; }
25+
26+
// Sozlesme durumunu yeniden kontrol et
27+
Q_INVOKABLE void refreshProprietaryAgreement();
28+
29+
// Kapali kaynak kurulum (kullanici onayi bilgisiyle)
30+
Q_INVOKABLE void installProprietary(bool agreementAccepted);
1431

15-
// Sürücüyü kur (akmod-nvidia)
16-
Q_INVOKABLE void install();
32+
// Acik kaynak surucuye gecis/kurulum
33+
Q_INVOKABLE void installOpenSource();
1734

18-
// Sürücüyü kaldır
19-
Q_INVOKABLE void remove();
35+
// Sürücüyü kur (akmod-nvidia)
36+
Q_INVOKABLE void install();
2037

21-
// Eski sürücü kalıntılarını temizle
22-
Q_INVOKABLE void deepClean();
38+
// Sürücüyü kaldır
39+
Q_INVOKABLE void remove();
40+
41+
// Eski sürücü kalıntılarını temizle
42+
Q_INVOKABLE void deepClean();
2343

2444
signals:
25-
// İşlem adımları — QML'e ilerleme göstermek için
26-
void progressMessage(const QString &message);
45+
// İşlem adımları — QML'e ilerleme göstermek için
46+
void progressMessage(const QString &message);
47+
48+
void proprietaryAgreementChanged();
49+
50+
// İşlem tamamlandı
51+
void installFinished(bool success, const QString &message);
52+
void removeFinished(bool success, const QString &message);
53+
54+
private:
55+
void setProprietaryAgreement(bool required, const QString &text);
56+
QString detectSessionType() const;
57+
bool applySessionSpecificSetup(CommandRunner &runner,
58+
const QString &sessionType,
59+
QString *errorMessage);
2760

28-
// İşlem tamamlandı
29-
void installFinished(bool success, const QString &message);
30-
void removeFinished(bool success, const QString &message);
61+
bool m_proprietaryAgreementRequired = false;
62+
QString m_proprietaryAgreementText;
3163
};

0 commit comments

Comments
 (0)