diff --git a/src/app/main.cpp b/src/app/main.cpp index 32651d643063d..5b767c32c83f3 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -100,7 +100,11 @@ int main(int argc, char** argv) } #ifdef Q_OS_LINUX - if (qEnvironmentVariable("MU_QT_QPA_PLATFORM") != "offscreen") { + // NOTE: gtk3 is forced by default because it fixed keyboard input in file dialogs (#13113). + // Respect an explicitly configured theme (e.g. "xdgdesktopportal") instead of overriding it, + // so desktop environments that rely on the portal for native/sandboxed dialogs keep working. + if (qEnvironmentVariable("MU_QT_QPA_PLATFORM") != "offscreen" + && !qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME")) { qputenv("QT_QPA_PLATFORMTHEME", "gtk3"); } diff --git a/src/project/internal/exportprojectscenario.cpp b/src/project/internal/exportprojectscenario.cpp index 74fcc4c0253a7..2d64b098c480a 100644 --- a/src/project/internal/exportprojectscenario.cpp +++ b/src/project/internal/exportprojectscenario.cpp @@ -99,6 +99,20 @@ RetVal ExportProjectScenario::askExportPath(const INotationPtr RetVal exportPath; exportPath.val = interactive()->selectSavingFileSync(muse::trc("project/export", "Export"), defaultPath, exportType.filter(), isCreatingOnlyOneFile); + + if (!exportPath.val.empty()) { + // Some Linux file dialogs don't auto-append the extension the user didn't type, + // which would otherwise leave us without a writer for this path in exportScores(). + std::string actualSuffix = io::suffix(exportPath.val); + bool hasKnownSuffix = std::find_if(exportType.suffixes.cbegin(), exportType.suffixes.cend(), [&actualSuffix](const QString& s) { + return s.toStdString() == actualSuffix; + }) != exportType.suffixes.cend(); + + if (!hasKnownSuffix) { + exportPath.val = exportPath.val.appendingSuffix(exportType.suffixes.front().toStdString()); + } + } + exportPath.ret = !exportPath.val.empty(); return exportPath;