mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-25 10:44:41 +02:00
Add support for open with on linux
This commit is contained in:
parent
3a45957ceb
commit
91a2ec225a
4 changed files with 129 additions and 5 deletions
|
@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "platform/linux/specific_linux.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "base/qt_adapters.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "core/application.h"
|
||||
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
|
@ -35,6 +37,58 @@ extern "C" {
|
|||
|
||||
namespace Platform {
|
||||
namespace File {
|
||||
namespace {
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
bool ShowOpenWithSupported() {
|
||||
return Platform::internal::GdkHelperLoaded()
|
||||
&& (Libs::gtk_app_chooser_dialog_new != nullptr)
|
||||
&& (Libs::gtk_app_chooser_get_app_info != nullptr)
|
||||
&& (Libs::gtk_app_chooser_get_type != nullptr)
|
||||
&& (Libs::gtk_widget_get_type != nullptr)
|
||||
&& (Libs::gtk_widget_get_window != nullptr)
|
||||
&& (Libs::gtk_widget_realize != nullptr)
|
||||
&& (Libs::gtk_widget_show != nullptr)
|
||||
&& (Libs::gtk_widget_destroy != nullptr);
|
||||
}
|
||||
|
||||
void HandleAppChooserResponse(
|
||||
GtkDialog *dialog,
|
||||
int responseId,
|
||||
GFile *file) {
|
||||
GAppInfo *chosenAppInfo = nullptr;
|
||||
|
||||
switch (responseId) {
|
||||
case GTK_RESPONSE_OK:
|
||||
chosenAppInfo = Libs::gtk_app_chooser_get_app_info(
|
||||
Libs::gtk_app_chooser_cast(dialog));
|
||||
|
||||
if (chosenAppInfo) {
|
||||
GList *uris = nullptr;
|
||||
uris = g_list_prepend(uris, g_file_get_uri(file));
|
||||
g_app_info_launch_uris(chosenAppInfo, uris, nullptr, nullptr);
|
||||
g_list_free(uris);
|
||||
g_object_unref(chosenAppInfo);
|
||||
}
|
||||
|
||||
g_object_unref(file);
|
||||
Libs::gtk_widget_destroy(Libs::gtk_widget_cast(dialog));
|
||||
break;
|
||||
|
||||
case GTK_RESPONSE_CANCEL:
|
||||
case GTK_RESPONSE_DELETE_EVENT:
|
||||
g_object_unref(file);
|
||||
Libs::gtk_widget_destroy(Libs::gtk_widget_cast(dialog));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
QByteArray EscapeShell(const QByteArray &content) {
|
||||
|
@ -78,6 +132,44 @@ void UnsafeOpenEmailLink(const QString &email) {
|
|||
UnsafeOpenUrl(qstr("mailto:") + email);
|
||||
}
|
||||
|
||||
bool UnsafeShowOpenWith(const QString &filepath) {
|
||||
#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
if (InFlatpak()
|
||||
|| InSnap()
|
||||
|| !ShowOpenWithSupported()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
||||
auto gfileInstance = g_file_new_for_path(absolutePath.toUtf8());
|
||||
|
||||
auto appChooserDialog = Libs::gtk_app_chooser_dialog_new(
|
||||
nullptr,
|
||||
GTK_DIALOG_MODAL,
|
||||
gfileInstance);
|
||||
|
||||
g_signal_connect(
|
||||
appChooserDialog,
|
||||
"response",
|
||||
G_CALLBACK(HandleAppChooserResponse),
|
||||
gfileInstance);
|
||||
|
||||
Libs::gtk_widget_realize(appChooserDialog);
|
||||
|
||||
if (const auto activeWindow = Core::App().activeWindow()) {
|
||||
Platform::internal::XSetTransientForHint(
|
||||
Libs::gtk_widget_get_window(appChooserDialog),
|
||||
activeWindow->widget().get()->windowHandle()->winId());
|
||||
}
|
||||
|
||||
Libs::gtk_widget_show(appChooserDialog);
|
||||
|
||||
return true;
|
||||
#else // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
return false;
|
||||
#endif // TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
}
|
||||
|
||||
void UnsafeLaunch(const QString &filepath) {
|
||||
const auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
||||
|
||||
|
@ -85,7 +177,9 @@ void UnsafeLaunch(const QString &filepath) {
|
|||
g_filename_to_uri(absolutePath.toUtf8(), nullptr, nullptr),
|
||||
nullptr,
|
||||
nullptr)) {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(filepath));
|
||||
if (!UnsafeShowOpenWith(filepath)) {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(filepath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,6 @@ inline bool UnsafeShowOpenWithDropdown(const QString &filepath, QPoint menuPosit
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool UnsafeShowOpenWith(const QString &filepath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void PostprocessDownloaded(const QString &filepath) {
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ bool setupGtkBase(QLibrary &lib_gtk) {
|
|||
if (!LOAD_SYMBOL(lib_gtk, "gtk_widget_realize", gtk_widget_realize)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_widget_hide_on_delete", gtk_widget_hide_on_delete)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_widget_destroy", gtk_widget_destroy)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_widget_get_type", gtk_widget_get_type)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_clipboard_get", gtk_clipboard_get)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_clipboard_store", gtk_clipboard_store)) return false;
|
||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents)) return false;
|
||||
|
@ -211,6 +212,7 @@ f_gtk_widget_get_window gtk_widget_get_window = nullptr;
|
|||
f_gtk_widget_realize gtk_widget_realize = nullptr;
|
||||
f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete = nullptr;
|
||||
f_gtk_widget_destroy gtk_widget_destroy = nullptr;
|
||||
f_gtk_widget_get_type gtk_widget_get_type = nullptr;
|
||||
f_gtk_clipboard_get gtk_clipboard_get = nullptr;
|
||||
f_gtk_clipboard_store gtk_clipboard_store = nullptr;
|
||||
f_gtk_clipboard_wait_for_contents gtk_clipboard_wait_for_contents = nullptr;
|
||||
|
@ -246,6 +248,9 @@ f_gtk_image_set_from_pixbuf gtk_image_set_from_pixbuf = nullptr;
|
|||
f_gtk_dialog_get_widget_for_response gtk_dialog_get_widget_for_response = nullptr;
|
||||
f_gtk_button_set_label gtk_button_set_label = nullptr;
|
||||
f_gtk_button_get_type gtk_button_get_type = nullptr;
|
||||
f_gtk_app_chooser_dialog_new gtk_app_chooser_dialog_new = nullptr;
|
||||
f_gtk_app_chooser_get_app_info gtk_app_chooser_get_app_info = nullptr;
|
||||
f_gtk_app_chooser_get_type gtk_app_chooser_get_type = nullptr;
|
||||
f_gdk_set_allowed_backends gdk_set_allowed_backends = nullptr;
|
||||
f_gdk_window_set_modal_hint gdk_window_set_modal_hint = nullptr;
|
||||
f_gdk_window_focus gdk_window_focus = nullptr;
|
||||
|
@ -304,6 +309,10 @@ void start() {
|
|||
LOAD_SYMBOL(lib_gtk, "gtk_button_set_label", gtk_button_set_label);
|
||||
LOAD_SYMBOL(lib_gtk, "gtk_button_get_type", gtk_button_get_type);
|
||||
|
||||
LOAD_SYMBOL(lib_gtk, "gtk_app_chooser_dialog_new", gtk_app_chooser_dialog_new);
|
||||
LOAD_SYMBOL(lib_gtk, "gtk_app_chooser_get_app_info", gtk_app_chooser_get_app_info);
|
||||
LOAD_SYMBOL(lib_gtk, "gtk_app_chooser_get_type", gtk_app_chooser_get_type);
|
||||
|
||||
SetIconTheme();
|
||||
|
||||
const auto settings = gtk_settings_get_default();
|
||||
|
|
|
@ -18,6 +18,9 @@ extern "C" {
|
|||
#define signals public
|
||||
} // extern "C"
|
||||
|
||||
// present start with gtk 3.0, we're building with gtk 2.0 headers
|
||||
typedef struct _GtkAppChooser GtkAppChooser;
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
|
||||
#if defined DESKTOP_APP_USE_PACKAGED && !defined DESKTOP_APP_USE_PACKAGED_LAZY
|
||||
|
@ -172,6 +175,12 @@ extern f_gtk_image_new gtk_image_new;
|
|||
typedef void (*f_gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf);
|
||||
extern f_gtk_image_set_from_pixbuf gtk_image_set_from_pixbuf;
|
||||
|
||||
typedef GtkWidget* (*f_gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file);
|
||||
extern f_gtk_app_chooser_dialog_new gtk_app_chooser_dialog_new;
|
||||
|
||||
typedef GAppInfo* (*f_gtk_app_chooser_get_app_info)(GtkAppChooser *self);
|
||||
extern f_gtk_app_chooser_get_app_info gtk_app_chooser_get_app_info;
|
||||
|
||||
typedef void (*f_gdk_set_allowed_backends)(const gchar *backends);
|
||||
extern f_gdk_set_allowed_backends gdk_set_allowed_backends;
|
||||
|
||||
|
@ -226,6 +235,22 @@ inline GtkWindow *gtk_window_cast(Object *obj) {
|
|||
return g_type_cic_helper<GtkWindow, Object>(obj, gtk_window_get_type());
|
||||
}
|
||||
|
||||
typedef GType (*f_gtk_widget_get_type)(void) G_GNUC_CONST;
|
||||
extern f_gtk_widget_get_type gtk_widget_get_type;
|
||||
|
||||
template <typename Object>
|
||||
inline GtkWidget *gtk_widget_cast(Object *obj) {
|
||||
return g_type_cic_helper<GtkWidget, Object>(obj, gtk_widget_get_type());
|
||||
}
|
||||
|
||||
typedef GType (*f_gtk_app_chooser_get_type)(void) G_GNUC_CONST;
|
||||
extern f_gtk_app_chooser_get_type gtk_app_chooser_get_type;
|
||||
|
||||
template <typename Object>
|
||||
inline GtkAppChooser *gtk_app_chooser_cast(Object *obj) {
|
||||
return g_type_cic_helper<GtkAppChooser, Object>(obj, gtk_app_chooser_get_type());
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
inline bool g_type_cit_helper(Object *instance, GType iface_type) {
|
||||
if (!instance) return false;
|
||||
|
|
Loading…
Add table
Reference in a new issue