mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 23:53:58 +02:00
Make open with dialog modal on Linux
This commit is contained in:
parent
b28da30038
commit
15a9842b9f
3 changed files with 62 additions and 45 deletions
|
@ -45,45 +45,95 @@ bool ShowOpenWithSupported() {
|
||||||
&& (Libs::gtk_app_chooser_dialog_new != nullptr)
|
&& (Libs::gtk_app_chooser_dialog_new != nullptr)
|
||||||
&& (Libs::gtk_app_chooser_get_app_info != nullptr)
|
&& (Libs::gtk_app_chooser_get_app_info != nullptr)
|
||||||
&& (Libs::gtk_app_chooser_get_type != nullptr)
|
&& (Libs::gtk_app_chooser_get_type != nullptr)
|
||||||
&& (Libs::gtk_widget_get_type != nullptr)
|
|
||||||
&& (Libs::gtk_widget_get_window != nullptr)
|
&& (Libs::gtk_widget_get_window != nullptr)
|
||||||
&& (Libs::gtk_widget_realize != nullptr)
|
&& (Libs::gtk_widget_realize != nullptr)
|
||||||
&& (Libs::gtk_widget_show != nullptr)
|
&& (Libs::gtk_widget_show != nullptr)
|
||||||
&& (Libs::gtk_widget_destroy != nullptr);
|
&& (Libs::gtk_widget_destroy != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAppChooserResponse(
|
class OpenWithDialog : public QWindow {
|
||||||
GtkDialog *dialog,
|
public:
|
||||||
int responseId,
|
OpenWithDialog(const QString &filepath);
|
||||||
GFile *file) {
|
~OpenWithDialog();
|
||||||
|
|
||||||
|
bool exec();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void handleResponse(OpenWithDialog *dialog, int responseId);
|
||||||
|
|
||||||
|
GFile *_gfileInstance = nullptr;
|
||||||
|
GtkWidget *_gtkWidget = nullptr;
|
||||||
|
QEventLoop _loop;
|
||||||
|
std::optional<bool> _result = std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
OpenWithDialog::OpenWithDialog(const QString &filepath)
|
||||||
|
: _gfileInstance(g_file_new_for_path(filepath.toUtf8()))
|
||||||
|
, _gtkWidget(Libs::gtk_app_chooser_dialog_new(
|
||||||
|
nullptr,
|
||||||
|
GTK_DIALOG_MODAL,
|
||||||
|
_gfileInstance)) {
|
||||||
|
g_signal_connect_swapped(
|
||||||
|
_gtkWidget,
|
||||||
|
"response",
|
||||||
|
G_CALLBACK(handleAppChooserResponse),
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenWithDialog::~OpenWithDialog() {
|
||||||
|
Libs::gtk_widget_destroy(_gtkWidget);
|
||||||
|
g_object_unref(_gfileInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenWithDialog::exec() {
|
||||||
|
Libs::gtk_widget_realize(_gtkWidget);
|
||||||
|
|
||||||
|
if (const auto activeWindow = Core::App().activeWindow()) {
|
||||||
|
Platform::internal::XSetTransientForHint(
|
||||||
|
Libs::gtk_widget_get_window(_gtkWidget),
|
||||||
|
activeWindow->widget().get()->windowHandle()->winId());
|
||||||
|
}
|
||||||
|
|
||||||
|
QGuiApplicationPrivate::showModalWindow(this);
|
||||||
|
Libs::gtk_widget_show(_gtkWidget);
|
||||||
|
|
||||||
|
if (!_result.has_value()) {
|
||||||
|
_loop.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
QGuiApplicationPrivate::hideModalWindow(this);
|
||||||
|
return *_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWithDialog::handleResponse(OpenWithDialog *dialog, int responseId) {
|
||||||
GAppInfo *chosenAppInfo = nullptr;
|
GAppInfo *chosenAppInfo = nullptr;
|
||||||
|
dialog->_result = true;
|
||||||
|
|
||||||
switch (responseId) {
|
switch (responseId) {
|
||||||
case GTK_RESPONSE_OK:
|
case GTK_RESPONSE_OK:
|
||||||
chosenAppInfo = Libs::gtk_app_chooser_get_app_info(
|
chosenAppInfo = Libs::gtk_app_chooser_get_app_info(
|
||||||
Libs::gtk_app_chooser_cast(dialog));
|
Libs::gtk_app_chooser_cast(dialog->_gtkWidget));
|
||||||
|
|
||||||
if (chosenAppInfo) {
|
if (chosenAppInfo) {
|
||||||
GList *uris = nullptr;
|
GList *uris = nullptr;
|
||||||
uris = g_list_prepend(uris, g_file_get_uri(file));
|
uris = g_list_prepend(uris, g_file_get_uri(dialog->_gfileInstance));
|
||||||
g_app_info_launch_uris(chosenAppInfo, uris, nullptr, nullptr);
|
g_app_info_launch_uris(chosenAppInfo, uris, nullptr, nullptr);
|
||||||
g_list_free(uris);
|
g_list_free(uris);
|
||||||
g_object_unref(chosenAppInfo);
|
g_object_unref(chosenAppInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref(file);
|
|
||||||
Libs::gtk_widget_destroy(Libs::gtk_widget_cast(dialog));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_RESPONSE_CANCEL:
|
case GTK_RESPONSE_CANCEL:
|
||||||
case GTK_RESPONSE_DELETE_EVENT:
|
case GTK_RESPONSE_DELETE_EVENT:
|
||||||
g_object_unref(file);
|
|
||||||
Libs::gtk_widget_destroy(Libs::gtk_widget_cast(dialog));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
dialog->_result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialog->_loop.quit();
|
||||||
}
|
}
|
||||||
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
|
|
||||||
|
@ -141,30 +191,7 @@ bool UnsafeShowOpenWith(const QString &filepath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
const auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
||||||
auto gfileInstance = g_file_new_for_path(absolutePath.toUtf8());
|
return OpenWithDialog(absolutePath).exec();
|
||||||
|
|
||||||
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
|
#else // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
return false;
|
return false;
|
||||||
#endif // TDESKTOP_DISABLE_GTK_INTEGRATION
|
#endif // TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
|
|
|
@ -74,7 +74,6 @@ 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_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_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_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_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_store", gtk_clipboard_store)) return false;
|
||||||
if (!LOAD_SYMBOL(lib_gtk, "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents)) return false;
|
if (!LOAD_SYMBOL(lib_gtk, "gtk_clipboard_wait_for_contents", gtk_clipboard_wait_for_contents)) return false;
|
||||||
|
@ -236,7 +235,6 @@ f_gtk_widget_get_window gtk_widget_get_window = nullptr;
|
||||||
f_gtk_widget_realize gtk_widget_realize = nullptr;
|
f_gtk_widget_realize gtk_widget_realize = nullptr;
|
||||||
f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete = nullptr;
|
f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete = nullptr;
|
||||||
f_gtk_widget_destroy gtk_widget_destroy = 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_get gtk_clipboard_get = nullptr;
|
||||||
f_gtk_clipboard_store gtk_clipboard_store = nullptr;
|
f_gtk_clipboard_store gtk_clipboard_store = nullptr;
|
||||||
f_gtk_clipboard_wait_for_contents gtk_clipboard_wait_for_contents = nullptr;
|
f_gtk_clipboard_wait_for_contents gtk_clipboard_wait_for_contents = nullptr;
|
||||||
|
|
|
@ -235,14 +235,6 @@ inline GtkWindow *gtk_window_cast(Object *obj) {
|
||||||
return g_type_cic_helper<GtkWindow, Object>(obj, gtk_window_get_type());
|
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;
|
typedef GType (*f_gtk_app_chooser_get_type)(void) G_GNUC_CONST;
|
||||||
extern f_gtk_app_chooser_get_type gtk_app_chooser_get_type;
|
extern f_gtk_app_chooser_get_type gtk_app_chooser_get_type;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue