gui: bypass XDG portal for all file/dir dialogs in Flatpak

The v0.1.2 fix that forced Qt's non-native dialog for the "open test"
dialog only covered one call site. The same XDG-portal-vs-sibling-files
problem applies to every other QFileDialog in the GUI (save report,
log file path, default report/log dirs in preferences, python/lua
interpreter pickers).

Extracted a single ``file_dialog.options()`` helper in main_win/ and
threaded it through every getOpenFileName / getSaveFileName /
getExistingDirectory call in main_win/. Outside Flatpak the helper
returns an empty Options(), so the native dialog stays in use on
KDE / GNOME / Windows / macOS.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 08:32:14 +02:00
parent 4d8cafb5a0
commit dd584c9064
5 changed files with 55 additions and 12 deletions

View File

@@ -1,3 +1,22 @@
version 0.1.3
==============
- Stop interrupts engaged blocking steps (console, py_func, lua_func,
json_rpc, sleep) within ~200 ms instead of waiting for the step
to finish.
- GUI Start / Stop / Pause flow simplified.
- lua_func: a function returning nil is no longer reported as a failure.
- ``-d python_bin=...`` and the GUI ``python_bin`` preference now reach
the eval subprocess (used to be silently ignored). ``param.yaml`` can
also override ``python_bin`` for py_func / cycle / post_exec.
- Validation suite: ``test/validation/run.sh`` (and ``run.bat``)
runs the suite inside a dedicated venv in the system temp dir.
- build_all.sh: ``release_note.txt`` and the user manual copied into
``dist/``; warning if the file has no entry for the version being built.
- Flatpak: every GUI file/directory dialog (open test, save report, log
path, default report/log dirs, python/lua interpreter pickers) now
bypasses the XDG document portal — the v0.1.2 fix was only on the
"open test" dialog.
version 0.1.2
==============
- Flatpak: opening a test from the GUI now correctly finds its companion

View File

@@ -0,0 +1,21 @@
"""Helpers for Qt file/directory dialogs.
In Flatpak the native QFileDialog goes through the XDG document portal,
which returns ``/run/user/UID/doc/.../<file>`` and only exposes the
selected file — sibling files (param.yaml, scripts, recent paths in
preferences, ...) are unreachable. Forcing Qt's own non-native dialog
makes it walk the real filesystem mounted via ``--filesystem=home``
and return a regular path.
"""
import os
from PySide6.QtWidgets import QFileDialog
def options():
"""Default ``QFileDialog`` options for the current runtime."""
opts = QFileDialog.Options()
if os.path.isfile("/.flatpak-info"):
opts |= QFileDialog.Option.DontUseNativeDialog
return opts

View File

@@ -3,6 +3,7 @@ from PySide6.QtWidgets import QDialog, QFileDialog
from PySide6.QtGui import QFont
from main_win.preference_win.preference_core_win import Ui_preferenceWindow
from main_win import file_dialog
import interpreter.utils.settings as prefs
@@ -193,6 +194,7 @@ class PrefWindow(QDialog):
self,
caption="Select the default report directory",
dir=self.ui.editDefaultReportPath.text(),
options=file_dialog.options(),
)
if path:
self.ui.editDefaultReportPath.setText(path)
@@ -203,6 +205,7 @@ class PrefWindow(QDialog):
self,
caption="Select the default log directory",
dir=self.ui.editDefaultLogPath.text(),
options=file_dialog.options(),
)
if path:
self.ui.editDefaultLogPath.setText(path)
@@ -213,6 +216,7 @@ class PrefWindow(QDialog):
self,
caption="Select the python interpreter",
dir=self.ui.editPythonPath.text(),
options=file_dialog.options(),
)
if path:
self.ui.editPythonPath.setText(path)
@@ -220,7 +224,10 @@ class PrefWindow(QDialog):
@Slot()
def on_butLuaPath_pressed(self):
path, _ = QFileDialog.getOpenFileName(
self, caption="Select the lua interpreter", dir=self.ui.editLuaPath.text()
self,
caption="Select the lua interpreter",
dir=self.ui.editLuaPath.text(),
options=file_dialog.options(),
)
if path:
self.ui.editLuaPath.setText(path)

View File

@@ -9,6 +9,7 @@ from PySide6.QtWidgets import QApplication, QFileDialog, QProgressDialog
from interpreter.process import TestProcess
from interpreter.utils.test_ctrl import TestSetController
from main_win.test_controller_service import TestControllerService
from main_win import file_dialog
import interpreter.utils.settings as prefs
from runtime.tum_except import ETUMFileError, ETUMRuntimeError
@@ -212,17 +213,9 @@ class TestFileManager:
d = ""
if w.testFile is not None:
d = os.path.dirname(w.testFile)
# In Flatpak the native dialog goes through the XDG document portal,
# which returns /run/user/UID/doc/.../test.tum and only exposes the
# selected file — sibling files (param.yaml, .py, etc.) are unreachable.
# Force Qt's own dialog, which walks the real filesystem mounted via
# --filesystem=home and returns a regular path with sibling access.
options = QFileDialog.Options()
if os.path.isfile("/.flatpak-info"):
options |= QFileDialog.Option.DontUseNativeDialog
file_name, _ = QFileDialog.getOpenFileName(
w, "Open the test file", d,
"testium file (*.tum);;All Files (*)", options=options
"testium file (*.tum);;All Files (*)", options=file_dialog.options()
)
if file_name:
self.reload(file_name)

View File

@@ -37,6 +37,7 @@ from interpreter.utils.icons import icon_prefix
from main_win.test_run.outlog import OutLog
from main_win.test_run.test_run import ThreadTestStatus
from main_win import file_dialog
import interpreter.utils.settings as prefs
from runtime.stdout_redirect import stdio_redir
import api.testium as tm
@@ -484,7 +485,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
else:
initialPath = None
fileName, _ = QFileDialog.getSaveFileName(
self, "Path to Log file", initialPath, "Log Files (*.log);;All Files (*)"
self, "Path to Log file", initialPath, "Log Files (*.log);;All Files (*)",
options=file_dialog.options(),
)
if fileName:
shutil.copy(self.logFileName, fileName)
@@ -525,7 +527,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
else:
initialPath = None
fileName, _ = QFileDialog.getSaveFileName(
self, "Path to log file", initialPath, "Log Files (*.log);;All Files (*)"
self, "Path to log file", initialPath, "Log Files (*.log);;All Files (*)",
options=file_dialog.options(),
)
if fileName:
self.editLogFilePath.setText(fileName)