perf: eliminate recursive disk globs and ensure instant process detaching to prevent lag after game exits

This commit is contained in:
Sho 2026-08-02 14:49:02 +09:00
parent 684bc91fd4
commit 059395c3d3
2 changed files with 40 additions and 23 deletions

View File

@ -236,6 +236,19 @@ def resolve_game_info(app_lower):
return None
_desktop_file_cache = None
def get_all_desktop_files():
global _desktop_file_cache
if _desktop_file_cache is None:
_desktop_file_cache = (
glob.glob('/usr/share/applications/*.desktop') +
glob.glob(os.path.expanduser('~/.local/share/applications/*.desktop')) +
glob.glob(os.path.expanduser('~/.local/share/flatpak/exports/share/applications/*.desktop')) +
glob.glob('/var/lib/flatpak/exports/share/applications/*.desktop')
)
return _desktop_file_cache
def resolve_app_info(app_id):
if not app_id:
return {"appId": "", "name": "Application", "icon": ""}
@ -249,12 +262,7 @@ def resolve_app_info(app_id):
_icon_cache[app_lower] = game_info
return game_info
desktop_files = (
glob.glob('/usr/share/applications/*.desktop') +
glob.glob('/usr/share/applications/**/*.desktop', recursive=True) +
glob.glob(os.path.expanduser('~/.local/share/applications/*.desktop')) +
glob.glob(os.path.expanduser('~/.local/share/applications/**/*.desktop'), recursive=True)
)
desktop_files = get_all_desktop_files()
icon_name = None
app_name = None
@ -262,16 +270,28 @@ def resolve_app_info(app_id):
for df in desktop_files:
basename = os.path.basename(df).lower()
base_no_ext = basename.replace('.desktop', '')
if app_lower == base_no_ext or app_lower in basename or base_no_ext in app_lower:
if app_lower == base_no_ext:
entry = parse_desktop(df)
if entry:
if 'Icon' in entry and not icon_name:
icon_name = entry['Icon']
if 'Name' in entry and not app_name:
app_name = entry['Name']
icon_name = entry.get('Icon')
app_name = entry.get('Name')
if icon_name and app_name:
break
if not icon_name or not app_name:
for df in desktop_files:
basename = os.path.basename(df).lower()
base_no_ext = basename.replace('.desktop', '')
if app_lower in basename or base_no_ext in app_lower:
entry = parse_desktop(df)
if entry:
if 'Icon' in entry and not icon_name:
icon_name = entry['Icon']
if 'Name' in entry and not app_name:
app_name = entry['Name']
if icon_name and app_name:
break
if not icon_name:
icon_name = app_lower
if not app_name:
@ -289,10 +309,6 @@ def resolve_app_info(app_id):
if os.path.exists(target):
resolved_icon_path = target
break
matches = glob.glob(os.path.join(d, f'*{icon_name}*{ext}'))
if matches:
resolved_icon_path = matches[0]
break
if resolved_icon_path:
break

View File

@ -69,29 +69,30 @@ def launch():
for fp_id in candidates_flatpak:
if fp_id in installed_flatpaks:
subprocess.Popen(["flatpak", "run", fp_id], start_new_session=True)
return
subprocess.Popen(["flatpak", "run", fp_id], start_new_session=True, close_fds=True)
sys.exit(0)
# Fallback check via flatpak info
check = subprocess.run(["flatpak", "info", fp_id], capture_output=True, text=True)
if check.returncode == 0:
subprocess.Popen(["flatpak", "run", fp_id], start_new_session=True)
return
subprocess.Popen(["flatpak", "run", fp_id], start_new_session=True, close_fds=True)
sys.exit(0)
# 2. GTK Desktop launcher check (using clean desktop ID without paths)
if shutil.which("gtk-launch"):
for gtk_id in [base_name, f"{base_name}.desktop", lower_name]:
res = subprocess.run(["gtk-launch", gtk_id], capture_output=True, text=True)
if res.returncode == 0:
return
sys.exit(0)
# 3. Direct binary execution
bin_name = clean_cmd.split()[0]
if shutil.which(bin_name):
subprocess.Popen(clean_cmd, shell=True, start_new_session=True)
return
subprocess.Popen(clean_cmd, shell=True, start_new_session=True, close_fds=True)
sys.exit(0)
# 4. Fallback execution
subprocess.Popen(f"{clean_cmd} &", shell=True, start_new_session=True)
subprocess.Popen(f"{clean_cmd} &", shell=True, start_new_session=True, close_fds=True)
sys.exit(0)
if __name__ == '__main__':
launch()