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-06 --- 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::trust"; 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::trust") == G_FILE_ATTRIBUTE_TYPE_STRING) { + if(const auto data = g_file_info_get_attribute_string(inf_.get(), "metadata::trust")) { + return (strcmp(data, "true") == 0); + } + } + } + return false; +} + +void FileInfo::setTrustable(bool trust) const { + if(!isExecutableType()) { + return; // "metadata::trust" 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::trust", "true"); + g_file_info_set_attribute_string(inf_.get(), "metadata::trust", "true"); + } + else { + g_file_info_set_attribute(info.get(), "metadata::trust", G_FILE_ATTRIBUTE_TYPE_INVALID, nullptr); + g_file_info_set_attribute(inf_.get(), "metadata::trust", 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; }