From 007218cc13e4e1d187c5db0fdb2bc0dbd7af0f20 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Thu, 24 Jun 2021 09:03:14 +0400 Subject: [PATCH] Use C++ wrappers in GtkOpenWithDialog --- .../platform/linux/linux_gtk_integration_p.h | 7 +-- .../linux/linux_gtk_open_with_dialog.cpp | 45 ++++++++++--------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h index c3544c2ef..a94d305e3 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h @@ -52,6 +52,7 @@ inline void (*gtk_file_chooser_set_preview_widget_active)(GtkFileChooser *choose inline GtkFileFilter* (*gtk_file_filter_new)(void) = nullptr; inline GtkWidget* (*gtk_image_new)(void) = nullptr; inline void (*gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf) = nullptr; +inline GType (*gtk_app_chooser_get_type)(void) G_GNUC_CONST = nullptr; inline GtkWidget* (*gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file) = nullptr; inline GAppInfo* (*gtk_app_chooser_get_app_info)(GtkAppChooser *self) = nullptr; inline void (*gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal) = nullptr; @@ -92,12 +93,6 @@ inline GtkWindow *gtk_window_cast(Object *obj) { return g_type_cic_helper(obj, gtk_window_get_type()); } -inline GType (*gtk_app_chooser_get_type)(void) G_GNUC_CONST = nullptr; -template -inline GtkAppChooser *gtk_app_chooser_cast(Object *obj) { - return g_type_cic_helper(obj, gtk_app_chooser_get_type()); -} - template inline bool g_type_cit_helper(Object *instance, GType iface_type) { if (!instance) return false; diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp index 4994ebe7d..3c8aac4b4 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_open_with_dialog.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include +#include namespace Platform { namespace File { @@ -21,6 +22,12 @@ namespace { using namespace Platform::Gtk; +struct GtkWidgetDeleter { + void operator()(GtkWidget *widget) { + gtk_widget_destroy(widget); + } +}; + bool Supported() { return (gtk_app_chooser_dialog_new != nullptr) && (gtk_app_chooser_get_app_info != nullptr) @@ -34,48 +41,42 @@ bool Supported() { class GtkOpenWithDialog : public QWindow { public: GtkOpenWithDialog(const QString &filepath); - ~GtkOpenWithDialog(); bool exec(); private: static void handleResponse(GtkOpenWithDialog *dialog, int responseId); - GFile *_gfileInstance = nullptr; - GtkWidget *_gtkWidget = nullptr; + const Glib::RefPtr _file; + const std::unique_ptr _gtkWidget; QEventLoop _loop; std::optional _result; }; GtkOpenWithDialog::GtkOpenWithDialog(const QString &filepath) -: _gfileInstance(g_file_new_for_path(filepath.toUtf8().constData())) +: _file(Gio::File::create_for_path(filepath.toStdString())) , _gtkWidget(gtk_app_chooser_dialog_new( nullptr, GTK_DIALOG_MODAL, - _gfileInstance)) { + _file->gobj())) { g_signal_connect_swapped( - _gtkWidget, + _gtkWidget.get(), "response", G_CALLBACK(handleResponse), this); } -GtkOpenWithDialog::~GtkOpenWithDialog() { - gtk_widget_destroy(_gtkWidget); - g_object_unref(_gfileInstance); -} - bool GtkOpenWithDialog::exec() { - gtk_widget_realize(_gtkWidget); + gtk_widget_realize(_gtkWidget.get()); if (const auto activeWindow = Core::App().activeWindow()) { Platform::internal::GdkSetTransientFor( - gtk_widget_get_window(_gtkWidget), + gtk_widget_get_window(_gtkWidget.get()), activeWindow->widget()->windowHandle()); } QGuiApplicationPrivate::showModalWindow(this); - gtk_widget_show(_gtkWidget); + gtk_widget_show(_gtkWidget.get()); if (!_result.has_value()) { _loop.exec(); @@ -86,20 +87,20 @@ bool GtkOpenWithDialog::exec() { } void GtkOpenWithDialog::handleResponse(GtkOpenWithDialog *dialog, int responseId) { - GAppInfo *chosenAppInfo = nullptr; + Glib::RefPtr chosenAppInfo; dialog->_result = true; switch (responseId) { case GTK_RESPONSE_OK: - chosenAppInfo = gtk_app_chooser_get_app_info( - gtk_app_chooser_cast(dialog->_gtkWidget)); + chosenAppInfo = Glib::wrap(gtk_app_chooser_get_app_info( + GTK_APP_CHOOSER(dialog->_gtkWidget.get()))); if (chosenAppInfo) { - GList *uris = nullptr; - uris = g_list_prepend(uris, g_file_get_uri(dialog->_gfileInstance)); - g_app_info_launch_uris(chosenAppInfo, uris, nullptr, nullptr); - g_list_free(uris); - g_object_unref(chosenAppInfo); + try { + chosenAppInfo->launch_uri(dialog->_file->get_uri()); + } catch (...) { + } + chosenAppInfo = {}; } break;