Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Linux] Fix opening files in external apps #1954

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 9 additions & 59 deletions launcher/DesktopServices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <QDesktopServices>
#include <QDir>
#include <QProcess>
#include "FileSystem.h"

/**
* This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing.
Expand Down Expand Up @@ -96,81 +97,30 @@ bool IndirectOpen(T callable, qint64* pid_forked = nullptr)
#endif

namespace DesktopServices {
bool openDirectory(const QString& path, [[maybe_unused]] bool ensureExists)
bool openPath(const QFileInfo& path, [[maybe_unused]] bool ensureExists)
{
qDebug() << "Opening directory" << path;
QDir parentPath;
QDir dir(path);
if (ensureExists && !dir.exists()) {
parentPath.mkpath(dir.absolutePath());
qDebug() << "Opening path" << path;
if (ensureExists) {
FS::ensureFolderPathExists(path);
}
auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath())); };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if (!isSandbox()) {
return IndirectOpen(f);
}
#endif
return f();
return openUrl(QUrl::fromLocalFile(QFileInfo(path).absolutePath()));
}

bool openFile(const QString& path)
bool openPath(const QString& path, [[maybe_unused]] bool ensureExists)
Scrumplex marked this conversation as resolved.
Show resolved Hide resolved
{
qDebug() << "Opening file" << path;
auto f = [&]() { return QDesktopServices::openUrl(QUrl::fromLocalFile(path)); };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if (!isSandbox()) {
return IndirectOpen(f);
} else {
return f();
}
#else
return f();
#endif
}

bool openFile(const QString& application, const QString& path, const QString& workingDirectory, qint64* pid)
{
qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
if (!isSandbox()) {
return IndirectOpen([&]() { return QProcess::startDetached(application, QStringList() << path, workingDirectory); }, pid);
} else {
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
}
#else
return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
#endif
return openPath(QFileInfo(path), ensureExists);
}

bool run(const QString& application, const QStringList& args, const QString& workingDirectory, qint64* pid)
{
qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if (!isSandbox()) {
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]() { return QProcess::startDetached(application, args, workingDirectory); }, pid);
} else {
return QProcess::startDetached(application, args, workingDirectory, pid);
}
#else
return QProcess::startDetached(application, args, workingDirectory, pid);
#endif
}

bool openUrl(const QUrl& url)
{
qDebug() << "Opening URL" << url.toString();
auto f = [&]() { return QDesktopServices::openUrl(url); };
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if (!isSandbox()) {
return IndirectOpen(f);
} else {
return f();
}
#else
return f();
#endif
return QDesktopServices::openUrl(url);
}

bool isFlatpak()
Expand Down
17 changes: 8 additions & 9 deletions launcher/DesktopServices.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,30 @@
#include <QString>
#include <QUrl>

class QFileInfo;

/**
* This wraps around QDesktopServices and adds workarounds where needed
* Use this instead of QDesktopServices!
*/
namespace DesktopServices {
/**
* Open a file in whatever application is applicable
* Open a path in whatever application is applicable.
* @param ensurePathExists Make sure the path exists
*/
bool openFile(const QString& path);
bool openPath(const QFileInfo& path, bool ensurePathExists = false);
Scrumplex marked this conversation as resolved.
Show resolved Hide resolved

/**
* Open a file in the specified application
* Open a path in whatever application is applicable.
* @param ensurePathExists Make sure the path exists
*/
bool openFile(const QString& application, const QString& path, const QString& workingDirectory = QString(), qint64* pid = 0);
bool openPath(const QString& path, bool ensurePathExists = false);

/**
* Run an application
*/
bool run(const QString& application, const QStringList& args, const QString& workingDirectory = QString(), qint64* pid = 0);

/**
* Open a directory
*/
bool openDirectory(const QString& path, bool ensureExists = false);

/**
* Open the URL, most likely in a browser. Maybe.
*/
Expand Down
10 changes: 7 additions & 3 deletions launcher/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,19 @@ bool ensureFilePathExists(QString filenamepath)
return success;
}

bool ensureFolderPathExists(QString foldernamepath)
bool ensureFolderPathExists(const QFileInfo folderPath)
{
QFileInfo a(foldernamepath);
QDir dir;
QString ensuredPath = a.filePath();
QString ensuredPath = folderPath.filePath();
bool success = dir.mkpath(ensuredPath);
return success;
}

bool ensureFolderPathExists(const QString folderPathName)
{
return ensureFolderPathExists(QFileInfo(folderPathName));
}

bool copyFileAttributes(QString src, QString dst)
{
#ifdef Q_OS_WIN32
Expand Down
8 changes: 7 additions & 1 deletion launcher/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ bool ensureFilePathExists(QString filenamepath);
* Creates all the folders in a path for the specified path
* last segment of the path is treated as a folder name and is created!
*/
bool ensureFolderPathExists(QString filenamepath);
bool ensureFolderPathExists(const QFileInfo folderPath);

/**
* Creates all the folders in a path for the specified path
* last segment of the path is treated as a folder name and is created!
*/
bool ensureFolderPathExists(const QString folderPathName);

/**
* @brief Copies a directory and it's contents from src to dest
Expand Down
18 changes: 9 additions & 9 deletions launcher/ui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,43 +1197,43 @@ void MainWindow::undoTrashInstance()

void MainWindow::on_actionViewLauncherRootFolder_triggered()
{
DesktopServices::openDirectory(".");
DesktopServices::openPath(".");
}

void MainWindow::on_actionViewInstanceFolder_triggered()
{
QString str = APPLICATION->settings()->get("InstanceDir").toString();
DesktopServices::openDirectory(str);
DesktopServices::openPath(str);
}

void MainWindow::on_actionViewCentralModsFolder_triggered()
{
DesktopServices::openDirectory(APPLICATION->settings()->get("CentralModsDir").toString(), true);
DesktopServices::openPath(APPLICATION->settings()->get("CentralModsDir").toString(), true);
}

void MainWindow::on_actionViewIconThemeFolder_triggered()
{
DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path(), true);
DesktopServices::openPath(APPLICATION->themeManager()->getIconThemesFolder().path(), true);
}

void MainWindow::on_actionViewWidgetThemeFolder_triggered()
{
DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path(), true);
DesktopServices::openPath(APPLICATION->themeManager()->getApplicationThemesFolder().path(), true);
}

void MainWindow::on_actionViewCatPackFolder_triggered()
{
DesktopServices::openDirectory(APPLICATION->themeManager()->getCatPacksFolder().path(), true);
DesktopServices::openPath(APPLICATION->themeManager()->getCatPacksFolder().path(), true);
}

void MainWindow::on_actionViewIconsFolder_triggered()
{
DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true);
DesktopServices::openPath(APPLICATION->icons()->getDirectory(), true);
}

void MainWindow::on_actionViewLogsFolder_triggered()
{
DesktopServices::openDirectory("logs", true);
DesktopServices::openPath("logs", true);
}

void MainWindow::refreshInstances()
Expand Down Expand Up @@ -1452,7 +1452,7 @@ void MainWindow::on_actionViewSelectedInstFolder_triggered()
{
if (m_selectedInstance) {
QString str = m_selectedInstance->instanceRoot();
DesktopServices::openDirectory(QDir(str).absolutePath());
DesktopServices::openPath(QDir(str).absolutePath());
}
}

Expand Down
2 changes: 1 addition & 1 deletion launcher/ui/dialogs/IconPickerDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,5 @@ IconPickerDialog::~IconPickerDialog()

void IconPickerDialog::openFolder()
{
DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true);
DesktopServices::openPath(APPLICATION->icons()->getDirectory(), true);
}
4 changes: 2 additions & 2 deletions launcher/ui/pages/instance/ExternalResourcesPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ void ExternalResourcesPage::disableItem()

void ExternalResourcesPage::viewConfigs()
{
DesktopServices::openDirectory(m_instance->instanceConfigFolder(), true);
DesktopServices::openPath(m_instance->instanceConfigFolder(), true);
}

void ExternalResourcesPage::viewFolder()
{
DesktopServices::openDirectory(m_model->dir().absolutePath(), true);
DesktopServices::openPath(m_model->dir().absolutePath(), true);
}

bool ExternalResourcesPage::current(const QModelIndex& current, const QModelIndex& previous)
Expand Down
4 changes: 2 additions & 2 deletions launcher/ui/pages/instance/ScreenshotsPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ void ScreenshotsPage::onItemActivated(QModelIndex index)
return;
auto info = m_model->fileInfo(index);
QString fileName = info.absoluteFilePath();
DesktopServices::openFile(info.absoluteFilePath());
DesktopServices::openPath(info.absoluteFilePath());
Scrumplex marked this conversation as resolved.
Show resolved Hide resolved
}

void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection& selected)
Expand All @@ -352,7 +352,7 @@ void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection& selected)

void ScreenshotsPage::on_actionView_Folder_triggered()
{
DesktopServices::openDirectory(m_folder, true);
DesktopServices::openPath(m_folder, true);
}

void ScreenshotsPage::on_actionUpload_triggered()
Expand Down
4 changes: 2 additions & 2 deletions launcher/ui/pages/instance/VersionPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,12 @@ void VersionPage::on_actionAdd_Empty_triggered()

void VersionPage::on_actionLibrariesFolder_triggered()
{
DesktopServices::openDirectory(m_inst->getLocalLibraryPath(), true);
DesktopServices::openPath(m_inst->getLocalLibraryPath(), true);
}

void VersionPage::on_actionMinecraftFolder_triggered()
{
DesktopServices::openDirectory(m_inst->gameRoot(), true);
DesktopServices::openPath(m_inst->gameRoot(), true);
}

void VersionPage::versionCurrent(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous)
Expand Down
4 changes: 2 additions & 2 deletions launcher/ui/pages/instance/WorldListPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ void WorldListPage::on_actionRemove_triggered()

void WorldListPage::on_actionView_Folder_triggered()
{
DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
DesktopServices::openPath(m_worlds->dir().absolutePath(), true);
}

void WorldListPage::on_actionDatapacks_triggered()
Expand All @@ -223,7 +223,7 @@ void WorldListPage::on_actionDatapacks_triggered()

auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();

DesktopServices::openDirectory(FS::PathCombine(fullPath, "datapacks"), true);
DesktopServices::openPath(FS::PathCombine(fullPath, "datapacks"), true);
}

void WorldListPage::on_actionReset_Icon_triggered()
Expand Down
6 changes: 3 additions & 3 deletions launcher/ui/widgets/ThemeCustomizationWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget* parent) : QWidget(pa
connect(ui->backgroundCatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme);

connect(ui->iconsFolder, &QPushButton::clicked, this,
[] { DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path()); });
[] { DesktopServices::openPath(APPLICATION->themeManager()->getIconThemesFolder().path()); });
connect(ui->widgetStyleFolder, &QPushButton::clicked, this,
[] { DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path()); });
[] { DesktopServices::openPath(APPLICATION->themeManager()->getApplicationThemesFolder().path()); });
connect(ui->catPackFolder, &QPushButton::clicked, this,
[] { DesktopServices::openDirectory(APPLICATION->themeManager()->getCatPacksFolder().path()); });
[] { DesktopServices::openPath(APPLICATION->themeManager()->getCatPacksFolder().path()); });
}

ThemeCustomizationWidget::~ThemeCustomizationWidget()
Expand Down