Skip to content

Releases: Switch-Bros/SteamLibraryManager

v1.5.1

12 May 13:14

Choose a tag to compare

Fixed

  • External-game shortcuts now actually launch from Steam. Since v1.4.4
    every Heroic / Lutris / Flatpak / itch shortcut SLM added to Steam was
    broken: the URI or flatpak run ... command was written into Steam's
    exe field, which Steam treats as a file path. Clicking Play silently
    did nothing or, with Heroic in particular, crashed Steam outright when
    the overlay tried to attach to Electron.

    The launch command is now split into exe + launch_options, with
    three additional protections applied to every external launch:

    1. URIs are routed through their native launcher binary
      (/usr/bin/heroic, /usr/bin/lutris) so the dbus-bound xdg-open
      hop isn't needed - xdg-open is unreliable inside Steam's runtime.
    2. The whole invocation is wrapped in setsid -f so the launcher
      detaches into its own session and Steam stops tracking it
      immediately - no more "Anhalten" hangs, no more crashes when Steam
      waits forever for an Electron app to exit.
    3. env -u LD_PRELOAD -u LD_LIBRARY_PATH -u SteamAppId ... strips
      Steam's overlay shim and bookkeeping vars from the environment so
      Heroic / Proton / Wine start clean. Without this the Steam
      overlay's 32-bit shim leaks into 64-bit Wine processes and the
      game silently fails to launch.

    After updating, existing broken shortcuts in shortcuts.vdf need to
    be removed and re-added via the External Games dialog for the fix
    to take effect.

v1.5.0

12 May 10:37

Choose a tag to compare

Added

  • Heroic Sideload Parser: Manually added (sideloaded) apps in Heroic
    Games Launcher are now visible in the "Externe Spiele verwalten"
    dialog under platform "Heroic (Sideload)". Previously SLM only saw
    GOG/Epic/Amazon games in Heroic - sideloads like Adobe Photoshop or
    WarCraft 2 remastered were invisible.
  • Cover fallback in batch_add_to_steam: After a shortcut is added,
    SLM now automatically tries to fetch a cover via SteamGridDB name
    search. If SteamGridDB returns nothing, it falls back to the
    art_cover URL the source platform already chose (e.g. Heroic's
    pre-selected SteamGridDB image). Failures never break the add flow.
  • New optional cover_url_hint field on ExternalGame model for
    source-provided cover URLs. Other parsers can populate it later.

Changed

  • BaseHeroicParser._RUNNER docstring now lists all four valid runner
    values (legendary, gog, nile, sideload).

Fixed

  • _try_fetch_cover used get_images_by_type(sgdb_game_id, ...) which
    internally tried to convert the input as a Steam app id. Switched to
    get_images_by_type_paged(0, "grids", game_id_override=top_id) so
    the SGDB game id is used directly.

v1.4.5 - Critical appinfo.vdf metadata fix

07 May 14:35

Choose a tag to compare

Fixed

  • Critical: Metadata edits now actually visible to Steam. A latent bug
    caused update_app_metadata to write into data["common"] (top-level)
    while Steam reads from data["appinfo"]["common"]. As a result, every
    metadata edit since the feature was introduced silently went into a
    parallel section that Steam ignored - users saw the change in SLM but
    never in the Steam Library. The writer now targets the correct path,
    cleans up stale data["common"] entries from older SLM versions, and
    the drift detector compares against the path Steam actually reads.
  • The _find_common_section lookup order is reversed to match Steam's
    reading order (appinfo.common first, top-level common as fallback).

Added

  • Auto-Reapply on startup: AppInfoManager.verify_and_reapply() runs
    after every load_appinfo. If Steam overwrote the file with fresh CDN
    data and wiped out the user's edits, SLM detects the drift and re-applies
    the saved modifications immediately - no manual restore button needed.
  • Live file watcher on appinfo.vdf via QFileSystemWatcher. While
    SLM is running, any external rewrite of the file (Steam refresh, manual
    edit, etc.) is detected and re-applied. Debounced 800 ms to coalesce
    Steam's burst writes; self-write suppression via timestamp window so the
    watcher does not loop on our own writes.
  • Immediate VDF write after every save. Previously the binary VDF was
    only flushed on SLM exit, so a crash between save and exit would lose
    the edit. save_appinfo() now writes the VDF as soon as the in-memory
    state is dirty.
  • 16 new unit tests covering drift detection, partial drift across
    multiple apps, fallback paths, and the new save-triggers-write behavior.

Changed

  • update_app_metadata no longer creates a top-level common block;
    always targets appinfo.common. Stale top-level blocks are removed on
    the next write so the file converges back to Steam's expected layout.

v1.4.4 - Complete External Games Overhaul

06 May 20:03

Choose a tag to compare

Added

  • Smart Emulator Detection - SLM detects 9 emulators (Eden, Citron, Ryujinx,
    Cemu, Dolphin, Azahar, RetroArch, PPSSPP, melonDS, DOSBox) by reading their
    own config files for game directories. No more hardcoded ROM search paths.
  • Settings tab "Emulators" - per-emulator status, custom game directories,
    default-emulator-per-system picker, executable override.
  • EmuDeck hint provider - reads ~/emudeck/settings.sh as a fallback for
    emulators that have no library config of their own. Works around EmuDeck's
    known concatenation bug by parsing emulationPath and deriving rom dirs
    ourselves.
  • AppImage auto-discovery in standard Linux user locations (~/Applications,
    ~/AppImages, ~/Apps, ~/.local/bin, ~/bin) - covers the common case
    where users park AppImages outside the system PATH.
  • Shortcuts importer - shortcuts.vdf non-Steam entries now show up in the
    main library, with their tags surfaced as SLM categories.
  • Bidirectional category sync for shortcuts - SLM-side category changes
    write back to both shortcuts.vdf (Steam UI live read) and cloud-storage
    from-tag-X collections (Steam library sidebar). Steam shows the collection
    populated after a restart, no manual tagging needed.
  • Manual SteamGridDB search - the cover picker now has a search box that
    lets you look up a game by name. For non-Steam shortcuts (whose hash appids
    are unknown to SteamGridDB) it auto-runs the name lookup on open.
  • External Games dialog: deselect-all / select-all toggle button and
    user-resizable column headers.
  • DB Schema v12 with new tables emulator_settings and emulator_games.

Fixed

  • Crash on click on non-Steam shortcuts - Steam Store API was being called
    with negative shortcut appids and crashed on the None JSON response. Now
    guarded: appids outside the positive int32 range skip the remote fetch, and
    malformed responses no longer index into None.
  • Cover filenames for non-Steam shortcuts - SLM now writes covers under
    the unsigned uint32 form of the shortcut appid, which is what Steam expects.
    Old signed-form covers are still found by the lookup so existing setups
    keep working.

Changed

  • ROM_SEARCH_PATHS, APPIMAGE_DIRS, EMUDECK_LAUNCHER_DIRS constants
    removed in favour of config-driven emulator discovery.
  • Game.app_id for shortcuts is now the canonical unsigned uint32 form,
    matching Steam's own convention for cover paths and cloud-storage collection
    entries. Conversion to/from the signed form happens at the shortcuts.vdf
    boundary only.
  • RomParser is now a thin facade over EmulatorService.

v1.4.3

05 May 13:46

Choose a tag to compare

Fixed

  • AppImage on Mint 21.3 / Ubuntu 22.04 (GH #13) - Qt 6.5+ requires
    libxcb-cursor.so.0 for the xcb platform plugin, which older Debian/Ubuntu/
    Mint releases do not ship by default. The library is now bundled into the
    AppImage via linuxdeploy --library. Build aborts early if the dependency
    is missing on the build host.

Changed

  • build-appimage.sh and .github/workflows/build-appimage.yml resolve
    libxcb-cursor.so.0 via ldconfig -p and pass the path to linuxdeploy.
  • CI installs libxcb-cursor0 so the workflow finds the library.

Added

  • Bug-Report-Template Versions-Dropdown auf v1.4.3, v1.4.2, v1.4.0, v1.3.9
    erweitert.

v1.4.2

16 Apr 10:50

Choose a tag to compare

Fixed

  • Statistics i18n - all chart labels fully translated (Deck status, ProtonDB
    tiers, review scores, PEGI ratings, achievement buckets, playtime ranges).
    Labels built lazily to avoid circular import issues at module init.
  • Genre tab - falls back to Steam tags when game_genres table is empty.
  • Comparison tab - triggers on autocomplete selection (not just Enter).
    HLTB values rounded to 1 decimal place.
  • Donut "Others" overflow bucket label translated.
  • Readable bucket labels - all internal keys (op_95, lt_1h, etc.) replaced
    with human-readable text in all chart legends.

Added

  • Statistics screenshots (EN + DE) in README.

v1.4.0

16 Apr 08:03

Choose a tag to compare

Added

  • Statistics Dashboard - complete overhaul with 7 interactive tabs:
    • Overview: 4 metric cards (total games, playtime, never played, perfect games)
      • genre donut chart + top 5 most played bar chart
    • Genre: side-by-side donuts (by count vs by playtime) with insight text
      showing "You own most RPGs but play Shooters the most"
    • Platform: 3 donuts showing real per-platform playtime (Windows/Linux/
      Steam Deck/Mac), Deck compatibility status, and ProtonDB tier distribution
    • Achievements: metric cards (unlocked, rare, ultra-rare, perfect) +
      completion buckets donut + almost-done bar + Trophy Wall with cover art
    • Playtime: playtime buckets + HLTB analysis + shame pile (installed
      never-played games sorted by HLTB estimate)
    • Ratings: PEGI distribution + review score buckets + top 10 developers
    • Comparison: search and compare any 2 games side-by-side across all metrics
  • Chart Engine - custom QPainter-based DonutChart and BarChart widgets
    with hover effects, responsive legends, and "Others" bucketing. No external
    charting dependencies.
  • Platform Playtime Tracking - per-platform playtime (Windows, Linux, Mac,
    Steam Deck) persisted in database from Steam API. Shows where you actually
    play instead of just "supported platforms".
  • Playtime Persistence - game playtime and last-played timestamps saved to
    SQLite database, surviving Steam API outages.

Changed

  • DB Schema v11 - added playtime_minutes, last_played, playtime_windows,
    playtime_linux, playtime_mac, playtime_deck columns to games table.
  • Statistics dialog rebuilt as tabbed package (ui/dialogs/statistics/)
    replacing the old 177-line monolithic dialog.

Fixed

  • API keys not loading from keyring - circular import at module init time
    prevented TokenStore from loading keys. Now deferred to bootstrap phase.

v1.3.9

14 Apr 09:19

Choose a tag to compare

Improved

  • i18n: Massive cleanup - eliminated 120+ duplicate translation keys across
    all JSON files. Common terms (Username, Password, Settings, Name, Platform,
    etc.) consolidated into common.json. Cloud Sync keys moved from main.json
    to settings.json where they belong.
  • i18n: rclone setup dialog - German labels ("Passwort", "Benutzername")
    hardcoded in Python source replaced with proper t() calls. English users
    no longer see German UI text.

Changed

  • DRY: User-Agent constants - Chrome and app User-Agent strings centralized
    in config.py (USER_AGENT_BROWSER, USER_AGENT_APP), replacing 7 scattered
    hardcoded copies.
  • DRY: Database path - duplicated _get_db_path() in 4 action files replaced
    with a single MainWindow.db_path property.

Fixed

  • Steam Store rate limiting - increased request interval to 1.5s and added
    automatic 30s backoff on HTTP 429 responses. Prevents Steam from DNS-blocking
    the client during bulk PEGI rating fetches.
  • Network error abort - all enrichment threads now abort after 3 consecutive
    DNS resolution or rate-limit errors instead of pointlessly retrying thousands
    of requests against an unreachable server.

Security

  • API keys moved to system keyring - STEAM_API_KEY and STEAMGRIDDB_API_KEY
    are now stored in the OS keyring (or encrypted file fallback) instead of
    plaintext settings.json. Existing keys are auto-migrated on first launch.

v1.3.8

09 Apr 08:04

Choose a tag to compare

Fixed

  • Steam-Running false positive: steam.pipe persists after Steam exits,
    causing SLM to always detect Steam as running. Now uses non-blocking pipe
    open to check if Steam is actually reading the pipe (ENXIO = not running).
    Fixes GitHub #12.

v1.3.7

08 Apr 11:28

Choose a tag to compare

Fixed

  • Flatpak: Steam-Running detection: The Steam-running warning never appeared
    when running as Flatpak because psutil.process_iter() cannot see host
    processes from inside the sandbox. Now checks for Steam's named pipe
    (~/.steam/steam.pipe) first, which is visible via --filesystem=~/.steam:ro.
    Falls back to psutil for native installations.

Changed

  • Flatpak dependencies: Added missing pybind11 (Pillow build dependency)
    and six (steam library dependency) to Flatpak manifest.