mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +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<
|
||||
Glib::ustring>(parametersCopy.get_child(1));
|
||||
|
||||
const auto result = File::internal::ShowGtkOpenWithDialog(
|
||||
const auto dialog = File::internal::CreateGtkOpenWithDialog(
|
||||
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({});
|
||||
return;
|
||||
}
|
||||
|
@ -340,23 +357,6 @@ int GtkIntegration::exec(const QString &parentDBusName, int ppid) {
|
|||
_private->introspectionData->lookup_interface(),
|
||||
_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);
|
||||
app->hold();
|
||||
_private->parentServiceWatcherId = base::Platform::DBus::RegisterServiceWatcher(
|
||||
|
@ -459,21 +459,24 @@ bool GtkIntegration::showOpenWithDialog(const QString &filepath) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!File::internal::ShowGtkOpenWithDialog(parent, filepath)) {
|
||||
const auto dialog = File::internal::CreateGtkOpenWithDialog(
|
||||
parent,
|
||||
filepath);
|
||||
|
||||
if (!dialog) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto context = Glib::MainContext::create();
|
||||
const auto loop = Glib::MainLoop::create(context);
|
||||
g_main_context_push_thread_default(context->gobj());
|
||||
rpl::lifetime lifetime;
|
||||
bool result = false;
|
||||
|
||||
File::internal::GtkOpenWithDialogResponse(
|
||||
dialog->response(
|
||||
) | rpl::start_with_next([&](bool response) {
|
||||
result = response;
|
||||
loop->quit();
|
||||
}, lifetime);
|
||||
}, dialog->lifetime());
|
||||
|
||||
QWindow window;
|
||||
QGuiApplicationPrivate::showModalWindow(&window);
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace {
|
|||
|
||||
using namespace Platform::Gtk;
|
||||
|
||||
rpl::event_stream<bool> GtkOpenWithDialogResponseStream;
|
||||
|
||||
struct GtkWidgetDeleter {
|
||||
void operator()(GtkWidget *widget) {
|
||||
gtk_widget_destroy(widget);
|
||||
|
@ -37,20 +35,25 @@ bool Supported() {
|
|||
&& (gtk_widget_destroy != nullptr);
|
||||
}
|
||||
|
||||
class GtkOpenWithDialog {
|
||||
} // namespace
|
||||
|
||||
class GtkOpenWithDialog::Private {
|
||||
public:
|
||||
GtkOpenWithDialog(
|
||||
Private(
|
||||
const QString &parent,
|
||||
const QString &filepath);
|
||||
|
||||
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 std::unique_ptr<GtkWidget, GtkWidgetDeleter> _gtkWidget;
|
||||
rpl::event_stream<bool> _responseStream;
|
||||
};
|
||||
|
||||
GtkOpenWithDialog::GtkOpenWithDialog(
|
||||
GtkOpenWithDialog::Private::Private(
|
||||
const QString &parent,
|
||||
const QString &filepath)
|
||||
: _file(Gio::File::create_for_path(filepath.toStdString()))
|
||||
|
@ -73,7 +76,7 @@ GtkOpenWithDialog::GtkOpenWithDialog(
|
|||
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;
|
||||
bool result = true;
|
||||
|
||||
|
@ -101,24 +104,29 @@ void GtkOpenWithDialog::handleResponse(GtkOpenWithDialog *dialog, int responseId
|
|||
break;
|
||||
}
|
||||
|
||||
GtkOpenWithDialogResponseStream.fire_copy(result);
|
||||
delete dialog;
|
||||
dialog->_responseStream.fire_copy(result);
|
||||
}
|
||||
|
||||
} // 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 &filepath) {
|
||||
if (!Supported()) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new GtkOpenWithDialog(parent, filepath);
|
||||
}
|
||||
|
||||
rpl::producer<bool> GtkOpenWithDialogResponse() {
|
||||
return GtkOpenWithDialogResponseStream.events();
|
||||
return std::make_unique<GtkOpenWithDialog>(parent, filepath);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
|
|
@ -11,12 +11,30 @@ namespace Platform {
|
|||
namespace File {
|
||||
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 &filepath);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> GtkOpenWithDialogResponse();
|
||||
|
||||
} // namespace internal
|
||||
} // namespace File
|
||||
} // namespace Platform
|
||||
|
|
Loading…
Add table
Reference in a new issue