diff --git a/debian/changelog b/debian/changelog index 8fce8bc..bc7bc43 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ libfm-qt (0.14.0-0ubuntu1) UNRELEASED; urgency=medium * New upstream release. + - Remove reverse-applicable patches. -- Simon Quigley Fri, 25 Jan 2019 22:54:43 -0600 diff --git a/debian/patches/add-lxqt-archiver-integration.patch b/debian/patches/add-lxqt-archiver-integration.patch deleted file mode 100644 index b33b5d2..0000000 --- a/debian/patches/add-lxqt-archiver-integration.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: Add integration for LXQt Archiver -Author: "Hong Jen Yee (PCMan)" -Origin: upstream -Applied-Upstream: commit:9a3bf23 -Last-Update: 2018-07-14 ---- a/data/archivers.list -+++ b/data/archivers.list -@@ -1,3 +1,10 @@ -+[lxqt-archiver] -+create=lxqt-archiver --add %U -+extract=lxqt-archiver --extract %U -+extract_to=lxqt-archiver --extract-to %d %U -+mime_types=application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-rar;application/x-rar-compressed;application/vnd.rar;application/x-rpm;application/x-rzip;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;multipart/x-zip; -+supports_uris=true -+ - [file-roller] - create=file-roller --add %U - extract=file-roller --extract %U diff --git a/debian/patches/add-metadata-for-trusting-executables.patch b/debian/patches/add-metadata-for-trusting-executables.patch deleted file mode 100644 index 138da3f..0000000 --- a/debian/patches/add-metadata-for-trusting-executables.patch +++ /dev/null @@ -1,166 +0,0 @@ -Description: Support adding metadata for trusting executables. -Author: Tsu Jan -Applied-Upstream: https://github.com/lxqt/libfm-qt/pull/242/commits/9c2f00c2e22b8054bcaedad89ef74f0432b9f7fe -Last-Update: 2018-10-15 ---- a/src/core/basicfilelauncher.cpp -+++ b/src/core/basicfilelauncher.cpp -@@ -176,7 +176,7 @@ bool BasicFileLauncher::launchDesktopEnt - const char* desktopEntryName = nullptr; - FilePathList shortcutTargetPaths; - if(fileInfo->isExecutableType()) { -- auto act = quickExec_ ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo); -+ auto act = (quickExec_ || fileInfo->isTrustable()) ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo); - switch(act) { - case ExecAction::EXEC_IN_TERMINAL: - case ExecAction::DIRECT_EXEC: { -@@ -275,7 +275,7 @@ bool BasicFileLauncher::launchExecutable - auto filename = fileInfo->path().localPath(); - /* FIXME: we need to use eaccess/euidaccess here. */ - if(g_file_test(filename.get(), G_FILE_TEST_IS_EXECUTABLE)) { -- auto act = quickExec_ ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo); -+ auto act = (quickExec_ || fileInfo->isTrustable()) ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo); - int flags = G_APP_INFO_CREATE_NONE; - switch(act) { - case ExecAction::EXEC_IN_TERMINAL: ---- a/src/core/fileinfo.cpp -+++ b/src/core/fileinfo.cpp -@@ -9,7 +9,8 @@ const char defaultGFileInfoQueryAttribs[ - "time::*," - "access::*," - "id::filesystem," -- "metadata::emblems"; -+ "metadata::emblems," -+ "metadata::trusted"; - - FileInfo::FileInfo() { - // FIXME: initialize numeric data members -@@ -23,6 +24,7 @@ FileInfo::~FileInfo() { - } - - void FileInfo::setFromGFileInfo(const GObjectPtr& inf, const FilePath& parentDirPath) { -+ inf_ = inf; - dirPath_ = parentDirPath; - const char* tmp, *uri; - GIcon* gicon; -@@ -377,6 +379,37 @@ bool FileInfo::isExecutableType() const - return mimeType_->canBeExecutable(); - } - -+bool FileInfo::isTrustable() const { -+ if(isExecutableType()) { -+ /* to avoid GIO assertion warning: */ -+ if(g_file_info_get_attribute_type(inf_.get(), "metadata::trusted") == G_FILE_ATTRIBUTE_TYPE_STRING) { -+ if(const auto data = g_file_info_get_attribute_string(inf_.get(), "metadata::trusted")) { -+ return (strcmp(data, "true") == 0); -+ } -+ } -+ } -+ return false; -+} -+ -+void FileInfo::setTrustable(bool trust) const { -+ if(!isExecutableType()) { -+ return; // "metadata::trusted" is only for executables -+ } -+ GObjectPtr info {g_file_info_new()}; // used to set only this attribute -+ if(trust) { -+ g_file_info_set_attribute_string(info.get(), "metadata::trusted", "true"); -+ g_file_info_set_attribute_string(inf_.get(), "metadata::trusted", "true"); -+ } -+ else { -+ g_file_info_set_attribute(info.get(), "metadata::trusted", G_FILE_ATTRIBUTE_TYPE_INVALID, nullptr); -+ g_file_info_set_attribute(inf_.get(), "metadata::trusted", G_FILE_ATTRIBUTE_TYPE_INVALID, nullptr); -+ } -+ g_file_set_attributes_from_info(path().gfile().get(), -+ info.get(), -+ G_FILE_QUERY_INFO_NONE, -+ nullptr, nullptr); -+} -+ - - bool FileInfoList::isSameType() const { - if(!empty()) { ---- a/src/core/fileinfo.h -+++ b/src/core/fileinfo.h -@@ -214,7 +214,12 @@ public: - return emblems_; - } - -+ bool isTrustable() const; -+ -+ void setTrustable(bool trust) const; -+ - private: -+ GObjectPtr inf_; - std::string name_; - QString dispName_; - ---- a/src/filemenu.cpp -+++ b/src/filemenu.cpp -@@ -245,6 +245,18 @@ FileMenu::FileMenu(Fm::FileInfoList file - FileMenu::~FileMenu() { - } - -+void FileMenu::addTrustAction() { -+ if(info_->isExecutableType() && (!fileLauncher_ || !fileLauncher_->quickExec())) { -+ QAction* trustAction = new QAction(files_.size() > 1 -+ ? tr("Trust selected executables") -+ : tr("Trust this executable"), -+ this); -+ trustAction->setCheckable(true); -+ trustAction->setChecked(info_->isTrustable()); -+ connect(trustAction, &QAction::toggled, this, &FileMenu::onTrustToggled); -+ insertAction(propertiesAction_, trustAction); -+ } -+} - - void FileMenu::addCustomActionItem(QMenu* menu, std::shared_ptr item) { - if(!item) { // separator -@@ -329,6 +341,12 @@ void FileMenu::onCustomActionTrigerred() - } - } - -+void FileMenu::onTrustToggled(bool checked) { -+ for(auto& file: files_) { -+ file->setTrustable(checked); -+ } -+} -+ - void FileMenu::onFilePropertiesTriggered() { - FilePropsDialog::showForFiles(files_); - } ---- a/src/filemenu.h -+++ b/src/filemenu.h -@@ -41,6 +41,8 @@ public: - explicit FileMenu(Fm::FileInfoList files, std::shared_ptr info, Fm::FilePath cwd, bool isWritableDir = true, const QString& title = QString(), QWidget* parent = nullptr); - ~FileMenu(); - -+ void addTrustAction(); -+ - bool useTrash() { - return useTrash_; - } -@@ -162,6 +164,7 @@ protected: - protected Q_SLOTS: - void onOpenTriggered(); - void onOpenWithTriggered(); -+ void onTrustToggled(bool checked); - void onFilePropertiesTriggered(); - void onApplicationTriggered(); - void onCustomActionTrigerred(); ---- a/src/folderview.cpp -+++ b/src/folderview.cpp -@@ -1318,11 +1318,11 @@ void FolderView::onFileClicked(int type, - // show context menu - auto files = selectedFiles(); - if(!files.empty()) { -- QModelIndexList selIndexes = mode == DetailedListMode ? selectedRows() : selectedIndexes(); -- Fm::FileMenu* fileMenu = (view && selIndexes.size() == 1) -+ Fm::FileMenu* fileMenu = (view && files.size() == 1) - ? new Fm::FileMenu(files, fileInfo, folderPath, isWritableDir, QString(), view) - : new Fm::FileMenu(files, fileInfo, folderPath, isWritableDir); - fileMenu->setFileLauncher(fileLauncher_); -+ fileMenu->addTrustAction(); - prepareFileMenu(fileMenu); - menu = fileMenu; - } diff --git a/debian/patches/fix-incorrect-file-info-handling-1.patch b/debian/patches/fix-incorrect-file-info-handling-1.patch deleted file mode 100644 index c4a8ea8..0000000 --- a/debian/patches/fix-incorrect-file-info-handling-1.patch +++ /dev/null @@ -1,251 +0,0 @@ -Description: Fix failure to open smb:// caused by incorrect file info handling -Author: "Hong Jen Yee (PCMan)" -Origin: upstream -Applied-Upstream: commit:1a6fa26 -Last-Update: 2018-07-14 ---- a/src/core/basicfilelauncher.cpp -+++ b/src/core/basicfilelauncher.cpp -@@ -27,11 +27,13 @@ bool BasicFileLauncher::launchFiles(cons - FilePathList pathsToLaunch; - // classify files according to different mimetypes - for(auto& fileInfo : fileInfos) { -- // qDebug("path: %s, target: %s", fileInfo->path().toString().get(), fileInfo->target().c_str()); -- if(fileInfo->isDir()) { -- folderInfos.emplace_back(fileInfo); -- } -- else if(fileInfo->isMountable()) { -+ /* -+ qDebug("path: %s, type: %s, target: %s, isDir: %i, isDesktopEntry: %i", -+ fileInfo->path().toString().get(), fileInfo->mimeType()->name(), fileInfo->target().c_str(), -+ fileInfo->isDir(), fileInfo->isDesktopEntry()); -+ */ -+ -+ if(fileInfo->isMountable()) { - if(fileInfo->target().empty()) { - // the mountable is not yet mounted so we have no target URI. - GErrorPtr err{G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED, -@@ -65,6 +67,9 @@ bool BasicFileLauncher::launchFiles(cons - pathsToLaunch.emplace_back(path); - } - } -+ else if(fileInfo->isDir()) { -+ folderInfos.emplace_back(fileInfo); -+ } - else { - auto& mimeType = fileInfo->mimeType(); - mimeTypeToFiles[mimeType->name()].emplace_back(fileInfo); -@@ -101,16 +106,27 @@ bool BasicFileLauncher::launchFiles(cons - bool BasicFileLauncher::launchPaths(FilePathList paths, GAppLaunchContext* ctx) { - // FIXME: blocking with an event loop is not a good design :-( - QEventLoop eventLoop; -- - auto job = new FileInfoJob{paths}; - job->setAutoDelete(false); // do not automatically delete the job since we want its results later. - - GObjectPtr ctxPtr{ctx}; -+ -+ // error handling (for example: handle path not mounted error) -+ QObject::connect(job, &FileInfoJob::error, -+ &eventLoop, [this, job, ctx](const GErrorPtr & err, Job::ErrorSeverity /* severity */ , Job::ErrorAction &act) { -+ auto path = job->currentPath(); -+ if(showError(ctx, err, path, nullptr)) { -+ // the user handled the error and ask for retry -+ act = Job::ErrorAction::RETRY; -+ } -+ }, Qt::BlockingQueuedConnection); // BlockingQueuedConnection is required here to pause the job and wait for user response -+ - QObject::connect(job, &FileInfoJob::finished, - [&eventLoop]() { - // exit the event loop when the job is done - eventLoop.exit(); - }); -+ - // run the job in another thread to not block the UI - job->runAsync(); - -@@ -143,7 +159,7 @@ BasicFileLauncher::ExecAction BasicFileL - return ExecAction::DIRECT_EXEC; - } - --bool BasicFileLauncher::showError(GAppLaunchContext* /* ctx */, GErrorPtr& /* err */, const FilePath& /* path */, const FileInfoPtr& /* info */) { -+bool BasicFileLauncher::showError(GAppLaunchContext* /* ctx */, const GErrorPtr & /* err */, const FilePath& /* path */, const FileInfoPtr& /* info */) { - return false; - } - -@@ -247,13 +263,21 @@ bool BasicFileLauncher::launchDesktopEnt - - FilePath BasicFileLauncher::handleShortcut(const FileInfoPtr& fileInfo, GAppLaunchContext* ctx) { - auto target = fileInfo->target(); -+ -+ // if we know the target is a dir, we are not going to open it using other apps -+ // for example: `network:///smb-root' is a shortcut targeting `smb:///' and it's also a dir -+ if(fileInfo->isDir()) { -+ return FilePath::fromPathStr(target.c_str()); -+ } -+ - auto scheme = CStrPtr{g_uri_parse_scheme(target.c_str())}; - if(scheme) { - // collect the uri schemes we support - if(strcmp(scheme.get(), "file") == 0 - || strcmp(scheme.get(), "trash") == 0 - || strcmp(scheme.get(), "network") == 0 -- || strcmp(scheme.get(), "computer") == 0) { -+ || strcmp(scheme.get(), "computer") == 0 -+ || strcmp(scheme.get(), "menu") == 0) { - return FilePath::fromUri(fileInfo->target().c_str()); - } - else { ---- a/src/core/basicfilelauncher.h -+++ b/src/core/basicfilelauncher.h -@@ -53,7 +53,7 @@ protected: - - virtual bool openFolder(GAppLaunchContext* ctx, const FileInfoList& folderInfos, GErrorPtr& err); - -- virtual bool showError(GAppLaunchContext* ctx, GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}); -+ virtual bool showError(GAppLaunchContext* ctx, const GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}); - - virtual ExecAction askExecFile(const FileInfoPtr& file); - ---- a/src/core/fileinfo.cpp -+++ b/src/core/fileinfo.cpp -@@ -36,10 +36,9 @@ void FileInfo::setFromGFileInfo(const GO - size_ = g_file_info_get_size(inf.get()); - - tmp = g_file_info_get_content_type(inf.get()); -- if(!tmp) { -- tmp = "application/octet-stream"; -+ if(tmp) { -+ mimeType_ = MimeType::fromName(tmp); - } -- mimeType_ = MimeType::fromName(tmp); - - mode_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_MODE); - -@@ -196,6 +195,10 @@ _file_is_symlink: - } - } - -+ if(!mimeType_) { -+ mimeType_ = MimeType::fromName("application/octet-stream"); -+ } -+ - /* if there is a custom folder icon, use it */ - if(isNative() && type == G_FILE_TYPE_DIRECTORY) { - auto local_path = path().localPath(); ---- a/src/core/fileinfojob.cpp -+++ b/src/core/fileinfojob.cpp -@@ -13,31 +13,41 @@ FileInfoJob::FileInfoJob(FilePathList pa - - void FileInfoJob::exec() { - for(const auto& path: paths_) { -- if(!isCancelled()) { -+ if(isCancelled()) { -+ break; -+ } -+ currentPath_ = path; -+ -+ bool retry; -+ do { -+ retry = false; - GErrorPtr err; - GFileInfoPtr inf{ - g_file_query_info(path.gfile().get(), defaultGFileInfoQueryAttribs, - G_FILE_QUERY_INFO_NONE, cancellable().get(), &err), - false - }; -- if(!inf) { -- continue; -- } -- -- // Reuse the same dirPath object when the path remains the same (optimize for files in the same dir) -- auto dirPath = commonDirPath_.isValid() ? commonDirPath_ : path.parent(); -- FileInfo fileInfo(inf, dirPath); -+ if(inf) { -+ // Reuse the same dirPath object when the path remains the same (optimize for files in the same dir) -+ auto dirPath = commonDirPath_.isValid() ? commonDirPath_ : path.parent(); -+ auto fileInfoPtr = std::make_shared(inf, dirPath); -+ -+ // FIXME: this is not elegant -+ if(cutFilesHashSet_ -+ && cutFilesHashSet_->count(path.hash())) { -+ fileInfoPtr->bindCutFiles(cutFilesHashSet_); -+ } - -- if(cutFilesHashSet_ -- && cutFilesHashSet_->count(fileInfo.path().hash())) { -- fileInfo.bindCutFiles(cutFilesHashSet_); -+ results_.push_back(fileInfoPtr); -+ Q_EMIT gotInfo(path, results_.back()); - } -- -- auto fileInfoPtr = std::make_shared(fileInfo); -- -- results_.push_back(fileInfoPtr); -- Q_EMIT gotInfo(path, fileInfoPtr); -- } -+ else { -+ auto act = emitError(err); -+ if(act == Job::ErrorAction::RETRY) { -+ retry = true; -+ } -+ } -+ } while(retry && !isCancelled()); - } - } - ---- a/src/core/fileinfojob.h -+++ b/src/core/fileinfojob.h -@@ -27,6 +27,10 @@ public: - return results_; - } - -+ const FilePath& currentPath() const { -+ return currentPath_; -+ } -+ - Q_SIGNALS: - void gotInfo(const FilePath& path, std::shared_ptr& info); - -@@ -39,6 +43,7 @@ private: - FileInfoList results_; - FilePath commonDirPath_; - const std::shared_ptr cutFilesHashSet_; -+ FilePath currentPath_; - }; - - } // namespace Fm ---- a/src/core/gioptrs.h -+++ b/src/core/gioptrs.h -@@ -112,6 +112,10 @@ public: - return err_; - } - -+ const GError* operator->() const { -+ return err_; -+ } -+ - bool operator == (const GErrorPtr& other) const { - return err_ == other.err_; - } ---- a/src/filelauncher.cpp -+++ b/src/filelauncher.cpp -@@ -76,7 +76,7 @@ bool FileLauncher::openFolder(GAppLaunch - return BasicFileLauncher::openFolder(ctx, folderInfos, err); - } - --bool FileLauncher::showError(GAppLaunchContext* /*ctx*/, GErrorPtr &err, const FilePath &path, const FileInfoPtr &info) { -+bool FileLauncher::showError(GAppLaunchContext* /*ctx*/, const GErrorPtr &err, const FilePath &path, const FileInfoPtr &info) { - /* ask for mount if trying to launch unmounted path */ - if(err->domain == G_IO_ERROR) { - if(path && err->code == G_IO_ERROR_NOT_MOUNTED) { ---- a/src/filelauncher.h -+++ b/src/filelauncher.h -@@ -43,7 +43,7 @@ protected: - - bool openFolder(GAppLaunchContext* ctx, const FileInfoList& folderInfos, GErrorPtr& err) override; - -- bool showError(GAppLaunchContext* ctx, GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}) override; -+ bool showError(GAppLaunchContext* ctx, const GErrorPtr &err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}) override; - - ExecAction askExecFile(const FileInfoPtr& file) override; - diff --git a/debian/patches/fix-incorrect-file-info-handling-2.patch b/debian/patches/fix-incorrect-file-info-handling-2.patch deleted file mode 100644 index 27d6069..0000000 --- a/debian/patches/fix-incorrect-file-info-handling-2.patch +++ /dev/null @@ -1,68 +0,0 @@ -Description: Correctly handle mountable types -Author: "Hong Jen Yee (PCMan)" -Origin: upstream -Applied-Upstream: commit:dc7a575 -Last-Update: 2018-07-14 ---- a/src/core/basicfilelauncher.cpp -+++ b/src/core/basicfilelauncher.cpp -@@ -28,11 +28,10 @@ bool BasicFileLauncher::launchFiles(cons - // classify files according to different mimetypes - for(auto& fileInfo : fileInfos) { - /* -- qDebug("path: %s, type: %s, target: %s, isDir: %i, isDesktopEntry: %i", -+ qDebug("path: %s, type: %s, target: %s, isDir: %i, isShortcut: %i, isMountable: %i, isDesktopEntry: %i", - fileInfo->path().toString().get(), fileInfo->mimeType()->name(), fileInfo->target().c_str(), -- fileInfo->isDir(), fileInfo->isDesktopEntry()); -+ fileInfo->isDir(), fileInfo->isShortcut(), fileInfo->isMountable(), fileInfo->isDesktopEntry()); - */ -- - if(fileInfo->isMountable()) { - if(fileInfo->target().empty()) { - // the mountable is not yet mounted so we have no target URI. -@@ -267,6 +266,7 @@ FilePath BasicFileLauncher::handleShortc - // if we know the target is a dir, we are not going to open it using other apps - // for example: `network:///smb-root' is a shortcut targeting `smb:///' and it's also a dir - if(fileInfo->isDir()) { -+ qDebug("shortcut is dir: %s", target.c_str()); - return FilePath::fromPathStr(target.c_str()); - } - ---- a/src/core/fileinfo.cpp -+++ b/src/core/fileinfo.cpp -@@ -118,7 +118,8 @@ void FileInfo::setFromGFileInfo(const GO - isDeletable_ = true; - } - -- isShortcut_ = false; -+ isShortcut_ = (type == G_FILE_TYPE_SHORTCUT); -+ isMountable_ = (type == G_FILE_TYPE_MOUNTABLE); - - /* special handling for symlinks */ - if(g_file_info_get_is_symlink(inf.get())) { -@@ -129,7 +130,6 @@ void FileInfo::setFromGFileInfo(const GO - - switch(type) { - case G_FILE_TYPE_SHORTCUT: -- isShortcut_ = true; - /* Falls through. */ - case G_FILE_TYPE_MOUNTABLE: - uri = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); ---- a/src/core/fileinfo.h -+++ b/src/core/fileinfo.h -@@ -151,7 +151,7 @@ public: - } - - bool isMountable() const { -- return mimeType_->isMountable(); -+ return isMountable_; - } - - bool isShortcut() const { -@@ -239,6 +239,7 @@ private: - std::string target_; /* target of shortcut or mountable. */ - - bool isShortcut_ : 1; /* TRUE if file is shortcut type */ -+ bool isMountable_ : 1; /* TRUE if file is mountable type */ - bool isAccessible_ : 1; /* TRUE if can be read by user */ - bool isWritable_ : 1; /* TRUE if can be written to by user */ - bool isDeletable_ : 1; /* TRUE if can be deleted by user */ diff --git a/debian/patches/fix-launching-desktop-files.patch b/debian/patches/fix-launching-desktop-files.patch deleted file mode 100644 index 7239b66..0000000 --- a/debian/patches/fix-launching-desktop-files.patch +++ /dev/null @@ -1,29 +0,0 @@ -Description: Fix launching desktop files -Author: Tsu Jan -Applied-Upstream: https://github.com/lxqt/libfm-qt/commit/9af480812bdef4a7cca7db7416b24d96b179ebf1 -Last-Update: 2018-11-21 ---- a/src/core/basicfilelauncher.cpp -+++ b/src/core/basicfilelauncher.cpp -@@ -250,7 +250,21 @@ bool BasicFileLauncher::launchDesktopEnt - it cannot be launched in fact */ - - if(app) { -- return launchWithApp(app, paths, ctx); -+ // don't call launchWithApp() because it calls g_app_info_launch_uris(), -+ // which uses the hard-coded terminal list of GLib -> gdesktopappinfo.c -+ GList* uris = nullptr; -+ for(auto& path : paths) { -+ auto uri = path.uri(); -+ uris = g_list_prepend(uris, uri.release()); -+ } -+ GErrorPtr err; -+ ret = bool(fm_app_info_launch(app, uris, ctx, &err)); -+ g_list_foreach(uris, reinterpret_cast(g_free), nullptr); -+ g_list_free(uris); -+ if(!ret) { -+ // FIXME: show error for all files -+ showError(ctx, err, paths[0]); -+ } - } - else { - QString msg = QObject::tr("Invalid desktop entry file: '%1'").arg(desktopEntryName); diff --git a/debian/patches/fix-places-font-color.patch b/debian/patches/fix-places-font-color.patch deleted file mode 100644 index a5e2a45..0000000 --- a/debian/patches/fix-places-font-color.patch +++ /dev/null @@ -1,52 +0,0 @@ -Description: Use window text color for places view -Author: tsujan -Origin: upstream -Bug: https://github.com/lxqt/pcmanfm-qt/issues/696 -Applied-Upstream: commit:87df010 -Last-Update: 2018-07-14 ---- a/src/folderitemdelegate.cpp -+++ b/src/folderitemdelegate.cpp -@@ -361,7 +361,8 @@ QWidget* FolderItemDelegate::createEdito - // ensure that its background isn't transparent (on the side-pane) - QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index); - QPalette p = editor->palette(); -- p.setColor(QPalette::Base, QApplication::palette().color(QPalette::Base)); -+ p.setColor(QPalette::Text, qApp->palette().text().color()); -+ p.setColor(QPalette::Base, qApp->palette().color(QPalette::Base)); - editor->setPalette(p); - return editor; - } ---- a/src/placesview.cpp -+++ b/src/placesview.cpp -@@ -131,13 +131,6 @@ PlacesView::PlacesView(QWidget* parent): - setHeaderHidden(true); - setIndentation(12); - -- /* merge with the surroundings */ -- setFrameShape(QFrame::NoFrame); -- QPalette p = palette(); -- p.setColor(QPalette::Base, QColor(Qt::transparent)); -- setPalette(p); -- viewport()->setAutoFillBackground(false); -- - connect(this, &QTreeView::clicked, this, &PlacesView::onClicked); - connect(this, &QTreeView::pressed, this, &PlacesView::onPressed); - ---- a/src/sidepane.cpp -+++ b/src/sidepane.cpp -@@ -158,6 +158,15 @@ void SidePane::setMode(Mode mode) { - switch(mode) { - case ModePlaces: { - PlacesView* placesView = new Fm::PlacesView(this); -+ -+ // visually merge it with its surroundings -+ placesView->setFrameShape(QFrame::NoFrame); -+ QPalette p = placesView->palette(); -+ p.setColor(QPalette::Base, QColor(Qt::transparent)); -+ p.setColor(QPalette::Text, p.color(QPalette::WindowText)); -+ placesView->setPalette(p); -+ placesView->viewport()->setAutoFillBackground(false); -+ - view_ = placesView; - placesView->restoreHiddenItems(restorableHiddenPlaces_); - placesView->setIconSize(iconSize_); diff --git a/debian/patches/move-in-file-dialog.patch b/debian/patches/move-in-file-dialog.patch deleted file mode 100644 index de4e435..0000000 --- a/debian/patches/move-in-file-dialog.patch +++ /dev/null @@ -1,373 +0,0 @@ -Description: Move the Qt file dialog helper into libfm-qt. -Author: Hong Jen Yee (PCMan) -Origin: upstream -Applied-Upstream: commit:cc63bc7 -Last-Update: 2018-07-30 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -83,6 +83,7 @@ set(libfm_SRCS - filedialog.cpp - fm-search.c # might be moved to libfm later - xdndworkaround.cpp -+ filedialoghelper.cpp - ) - - set(libfm_UIS ---- /dev/null -+++ b/src/filedialoghelper.cpp -@@ -0,0 +1,290 @@ -+#include "filedialoghelper.h" -+ -+#include "libfmqt.h" -+#include "filedialog.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+namespace Fm { -+ -+inline static const QString viewModeToString(Fm::FolderView::ViewMode value); -+inline static Fm::FolderView::ViewMode viewModeFromString(const QString& str); -+ -+FileDialogHelper::FileDialogHelper() { -+ // can only be used after libfm-qt initialization -+ dlg_ = std::unique_ptr(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, &FileDialogHelper::fileSelected); -+ connect(dlg_.get(), &Fm::FileDialog::filesSelected, this, &FileDialogHelper::filesSelected); -+ connect(dlg_.get(), &Fm::FileDialog::currentChanged, this, &FileDialogHelper::currentChanged); -+ connect(dlg_.get(), &Fm::FileDialog::directoryEntered, this, &FileDialogHelper::directoryEntered); -+ connect(dlg_.get(), &Fm::FileDialog::filterSelected, this, &FileDialogHelper::filterSelected); -+} -+ -+FileDialogHelper::~FileDialogHelper() { -+} -+ -+void FileDialogHelper::exec() { -+ dlg_->exec(); -+} -+ -+bool FileDialogHelper::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 FileDialogHelper::hide() { -+ dlg_->hide(); -+} -+ -+bool FileDialogHelper::defaultNameFilterDisables() const { -+ return false; -+} -+ -+void FileDialogHelper::setDirectory(const QUrl& directory) { -+ dlg_->setDirectory(directory); -+} -+ -+QUrl FileDialogHelper::directory() const { -+ return dlg_->directory(); -+} -+ -+void FileDialogHelper::selectFile(const QUrl& filename) { -+ dlg_->selectFile(filename); -+} -+ -+QList FileDialogHelper::selectedFiles() const { -+ return dlg_->selectedFiles(); -+} -+ -+void FileDialogHelper::setFilter() { -+ // FIXME: what's this? -+ // The gtk+ 3 file dialog helper in Qt5 update options in this method. -+ applyOptions(); -+} -+ -+void FileDialogHelper::selectNameFilter(const QString& filter) { -+ dlg_->selectNameFilter(filter); -+} -+ -+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) -+QString FileDialogHelper::selectedMimeTypeFilter() const { -+ return dlg_->selectedMimeTypeFilter(); -+} -+ -+void FileDialogHelper::selectMimeTypeFilter(const QString& filter) { -+ dlg_->selectMimeTypeFilter(filter); -+} -+#endif -+ -+QString FileDialogHelper::selectedNameFilter() const { -+ return dlg_->selectedNameFilter(); -+} -+ -+bool FileDialogHelper::isSupportedUrl(const QUrl& url) const { -+ return dlg_->isSupportedUrl(url); -+} -+ -+void FileDialogHelper::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(i); -+ if(opt->isLabelExplicitlySet(label)) { -+ dlg_->setLabelText(static_cast(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 FileDialogHelper::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 FileDialogHelper::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 FileDialogHelper(); -+} -+*/ -+ -+} // namespace Fm -+ -+ -+QPlatformFileDialogHelper *createFileDialogHelper() { -+ // When a process has this environment set, that means glib event loop integration is disabled. -+ // In this case, libfm just won't work. So let's disable the file dialog helper and return nullptr. -+ if(qgetenv("QT_NO_GLIB") == "1") { -+ return nullptr; -+ } -+ -+ static std::unique_ptr libfmQtContext_; -+ if(!libfmQtContext_) { -+ // initialize libfm-qt only once -+ libfmQtContext_ = std::unique_ptr{new Fm::LibFmQt()}; -+ } -+ return new Fm::FileDialogHelper{}; -+} ---- /dev/null -+++ b/src/filedialoghelper.h -@@ -0,0 +1,62 @@ -+#ifndef FILEDIALOGHELPER_H -+#define FILEDIALOGHELPER_H -+ -+#include "libfmqtglobals.h" -+#include // this private header is subject to changes -+#include -+ -+namespace Fm { -+ -+class FileDialog; -+ -+class LIBFM_QT_API FileDialogHelper : public QPlatformFileDialogHelper { -+ Q_OBJECT -+ -+public: -+ FileDialogHelper(); -+ -+ virtual ~FileDialogHelper(); -+ -+ // 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 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 dlg_; -+}; -+ -+} // namespace Fm -+ -+// export a C API without C++ name mangling so others can dynamically load libfm-qt at runtime -+// to call this API and get a new QPlatformFileDialogHelper object. -+ -+extern "C" { -+ -+// if the process calling this API fail to load libfm-qt, nullptr will be returned instead. -+LIBFM_QT_API QPlatformFileDialogHelper* createFileDialogHelper(); -+ -+} -+ -+#endif // FILEDIALOGHELPER_H diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 8c26d1a..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,7 +0,0 @@ -add-lxqt-archiver-integration.patch -fix-incorrect-file-info-handling-1.patch -fix-incorrect-file-info-handling-2.patch -fix-places-font-color.patch -move-in-file-dialog.patch -add-metadata-for-trusting-executables.patch -fix-launching-desktop-files.patch