forked from Mirrors/RGSX
v2.2.0.3 - fix virtual keyboard now showing when controller is plugged in or handheld like steamdeck
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import os
|
||||
os.environ["SDL_FBDEV"] = "/dev/fb0"
|
||||
import pygame # type: ignore
|
||||
import asyncio
|
||||
import platform
|
||||
# Ne pas forcer SDL_FBDEV ici; si déjà défini par l'environnement, on le garde
|
||||
try:
|
||||
if "SDL_FBDEV" in os.environ:
|
||||
pass # respecter la configuration existante
|
||||
except Exception:
|
||||
pass
|
||||
import pygame # type: ignore
|
||||
import time
|
||||
import asyncio
|
||||
import logging
|
||||
import requests
|
||||
import queue
|
||||
@@ -27,8 +33,8 @@ from controls import handle_controls, validate_menu_state, process_key_repeats,
|
||||
from controls_mapper import map_controls, draw_controls_mapping, get_actions
|
||||
from controls import load_controls_config
|
||||
from utils import (
|
||||
detect_non_pc, load_sources, check_extension_before_download, extract_zip_data,
|
||||
play_random_music, load_music_config, silence_alsa_warnings, enable_alsa_stderr_filter
|
||||
load_sources, check_extension_before_download, extract_zip_data,
|
||||
play_random_music, load_music_config
|
||||
)
|
||||
from history import load_history, save_history
|
||||
from config import OTA_data_ZIP
|
||||
@@ -79,6 +85,37 @@ def _run_windows_gamelist_update():
|
||||
|
||||
_run_windows_gamelist_update()
|
||||
|
||||
# Vérifier et appliquer les mises à jour AVANT tout chargement des contrôles
|
||||
try:
|
||||
# Internet rapide (synchrone) avant init graphique complète
|
||||
if test_internet():
|
||||
logger.debug("Pré-boot: connexion Internet OK, vérification des mises à jour")
|
||||
# Initialiser un mini-contexte de chargement pour feedback si l'écran est prêt
|
||||
config.menu_state = "loading"
|
||||
config.current_loading_system = _("loading_check_updates")
|
||||
config.loading_progress = 5.0
|
||||
config.needs_redraw = True
|
||||
# Lancer la vérification en mode synchrone via boucle temporaire
|
||||
# Utilise une boucle d'événements courte pour permettre pygame d'initialiser
|
||||
try:
|
||||
# Créer une boucle asyncio ad-hoc si non présente
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
success, _msg = loop.run_until_complete(check_for_updates())
|
||||
logger.debug(f"Pré-boot: check_for_updates terminé success={success}")
|
||||
except Exception as e:
|
||||
logger.error(f"Pré-boot: échec check_for_updates: {e}")
|
||||
finally:
|
||||
try:
|
||||
loop.close()
|
||||
except Exception:
|
||||
pass
|
||||
config.update_checked = True
|
||||
else:
|
||||
logger.debug("Pré-boot: pas d'Internet, pas de vérification des mises à jour")
|
||||
except Exception as e:
|
||||
logger.exception(f"Pré-boot update check a échoué: {e}")
|
||||
|
||||
|
||||
# Initialisation de Pygame
|
||||
pygame.init()
|
||||
@@ -96,56 +133,7 @@ except Exception as e:
|
||||
logger.exception(f"Échec du nettoyage des anciens fichiers: {e}")
|
||||
|
||||
|
||||
#Récupération des noms des joysticks si pas de joystick connecté, verifier si clavier connecté
|
||||
joystick_names = [pygame.joystick.Joystick(i).get_name() for i in range(pygame.joystick.get_count())]
|
||||
if not joystick_names:
|
||||
joystick_names = ["Clavier"]
|
||||
print("Aucun joystick détecté, utilisation du clavier par défaut")
|
||||
logger.debug("Aucun joystick détecté, utilisation du clavier par défaut.")
|
||||
config.joystick = False
|
||||
config.keyboard = True
|
||||
else:
|
||||
config.joystick = True
|
||||
config.keyboard = False
|
||||
print(f"Joysticks détectés: {joystick_names}")
|
||||
logger.debug(f"Joysticks détectés: {joystick_names}, utilisation du joystick par défaut.")
|
||||
# Test des boutons du joystick
|
||||
for name in joystick_names:
|
||||
if "Xbox" in name or "360" in name or "X-Box" in name:
|
||||
config.xbox_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
break
|
||||
elif "PlayStation" in name:
|
||||
config.playstation_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
break
|
||||
elif "Nintendo" in name:
|
||||
config.nintendo_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "Logitech" in name:
|
||||
config.logitech_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "8Bitdo" in name:
|
||||
config.eightbitdo_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "Steam" in name:
|
||||
config.steam_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "TRIMUI Smart Pro" in name:
|
||||
config.trimui_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
else:
|
||||
config.generic_controller = True
|
||||
logger.debug(f"Generic controller detected : {name}")
|
||||
print(f"Generic controller detected : {name}")
|
||||
|
||||
|
||||
# Chargement des paramètres d'accessibilité
|
||||
config.accessibility_settings = load_accessibility_settings()
|
||||
# Appliquer la grille d'affichage depuis les paramètres
|
||||
@@ -169,8 +157,22 @@ config.sources_mode = get_sources_mode()
|
||||
config.custom_sources_url = get_custom_sources_url()
|
||||
logger.debug(f"Mode sources initial: {config.sources_mode}, URL custom: {config.custom_sources_url}")
|
||||
|
||||
# Détection du système non-PC
|
||||
config.is_non_pc = detect_non_pc()
|
||||
# Détection du système grace a une commande windows / linux (on oublie is non-pc c'est juste pour connaitre le materiel et le systeme d'exploitation)
|
||||
def detect_system_info():
|
||||
"""Détecte les informations système (OS, architecture) via des commandes appropriées."""
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
# Commande pour Windows
|
||||
result = subprocess.run(["wmic", "os", "get", "caption"], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
logger.info(f"Système détecté (Windows): {result.stdout.strip()}")
|
||||
else:
|
||||
# Commande pour Linux
|
||||
result = subprocess.run(["lsb_release", "-d"], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
logger.info(f"Système détecté (Linux): {result.stdout.strip()}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la détection du système: {e}")
|
||||
|
||||
# Initialisation de l’écran
|
||||
screen = init_display()
|
||||
@@ -185,6 +187,64 @@ config.init_font()
|
||||
config.screen_width, config.screen_height = pygame.display.get_surface().get_size()
|
||||
logger.debug(f"Résolution d'écran : {config.screen_width}x{config.screen_height}")
|
||||
|
||||
# Détection des joysticks après init_display (plus stable sur Batocera)
|
||||
try:
|
||||
if platform.system() != "Windows":
|
||||
time.sleep(0.05) # petite latence pour stabiliser SDL sur certains builds
|
||||
count = pygame.joystick.get_count()
|
||||
except Exception:
|
||||
count = 0
|
||||
joystick_names = []
|
||||
for i in range(count):
|
||||
try:
|
||||
j = pygame.joystick.Joystick(i)
|
||||
joystick_names.append(j.get_name())
|
||||
except Exception as e:
|
||||
logger.debug(f"Impossible de lire le nom du joystick {i}: {e}")
|
||||
normalized_names = [n.lower() for n in joystick_names]
|
||||
if not joystick_names:
|
||||
joystick_names = ["Clavier"]
|
||||
print("Aucun joystick détecté, utilisation du clavier par défaut")
|
||||
logger.debug("Aucun joystick détecté, utilisation du clavier par défaut.")
|
||||
config.joystick = False
|
||||
config.keyboard = True
|
||||
else:
|
||||
config.joystick = True
|
||||
config.keyboard = False
|
||||
print(f"Joysticks détectés: {joystick_names}")
|
||||
logger.debug(f"Joysticks détectés: {joystick_names}, utilisation du joystick par défaut.")
|
||||
for idx, name in enumerate(joystick_names):
|
||||
lname = name.lower()
|
||||
if ("xbox" in lname) or ("x-box" in lname) or ("xinput" in lname) or ("microsoft x-box" in lname) or ("x-box 360" in lname) or ("360" in lname):
|
||||
config.xbox_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
break
|
||||
elif "playstation" in lname:
|
||||
config.playstation_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
break
|
||||
elif "nintendo" in lname:
|
||||
config.nintendo_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "logitech" in lname:
|
||||
config.logitech_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "8bitdo" in name or "8-bitdo" in lname:
|
||||
config.eightbitdo_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
elif "steam" in lname:
|
||||
config.steam_controller = True
|
||||
logger.debug(f"Controller detected : {name}")
|
||||
print(f"Controller detected : {name}")
|
||||
# Note: virtual keyboard display now depends on controller presence (config.joystick)
|
||||
print(f"Generic controller detected : {name}")
|
||||
logger.debug(f"Flags contrôleur: xbox={config.xbox_controller}, ps={config.playstation_controller}, nintendo={config.nintendo_controller}, eightbitdo={config.eightbitdo_controller}, steam={config.steam_controller}, trimui={config.trimui_controller}, logitech={config.logitech_controller}, generic={config.generic_controller}")
|
||||
|
||||
|
||||
# Vérification des dossiers pour le débogage
|
||||
logger.debug(f"SYSTEM_FOLDER: {config.SYSTEM_FOLDER}")
|
||||
@@ -205,19 +265,12 @@ config.repeat_key = None
|
||||
config.repeat_start_time = 0
|
||||
config.repeat_last_action = 0
|
||||
|
||||
# Initialisation des variables pour la popup de musique
|
||||
|
||||
|
||||
# Réduction du bruit ALSA (VM Batocera/alsa)
|
||||
try:
|
||||
silence_alsa_warnings()
|
||||
enable_alsa_stderr_filter()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Initialisation du mixer Pygame
|
||||
pygame.mixer.pre_init(44100, -16, 2, 4096)
|
||||
pygame.mixer.init()
|
||||
try:
|
||||
pygame.mixer.init()
|
||||
except Exception as e:
|
||||
logger.warning(f"Échec init mixer: {e}")
|
||||
|
||||
# Charger la configuration de la musique AVANT de lancer la musique
|
||||
load_music_config()
|
||||
@@ -245,7 +298,7 @@ config.current_music = current_music # Met à jour la musique en cours dans con
|
||||
config.history = load_history()
|
||||
logger.debug(f"Historique de téléchargement : {len(config.history)} entrées")
|
||||
|
||||
# Vérification et chargement de la configuration des contrôles
|
||||
# Vérification et chargement de la configuration des contrôles (après mises à jour et détection manette)
|
||||
config.controls_config = load_controls_config()
|
||||
|
||||
# S'assurer que config.controls_config n'est jamais None
|
||||
@@ -267,14 +320,16 @@ else:
|
||||
# Initialisation du gamepad
|
||||
joystick = None
|
||||
if pygame.joystick.get_count() > 0:
|
||||
joystick = pygame.joystick.Joystick(0)
|
||||
joystick.init()
|
||||
logger.debug("Gamepad initialisé")
|
||||
try:
|
||||
joystick = pygame.joystick.Joystick(0)
|
||||
joystick.init()
|
||||
logger.debug("Gamepad initialisé")
|
||||
except Exception as e:
|
||||
logger.warning(f"Échec initialisation gamepad: {e}")
|
||||
|
||||
|
||||
# Boucle principale
|
||||
async def main():
|
||||
# amazonq-ignore-next-line
|
||||
global current_music, music_files, music_folder
|
||||
logger.debug("Début main")
|
||||
running = True
|
||||
@@ -728,7 +783,7 @@ async def main():
|
||||
draw_game_list(screen)
|
||||
if config.search_mode:
|
||||
draw_game_list(screen)
|
||||
if config.is_non_pc:
|
||||
if getattr(config, 'joystick', False):
|
||||
draw_virtual_keyboard(screen)
|
||||
elif config.menu_state == "download_progress":
|
||||
draw_progress_screen(screen)
|
||||
@@ -847,6 +902,14 @@ async def main():
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Erreur : {config.error_message}")
|
||||
elif loading_step == "check_ota":
|
||||
# Si mise à jour déjà vérifiée au pré-boot, sauter cette étape
|
||||
if getattr(config, "update_checked", False):
|
||||
logger.debug("Mises à jour déjà vérifiées au pré-boot, on saute check_for_updates()")
|
||||
loading_step = "check_data"
|
||||
config.current_loading_system = _("loading_downloading_games_images")
|
||||
config.loading_progress = max(config.loading_progress, 50.0)
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
logger.debug("Exécution de check_for_updates()")
|
||||
success, message = await check_for_updates()
|
||||
logger.debug(f"Résultat de check_for_updates : success={success}, message={message}")
|
||||
@@ -986,11 +1049,15 @@ async def main():
|
||||
pygame.quit()
|
||||
logger.debug("Application terminée")
|
||||
|
||||
result2 = subprocess.run(["batocera-es-swissknife", "--emukill"])
|
||||
if result2 == 0:
|
||||
logger.debug(f"Quitté avec succès")
|
||||
else:
|
||||
logger.debug("Error en essayant de quitter batocera-es-swissknife.")
|
||||
try:
|
||||
if platform.system() != "Windows":
|
||||
result2 = subprocess.run(["batocera-es-swissknife", "--emukill"])
|
||||
if result2 == 0:
|
||||
logger.debug(f"Quitté avec succès")
|
||||
else:
|
||||
logger.debug("Error en essayant de quitter batocera-es-swissknife.")
|
||||
except FileNotFoundError:
|
||||
logger.debug("batocera-es-swissknife introuvable, saut de l'étape d'arrêt (environnement non Batocera)")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
import platform
|
||||
|
||||
# Version actuelle de l'application
|
||||
app_version = "2.2.0.0"
|
||||
app_version = "2.2.0.3"
|
||||
|
||||
def get_operating_system():
|
||||
"""Renvoie le nom du système d'exploitation."""
|
||||
@@ -196,7 +196,6 @@ last_state_change_time = 0 # Temps du dernier changement d'état pour debounce
|
||||
debounce_delay = 200 # Délai de debounce en millisecondes
|
||||
platform_dicts = [] # Liste des dictionnaires de plateformes
|
||||
selected_key = (0, 0) # Position du curseur dans le clavier virtuel
|
||||
is_non_pc = True # Indicateur pour plateforme non-PC (par exemple, console)
|
||||
redownload_confirm_selection = 0 # Sélection pour la confirmation de redownload
|
||||
popup_message = "" # Message à afficher dans les popups
|
||||
popup_timer = 0 # Temps restant pour le popup en millisecondes (0 = inactif)
|
||||
@@ -208,6 +207,18 @@ batch_download_indices = [] # File d'attente des indices de jeux à traiter en
|
||||
batch_in_progress = False # Indique qu'un lot est en cours
|
||||
batch_pending_game = None # Données du jeu en attente de confirmation d'extension
|
||||
|
||||
# Indicateurs d'entrée (détectés au démarrage)
|
||||
joystick = False
|
||||
keyboard = False
|
||||
xbox_controller = False
|
||||
playstation_controller = False
|
||||
nintendo_controller = False
|
||||
logitech_controller = False
|
||||
eightbitdo_controller = False
|
||||
steam_controller = False
|
||||
trimui_controller = False
|
||||
generic_controller = False
|
||||
|
||||
# --- Filtre plateformes (UI) ---
|
||||
selected_filter_index = 0 # index dans la liste visible triée
|
||||
filter_platforms_scroll_offset = 0 # défilement si liste longue
|
||||
@@ -266,6 +277,9 @@ def init_font():
|
||||
search_font = None
|
||||
small_font = None
|
||||
|
||||
# Indique si une vérification/installation des mises à jour a déjà été effectuée au démarrage
|
||||
update_checked = False
|
||||
|
||||
def validate_resolution():
|
||||
"""Valide la résolution de l'écran par rapport aux capacités de l'écran."""
|
||||
display_info = pygame.display.Info()
|
||||
|
||||
@@ -338,7 +338,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
# Jeux
|
||||
elif config.menu_state == "game":
|
||||
games = config.filtered_games if config.filter_active or config.search_mode else config.games
|
||||
if config.search_mode and config.is_non_pc:
|
||||
if config.search_mode and getattr(config, 'joystick', False):
|
||||
keyboard_layout = [
|
||||
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
['A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
|
||||
@@ -416,7 +416,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.filter_active = bool(config.search_query)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Validation du filtre avec manette: query={config.search_query}, filter_active={config.filter_active}")
|
||||
elif config.search_mode and not config.is_non_pc:
|
||||
elif config.search_mode and not getattr(config, 'joystick', False):
|
||||
# Gestion de la recherche sur PC (clavier et manette)
|
||||
if is_input_matched(event, "confirm"):
|
||||
config.search_mode = False
|
||||
|
||||
@@ -30,115 +30,7 @@ unavailable_systems = []
|
||||
|
||||
# Cache/process flags for extensions generation/loading
|
||||
|
||||
|
||||
def silence_alsa_warnings():
|
||||
"""Silence ALSA stderr spam (e.g., 'underrun occurred') on Linux by overriding the error handler.
|
||||
|
||||
Safe no-op on non-Linux or if libasound is unavailable.
|
||||
"""
|
||||
try:
|
||||
if platform.system() == "Linux":
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
lib = ctypes.util.find_library('asound')
|
||||
if not lib:
|
||||
return
|
||||
asound = ctypes.CDLL(lib)
|
||||
CErrorHandler = ctypes.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p)
|
||||
|
||||
def py_error_handler(filename, line, function, err, fmt):
|
||||
return
|
||||
|
||||
handler = CErrorHandler(py_error_handler)
|
||||
try:
|
||||
asound.snd_lib_error_set_handler(handler)
|
||||
logger.info("ALSA warnings silenced via snd_lib_error_set_handler")
|
||||
except Exception as inner:
|
||||
logger.debug(f"snd_lib_error_set_handler not available: {inner}")
|
||||
except Exception as e:
|
||||
logger.debug(f"Unable to silence ALSA warnings: {e}")
|
||||
|
||||
|
||||
def enable_alsa_stderr_filter():
|
||||
"""Filter ALSA 'underrun occurred' spam from stderr by intercepting FD 2.
|
||||
|
||||
Works on Linux by routing stderr through a pipe and dropping matching lines.
|
||||
No-op on non-Linux systems. Safe to call multiple times; installs once.
|
||||
"""
|
||||
try:
|
||||
if platform.system() != "Linux":
|
||||
return
|
||||
# Avoid double-install
|
||||
if getattr(config, "_alsa_filter_installed", False):
|
||||
return
|
||||
|
||||
import os as _os
|
||||
import threading as _threading
|
||||
|
||||
patterns = [
|
||||
"ALSA lib pcm.c:",
|
||||
"snd_pcm_recover) underrun occurred",
|
||||
]
|
||||
|
||||
# Save original stderr fd and create pipe
|
||||
save_fd = _os.dup(2)
|
||||
rfd, wfd = _os.pipe()
|
||||
_os.dup2(wfd, 2) # redirect current process stderr to pipe writer
|
||||
_os.close(wfd)
|
||||
|
||||
stop_event = _threading.Event()
|
||||
|
||||
def _reader():
|
||||
try:
|
||||
with _os.fdopen(rfd, 'rb', buffering=0) as r, _os.fdopen(save_fd, 'wb', buffering=0) as orig:
|
||||
buf = b''
|
||||
while not stop_event.is_set():
|
||||
chunk = r.read(1024)
|
||||
if not chunk:
|
||||
break
|
||||
buf += chunk
|
||||
while b"\n" in buf:
|
||||
line, buf = buf.split(b"\n", 1)
|
||||
try:
|
||||
s = line.decode('utf-8', errors='ignore')
|
||||
if not any(p in s for p in patterns):
|
||||
orig.write(line + b"\n")
|
||||
orig.flush()
|
||||
except Exception:
|
||||
# Swallow any decode/write errors; keep filtering
|
||||
pass
|
||||
if buf:
|
||||
try:
|
||||
s = buf.decode('utf-8', errors='ignore')
|
||||
if not any(p in s for p in patterns):
|
||||
orig.write(buf)
|
||||
orig.flush()
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
try:
|
||||
# Best-effort: restore original stderr on failure
|
||||
_os.dup2(save_fd, 2)
|
||||
except Exception:
|
||||
pass
|
||||
logger.debug(f"ALSA stderr filter reader error: {e}")
|
||||
|
||||
t = _threading.Thread(target=_reader, daemon=True)
|
||||
t.start()
|
||||
|
||||
def _restore():
|
||||
try:
|
||||
_os.dup2(save_fd, 2)
|
||||
except Exception:
|
||||
pass
|
||||
stop_event.set()
|
||||
|
||||
# Expose restore in config for future use if needed
|
||||
config._alsa_filter_installed = True
|
||||
config._alsa_filter_restore = _restore
|
||||
logger.info("ALSA underrun stderr filter installed")
|
||||
except Exception as e:
|
||||
logger.debug(f"Unable to install ALSA stderr filter: {e}")
|
||||
|
||||
def restart_application(delay_ms: int = 2000):
|
||||
"""Schedule a restart with a visible popup; actual restart happens in the main loop.
|
||||
|
||||
@@ -181,22 +73,6 @@ _extensions_cache = None # type: ignore
|
||||
_extensions_json_regenerated = False
|
||||
|
||||
|
||||
# Détection système non-PC
|
||||
def detect_non_pc():
|
||||
arch = platform.machine()
|
||||
try:
|
||||
result = subprocess.run(["batocera-es-swissknife", "--arch"], capture_output=True, text=True, timeout=2)
|
||||
if result.returncode == 0:
|
||||
arch = result.stdout.strip()
|
||||
#logger.debug(f"Architecture via batocera-es-swissknife: {arch}")
|
||||
except (subprocess.SubprocessError, FileNotFoundError):
|
||||
logger.debug(f"batocera-es-swissknife non disponible, utilisation de platform.machine(): {arch}")
|
||||
|
||||
is_non_pc = arch not in ["x86_64", "amd64", "AMD64"]
|
||||
logger.debug(f"Système détecté: {platform.system()}, architecture: {arch}, is_non_pc={is_non_pc}")
|
||||
return is_non_pc
|
||||
|
||||
|
||||
# Fonction pour charger le fichier JSON des extensions supportées
|
||||
def load_extensions_json():
|
||||
"""Charge le JSON des extensions supportées.
|
||||
|
||||
Reference in New Issue
Block a user