Skip to content

Commit 62e3067

Browse files
authored
feat: detect opengl version (#389)
* feat: detect opengl version * feat: add glxinfo package
1 parent 275fc1d commit 62e3067

File tree

4 files changed

+88
-18
lines changed

4 files changed

+88
-18
lines changed

ou_dedetai/installer.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
from pathlib import Path
77
from typing import Optional
88

9-
from ou_dedetai import system
109
from ou_dedetai.app import App, UserExitedFromAsk
1110

1211
from . import constants
1312
from . import network
13+
from . import system
1414
from . import utils
1515
from . import wine
1616

17+
from ou_dedetai.system import OpenGLIncompatible
1718

1819
# This step doesn't do anything per-say, but "collects" all the choices in one step
1920
# The app would continue to work without this function
@@ -78,10 +79,6 @@ def check_for_known_bugs(app: App):
7879
"""Checks for any known bug conditions and recommends user action.
7980
This is a best-effort check
8081
"""
81-
app.installer_step_count += 1
82-
ensure_sys_deps(app=app)
83-
app.installer_step += 1
84-
8582
# Begin workaround #435
8683
# FIXME: #435 Remove this check when the issue is fixed upstream in wine
8784
# Check to see if our default browser is chromium, google-chrome, brave, or vivaldi
@@ -163,20 +160,46 @@ def check_for_known_bugs(app: App):
163160

164161
# End workaround #435
165162

163+
def check_opengl(app: App):
164+
app.status("Checking available OpenGL version…")
165+
try:
166+
opengl_version, reason = system.check_opengl_version(app)
167+
app.status(reason)
168+
except OpenGLIncompatible:
169+
app.status(f"Incompatible OpenGL version.")
170+
question = "Incompatible OpenGL version. Logos will be unable to launch. Should the install continue anyways?"
171+
if app.approve(question):
172+
logging.debug("> User continuing with incompatible OpenGL.")
173+
else:
174+
app.status("Exiting install…")
175+
sys.exit() # Exits the install thread.
166176

167-
def ensure_appimage_download(app: App):
168-
app.installer_step_count += 1
177+
logging.debug("> Done.")
178+
179+
180+
def check_system_compatibility(app: App):
169181
try:
170182
check_for_known_bugs(app=app)
171183
except Exception:
172184
logging.exception("Failed to check for known bugs - assuming everything is fine and continuing install.")
173-
app.installer_step += 1
174185
if (
175-
app.conf.faithlife_product_version != '9'
186+
app.conf.faithlife_product_version != '9'
176187
and not str(app.conf.wine_binary).lower().endswith('appimage')
177188
and app.conf.wine_binary not in [constants.WINE_BETA_SIGIL, constants.WINE_RECOMMENDED_SIGIL]
178189
):
179190
return
191+
192+
check_opengl(app=app)
193+
194+
195+
def ensure_appimage_download(app: App):
196+
app.installer_step_count += 1
197+
ensure_sys_deps(app=app)
198+
check_system_compatibility(app=app)
199+
app.installer_step += 1
200+
201+
if app.conf.faithlife_product_version != '9' and not str(app.conf.wine_binary).lower().endswith('appimage'):
202+
return
180203
app.status("Ensuring wine AppImage is downloaded…")
181204

182205
downloaded_file = None
@@ -401,6 +424,7 @@ def ensure_launcher_shortcuts(app: App):
401424
f"Runmode is '{constants.RUNMODE}'. Won't create desktop shortcuts",
402425
)
403426

427+
404428
def install(app: App):
405429
"""Entrypoint for installing"""
406430
app.status('Installing…')

ou_dedetai/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import os
1414
import sys
1515

16-
from ou_dedetai.repair import detect_and_recover
16+
from .repair import detect_and_recover
1717

1818
from . import cli
1919
from . import constants

ou_dedetai/system.py

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
from dataclasses import dataclass
2-
from pathlib import Path
3-
from typing import Optional, Tuple
4-
from collections.abc import MutableMapping
5-
import zipfile
1+
import re
2+
63
import distro
74
import logging
85
import os
@@ -13,12 +10,19 @@
1310
import subprocess
1411
import sys
1512
import time
13+
import zipfile
1614

17-
from ou_dedetai import constants, network
15+
from collections.abc import MutableMapping
16+
from dataclasses import dataclass
17+
from packaging.version import Version
18+
from pathlib import Path
19+
from typing import Optional, Tuple
20+
21+
from ou_dedetai import constants, network, wine
1822
from ou_dedetai.app import App
1923

2024

21-
def fix_ld_library_path(env: Optional[MutableMapping[str, str]]) -> dict[str, str]:
25+
def fix_ld_library_path(env: Optional[MutableMapping[str, str]]) -> dict[str, str]:
2226
"""Removes pyinstaller bundled dynamic linked libraries when executing commands
2327
2428
- https://pyinstaller.org/en/latest/common-issues-and-pitfalls.html#launching-external-programs-from-the-frozen-application
@@ -366,6 +370,34 @@ class SuperuserCommandNotFound(Exception):
366370
"""Superuser command not found. Install pkexec or sudo or doas"""
367371

368372

373+
class OpenGLIncompatible(Exception):
374+
"""OpenGL version is incompatible."""
375+
376+
377+
def check_opengl_version(app: App, required_version="3.2") -> tuple[bool, str]:
378+
try:
379+
env = wine.get_wine_env(app, None)
380+
result = run_command(['glxinfo'], env=fix_ld_library_path(env), capture_output=True, text=True, check=True)
381+
except FileNotFoundError:
382+
return False, "glxinfo command not found. Please install mesa-utils or equivalent."
383+
except subprocess.CalledProcessError as e:
384+
return False, f"glxinfo command failed: {e.stderr.strip()}"
385+
386+
match = re.search(r"OpenGL version string:\s+([\d\.]+)", result.stdout)
387+
if not match:
388+
return False, "Failed to parse OpenGL version from glxinfo output."
389+
390+
opengl_version = match.group(1)
391+
if Version(opengl_version) >= Version(required_version):
392+
message = f"OpenGL Version: {opengl_version} is supported (>= {required_version})."
393+
logging.info(message)
394+
return True, message
395+
else:
396+
message = f"OpenGL Version: {opengl_version} is not supported (must be >= {required_version})."
397+
logging.info(message)
398+
raise OpenGLIncompatible()
399+
400+
369401
def get_superuser_command() -> str:
370402
if shutil.which('pkexec'):
371403
return "pkexec"
@@ -420,6 +452,7 @@ def get_package_manager() -> PackageManager | None:
420452
"binutils wget winbind " # wine
421453
"p7zip-full cabextract " # winetricks
422454
"xdg-utils " # For xdg-mime needed for custom url scheme registration
455+
"mesa-utils" # verify opengl version
423456
)
424457

425458
# Now set the appimage packages, this has changed over time
@@ -470,6 +503,7 @@ def get_package_manager() -> PackageManager | None:
470503
"mod_auth_ntlm_winbind samba-winbind samba-winbind-clients " # wine
471504
"cabextract " # winetricks
472505
"xdg-utils " # For xdg-mime needed for custom url scheme registration
506+
"glx-utils" # verify opengl version
473507
)
474508
incompatible_packages = "" # appimagelauncher handled separately
475509
elif shutil.which('zypper') is not None: # OpenSUSE
@@ -485,6 +519,7 @@ def get_package_manager() -> PackageManager | None:
485519
"curl gawk grep " # other
486520
"7zip cabextract " # winetricks
487521
"xdg-utils " # For xdg-mime needed for custom url scheme registration
522+
"Mesa-demo-x" # verify opengl version
488523
)
489524
incompatible_packages = "" # appimagelauncher handled separately
490525
elif shutil.which('apk') is not None: # alpine
@@ -496,11 +531,12 @@ def get_package_manager() -> PackageManager | None:
496531
packages = (
497532
"bash bash-completion " # bash support
498533
"gcompat " # musl to glibc
499-
#"fuse-common fuse fuse3 " # appimages
534+
#"fuse-common fuse fuse3 " # appimages; incompatible with muslc
500535
"wget curl " # network
501536
"7zip cabextract " # winetricks
502537
"samba sed grep gawk bash bash-completion " # other
503538
"xdg-utils " # For xdg-mime needed for custom url scheme registration
539+
"mesa-demos" # verify opengl version
504540
)
505541
incompatible_packages = "" # appimagelauncher handled separately
506542
elif shutil.which('pamac') is not None: # manjaro
@@ -515,6 +551,7 @@ def get_package_manager() -> PackageManager | None:
515551
"curl gawk grep " # other
516552
"7zip cabextract " # winetricks (7zip used to be called p7zip)
517553
"xdg-utils " # For xdg-mime needed for custom url scheme registration
554+
"mesa-utils" # verify opengl version
518555
)
519556
incompatible_packages = "" # appimagelauncher handled separately
520557
elif shutil.which('pacman') is not None: # arch, steamOS
@@ -536,6 +573,7 @@ def get_package_manager() -> PackageManager | None:
536573
"lib32-ncurses ocl-icd lib32-ocl-icd libxslt lib32-libxslt libva lib32-libva gtk3 lib32-gtk3 "
537574
"gst-plugins-base-libs lib32-gst-plugins-base-libs vulkan-icd-loader lib32-vulkan-icd-loader "
538575
"xdg-utils " # For xdg-mime needed for custom url scheme registration
576+
"mesa-utils" # verify opengl version
539577
)
540578
else: # arch
541579
packages = (
@@ -548,6 +586,7 @@ def get_package_manager() -> PackageManager | None:
548586
"libva mpg123 v4l-utils " # video
549587
"libxslt sqlite " # misc
550588
"xdg-utils " # For xdg-mime needed for custom url scheme registration
589+
"mesa-utils" # verify opengl version
551590
)
552591
incompatible_packages = "" # appimagelauncher handled separately
553592
elif os_name == "org.freedesktop.platform":

ou_dedetai/tui_app.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,12 @@ def utilities_menu_select(self, choice):
772772
self.reset_screen()
773773
self.logos.switch_logging()
774774
self.go_to_main_menu()
775+
elif choice == "Check OpenGL":
776+
self.reset_screen()
777+
opengl_version, reason = system.check_opengl_version(self)
778+
logging.info(reason)
779+
self.status(reason)
780+
self.go_to_main_menu()
775781
elif choice == "Uninstall":
776782
control.uninstall(self)
777783
self.go_to_main_menu()
@@ -1089,6 +1095,7 @@ def set_utilities_menu_options(self):
10891095
)
10901096
labels.append(label)
10911097

1098+
labels.append("Check OpenGL")
10921099
labels.append("Return to Main Menu")
10931100

10941101
options = self.which_dialog_options(labels)

0 commit comments

Comments
 (0)