parent
b6a413b3f3
commit
5d752b4944
@ -1,432 +0,0 @@
|
||||
Description: Dynamically load libfm-qt
|
||||
Dynamically load libfm-qt on demand to create the file dialog helper to
|
||||
prevent the hard dependency on libfm-qt. This speed up the loading of the QPA
|
||||
plugin and also avoid loading libfm-qt in Qt programs having QT_NO_GLIB=1.
|
||||
Author: Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||
Origin: upstream
|
||||
Applied-Upstream: commit:334394a
|
||||
Last-Update: 2018-07-30
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -18,10 +18,6 @@ find_package(Qt5XdgIconLoader REQUIRED)
|
||||
|
||||
# Patch Version 0
|
||||
|
||||
-# for file dialog support
|
||||
-find_package(Qt5X11Extras REQUIRED)
|
||||
-find_package(fm-qt REQUIRED)
|
||||
-
|
||||
include(LXQtPreventInSourceBuilds)
|
||||
include(LXQtCompilerSettings NO_POLICY_SCOPE)
|
||||
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -6,7 +6,6 @@ include_directories(
|
||||
set(qtlxqt_HDRS
|
||||
lxqtplatformtheme.h
|
||||
lxqtsystemtrayicon.h
|
||||
- lxqtfiledialoghelper.h
|
||||
statusnotifieritem/statusnotifieritem.h
|
||||
statusnotifieritem/dbustypes.h
|
||||
)
|
||||
@@ -15,7 +14,6 @@ set(qtlxqt_SRCS
|
||||
main.cpp
|
||||
lxqtplatformtheme.cpp
|
||||
lxqtsystemtrayicon.cpp
|
||||
- lxqtfiledialoghelper.cpp
|
||||
statusnotifieritem/statusnotifieritem.cpp
|
||||
statusnotifieritem/dbustypes.cpp
|
||||
)
|
||||
@@ -38,7 +36,6 @@ target_link_libraries(qtlxqt
|
||||
Qt5::DBus
|
||||
dbusmenu-qt5
|
||||
Qt5XdgIconLoader
|
||||
- fm-qt
|
||||
)
|
||||
|
||||
|
||||
--- a/src/lxqtfiledialoghelper.cpp
|
||||
+++ /dev/null
|
||||
@@ -1,276 +0,0 @@
|
||||
-#include "lxqtfiledialoghelper.h"
|
||||
-
|
||||
-#include <libfm-qt/libfmqt.h>
|
||||
-#include <libfm-qt/filedialog.h>
|
||||
-
|
||||
-#include <QWindow>
|
||||
-#include <QDebug>
|
||||
-#include <QTimer>
|
||||
-#include <QSettings>
|
||||
-
|
||||
-#include <memory>
|
||||
-
|
||||
-static std::unique_ptr<Fm::LibFmQt> libfmQtContext_;
|
||||
-
|
||||
-inline static const QString viewModeToString(Fm::FolderView::ViewMode value);
|
||||
-inline static Fm::FolderView::ViewMode viewModeFromString(const QString& str);
|
||||
-
|
||||
-LXQtFileDialogHelper::LXQtFileDialogHelper() {
|
||||
- if(!libfmQtContext_) {
|
||||
- // initialize libfm-qt only once
|
||||
- libfmQtContext_ = std::unique_ptr<Fm::LibFmQt>{new Fm::LibFmQt()};
|
||||
- }
|
||||
-
|
||||
- // can only be used after libfm-qt initialization
|
||||
- dlg_ = std::unique_ptr<Fm::FileDialog>(new Fm::FileDialog());
|
||||
- connect(dlg_.get(), &Fm::FileDialog::accepted, [this]() {
|
||||
- saveSettings();
|
||||
- accept();
|
||||
- });
|
||||
- connect(dlg_.get(), &Fm::FileDialog::rejected, [this]() {
|
||||
- saveSettings();
|
||||
- reject();
|
||||
- });
|
||||
-
|
||||
- connect(dlg_.get(), &Fm::FileDialog::fileSelected, this, &LXQtFileDialogHelper::fileSelected);
|
||||
- connect(dlg_.get(), &Fm::FileDialog::filesSelected, this, &LXQtFileDialogHelper::filesSelected);
|
||||
- connect(dlg_.get(), &Fm::FileDialog::currentChanged, this, &LXQtFileDialogHelper::currentChanged);
|
||||
- connect(dlg_.get(), &Fm::FileDialog::directoryEntered, this, &LXQtFileDialogHelper::directoryEntered);
|
||||
- connect(dlg_.get(), &Fm::FileDialog::filterSelected, this, &LXQtFileDialogHelper::filterSelected);
|
||||
-}
|
||||
-
|
||||
-LXQtFileDialogHelper::~LXQtFileDialogHelper() {
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::exec() {
|
||||
- dlg_->exec();
|
||||
-}
|
||||
-
|
||||
-bool LXQtFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow* parent) {
|
||||
- dlg_->setAttribute(Qt::WA_NativeWindow, true); // without this, sometimes windowHandle() will return nullptr
|
||||
-
|
||||
- dlg_->setWindowFlags(windowFlags);
|
||||
- dlg_->setWindowModality(windowModality);
|
||||
-
|
||||
- // Reference: KDE implementation
|
||||
- // https://github.com/KDE/plasma-integration/blob/master/src/platformtheme/kdeplatformfiledialoghelper.cpp
|
||||
- dlg_->windowHandle()->setTransientParent(parent);
|
||||
-
|
||||
- applyOptions();
|
||||
-
|
||||
- loadSettings();
|
||||
- // central positioning with respect to the parent window
|
||||
- if(parent && parent->isVisible()) {
|
||||
- dlg_->move(parent->x() + (parent->width() - dlg_->width()) / 2,
|
||||
- parent->y() + (parent->height() - dlg_->height()) / 2);
|
||||
- }
|
||||
-
|
||||
- // NOTE: the timer here is required as a workaround borrowed from KDE. Without this, the dialog UI will be blocked.
|
||||
- // QFileDialog calls our platform plugin to show our own native file dialog instead of showing its widget.
|
||||
- // However, it still creates a hidden dialog internally, and then make it modal.
|
||||
- // So user input from all other windows that are not the children of the QFileDialog widget will be blocked.
|
||||
- // This includes our own dialog. After the return of this show() method, QFileDialog creates its own window and
|
||||
- // then make it modal, which blocks our UI. The timer schedule a delayed popup of our file dialog, so we can
|
||||
- // show again after QFileDialog and override the modal state. Then our UI can be unblocked.
|
||||
- QTimer::singleShot(0, dlg_.get(), &QDialog::show);
|
||||
- dlg_->setFocus();
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::hide() {
|
||||
- dlg_->hide();
|
||||
-}
|
||||
-
|
||||
-bool LXQtFileDialogHelper::defaultNameFilterDisables() const {
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::setDirectory(const QUrl& directory) {
|
||||
- dlg_->setDirectory(directory);
|
||||
-}
|
||||
-
|
||||
-QUrl LXQtFileDialogHelper::directory() const {
|
||||
- return dlg_->directory();
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::selectFile(const QUrl& filename) {
|
||||
- dlg_->selectFile(filename);
|
||||
-}
|
||||
-
|
||||
-QList<QUrl> LXQtFileDialogHelper::selectedFiles() const {
|
||||
- return dlg_->selectedFiles();
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::setFilter() {
|
||||
- // FIXME: what's this?
|
||||
- // The gtk+ 3 file dialog helper in Qt5 update options in this method.
|
||||
- applyOptions();
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::selectNameFilter(const QString& filter) {
|
||||
- dlg_->selectNameFilter(filter);
|
||||
-}
|
||||
-
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
-QString LXQtFileDialogHelper::selectedMimeTypeFilter() const {
|
||||
- return dlg_->selectedMimeTypeFilter();
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::selectMimeTypeFilter(const QString& filter) {
|
||||
- dlg_->selectMimeTypeFilter(filter);
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-QString LXQtFileDialogHelper::selectedNameFilter() const {
|
||||
- return dlg_->selectedNameFilter();
|
||||
-}
|
||||
-
|
||||
-bool LXQtFileDialogHelper::isSupportedUrl(const QUrl& url) const {
|
||||
- return dlg_->isSupportedUrl(url);
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::applyOptions() {
|
||||
- auto& opt = options();
|
||||
-
|
||||
- // set title
|
||||
- if(opt->windowTitle().isEmpty()) {
|
||||
- dlg_->setWindowTitle(opt->acceptMode() == QFileDialogOptions::AcceptOpen ? tr("Open File")
|
||||
- : tr("Save File"));
|
||||
- }
|
||||
- else {
|
||||
- dlg_->setWindowTitle(opt->windowTitle());
|
||||
- }
|
||||
-
|
||||
- dlg_->setFilter(opt->filter());
|
||||
- dlg_->setFileMode(QFileDialog::FileMode(opt->fileMode()));
|
||||
- dlg_->setAcceptMode(QFileDialog::AcceptMode(opt->acceptMode())); // also sets a default label for accept button
|
||||
- // bool useDefaultNameFilters() const;
|
||||
- dlg_->setNameFilters(opt->nameFilters());
|
||||
- if(!opt->mimeTypeFilters().empty()) {
|
||||
- dlg_->setMimeTypeFilters(opt->mimeTypeFilters());
|
||||
- }
|
||||
-
|
||||
- dlg_->setDefaultSuffix(opt->defaultSuffix());
|
||||
- // QStringList history() const;
|
||||
-
|
||||
- // explicitly set labels
|
||||
- for(int i = 0; i < QFileDialogOptions::DialogLabelCount; ++i) {
|
||||
- auto label = static_cast<QFileDialogOptions::DialogLabel>(i);
|
||||
- if(opt->isLabelExplicitlySet(label)) {
|
||||
- dlg_->setLabelText(static_cast<QFileDialog::DialogLabel>(label), opt->labelText(label));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- auto url = opt->initialDirectory();
|
||||
- if(url.isValid()) {
|
||||
- dlg_->setDirectory(url);
|
||||
- }
|
||||
-
|
||||
-
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
- auto filter = opt->initiallySelectedMimeTypeFilter();
|
||||
- if(!filter.isEmpty()) {
|
||||
- selectMimeTypeFilter(filter);
|
||||
- }
|
||||
- else {
|
||||
- filter = opt->initiallySelectedNameFilter();
|
||||
- if(!filter.isEmpty()) {
|
||||
- selectNameFilter(opt->initiallySelectedNameFilter());
|
||||
- }
|
||||
- }
|
||||
-#else
|
||||
- auto filter = opt->initiallySelectedNameFilter();
|
||||
- if(!filter.isEmpty()) {
|
||||
- selectNameFilter(filter);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- auto selectedFiles = opt->initiallySelectedFiles();
|
||||
- for(const auto& selectedFile: selectedFiles) {
|
||||
- selectFile(selectedFile);
|
||||
- }
|
||||
- // QStringList supportedSchemes() const;
|
||||
-}
|
||||
-
|
||||
-static const QString viewModeToString(Fm::FolderView::ViewMode value) {
|
||||
- QString ret;
|
||||
- switch(value) {
|
||||
- case Fm::FolderView::DetailedListMode:
|
||||
- default:
|
||||
- ret = QLatin1String("Detailed");
|
||||
- break;
|
||||
- case Fm::FolderView::CompactMode:
|
||||
- ret = QLatin1String("Compact");
|
||||
- break;
|
||||
- case Fm::FolderView::IconMode:
|
||||
- ret = QLatin1String("Icon");
|
||||
- break;
|
||||
- case Fm::FolderView::ThumbnailMode:
|
||||
- ret = QLatin1String("Thumbnail");
|
||||
- break;
|
||||
- }
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-Fm::FolderView::ViewMode viewModeFromString(const QString& str) {
|
||||
- Fm::FolderView::ViewMode ret;
|
||||
- if(str == QLatin1String("Detailed")) {
|
||||
- ret = Fm::FolderView::DetailedListMode;
|
||||
- }
|
||||
- else if(str == QLatin1String("Compact")) {
|
||||
- ret = Fm::FolderView::CompactMode;
|
||||
- }
|
||||
- else if(str == QLatin1String("Icon")) {
|
||||
- ret = Fm::FolderView::IconMode;
|
||||
- }
|
||||
- else if(str == QLatin1String("Thumbnail")) {
|
||||
- ret = Fm::FolderView::ThumbnailMode;
|
||||
- }
|
||||
- else {
|
||||
- ret = Fm::FolderView::DetailedListMode;
|
||||
- }
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::loadSettings() {
|
||||
- QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
|
||||
- settings.beginGroup ("Sizes");
|
||||
- dlg_->resize(settings.value("WindowSize", QSize(700, 500)).toSize());
|
||||
- dlg_->setSplitterPos(settings.value("SplitterPos", 200).toInt());
|
||||
- settings.endGroup();
|
||||
-
|
||||
- settings.beginGroup ("View");
|
||||
- dlg_->setViewMode(viewModeFromString(settings.value("Mode", "Detailed").toString()));
|
||||
- settings.endGroup();
|
||||
-}
|
||||
-
|
||||
-void LXQtFileDialogHelper::saveSettings() {
|
||||
- QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
|
||||
- settings.beginGroup ("Sizes");
|
||||
- QSize windowSize = dlg_->size();
|
||||
- if(settings.value("WindowSize") != windowSize) { // no redundant write
|
||||
- settings.setValue("WindowSize", windowSize);
|
||||
- }
|
||||
- int splitterPos = dlg_->splitterPos();
|
||||
- if(settings.value("SplitterPos") != splitterPos) {
|
||||
- settings.setValue("SplitterPos", splitterPos);
|
||||
- }
|
||||
- settings.endGroup();
|
||||
-
|
||||
- settings.beginGroup ("View");
|
||||
- QString mode = viewModeToString(dlg_->viewMode());
|
||||
- if(settings.value("Mode") != mode) {
|
||||
- settings.setValue("Mode", mode);
|
||||
- }
|
||||
- settings.endGroup();
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
-FileDialogPlugin::FileDialogPlugin() {
|
||||
-
|
||||
-}
|
||||
-
|
||||
-QPlatformFileDialogHelper *FileDialogPlugin::createHelper() {
|
||||
- return new LXQtFileDialogHelper();
|
||||
-}
|
||||
-*/
|
||||
--- a/src/lxqtfiledialoghelper.h
|
||||
+++ /dev/null
|
||||
@@ -1,50 +0,0 @@
|
||||
-#ifndef LXQTFILEDIALOGHELPER_H
|
||||
-#define LXQTFILEDIALOGHELPER_H
|
||||
-
|
||||
-#include <qpa/qplatformdialoghelper.h> // this private header is subject to changes
|
||||
-#include <memory>
|
||||
-
|
||||
-namespace Fm {
|
||||
-class FileDialog;
|
||||
-}
|
||||
-
|
||||
-class Q_GUI_EXPORT LXQtFileDialogHelper : public QPlatformFileDialogHelper {
|
||||
- Q_OBJECT
|
||||
-
|
||||
-public:
|
||||
- LXQtFileDialogHelper();
|
||||
-
|
||||
- virtual ~LXQtFileDialogHelper();
|
||||
-
|
||||
- // QPlatformDialogHelper
|
||||
- void exec() override;
|
||||
- bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
|
||||
- void hide() override;
|
||||
-
|
||||
- // QPlatformFileDialogHelper
|
||||
- bool defaultNameFilterDisables() const override;
|
||||
- void setDirectory(const QUrl &directory) override;
|
||||
- QUrl directory() const override;
|
||||
- void selectFile(const QUrl &filename) override;
|
||||
- QList<QUrl> selectedFiles() const override;
|
||||
- void setFilter() override;
|
||||
- void selectNameFilter(const QString &filter) override;
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
- QString selectedMimeTypeFilter() const override;
|
||||
- void selectMimeTypeFilter(const QString &filter) override;
|
||||
-#endif
|
||||
- QString selectedNameFilter() const override;
|
||||
-
|
||||
- bool isSupportedUrl(const QUrl &url) const override;
|
||||
-
|
||||
-private:
|
||||
- void applyOptions();
|
||||
- void loadSettings();
|
||||
- void saveSettings();
|
||||
-
|
||||
-private:
|
||||
- std::unique_ptr<Fm::FileDialog> dlg_;
|
||||
-};
|
||||
-
|
||||
-
|
||||
-#endif // LXQTFILEDIALOGHELPER_H
|
||||
--- a/src/lxqtplatformtheme.cpp
|
||||
+++ b/src/lxqtplatformtheme.cpp
|
||||
@@ -45,8 +45,14 @@
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QStyle>
|
||||
#include <private/xdgiconloader/xdgiconloader_p.h>
|
||||
+#include <QLibrary>
|
||||
+
|
||||
+
|
||||
+// Function to create a new Fm::FileDialogHelper object.
|
||||
+// This is dynamically loaded at runtime on demand from libfm-qt.
|
||||
+typedef QPlatformDialogHelper* (*CreateFileDialogHelperFunc)();
|
||||
+static CreateFileDialogHelperFunc createFileDialogHelper = nullptr;
|
||||
|
||||
-#include "lxqtfiledialoghelper.h"
|
||||
|
||||
LXQtPlatformTheme::LXQtPlatformTheme():
|
||||
iconFollowColorScheme_(true)
|
||||
@@ -222,8 +228,32 @@ bool LXQtPlatformTheme::usePlatformNativ
|
||||
QPlatformDialogHelper *LXQtPlatformTheme::createPlatformDialogHelper(DialogType type) const {
|
||||
if(type == FileDialog
|
||||
&& qobject_cast<QApplication *>(QCoreApplication::instance())) { // QML may not have qApp
|
||||
- // use our own file dialog
|
||||
- return new LXQtFileDialogHelper();
|
||||
+ // use our own file dialog provided by libfm
|
||||
+
|
||||
+ // When a process has this environment set, that means glib event loop integration is disabled.
|
||||
+ // In this case, libfm-qt just won't work. So let's disable the file dialog helper and return nullptr.
|
||||
+ if(qgetenv("QT_NO_GLIB") == "1") {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ // The createFileDialogHelper() method is dynamically loaded from libfm-qt on demand
|
||||
+ if(createFileDialogHelper == nullptr) {
|
||||
+ // try to dynamically load libfm-qt.so
|
||||
+ QLibrary libfmQtLibrary{"libfm-qt"};
|
||||
+ libfmQtLibrary.load();
|
||||
+ if(!libfmQtLibrary.isLoaded()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ // try to resolve the symbol to get the function pointer
|
||||
+ createFileDialogHelper = reinterpret_cast<CreateFileDialogHelperFunc>(libfmQtLibrary.resolve("createFileDialogHelper"));
|
||||
+ if(!createFileDialogHelper) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // create a new file dialog helper provided by libfm
|
||||
+ return createFileDialogHelper();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
@ -1 +0,0 @@
|
||||
dynamically-load-file-dialog.patch
|
Loading…
Reference in new issue