From e178d6543feec56a4596eadf52c485e9a00c43fa Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 17 Feb 2026 04:36:25 +0100 Subject: [PATCH 1/4] chore: bump universal_gamepad to 1.2.0, bundle libmanette --- linux/CMakeLists.txt | 6 +++--- pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index b8666e01..f3d08f76 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -70,9 +70,9 @@ set_target_properties(${BINARY_NAME} ) -# Bundle SDL3 from source so the build works on systems without libsdl3-dev -# (e.g. arm64 Linux where no distro package exists yet). -set(BUNDLE_SDL3 ON CACHE BOOL "" FORCE) +# Bundle libmanette from source so the build works on systems without +# libmanette-0.2-dev (e.g. SteamOS where the rootfs is read-only). +set(BUNDLE_MANETTE ON CACHE BOOL "" FORCE) # Generated plugin build rules, which manage building the plugins and adding # them to the application. diff --git a/pubspec.yaml b/pubspec.yaml index 675bd827..1af9d5e9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,7 @@ dependencies: path: wakelock_plus path_provider: ^2.1.0 path: ^1.9.0 - universal_gamepad: ^1.1.1 + universal_gamepad: ^1.2.0 drift: ^2.28.2 sqlite3_flutter_libs: ^0.5.41 workmanager: ^0.9.0+3 From c8b6b70561dea83ea0a8a936fd635ef72e8ce42d Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 17 Feb 2026 04:40:58 +0100 Subject: [PATCH 2/4] fix: use system libmanette instead of bundling --- .github/workflows/build.yml | 8 ++++---- linux/CMakeLists.txt | 4 ---- scripts/steam.Dockerfile | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4b1e5248..b0fbd29c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -429,13 +429,13 @@ jobs: - name: Cache APT packages uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + packages: clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libmanette-0.2-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick version: 1.1 - name: Install Linux dependencies run: | sudo apt-get update - sudo apt-get install -y clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + sudo apt-get install -y clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libmanette-0.2-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick - name: Cache libmpv build id: libmpv-cache @@ -537,13 +537,13 @@ jobs: - name: Cache APT packages uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + packages: clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libmanette-0.2-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick version: 1.1 - name: Install Linux dependencies run: | sudo apt-get update - sudo apt-get install -y clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + sudo apt-get install -y clang cmake meson ninja-build pkg-config nasm libgtk-3-dev liblzma-dev libstdc++-12-dev libmanette-0.2-dev libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev libepoxy-dev libegl-dev libgl-dev libgnutls28-dev libpipewire-0.3-dev libva-dev libvdpau-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libwayland-dev wayland-protocols liblcms2-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick - name: Cache libmpv build id: libmpv-cache diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index f3d08f76..12906643 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -70,10 +70,6 @@ set_target_properties(${BINARY_NAME} ) -# Bundle libmanette from source so the build works on systems without -# libmanette-0.2-dev (e.g. SteamOS where the rootfs is read-only). -set(BUNDLE_MANETTE ON CACHE BOOL "" FORCE) - # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) diff --git a/scripts/steam.Dockerfile b/scripts/steam.Dockerfile index b6a875bd..3d44d287 100644 --- a/scripts/steam.Dockerfile +++ b/scripts/steam.Dockerfile @@ -8,7 +8,7 @@ COPY --from=runtime-snapshot /steam-rt-libs.txt /steam-rt-libs.txt # ─── Layer 1: apt deps (cached unless this block changes) ───────────────────── RUN apt-get update -qq && apt-get install -y -qq \ clang cmake meson ninja-build pkg-config nasm git curl unzip xz-utils \ - libgtk-3-dev liblzma-dev \ + libgtk-3-dev liblzma-dev libmanette-0.2-dev \ libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev \ libepoxy-dev libegl-dev libgl-dev libgnutls28-dev \ libpipewire-0.3-dev libva-dev libvdpau-dev \ From cded1a042bb255bd809a5c6f7ba4df8f9be2ff24 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 17 Feb 2026 05:02:45 +0100 Subject: [PATCH 3/4] fix: bundle all plugin deps in steam build --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- scripts/bundle_steam.sh | 42 +++++++++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 24fda279..bc7c98b3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1263,10 +1263,10 @@ packages: dependency: "direct main" description: name: universal_gamepad - sha256: ab16fd55ad164101cd36ff5ea2252006aa2ba2a4929c63e6e68206795ef16084 + sha256: "571461c8c1861b03c9ae4a160fb2cb5576b46fbbcd27f67a4f7a4bf5231c28ce" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.1" url_launcher: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 1af9d5e9..a508c4b3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,7 @@ dependencies: path: wakelock_plus path_provider: ^2.1.0 path: ^1.9.0 - universal_gamepad: ^1.2.0 + universal_gamepad: ^1.2.1 drift: ^2.28.2 sqlite3_flutter_libs: ^0.5.41 workmanager: ^0.9.0+3 diff --git a/scripts/bundle_steam.sh b/scripts/bundle_steam.sh index 2c39297d..2aa57e1b 100644 --- a/scripts/bundle_steam.sh +++ b/scripts/bundle_steam.sh @@ -10,31 +10,41 @@ LIBMPV_DIR=$(dirname "$(find /build/libmpv-prefix -name libmpv.so | head -1)") cp -a "$LIBMPV_DIR"/libmpv.so* "$BUNDLE_LIB/" cp -a /build/libmpv-prefix/lib/libshaderc_shared.so* "$BUNDLE_LIB/" -# Bundle libmpv's runtime deps that the Steam Runtime doesn't ship. +# Bundle runtime deps that the Steam Runtime doesn't ship. # /steam-rt-libs.txt was snapshot before we built anything (see Dockerfile). echo "" -echo "==> Bundling libmpv runtime dependencies..." +echo "==> Bundling runtime dependencies not in Steam Runtime..." RT_LIBS="/steam-rt-libs.txt" -ldd "$LIBMPV_DIR/libmpv.so" 2>/dev/null | grep "=> /" | awk '{print $3}' | while read dep; do - dep_name=$(basename "$dep") - if ! grep -qF "$dep_name" "$RT_LIBS"; then - if [ ! -f "$BUNDLE_LIB/$dep_name" ]; then - echo " Bundling $dep_name" - cp -a "$dep" "$BUNDLE_LIB/" - # Also copy any symlink variants - dep_dir=$(dirname "$dep") - dep_base=$(echo "$dep_name" | sed 's/\.so.*//') - cp -a "$dep_dir"/${dep_base}.so* "$BUNDLE_LIB/" 2>/dev/null || true + +# Collect all binaries to scan: main binary, libmpv, and all plugin .so files. +SCAN_BINS=("$BUNDLE/plezy" "$LIBMPV_DIR/libmpv.so") +for so in "$BUNDLE_LIB"/*.so; do + [ -f "$so" ] && SCAN_BINS+=("$so") +done + +for bin in "${SCAN_BINS[@]}"; do + ldd "$bin" 2>/dev/null | grep "=> /" | awk '{print $3}' | while read dep; do + dep_name=$(basename "$dep") + if ! grep -qF "$dep_name" "$RT_LIBS"; then + if [ ! -f "$BUNDLE_LIB/$dep_name" ]; then + echo " Bundling $dep_name (needed by $(basename "$bin"))" + cp -a "$dep" "$BUNDLE_LIB/" + dep_dir=$(dirname "$dep") + dep_base=$(echo "$dep_name" | sed 's/\.so.*//') + cp -a "$dep_dir"/${dep_base}.so* "$BUNDLE_LIB/" 2>/dev/null || true + fi fi - fi + done done # Verify all deps resolve echo "" echo "==> Checking dependencies..." -MISSING=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$BUNDLE/plezy" 2>&1 | grep "not found" || true) -MISSING_MPV=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$BUNDLE_LIB/libmpv.so" 2>&1 | grep "not found" || true) -MISSING="$MISSING$MISSING_MPV" +MISSING="" +for bin in "$BUNDLE/plezy" "$BUNDLE_LIB"/*.so*; do + [ -f "$bin" ] || continue + MISSING+=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$bin" 2>&1 | grep "not found" || true) +done if [[ -n "$MISSING" ]]; then echo "WARNING: Unresolved dependencies (will need Steam runtime):" echo "$MISSING" From d2def92241356e8c68fc8025d6ea73917ae9809e Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Mon, 16 Feb 2026 23:29:39 -0500 Subject: [PATCH 4/4] Handle mouse back button for navigation --- lib/main.dart | 31 +++++++++++++++++++++------- lib/utils/mouse_back_recognizer.dart | 27 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 lib/utils/mouse_back_recognizer.dart diff --git a/lib/main.dart b/lib/main.dart index 3a92545c..cb2b7aaa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; +import 'package:plezy/utils/mouse_back_recognizer.dart'; import 'dart:io' show Platform; import 'package:window_manager/window_manager.dart'; import 'package:provider/provider.dart'; @@ -187,6 +188,9 @@ void _registerShaderLicenses() { // Global RouteObserver for tracking navigation final RouteObserver routeObserver = RouteObserver(); +// Global navigator key for accessing navigator from anywhere +final GlobalKey navigatorKey = GlobalKey(); + class MainApp extends StatefulWidget { const MainApp({super.key}); @@ -317,14 +321,25 @@ class _MainAppState extends State with WidgetsBindingObserver { builder: (context, themeProvider, child) { return TranslationProvider( child: InputModeTracker( - child: MaterialApp( - title: t.app.title, - debugShowCheckedModeBanner: false, - theme: themeProvider.lightTheme, - darkTheme: themeProvider.darkTheme, - themeMode: themeProvider.materialThemeMode, - navigatorObservers: [routeObserver, BackKeySuppressorObserver()], - home: const OrientationAwareSetup(), + child: RawGestureDetector( + gestures: { + MouseBackRecognizer: GestureRecognizerFactoryWithHandlers( + () => MouseBackRecognizer(), + (instance) => instance.onTapDown = (details) { + navigatorKey.currentState?.maybePop(); + }, + ), + }, + child: MaterialApp( + navigatorKey: navigatorKey, + title: t.app.title, + debugShowCheckedModeBanner: false, + theme: themeProvider.lightTheme, + darkTheme: themeProvider.darkTheme, + themeMode: themeProvider.materialThemeMode, + navigatorObservers: [routeObserver, BackKeySuppressorObserver()], + home: const OrientationAwareSetup(), + ), ), ), ); diff --git a/lib/utils/mouse_back_recognizer.dart b/lib/utils/mouse_back_recognizer.dart new file mode 100644 index 00000000..fbea39a5 --- /dev/null +++ b/lib/utils/mouse_back_recognizer.dart @@ -0,0 +1,27 @@ +import 'package:flutter/gestures.dart'; + +// From here: https://github.com/flutter/flutter/issues/115641#issuecomment-2267579790 +class MouseBackRecognizer extends BaseTapGestureRecognizer { + GestureTapDownCallback? onTapDown; + + MouseBackRecognizer({super.debugOwner, super.supportedDevices, super.allowedButtonsFilter}); + + @override + void handleTapCancel({required PointerDownEvent down, PointerCancelEvent? cancel, required String reason}) {} + + @override + void handleTapDown({required PointerDownEvent down}) { + final TapDownDetails details = TapDownDetails( + globalPosition: down.position, + localPosition: down.localPosition, + kind: getKindForPointer(down.pointer), + ); + + if (down.buttons == kBackMouseButton && onTapDown != null) { + invokeCallback('onTapDown', () => onTapDown!(details)); + } + } + + @override + void handleTapUp({required PointerDownEvent down, required PointerUpEvent up}) {} +}