diff --git a/archinstall/default_profiles/custom.py b/archinstall/default_profiles/custom.py index 9650a4cb75..31a92535f1 100644 --- a/archinstall/default_profiles/custom.py +++ b/archinstall/default_profiles/custom.py @@ -1,217 +1 @@ -# from typing import List, Dict, Optional, TYPE_CHECKING, Any -# -# from ..lib import menu -# from archinstall.lib.output import log, FormattedOutput -# from archinstall.lib.profile.profiles_handler import profile_handler -# from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, ProfileInfo, TProfile -# -# if TYPE_CHECKING: -# from archinstall.lib.installer import Installer -# _: Any -# -# -# class CustomProfileList(menu.ListManager): -# def __init__(self, prompt: str, profiles: List[TProfile]): -# self._actions = [ -# str(_('Add profile')), -# str(_('Edit profile')), -# str(_('Delete profile')) -# ] -# super().__init__(prompt, profiles, [self._actions[0]], self._actions[1:]) -# -# def reformat(self, data: List[TProfile]) -> Dict[str, Optional[TProfile]]: -# table = FormattedOutput.as_table(data) -# rows = table.split('\n') -# -# # these are the header rows of the table and do not map to any profile obviously -# # we're adding 2 spaces as prefix because the menu selector '> ' will be put before -# # the selectable rows so the header has to be aligned -# display_data: Dict[str, Optional[TProfile]] = {f' {rows[0]}': None, f' {rows[1]}': None} -# -# for row, profile in zip(rows[2:], data): -# row = row.replace('|', '\\|') -# display_data[row] = profile -# -# return display_data -# -# def selected_action_display(self, profile: TProfile) -> str: -# return profile.name -# -# def handle_action( -# self, -# action: str, -# entry: Optional['CustomTypeProfile'], -# data: List['CustomTypeProfile'] -# ) -> List['CustomTypeProfile']: -# if action == self._actions[0]: # add -# new_profile = self._add_profile() -# if new_profile is not None: -# # in case a profile with the same name as an existing profile -# # was created we'll replace the existing one -# data = [d for d in data if d.name != new_profile.name] -# data += [new_profile] -# elif entry is not None: -# if action == self._actions[1]: # edit -# new_profile = self._add_profile(entry) -# if new_profile is not None: -# # we'll remove the original profile and add the modified version -# data = [d for d in data if d.name != entry.name and d.name != new_profile.name] -# data += [new_profile] -# elif action == self._actions[2]: # delete -# data = [d for d in data if d != entry] -# -# return data -# -# def _is_new_profile_name(self, name: str) -> bool: -# existing_profile = profile_handler.get_profile_by_name(name) -# if existing_profile is not None and existing_profile.profile_type != ProfileType.CustomType: -# return False -# return True -# -# def _add_profile(self, editing: Optional['CustomTypeProfile'] = None) -> Optional['CustomTypeProfile']: -# name_prompt = '\n\n' + str(_('Profile name: ')) -# -# while True: -# profile_name = menu.TextInput(name_prompt, editing.name if editing else '').run().strip() -# -# if not profile_name: -# return None -# -# if not self._is_new_profile_name(profile_name): -# error_prompt = str(_("The profile name you entered is already in use. Try again")) -# print(error_prompt) -# else: -# break -# -# packages_prompt = str(_('Packages to be install with this profile (space separated, leave blank to skip): ')) -# edit_packages = ' '.join(editing.packages) if editing else '' -# packages = menu.TextInput(packages_prompt, edit_packages).run().strip() -# -# services_prompt = str(_('Services to be enabled with this profile (space separated, leave blank to skip): ')) -# edit_services = ' '.join(editing.services) if editing else '' -# services = menu.TextInput(services_prompt, edit_services).run().strip() -# -# choice = menu.Menu( -# str(_('Should this profile be enabled for installation?')), -# menu.Menu.yes_no(), -# skip=False, -# default_option=menu.Menu.no(), -# clear_screen=False, -# show_search_hint=False -# ).run() -# -# enable_profile = True if choice.value == menu.Menu.yes() else False -# -# profile = CustomTypeProfile( -# profile_name, -# enabled=enable_profile, -# packages=packages.split(' '), -# services=services.split(' ') -# ) -# -# return profile -# -# -# # TODO -# # Still needs some ironing out -# class CustomProfile(): -# def __init__(self): -# super().__init__( -# 'Custom', -# ProfileType.Custom, -# ) -# -# def json(self) -> Dict[str, Any]: -# data: Dict[str, Any] = {'main': self.name, 'gfx_driver': self.gfx_driver, 'custom': []} -# -# for profile in self._current_selection: -# data['custom'].append({ -# 'name': profile.name, -# 'packages': profile.packages, -# 'services': profile.services, -# 'enabled': profile.custom_enabled -# }) -# -# return data -# -# def do_on_select(self) -> SelectResult: -# custom_profile_list = CustomProfileList('', profile_handler.get_custom_profiles()) -# custom_profiles = custom_profile_list.run() -# -# # we'll first remove existing custom default_profiles with -# # the same name and then add the new ones this -# # will avoid errors of default_profiles with duplicate naming -# profile_handler.remove_custom_profiles(custom_profiles) -# profile_handler.add_custom_profiles(custom_profiles) -# -# self.set_current_selection(custom_profiles) -# -# if custom_profile_list.is_last_choice_cancel(): -# return SelectResult.SameSelection -# -# enabled_profiles = [p for p in self._current_selection if p.custom_enabled] -# # in case we only created inactive default_profiles we wanna store them but -# # we want to reset the original setting -# if not enabled_profiles: -# return SelectResult.ResetCurrent -# -# return SelectResult.NewSelection -# -# def post_install(self, install_session: 'Installer'): -# for profile in self._current_selection: -# profile.post_install(install_session) -# -# def install(self, install_session: 'Installer'): -# driver_packages = self.gfx_driver_packages() -# install_session.add_additional_packages(driver_packages) -# -# for profile in self._current_selection: -# if profile.custom_enabled: -# log(f'Installing custom profile {profile.name}...') -# -# install_session.add_additional_packages(profile.packages) -# install_session.enable_service(profile.services) -# -# profile.install(install_session) -# -# def info(self) -> Optional[ProfileInfo]: -# enabled_profiles = [p for p in self._current_selection if p.custom_enabled] -# if enabled_profiles: -# details = ', '.join([p.name for p in enabled_profiles]) -# gfx_driver = self.gfx_driver -# return ProfileInfo(self.name, details, gfx_driver) -# -# return None -# -# def reset(self): -# for profile in self._current_selection: -# profile.set_enabled(False) -# -# self.gfx_driver = None -# -# -# class CustomTypeProfile(Profile): -# def __init__( -# self, -# name: str, -# enabled: bool = False, -# packages: List[str] = [], -# services: List[str] = [] -# ): -# super().__init__( -# name, -# ProfileType.CustomType, -# packages=packages, -# services=services, -# support_gfx_driver=True -# ) -# -# self.custom_enabled = enabled -# -# def json(self) -> Dict[str, Any]: -# return { -# 'name': self.name, -# 'packages': self.packages, -# 'services': self.services, -# 'enabled': self.custom_enabled -# } +# Placeholder to make your own diff --git a/archinstall/default_profiles/desktops/cosmic.py b/archinstall/default_profiles/desktops/cosmic.py index 96742de6f6..6c71179578 100644 --- a/archinstall/default_profiles/desktops/cosmic.py +++ b/archinstall/default_profiles/desktops/cosmic.py @@ -1,10 +1,10 @@ from typing import override from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile -class CosmicProfile(XorgProfile): +class CosmicProfile(WaylandProfile): def __init__(self) -> None: super().__init__('Cosmic', ProfileType.DesktopEnv) diff --git a/archinstall/default_profiles/desktops/gnome.py b/archinstall/default_profiles/desktops/gnome.py index 58936434b1..f78491b16b 100644 --- a/archinstall/default_profiles/desktops/gnome.py +++ b/archinstall/default_profiles/desktops/gnome.py @@ -1,10 +1,10 @@ from typing import override from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile -class GnomeProfile(XorgProfile): +class GnomeProfile(WaylandProfile): def __init__(self) -> None: super().__init__('GNOME', ProfileType.DesktopEnv) diff --git a/archinstall/default_profiles/desktops/hyprland.py b/archinstall/default_profiles/desktops/hyprland.py index 82aa4f6d7b..309533dbfa 100644 --- a/archinstall/default_profiles/desktops/hyprland.py +++ b/archinstall/default_profiles/desktops/hyprland.py @@ -2,7 +2,7 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile from archinstall.lib.translationhandler import tr from archinstall.tui.curses_menu import SelectMenu from archinstall.tui.menu_item import MenuItem, MenuItemGroup @@ -10,7 +10,7 @@ from archinstall.tui.types import Alignment, FrameProperties -class HyprlandProfile(XorgProfile): +class HyprlandProfile(WaylandProfile): def __init__(self) -> None: super().__init__('Hyprland', ProfileType.DesktopEnv) diff --git a/archinstall/default_profiles/desktops/labwc.py b/archinstall/default_profiles/desktops/labwc.py index 98f93b04cf..fbb6223e6f 100644 --- a/archinstall/default_profiles/desktops/labwc.py +++ b/archinstall/default_profiles/desktops/labwc.py @@ -2,7 +2,7 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile from archinstall.lib.translationhandler import tr from archinstall.tui.curses_menu import SelectMenu from archinstall.tui.menu_item import MenuItem, MenuItemGroup @@ -10,7 +10,7 @@ from archinstall.tui.types import Alignment, FrameProperties -class LabwcProfile(XorgProfile): +class LabwcProfile(WaylandProfile): def __init__(self) -> None: super().__init__( 'Labwc', diff --git a/archinstall/default_profiles/desktops/niri.py b/archinstall/default_profiles/desktops/niri.py index ff4edf9945..8756f99641 100644 --- a/archinstall/default_profiles/desktops/niri.py +++ b/archinstall/default_profiles/desktops/niri.py @@ -1,24 +1,16 @@ from typing import override -from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile -from archinstall.lib.translationhandler import tr -from archinstall.tui.curses_menu import SelectMenu -from archinstall.tui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.result import ResultType -from archinstall.tui.types import Alignment, FrameProperties +from archinstall.default_profiles.wayland import WaylandProfile -class NiriProfile(XorgProfile): +class NiriProfile(WaylandProfile): def __init__(self) -> None: super().__init__( 'Niri', ProfileType.WindowMgr, ) - self.custom_settings = {'seat_access': None} - @property @override def packages(self) -> list[str]: @@ -43,37 +35,3 @@ def packages(self) -> list[str]: @override def default_greeter_type(self) -> GreeterType: return GreeterType.Lightdm - - @property - @override - def services(self) -> list[str]: - if pref := self.custom_settings.get('seat_access', None): - return [pref] - return [] - - def _ask_seat_access(self) -> None: - # need to activate seat service and add to seat group - header = tr('niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)') - header += '\n' + tr('Choose an option to give niri access to your hardware') + '\n' - - items = [MenuItem(s.value, value=s) for s in SeatAccess] - group = MenuItemGroup(items, sort_items=True) - - default = self.custom_settings.get('seat_access', None) - group.set_default_by_value(default) - - result = SelectMenu[SeatAccess]( - group, - header=header, - allow_skip=False, - frame=FrameProperties.min(tr('Seat access')), - alignment=Alignment.CENTER, - ).run() - - if result.type_ == ResultType.Selection: - self.custom_settings['seat_access'] = result.get_value().value - - @override - def do_on_select(self) -> None: - self._ask_seat_access() - return None diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py index b26ae7cf9a..d9ef8a2479 100644 --- a/archinstall/default_profiles/desktops/plasma.py +++ b/archinstall/default_profiles/desktops/plasma.py @@ -1,10 +1,10 @@ from typing import override from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile -class PlasmaProfile(XorgProfile): +class PlasmaProfile(WaylandProfile): def __init__(self) -> None: super().__init__('KDE Plasma', ProfileType.DesktopEnv) diff --git a/archinstall/default_profiles/desktops/river.py b/archinstall/default_profiles/desktops/river.py index 8e1396bb41..79feb9ac66 100644 --- a/archinstall/default_profiles/desktops/river.py +++ b/archinstall/default_profiles/desktops/river.py @@ -1,23 +1,69 @@ from typing import override +from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile +from archinstall.lib.translationhandler import tr +from archinstall.tui.curses_menu import SelectMenu +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType +from archinstall.tui.types import Alignment, FrameProperties -class RiverProfile(XorgProfile): +class RiverProfile(WaylandProfile): def __init__(self) -> None: super().__init__('River', ProfileType.WindowMgr) + self.custom_settings = {'seat_access': None} + @property @override def packages(self) -> list[str]: + additional = [] + if seat := self.custom_settings.get('seat_access', None): + additional = [seat] + return [ 'foot', 'xdg-desktop-portal-wlr', 'river', - ] + ] + additional @property @override def default_greeter_type(self) -> GreeterType: return GreeterType.Lightdm + + @property + @override + def services(self) -> list[str]: + if pref := self.custom_settings.get('seat_access', None): + return [pref] + return [] + + def _ask_seat_access(self) -> None: + # need to activate seat service and add to seat group + header = tr('River needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)') + header += '\n' + tr('Choose an option to give River access to your hardware') + '\n' + + items = [MenuItem(s.value, value=s) for s in SeatAccess] + group = MenuItemGroup(items, sort_items=True) + + default = self.custom_settings.get('seat_access', None) + group.set_default_by_value(default) + + result = SelectMenu[SeatAccess]( + group, + header=header, + allow_skip=False, + frame=FrameProperties.min(tr('Seat access')), + alignment=Alignment.CENTER, + ).run() + + if result.type_ == ResultType.Selection: + self.custom_settings['seat_access'] = result.get_value().value + + @override + def do_on_select(self) -> None: + self._ask_seat_access() + return None diff --git a/archinstall/default_profiles/desktops/sway.py b/archinstall/default_profiles/desktops/sway.py index d01611b0e2..8f2d2d3b13 100644 --- a/archinstall/default_profiles/desktops/sway.py +++ b/archinstall/default_profiles/desktops/sway.py @@ -2,7 +2,7 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import GreeterType, ProfileType -from archinstall.default_profiles.xorg import XorgProfile +from archinstall.default_profiles.wayland import WaylandProfile from archinstall.lib.translationhandler import tr from archinstall.tui.curses_menu import SelectMenu from archinstall.tui.menu_item import MenuItem, MenuItemGroup @@ -10,7 +10,7 @@ from archinstall.tui.types import Alignment, FrameProperties -class SwayProfile(XorgProfile): +class SwayProfile(WaylandProfile): def __init__(self) -> None: super().__init__( 'Sway', diff --git a/archinstall/default_profiles/profile.py b/archinstall/default_profiles/profile.py index 8f63df66f9..8122cdee10 100644 --- a/archinstall/default_profiles/profile.py +++ b/archinstall/default_profiles/profile.py @@ -26,6 +26,11 @@ class ProfileType(Enum): Application = 'Application' +class DisplayServer(Enum): + X11 = 'x11' + Wayland = 'wayland' + + class GreeterType(Enum): Lightdm = 'lightdm-gtk-greeter' LightdmSlick = 'lightdm-slick-greeter' @@ -58,7 +63,6 @@ def __init__( self.custom_settings: dict[str, str | None] = {} self.advanced = advanced - self._support_gfx_driver = support_gfx_driver self._support_greeter = support_greeter # self.gfx_driver: str | None = None @@ -164,17 +168,14 @@ def is_tailored(self) -> bool: def is_custom_type_profile(self) -> bool: return self.profile_type == ProfileType.CustomType - def is_graphic_driver_supported(self) -> bool: - if not self.current_selection: - return self._support_gfx_driver - else: - if any([p._support_gfx_driver for p in self.current_selection]): - return True - return False - def is_greeter_supported(self) -> bool: return self._support_greeter + def display_servers(self) -> set[DisplayServer]: + from ..lib.profile.profiles_handler import profile_handler + + return profile_handler.display_servers(self) + def preview_text(self) -> str: """ Override this method to provide a preview text for the profile diff --git a/archinstall/default_profiles/wayland.py b/archinstall/default_profiles/wayland.py new file mode 100644 index 0000000000..d84e69bfb4 --- /dev/null +++ b/archinstall/default_profiles/wayland.py @@ -0,0 +1,30 @@ +from typing import override + +from archinstall.default_profiles.profile import DisplayServer, Profile, ProfileType +from archinstall.lib.translationhandler import tr + + +class WaylandProfile(Profile): + def __init__( + self, + name: str = 'Wayland', + profile_type: ProfileType = ProfileType.DesktopEnv, + advanced: bool = False, + ): + super().__init__( + name, + profile_type, + advanced=advanced, + ) + + @override + def preview_text(self) -> str: + text = tr('Environment type: {}').format(self.profile_type.value) + if packages := self.packages_text(): + text += f'\n{packages}' + + return text + + @override + def display_servers(self) -> set[DisplayServer]: + return {DisplayServer.Wayland} diff --git a/archinstall/default_profiles/xorg.py b/archinstall/default_profiles/xorg.py index 71b9bf6b6e..bb731d2654 100644 --- a/archinstall/default_profiles/xorg.py +++ b/archinstall/default_profiles/xorg.py @@ -1,6 +1,6 @@ from typing import override -from archinstall.default_profiles.profile import Profile, ProfileType +from archinstall.default_profiles.profile import DisplayServer, Profile, ProfileType from archinstall.lib.translationhandler import tr @@ -14,7 +14,6 @@ def __init__( super().__init__( name, profile_type, - support_gfx_driver=True, advanced=advanced, ) @@ -32,3 +31,7 @@ def packages(self) -> list[str]: return [ 'xorg-server', ] + + @override + def display_servers(self) -> set[DisplayServer]: + return {DisplayServer.X11} diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index aa5781f951..863dc7729d 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -3,6 +3,8 @@ from functools import cached_property from pathlib import Path +from archinstall.default_profiles.profile import DisplayServer + from .exceptions import SysCallError from .general import SysCommand from .networking import enrich_iface_types, list_interfaces @@ -71,8 +73,8 @@ def is_nvidia(self) -> bool: case _: return False - def packages_text(self) -> str: - pkg_names = [p.value for p in self.gfx_packages()] + def packages_text(self, servers: set[DisplayServer] | None = None) -> str: + pkg_names = [p.value for p in self.gfx_packages(servers)] text = tr('Installed packages') + ':\n' for p in sorted(pkg_names): @@ -80,8 +82,12 @@ def packages_text(self) -> str: return text - def gfx_packages(self) -> list[GfxPackage]: - packages = [GfxPackage.XorgServer, GfxPackage.XorgXinit] + def gfx_packages(self, servers: set[DisplayServer] | None = None) -> list[GfxPackage]: + packages = [] + + if servers is None or DisplayServer.X11 in servers: + packages = [GfxPackage.XorgServer, GfxPackage.XorgXinit] + # else: servers is empty set or doesn't contain X11 match self: case GfxDriver.AllOpenSource: @@ -134,6 +140,7 @@ def gfx_packages(self) -> list[GfxPackage]: case GfxDriver.VMOpenSource: packages += [ GfxPackage.Mesa, + GfxPackage.LibvaMesaDriver, ] return packages diff --git a/archinstall/lib/interactions/system_conf.py b/archinstall/lib/interactions/system_conf.py index 2f11362f7b..46da86f8b6 100644 --- a/archinstall/lib/interactions/system_conf.py +++ b/archinstall/lib/interactions/system_conf.py @@ -2,6 +2,7 @@ from typing import assert_never +from archinstall.default_profiles.profile import Profile from archinstall.lib.models.application import ZramAlgorithm, ZramConfiguration from archinstall.lib.translationhandler import tr from archinstall.tui.curses_menu import SelectMenu @@ -47,7 +48,7 @@ def select_kernel(preset: list[str] = []) -> list[str]: return result.get_values() -def select_driver(options: list[GfxDriver] = [], preset: GfxDriver | None = None) -> GfxDriver | None: +def select_driver(options: list[GfxDriver] = [], preset: GfxDriver | None = None, profile: Profile | None = None) -> GfxDriver | None: """ Somewhat convoluted function, whose job is simple. Select a graphics driver from a pre-defined set of popular options. @@ -58,7 +59,8 @@ def select_driver(options: list[GfxDriver] = [], preset: GfxDriver | None = None if not options: options = [driver for driver in GfxDriver] - items = [MenuItem(o.value, value=o, preview_action=lambda x: x.value.packages_text()) for o in options] + servers = profile.display_servers() if profile else None + items = [MenuItem(o.value, value=o, preview_action=lambda x: x.value.packages_text(servers)) for o in options] group = MenuItemGroup(items, sort_items=True) group.set_default_by_value(GfxDriver.AllOpenSource) diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py index d434fc2fb3..674697bd27 100644 --- a/archinstall/lib/profile/profile_menu.py +++ b/archinstall/lib/profile/profile_menu.py @@ -7,7 +7,7 @@ from archinstall.tui.curses_menu import SelectMenu from archinstall.tui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.result import ResultType -from archinstall.tui.types import Alignment, FrameProperties, Orientation +from archinstall.tui.types import Alignment, FrameProperties from ..hardware import GfxDriver from ..interactions.system_conf import select_driver @@ -46,9 +46,9 @@ def _define_menu_options(self) -> list[MenuItem]: MenuItem( text=tr('Graphics driver'), action=self._select_gfx_driver, - value=self._profile_config.gfx_driver if self._profile_config.profile and self._profile_config.profile.is_graphic_driver_supported() else None, + value=self._profile_config.gfx_driver if self._profile_config.profile else None, preview_action=self._prev_gfx, - enabled=self._profile_config.profile.is_graphic_driver_supported() if self._profile_config.profile else False, + enabled=bool(self._profile_config.profile and self._profile_config.profile.display_servers()), dependencies=['profile'], key='gfx_driver', ), @@ -56,7 +56,7 @@ def _define_menu_options(self) -> list[MenuItem]: text=tr('Greeter'), action=lambda x: select_greeter(preset=x), value=self._profile_config.greeter if self._profile_config.profile and self._profile_config.profile.is_greeter_supported() else None, - enabled=self._profile_config.profile.is_graphic_driver_supported() if self._profile_config.profile else False, + enabled=bool(self._profile_config.profile and self._profile_config.profile.is_greeter_supported()), preview_action=self._prev_greeter, dependencies=['profile'], key='greeter', @@ -72,12 +72,12 @@ def _select_profile(self, preset: Profile | None) -> Profile | None: profile = select_profile(preset) if profile is not None: - if not profile.is_graphic_driver_supported(): - self._item_group.find_by_key('gfx_driver').enabled = False - self._item_group.find_by_key('gfx_driver').value = None - else: + if profile.display_servers(): self._item_group.find_by_key('gfx_driver').enabled = True self._item_group.find_by_key('gfx_driver').value = GfxDriver.AllOpenSource + else: + self._item_group.find_by_key('gfx_driver').enabled = False + self._item_group.find_by_key('gfx_driver').value = None if not profile.is_greeter_supported(): self._item_group.find_by_key('greeter').enabled = False @@ -96,36 +96,16 @@ def _select_gfx_driver(self, preset: GfxDriver | None = None) -> GfxDriver | Non profile: Profile | None = self._item_group.find_by_key('profile').value if profile: - if profile.is_graphic_driver_supported(): - driver = select_driver(preset=preset) - - if driver and 'Sway' in profile.current_selection_names(): - if driver.is_nvidia(): - header = tr('The proprietary Nvidia driver is not supported by Sway.') + '\n' - header += tr('It is likely that you will run into issues, are you okay with that?') + '\n' - - group = MenuItemGroup.yes_no() - group.focus_item = MenuItem.no() - group.default_item = MenuItem.no() - - result = SelectMenu[bool]( - group, - header=header, - allow_skip=False, - columns=2, - orientation=Orientation.HORIZONTAL, - alignment=Alignment.CENTER, - ).run() - - if result.item() == MenuItem.no(): - return preset + driver = select_driver(preset=preset, profile=profile) return driver def _prev_gfx(self, item: MenuItem) -> str | None: if item.value: driver = item.get_value().value - packages = item.get_value().packages_text() + profile: Profile | None = self._item_group.find_by_key('profile').value + servers = profile.display_servers() if profile else None + packages = item.get_value().packages_text(servers) return f'Driver: {driver}\n{packages}' return None diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py index 96ce476aba..b024846e4e 100644 --- a/archinstall/lib/profile/profiles_handler.py +++ b/archinstall/lib/profile/profiles_handler.py @@ -12,7 +12,7 @@ from archinstall.lib.translationhandler import tr -from ...default_profiles.profile import GreeterType, Profile +from ...default_profiles.profile import DisplayServer, GreeterType, Profile from ..hardware import GfxDriver from ..models.profile import ProfileConfiguration from ..networking import fetch_data_from_url, list_interfaces @@ -226,7 +226,7 @@ def install_greeter(self, install_session: 'Installer', greeter: GreeterType) -> with open(path, 'w') as file: file.write(filedata) - def install_gfx_driver(self, install_session: 'Installer', driver: GfxDriver) -> None: + def install_gfx_driver(self, install_session: 'Installer', driver: GfxDriver, profile: Profile | None = None) -> None: debug(f'Installing GFX driver: {driver.value}') if driver in [GfxDriver.NvidiaOpenKernel, GfxDriver.NvidiaProprietary]: @@ -234,7 +234,9 @@ def install_gfx_driver(self, install_session: 'Installer', driver: GfxDriver) -> # Fixes https://github.com/archlinux/archinstall/issues/585 install_session.add_additional_packages(headers) - driver_pkgs = driver.gfx_packages() + # Determine display server requirements from profile + display_servers = profile.display_servers() if profile else None + driver_pkgs = driver.gfx_packages(display_servers) pkg_names = [p.value for p in driver_pkgs] install_session.add_additional_packages(pkg_names) @@ -247,7 +249,7 @@ def install_profile_config(self, install_session: 'Installer', profile_config: P profile.install(install_session) if profile_config.gfx_driver and (profile.is_xorg_type_profile() or profile.is_desktop_profile()): - self.install_gfx_driver(install_session, profile_config.gfx_driver) + self.install_gfx_driver(install_session, profile_config.gfx_driver, profile) if profile_config.greeter: self.install_greeter(install_session, profile_config.greeter) @@ -365,5 +367,19 @@ def reset_top_level_profiles(self, exclude: list[Profile] = []) -> None: if profile.name not in excluded_profiles: profile.reset() + def display_servers(self, profile: Profile) -> set[DisplayServer]: + """ + Returns the set of display servers required by this profile. + Aggregates requirements from sub-profiles if present. + Profiles inherit from XorgProfile or WaylandProfile to specify their display server. + """ + if profile.current_selection: + # Aggregate requirements from sub-profiles + servers = set() + for sub_profile in profile.current_selection: + servers.update(sub_profile.display_servers()) + return servers + return set() + profile_handler = ProfileHandler()