Qt: Implement "Show in Folder" using DBus.

On Linux (and presumably other DBus-using Unix-like OSes), right-clicking on a
file on the Welcome page and choosing "Show in Folder" would only ever open the
folder, and would not highlight the chosen file.

Adding DBus support to function desktop_show_in_folder allows for the file
itself to be shown -- subject to support from the user's desktop environment...
This commit is contained in:
Darius Davis 2024-02-09 09:05:37 +10:00 committed by AndersBroman
parent 99df5f588b
commit 30c0b28f87
3 changed files with 54 additions and 2 deletions

View File

@ -1264,6 +1264,7 @@ if(BUILD_wireshark OR BUILD_logray)
Widgets
Concurrent
Core5Compat
DBus
OPTIONAL_COMPONENTS
Multimedia
)
@ -1297,6 +1298,10 @@ if(BUILD_wireshark OR BUILD_logray)
if(WIN32)
list(APPEND QT5_PACKAGELIST Qt5WinExtras)
endif()
if(NOT WIN32 AND NOT APPLE)
# DBus is a core component of Qt6, but was an add-on in Qt5.
list(APPEND QT5_OPTIONAL_PACKAGELIST Qt5DBus)
endif()
foreach(_qt5_package IN LISTS QT5_PACKAGELIST)
find_package(${_qt5_package} REQUIRED ${QT5_FIND_PACKAGE_OPTIONS})
list(APPEND QT5_LIBRARIES ${${_qt5_package}_LIBRARIES})
@ -1335,6 +1340,9 @@ if(BUILD_wireshark OR BUILD_logray)
if(Qt6Multimedia_FOUND OR Qt5Multimedia_FOUND)
set(QT_MULTIMEDIA_LIB 1)
endif()
if(Qt6DBus_FOUND OR Qt5DBus_FOUND)
set(QT_DBUS_LIB 1)
endif()
if(NOT DEFINED MOC_OPTIONS)
# Squelch moc verbose "nothing to do" output
set(MOC_OPTIONS -nn)

View File

@ -212,6 +212,13 @@ gather_wireshark_qt_compiled_info(feature_list l)
#else
without_feature(l, "QtMultimedia");
#endif
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
#ifdef QT_DBUS_LIB
with_feature(l, "QtDBus");
#else
without_feature(l, "QtDBus");
#endif
#endif /* !Q_OS_WIN && !Q_OS_MAC */
const char *update_info = software_update_info();
if (update_info) {

View File

@ -23,6 +23,7 @@
#include "ui/ws_ui_util.h"
#include <wsutil/str_util.h>
#include <wsutil/file_util.h>
#include <QAction>
#include <QApplication>
@ -33,9 +34,14 @@
#include <QFontDatabase>
#include <QProcess>
#include <QUrl>
#include <QUuid>
#include <QScreen>
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && defined(QT_DBUS_LIB)
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusUnixFileDescriptor>
#endif
/*
* We might want to create our own "wsstring" class with convenience
* methods for handling g_malloc()ed strings, GStrings, and a shortcut
@ -246,8 +252,39 @@ void desktop_show_in_folder(const QString file_path)
<< "tell application \"Finder\" to activate";
QProcess::execute("/usr/bin/osascript", script_args);
}
#elif defined(QT_DBUS_LIB)
// First, try the FileManager1 DBus interface's "ShowItems" method.
// https://www.freedesktop.org/wiki/Specifications/file-manager-interface/
QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.FileManager1"),
QLatin1String("/org/freedesktop/FileManager1"),
QLatin1String("org.freedesktop.FileManager1"),
QLatin1String("ShowItems"));
QStringList uris(QUrl::fromLocalFile(file_path).toString());
message << uris << QString();
message = QDBusConnection::sessionBus().call(message);
success = message.type() == QDBusMessage::ReplyMessage;
// If that failed, perhaps we are sandboxed. Try using Portal Services.
// https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.OpenURI.html
if (!success) {
const int fd = ws_open(QFile::encodeName(file_path), O_CLOEXEC | O_PATH, 0000);
if (fd != -1) {
QDBusUnixFileDescriptor descriptor;
descriptor.giveFileDescriptor(fd);
QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
QLatin1String("/org/freedesktop/portal/desktop"),
QLatin1String("org.freedesktop.portal.OpenURI"),
QLatin1String("OpenDirectory"));
message << QString() << QVariant::fromValue(descriptor) << QVariantMap();
message = QDBusConnection::sessionBus().call(message);
success = message.type() == QDBusMessage::ReplyMessage;
ws_close(fd);
}
}
#else
// Is there a way to highlight the file using xdg-open?
// Any other possibilities to highlight the file before falling back to showing the folder?
#endif
if (!success) {
QFileInfo file_info(file_path);