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