mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Control GtkOpenWithDialog lifetime from outside
This commit is contained in:
parent
aece7c1096
commit
75ff7a6637
3 changed files with 73 additions and 44 deletions
|
@ -154,11 +154,28 @@ void GtkIntegration::Private::handleMethodCall(
|
||||||
const auto filepath = base::Platform::GlibVariantCast<
|
const auto filepath = base::Platform::GlibVariantCast<
|
||||||
Glib::ustring>(parametersCopy.get_child(1));
|
Glib::ustring>(parametersCopy.get_child(1));
|
||||||
|
|
||||||
const auto result = File::internal::ShowGtkOpenWithDialog(
|
const auto dialog = File::internal::CreateGtkOpenWithDialog(
|
||||||
QString::fromStdString(parent),
|
QString::fromStdString(parent),
|
||||||
QString::fromStdString(filepath));
|
QString::fromStdString(filepath)).release();
|
||||||
|
|
||||||
|
if (dialog) {
|
||||||
|
dialog->response(
|
||||||
|
) | rpl::start_with_next([=](bool response) {
|
||||||
|
try {
|
||||||
|
connection->emit_signal(
|
||||||
|
std::string(kObjectPath),
|
||||||
|
std::string(kInterface),
|
||||||
|
"OpenWithDialogResponse",
|
||||||
|
parentDBusName,
|
||||||
|
base::Platform::MakeGlibVariant(std::tuple{
|
||||||
|
response,
|
||||||
|
}));
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
|
||||||
|
delete dialog;
|
||||||
|
}, dialog->lifetime());
|
||||||
|
|
||||||
if (result) {
|
|
||||||
invocation->return_value({});
|
invocation->return_value({});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -340,23 +357,6 @@ int GtkIntegration::exec(const QString &parentDBusName, int ppid) {
|
||||||
_private->introspectionData->lookup_interface(),
|
_private->introspectionData->lookup_interface(),
|
||||||
_private->interfaceVTable);
|
_private->interfaceVTable);
|
||||||
|
|
||||||
rpl::lifetime lifetime;
|
|
||||||
|
|
||||||
File::internal::GtkOpenWithDialogResponse(
|
|
||||||
) | rpl::start_with_next([=](bool response) {
|
|
||||||
try {
|
|
||||||
_private->dbusConnection->emit_signal(
|
|
||||||
std::string(kObjectPath),
|
|
||||||
std::string(kInterface),
|
|
||||||
"OpenWithDialogResponse",
|
|
||||||
_private->parentDBusName,
|
|
||||||
base::Platform::MakeGlibVariant(std::tuple{
|
|
||||||
response,
|
|
||||||
}));
|
|
||||||
} catch (...) {
|
|
||||||
}
|
|
||||||
}, lifetime);
|
|
||||||
|
|
||||||
const auto app = Gio::Application::create(_private->serviceName);
|
const auto app = Gio::Application::create(_private->serviceName);
|
||||||
app->hold();
|
app->hold();
|
||||||
_private->parentServiceWatcherId = base::Platform::DBus::RegisterServiceWatcher(
|
_private->parentServiceWatcherId = base::Platform::DBus::RegisterServiceWatcher(
|
||||||
|
@ -459,21 +459,24 @@ bool GtkIntegration::showOpenWithDialog(const QString &filepath) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File::internal::ShowGtkOpenWithDialog(parent, filepath)) {
|
const auto dialog = File::internal::CreateGtkOpenWithDialog(
|
||||||
|
parent,
|
||||||
|
filepath);
|
||||||
|
|
||||||
|
if (!dialog) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto context = Glib::MainContext::create();
|
const auto context = Glib::MainContext::create();
|
||||||
const auto loop = Glib::MainLoop::create(context);
|
const auto loop = Glib::MainLoop::create(context);
|
||||||
g_main_context_push_thread_default(context->gobj());
|
g_main_context_push_thread_default(context->gobj());
|
||||||
rpl::lifetime lifetime;
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
File::internal::GtkOpenWithDialogResponse(
|
dialog->response(
|
||||||
) | rpl::start_with_next([&](bool response) {
|
) | rpl::start_with_next([&](bool response) {
|
||||||
result = response;
|
result = response;
|
||||||
loop->quit();
|
loop->quit();
|
||||||
}, lifetime);
|
}, dialog->lifetime());
|
||||||
|
|
||||||
QWindow window;
|
QWindow window;
|
||||||
QGuiApplicationPrivate::showModalWindow(&window);
|
QGuiApplicationPrivate::showModalWindow(&window);
|
||||||
|
|
|
@ -19,8 +19,6 @@ namespace {
|
||||||
|
|
||||||
using namespace Platform::Gtk;
|
using namespace Platform::Gtk;
|
||||||
|
|
||||||
rpl::event_stream<bool> GtkOpenWithDialogResponseStream;
|
|
||||||
|
|
||||||
struct GtkWidgetDeleter {
|
struct GtkWidgetDeleter {
|
||||||
void operator()(GtkWidget *widget) {
|
void operator()(GtkWidget *widget) {
|
||||||
gtk_widget_destroy(widget);
|
gtk_widget_destroy(widget);
|
||||||
|
@ -37,20 +35,25 @@ bool Supported() {
|
||||||
&& (gtk_widget_destroy != nullptr);
|
&& (gtk_widget_destroy != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GtkOpenWithDialog {
|
} // namespace
|
||||||
|
|
||||||
|
class GtkOpenWithDialog::Private {
|
||||||
public:
|
public:
|
||||||
GtkOpenWithDialog(
|
Private(
|
||||||
const QString &parent,
|
const QString &parent,
|
||||||
const QString &filepath);
|
const QString &filepath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void handleResponse(GtkOpenWithDialog *dialog, int responseId);
|
friend class GtkOpenWithDialog;
|
||||||
|
|
||||||
|
static void handleResponse(Private *dialog, int responseId);
|
||||||
|
|
||||||
const Glib::RefPtr<Gio::File> _file;
|
const Glib::RefPtr<Gio::File> _file;
|
||||||
const std::unique_ptr<GtkWidget, GtkWidgetDeleter> _gtkWidget;
|
const std::unique_ptr<GtkWidget, GtkWidgetDeleter> _gtkWidget;
|
||||||
|
rpl::event_stream<bool> _responseStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
GtkOpenWithDialog::GtkOpenWithDialog(
|
GtkOpenWithDialog::Private::Private(
|
||||||
const QString &parent,
|
const QString &parent,
|
||||||
const QString &filepath)
|
const QString &filepath)
|
||||||
: _file(Gio::File::create_for_path(filepath.toStdString()))
|
: _file(Gio::File::create_for_path(filepath.toStdString()))
|
||||||
|
@ -73,7 +76,7 @@ GtkOpenWithDialog::GtkOpenWithDialog(
|
||||||
gtk_widget_show(_gtkWidget.get());
|
gtk_widget_show(_gtkWidget.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GtkOpenWithDialog::handleResponse(GtkOpenWithDialog *dialog, int responseId) {
|
void GtkOpenWithDialog::Private::handleResponse(Private *dialog, int responseId) {
|
||||||
Glib::RefPtr<Gio::AppInfo> chosenAppInfo;
|
Glib::RefPtr<Gio::AppInfo> chosenAppInfo;
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
|
@ -101,24 +104,29 @@ void GtkOpenWithDialog::handleResponse(GtkOpenWithDialog *dialog, int responseId
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkOpenWithDialogResponseStream.fire_copy(result);
|
dialog->_responseStream.fire_copy(result);
|
||||||
delete dialog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
GtkOpenWithDialog::GtkOpenWithDialog(
|
||||||
|
const QString &parent,
|
||||||
|
const QString &filepath)
|
||||||
|
: _private(std::make_unique<Private>(parent, filepath)) {
|
||||||
|
}
|
||||||
|
|
||||||
bool ShowGtkOpenWithDialog(
|
GtkOpenWithDialog::~GtkOpenWithDialog() = default;
|
||||||
|
|
||||||
|
rpl::producer<bool> GtkOpenWithDialog::response() {
|
||||||
|
return _private->_responseStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<GtkOpenWithDialog> CreateGtkOpenWithDialog(
|
||||||
const QString &parent,
|
const QString &parent,
|
||||||
const QString &filepath) {
|
const QString &filepath) {
|
||||||
if (!Supported()) {
|
if (!Supported()) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GtkOpenWithDialog(parent, filepath);
|
return std::make_unique<GtkOpenWithDialog>(parent, filepath);
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<bool> GtkOpenWithDialogResponse() {
|
|
||||||
return GtkOpenWithDialogResponseStream.events();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
|
@ -11,12 +11,30 @@ namespace Platform {
|
||||||
namespace File {
|
namespace File {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
bool ShowGtkOpenWithDialog(
|
class GtkOpenWithDialog {
|
||||||
|
public:
|
||||||
|
GtkOpenWithDialog(
|
||||||
|
const QString &parent,
|
||||||
|
const QString &filepath);
|
||||||
|
|
||||||
|
~GtkOpenWithDialog();
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<bool> response();
|
||||||
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
|
return _lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
const std::unique_ptr<Private> _private;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<GtkOpenWithDialog> CreateGtkOpenWithDialog(
|
||||||
const QString &parent,
|
const QString &parent,
|
||||||
const QString &filepath);
|
const QString &filepath);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<bool> GtkOpenWithDialogResponse();
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace File
|
} // namespace File
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
Loading…
Add table
Reference in a new issue