gtk4 删除了以下的阻塞行为GtkDialogs
:
int res = gtk_dialog_run(GTK_DIALOG(dialog));
建议的替代方法是使对话框模态并连接"response"
信号。但这有一个很大的缺点:一些旧代码库具有线性和确定性的 CFG。仅更改调用和处理所有对话框的方式会导致这样一个事实,即如果在外部范围中预期对话的处理,则离开范围后代码可能是错误的。
为了避免这种情况,我使用了std::promise
,std::future
但这会阻止 gtk-event 循环:/。
我提出的解决方案是,“加入” gtk-event-loop,直到结果准备好。这将具有两种方法的优点:“不要停止世界”/处理事件循环并保持线性 CFG。但它有一个缺点,即在递归调用连接时可能导致堆栈溢出或饥饿。
建议/搜索解决方案的伪代码:
auto future_result = generate_future_for_dialog_result(dialog);
while(!future_result.isDone()){
g_join();
}
我的第一个不工作的方法:
auto wait_for_gtk_dialog_result =
[](GtkDialog* dialog) {
std::promise<int> promise;
auto future = promise.get_future();
g_signal_connect(dialog, "result",
GCallback(+[](GtkDialog* /*self*/, int result, std::promise<int>* promise) {
promise->set_value(result);
}),
&promise);
return future.get();
};
有加入事件循环的功能吗?
如果不; 有没有实现类似的好选择?
编辑:在文档中找到了一种有前途的方法:查看g_main_context_iteration
.
auto wait_for_gtk_dialog_result =
[](GtkDialog* dialog) {
std::promise<int> promise;
auto future = promise.get_future();
g_signal_connect(dialog, "result",
GCallback(+[](GtkDialog* /*self*/, int result, std::promise<int>* promise) {
promise->set_value(result);
}),
&promise);
do {
g_main_context_iteration(g_main_context_default(), false);
} while (future.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready);
return future.get();
};