From 4b86490ef68b6f6cb240769acda3f822b27992ef Mon Sep 17 00:00:00 2001 From: mirkobrombin Date: Sat, 10 Sep 2022 12:27:47 +0200 Subject: [PATCH] add support to nvidia proprietary drivers --- vanilla_first_setup/dialogs/meson.build | 1 + vanilla_first_setup/dialogs/prop_drivers.py | 26 +++++++++ vanilla_first_setup/gtk/dialog-prop-nvidia.ui | 36 ++++++++++++ vanilla_first_setup/gtk/window.ui | 57 +++++++++++++++++++ vanilla_first_setup/models/config.py | 27 +++++++-- vanilla_first_setup/models/preset.py | 1 + vanilla_first_setup/utils/checks.py | 5 ++ vanilla_first_setup/utils/configurator.py | 8 +++ .../vanilla-first-setup.gresource.xml | 1 + vanilla_first_setup/window.py | 35 ++++++++++-- 10 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 vanilla_first_setup/dialogs/prop_drivers.py create mode 100644 vanilla_first_setup/gtk/dialog-prop-nvidia.ui diff --git a/vanilla_first_setup/dialogs/meson.build b/vanilla_first_setup/dialogs/meson.build index 1d436de..41ed659 100644 --- a/vanilla_first_setup/dialogs/meson.build +++ b/vanilla_first_setup/dialogs/meson.build @@ -4,6 +4,7 @@ dialogsdir = join_paths(pkgdatadir, 'vanilla_first_setup/dialogs') sources = [ '__init__.py', 'subsystem.py', + 'prop_drivers.py', ] install_data(sources, install_dir: dialogsdir) \ No newline at end of file diff --git a/vanilla_first_setup/dialogs/prop_drivers.py b/vanilla_first_setup/dialogs/prop_drivers.py new file mode 100644 index 0000000..8075c9e --- /dev/null +++ b/vanilla_first_setup/dialogs/prop_drivers.py @@ -0,0 +1,26 @@ +# prop_nvidia.py +# +# Copyright 2022 mirkobrombin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundationat version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from gi.repository import Gtk, Adw + + +@Gtk.Template(resource_path='/pm/mirko/FirstSetup/gtk/dialog-prop-nvidia.ui') +class ProprietaryDriverDialog(Adw.Window): + __gtype_name__ = 'ProprietaryDriverDialog' + + def __init__(self, window, **kwargs): + super().__init__(**kwargs) + self.set_transient_for(window) diff --git a/vanilla_first_setup/gtk/dialog-prop-nvidia.ui b/vanilla_first_setup/gtk/dialog-prop-nvidia.ui new file mode 100644 index 0000000..c6849a6 --- /dev/null +++ b/vanilla_first_setup/gtk/dialog-prop-nvidia.ui @@ -0,0 +1,36 @@ + + + + + + \ No newline at end of file diff --git a/vanilla_first_setup/gtk/window.ui b/vanilla_first_setup/gtk/window.ui index 2fce80e..87c07cb 100644 --- a/vanilla_first_setup/gtk/window.ui +++ b/vanilla_first_setup/gtk/window.ui @@ -182,6 +182,63 @@ + + + + video-display-symbolic + Proprietary Nvidia Drivers + Want to use Nvidia proprietary drivers for better performance and compatibility? + fill + fill + true + false + + + vertical + True + True + fill + center + 10 + + + center + 10 + center + + + No + center + + + + + + Yes, install + center + + + + + + dialog-information-symbolic + + + + + + + + + + diff --git a/vanilla_first_setup/models/config.py b/vanilla_first_setup/models/config.py index 2958bbb..d374526 100644 --- a/vanilla_first_setup/models/config.py +++ b/vanilla_first_setup/models/config.py @@ -6,17 +6,30 @@ logger = logging.getLogger("FirstSetup::Config") class Config: - def __init__(self, snap: bool, flatpak: bool, appimage: bool, apport: bool, distrobox: bool): + def __init__( + self, + snap: bool, + flatpak: bool, + appimage: bool, + apport: bool, + distrobox: bool, + nvidia: bool + ): self.snap = snap self.flatpak = flatpak self.appimage = appimage self.apport = apport self.distrobox = distrobox + self.nvidia = nvidia def get_str(self) -> str: - return "snap::{0}|flatpak::{1}|appimage::{2}|apport::{3}|distrobox::{4}".format( - self.snap, self.flatpak, self.appimage, self.apport, self.distrobox - ) + keys = [ + "snap", "flatpak", "appimage", "apport", "distrobox", "nvidia" + ] + vals = [ + self.snap, self.flatpak, self.appimage, self.apport, self.distrobox, self.nvidia + ] + return "|".join([f"{key}::{val}" for key, val in zip(keys, vals)]) def set_val(self, key: str, val: bool): if key == "snap": @@ -29,6 +42,8 @@ class Config: self.apport = val elif key == "distrobox": self.distrobox = val + elif key == "nvidia": + self.nvidia = val else: return @@ -46,11 +61,13 @@ class Config: appimage = items[2].split('::')[1] apport = items[3].split('::')[1] distrobox = items[4].split('::')[1] + nvidia = items[5].split('::')[1] return cls( snap=get_bool(snap), flatpak=get_bool(flatpak), appimage=get_bool(appimage), apport=get_bool(apport), - distrobox=get_bool(distrobox) + distrobox=get_bool(distrobox), + nvidia=get_bool(nvidia) ) diff --git a/vanilla_first_setup/models/preset.py b/vanilla_first_setup/models/preset.py index 8c74f25..39ce0ad 100644 --- a/vanilla_first_setup/models/preset.py +++ b/vanilla_first_setup/models/preset.py @@ -5,3 +5,4 @@ class Preset: appimage: bool = False apport: bool = False distrobox: bool = True + nvidia: bool = False diff --git a/vanilla_first_setup/utils/checks.py b/vanilla_first_setup/utils/checks.py index d3c8425..29f556c 100644 --- a/vanilla_first_setup/utils/checks.py +++ b/vanilla_first_setup/utils/checks.py @@ -1,3 +1,4 @@ +import subprocess import shutil @@ -11,3 +12,7 @@ def is_flatpak_installed(): def is_apport_installed(): return shutil.which('apport') is not None + + +def has_nvidia_gpu(): + return subprocess.run(['lspci'], stdout=subprocess.PIPE).stdout.decode('utf-8').find('VGA compatible controller: NVIDIA Corporation') != -1 diff --git a/vanilla_first_setup/utils/configurator.py b/vanilla_first_setup/utils/configurator.py index 6a85c35..5006617 100644 --- a/vanilla_first_setup/utils/configurator.py +++ b/vanilla_first_setup/utils/configurator.py @@ -26,6 +26,8 @@ class Configurator: self.__enable_apport() if self.config.apport else self.__disable_apport() if self.config.distrobox: self.__enable_distrobox() + if self.config.nvidia: + self.__enable_nvidia() def __fake(self, msg: str): time.sleep(1) @@ -105,6 +107,12 @@ class Configurator: proc = subprocess.run(['curl', '-s', 'https://raw.githubusercontent.com/89luca89/distrobox/main/install'], stdout=subprocess.PIPE) proc = subprocess.run(['sudo', 'sh'], input=proc.stdout, stdout=subprocess.PIPE) + def __enable_nvidia(self): + if self.fake: + return self.__fake("Fake: Nvidia enabled") + + proc.subprocess.run(['sudo', 'ubuntu-drivers', 'install', '--recommended']) + def __disable_on_startup(self): if self.fake: return self.__fake("Fake: Disable on startup") diff --git a/vanilla_first_setup/vanilla-first-setup.gresource.xml b/vanilla_first_setup/vanilla-first-setup.gresource.xml index 57bbad6..14d788f 100644 --- a/vanilla_first_setup/vanilla-first-setup.gresource.xml +++ b/vanilla_first_setup/vanilla-first-setup.gresource.xml @@ -3,5 +3,6 @@ gtk/window.ui gtk/dialog-subsystem.ui + gtk/dialog-prop-nvidia.ui \ No newline at end of file diff --git a/vanilla_first_setup/window.py b/vanilla_first_setup/window.py index 5bfd789..dcd5d3e 100644 --- a/vanilla_first_setup/window.py +++ b/vanilla_first_setup/window.py @@ -22,7 +22,9 @@ from vanilla_first_setup.models.config import Config from vanilla_first_setup.utils.processor import Processor from vanilla_first_setup.utils.run_async import RunAsync from vanilla_first_setup.utils.welcome_langs import welcome +from vanilla_first_setup.utils.checks import has_nvidia_gpu from vanilla_first_setup.dialogs.subsystem import SubSystemDialog +from vanilla_first_setup.dialogs.prop_drivers import ProprietaryDriverDialog @Gtk.Template(resource_path='/pm/mirko/FirstSetup/gtk/window.ui') @@ -37,18 +39,23 @@ class FirstSetupWindow(Adw.ApplicationWindow): btn_no_subsystem = Gtk.Template.Child() btn_use_subsystem = Gtk.Template.Child() btn_info_subsystem = Gtk.Template.Child() + btn_no_prop_nvidia = Gtk.Template.Child() + btn_use_prop_nvidia = Gtk.Template.Child() + btn_info_prop_nvidia = Gtk.Template.Child() switch_snap = Gtk.Template.Child() switch_flatpak = Gtk.Template.Child() switch_appimage = Gtk.Template.Child() switch_apport = Gtk.Template.Child() spinner = Gtk.Template.Child() status_welcome = Gtk.Template.Child() + status_nvidia = Gtk.Template.Child() page_welcome = -1 page_configuration = 0 page_subsystem = 1 - page_extras = 2 - page_progress = 3 - page_done = 4 + page_nvidia_drivers = 2 + page_extras = 3 + page_progress = 4 + page_done = 5 def __init__(self, **kwargs): super().__init__(**kwargs) @@ -57,13 +64,18 @@ class FirstSetupWindow(Adw.ApplicationWindow): flatpak=Preset.flatpak, appimage=Preset.appimage, apport=Preset.apport, - distrobox=Preset.distrobox + distrobox=Preset.distrobox, + nvidia=Preset.nvidia, ) + self.__has_nvidia = has_nvidia_gpu() self.__buiild_ui() self.__connect_signals() self.__start_welcome_animation() def __buiild_ui(self): + if self.__has_nvidia: + self.status_nvidia.set_visible(True) + self.switch_snap.set_active(Preset.snap) self.switch_flatpak.set_active(Preset.flatpak) self.switch_appimage.set_active(Preset.appimage) @@ -74,9 +86,15 @@ class FirstSetupWindow(Adw.ApplicationWindow): self.btn_next.connect('clicked', self.__on_btn_next_clicked) self.btn_save.connect('clicked', self.on_btn_save_clicked) self.btn_close.connect('clicked', self.on_btn_close_clicked) + self.btn_no_subsystem.connect('clicked', self.on_btn_subsystem_clicked, False) self.btn_use_subsystem.connect('clicked', self.on_btn_subsystem_clicked, True) self.btn_info_subsystem.connect('clicked', self.__on_btn_info_subsystem_clicked) + + self.btn_no_prop_nvidia.connect('clicked', self.on_btn_prop_nvidia_clicked, False) + self.btn_use_prop_nvidia.connect('clicked', self.on_btn_prop_nvidia_clicked, True) + self.btn_info_prop_nvidia.connect('clicked', self.__on_btn_info_prop_nvidia_clicked) + self.switch_snap.connect('state-set', self.__on_switch_snap_state_set) self.switch_flatpak.connect( 'state-set', self.__on_switch_flatpak_state_set) @@ -120,10 +138,17 @@ class FirstSetupWindow(Adw.ApplicationWindow): def on_btn_subsystem_clicked(self, widget, state): self.__config.set_val('distrobox', state) - self.__show_page(self.page_extras) + self.__show_page(self.page_nvidia_drivers if self.__has_nvidia else self.page_extras) def __on_btn_info_subsystem_clicked(self, widget): SubSystemDialog(self).show() + + def on_btn_prop_nvidia_clicked(self, widget, state): + self.__config.set_val('nvidia', state) + self.__show_page(self.page_extras) + + def __on_btn_info_prop_nvidia_clicked(self, widget): + ProprietaryDriverDialog(self).show() def __start_welcome_animation(self): def change_langs():