Summary: tl;dr this fixes the need to have to select open or execute when clicking on a .desktop file. Test Plan: To be fair I'm not sure of the mechanism but somehow we should be able to set some property of our install.desktop so that when you double click on it, it executes rather than prompting. Reviewers: tsimonq2 Reviewed By: tsimonq2 Differential Revision: https://phab.lubuntu.me/D29ubuntu/cosmic
parent
b1b8e0fe3b
commit
c1952b6dda
@ -0,0 +1,166 @@
|
|||||||
|
Description: Support adding metadata for trusting executables.
|
||||||
|
Author: Tsu Jan <tsujan2000@gmail.com>
|
||||||
|
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<GFileInfo>& 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<GFileInfo> 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<GFileInfo> 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<const FileActionItem> 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<const Fm::FileInfo> 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;
|
||||||
|
}
|
Loading…
Reference in new issue