Linux: cefclient: Fix GTK behavior with multi-threaded-message-loop (fixes issue #3087)
Switch to using g_main_context_default() in MainMessageLoopMultithreadedGtk. As of M86 (https://crrev.com/b960daf4e6) Chromium now creates its own context in MessagePumpGlib so we can use the default context in cefclient. This is also more "correct" from a GTK usage perspective. As part of this change all GTK dialogs and callbacks are now executed on the main thread instead of the UI thread (note that these are the same thread when not using multi-threaded-message-loop).
This commit is contained in:
parent
7fe6a18f03
commit
b3ad79e2c5
|
@ -143,10 +143,6 @@ GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void RunCallback(base::Callback<void(GtkWindow*)> callback, GtkWindow* window) {
|
||||
callback.Run(window);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ClientDialogHandlerGtk::ClientDialogHandlerGtk() : gtk_dialog_(nullptr) {}
|
||||
|
@ -227,7 +223,7 @@ void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
|
|||
|
||||
void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
GtkWindow* window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
ScopedGdkThreadsEnter scoped_gdk_threads;
|
||||
|
||||
|
@ -367,7 +363,7 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
|||
|
||||
void ClientDialogHandlerGtk::OnJSDialogContinue(OnJSDialogParams params,
|
||||
GtkWindow* window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
ScopedGdkThreadsEnter scoped_gdk_threads;
|
||||
|
||||
|
@ -443,7 +439,7 @@ void ClientDialogHandlerGtk::GetWindowAndContinue(
|
|||
|
||||
GtkWindow* window = GetWindow(browser);
|
||||
if (window) {
|
||||
CefPostTask(TID_UI, base::Bind(RunCallback, callback, window));
|
||||
callback.Run(window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +447,7 @@ void ClientDialogHandlerGtk::GetWindowAndContinue(
|
|||
void ClientDialogHandlerGtk::OnDialogResponse(GtkDialog* dialog,
|
||||
gint response_id,
|
||||
ClientDialogHandlerGtk* handler) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
DCHECK_EQ(dialog, GTK_DIALOG(handler->gtk_dialog_));
|
||||
switch (response_id) {
|
||||
|
@ -466,7 +462,8 @@ void ClientDialogHandlerGtk::OnDialogResponse(GtkDialog* dialog,
|
|||
NOTREACHED();
|
||||
}
|
||||
|
||||
handler->OnResetDialogState(nullptr);
|
||||
CefPostTask(TID_UI, base::Bind(&ClientDialogHandlerGtk::OnResetDialogState,
|
||||
handler, nullptr));
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -78,10 +78,9 @@ MainMessageLoopMultithreadedGtk::~MainMessageLoopMultithreadedGtk() {
|
|||
int MainMessageLoopMultithreadedGtk::Run() {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
|
||||
// Chromium uses the default GLib context so we create our own context and
|
||||
// make it the default for this thread.
|
||||
main_context_ = g_main_context_new();
|
||||
g_main_context_push_thread_default(main_context_);
|
||||
// We use the default Glib context and Chromium creates its own context in
|
||||
// MessagePumpGlib (starting in M86).
|
||||
main_context_ = g_main_context_default();
|
||||
|
||||
main_loop_ = g_main_loop_new(main_context_, TRUE);
|
||||
|
||||
|
@ -100,8 +99,6 @@ int MainMessageLoopMultithreadedGtk::Run() {
|
|||
g_main_loop_unref(main_loop_);
|
||||
main_loop_ = nullptr;
|
||||
|
||||
g_main_context_pop_thread_default(main_context_);
|
||||
g_main_context_unref(main_context_);
|
||||
main_context_ = nullptr;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -94,13 +94,9 @@ void RootWindowGtk::Init(RootWindow::Delegate* delegate,
|
|||
|
||||
initialized_ = true;
|
||||
|
||||
// Create the native root window on the main thread.
|
||||
if (CURRENTLY_ON_MAIN_THREAD()) {
|
||||
CreateRootWindow(settings, config.initially_hidden);
|
||||
} else {
|
||||
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::CreateRootWindow, this,
|
||||
settings, config.initially_hidden));
|
||||
}
|
||||
// Always post asynchronously to avoid reentrancy of the GDK lock.
|
||||
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::CreateRootWindow, this, settings,
|
||||
config.initially_hidden));
|
||||
}
|
||||
|
||||
void RootWindowGtk::InitAsPopup(RootWindow::Delegate* delegate,
|
||||
|
@ -682,7 +678,7 @@ void RootWindowGtk::NotifyDestroyedIfDone(bool window_destroyed,
|
|||
gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (event->in) {
|
||||
self->NotifySetFocus();
|
||||
|
@ -698,7 +694,7 @@ gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
|
|||
gboolean RootWindowGtk::WindowState(GtkWidget* widget,
|
||||
GdkEventWindowState* event,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Called when the root window is iconified or restored. Hide the browser
|
||||
// window when the root window is iconified to reduce resource usage.
|
||||
|
@ -714,7 +710,7 @@ gboolean RootWindowGtk::WindowState(GtkWidget* widget,
|
|||
gboolean RootWindowGtk::WindowConfigure(GtkWindow* window,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
self->NotifyMoveOrResizeStarted();
|
||||
return FALSE; // Don't stop this message.
|
||||
}
|
||||
|
@ -729,7 +725,7 @@ void RootWindowGtk::WindowDestroy(GtkWidget* widget, RootWindowGtk* self) {
|
|||
gboolean RootWindowGtk::WindowDelete(GtkWidget* widget,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Called to query whether the root window should be closed.
|
||||
if (self->force_close_)
|
||||
|
@ -769,7 +765,7 @@ void RootWindowGtk::MenubarSizeAllocated(GtkWidget* widget,
|
|||
// static
|
||||
gboolean RootWindowGtk::MenuItemActivated(GtkWidget* widget,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Retrieve the menu ID set in AddMenuEntry.
|
||||
int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), kMenuIdKey));
|
||||
|
@ -787,33 +783,33 @@ void RootWindowGtk::ToolbarSizeAllocated(GtkWidget* widget,
|
|||
|
||||
// static
|
||||
void RootWindowGtk::BackButtonClicked(GtkButton* button, RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
self->NotifyButtonClicked(IDC_NAV_BACK);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::ForwardButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
self->NotifyButtonClicked(IDC_NAV_FORWARD);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::StopButtonClicked(GtkButton* button, RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
self->NotifyButtonClicked(IDC_NAV_STOP);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::ReloadButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
self->NotifyButtonClicked(IDC_NAV_RELOAD);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::URLEntryActivate(GtkEntry* entry, RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
const gchar* url = gtk_entry_get_text(entry);
|
||||
self->NotifyLoadURL(std::string(url));
|
||||
}
|
||||
|
@ -822,7 +818,7 @@ void RootWindowGtk::URLEntryActivate(GtkEntry* entry, RootWindowGtk* self) {
|
|||
gboolean RootWindowGtk::URLEntryButtonPress(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
RootWindowGtk* self) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Give focus to the GTK window. This is a work-around for bad focus-related
|
||||
// interaction between the root window managed by GTK and the browser managed
|
||||
|
|
Loading…
Reference in New Issue