我从GitHub用户hokein的wxWidgets的这个分支开始,因为它似乎可以用旧版本的CEF实现我想要的功能。基本上,我尝试使用cef3.2526.1354实现wxWebViewChromium(一个使用CEF作为后端的wxWebView),因为这是我们希望在应用程序中使用的版本。我在使用Hyper-V的虚拟机中运行带有GNOME的CentOS 7。
来自上面链接的存储库的原始代码(webview_chrmium.cpp的一部分)
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
info.SetAsChild( view_port );
m_parent->DoAddChild( this );
PostCreation( size );
gtk_widget_show( view_port );
#endif
当我试图编译并将其与cef_3.2526.1354链接时,我收到了与info.SetAsChild(viewport);
行相关的错误。我给它传了一个GtkWidget*
,它正期待着cef_window_handle_t, CefRect
。
到目前为止我尝试了什么
我在GtkWidget* view_port
:的基础上创建了这样的CefRect
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
CEF库代码中的typedef表示cef_window_handle_t
是unsigned long
,但CEF文档中说它是GtkWidget*
。。。我想是一样的,但这导致了一些最初的困惑。起初,我认为我需要从底层X11窗口传递X11窗口id(XID),但这产生了一个运行时错误:
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
简单地将GtkWidget*
转换为unsigned long
而不是使用底层X11窗口ID就消除了这个错误,所以我认为这就是函数所期望的。
我当前的代码(webview_chromium.cpp的一部分)
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(
(unsigned long) view_port,
cef_rect
);
m_parent->DoAddChild( this );
PostCreation( size );
// gtk_widget_show(view_port);
gtk_widget_show_all(m_widget);
gtk_widget_show_all(view_port);
#endif
发生了什么
我能够编译、链接和运行应用程序。我可以看到wxWidgets窗口,我可以像任何普通窗口一样最小化、最大化、调整大小和关闭窗口。窗户里什么都没有——只是一扇普通的、灰色的、空荡荡的窗户。我期待(或希望)看到CEF浏览器。在我用来启动应用程序的终端中,我得到以下消息:
[0727/132200:ERROR:browser_main_loop.cc(203)] Running without SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with sandbox on.
此URL似乎不再有任何用处。如果我从命令行启动./cefclient --no-sandbox
,我会收到同样的错误消息,但CEF客户端可以正常工作。如果我从命令行启动./cefclient
(不禁用沙箱),我会得到同样的消息,只是它不是ERROR
,而是说FATAL
和CEF客户端不工作(完全崩溃)。
我的问题
我对webview_chromium.cpp
文件的修改有什么错误吗?在这个文件中,我是否还有其他地方应该查找可能需要更新的内容,以便使用cef_3.2526.1354?如何对我看到的这个空窗口进行故障排除?
谢谢!
更新
Czarek Tomczak告诉我,这个版本的CEF需要一个X11窗口句柄,所以我修改了我的代码如下。
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
gtk_widget_show_all(m_widget);
gtk_widget_show_all(view_port);
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(
gdk_x11_drawable_get_xid(gtk_widget_get_window(view_port)),
cef_rect
);
m_parent->DoAddChild( this );
PostCreation( size );
#endif
但这仍然导致下面的运行时错误,输出的空白窗口与以前相同。
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
如果能为我指明正确的方向,我们将不胜感激。我还尝试在这里创建一个实际的GtkWindow,而不是一个带视口的滚动窗口。这消除了上面的运行时错误,但它打开了第二个窗口,这两个窗口都是空白的。我需要所有这些在一个窗口内工作。
更新2
在Czarek Tomczak、他发布的链接和这个常见问题解答的帮助下,我已经到了可以将CEF浏览器嵌入GtkWidget的地步,但只有当我将该小部件创建为顶级GTK窗口时,我才能做到这一点:
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
其中m_widget
是我试图创建的wxWebView的主要小部件。这个问题是,现在CEF浏览器出现在它自己的GTK窗口中,但我真正需要的是让CEF浏览器适应我正在添加wxWebViewChromium小部件的wxBoxSizer
。为了实现这一点,我将Create方法中的一些代码拆分到OnSize方法中,这样我就可以在GtkWidget实现后获得GtkWidWidget的XID,并在此之后创建CEF浏览器。OnSize方法连接到wxEVT_SIZE
。我的代码如下。
Create
方法的更新部分
// Actual creation of CEF browser moved to OnSize function so we
// can guarantee the widgets have been realized
this->Bind(wxEVT_SIZE, &wxWebViewChromium::OnSize, this);
// Works but as a top-level GTK window only
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// None of these work
//m_widget = gtk_drawing_area_new();
//m_widget = gtk_vbox_new(false, 0);
g_object_ref( m_widget );
OnSize
方法的更新部分
if (!cef_browser_created)
{
cef_browser_created = true;
CefBrowserSettings browsersettings;
CefWindowInfo info;
XSetErrorHandler(XErrorHandlerImpl);
XSetIOErrorHandler(XIOErrorHandlerImpl);
gtk_widget_realize(m_widget);
::Window xwindow = GTK_WINDOW_XID(gtk_widget_get_window(m_widget));
DCHECK(xwindow);
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(m_widget, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(xwindow, cef_rect);
m_parent->DoAddChild( this );
PostCreation( size );
CefBrowserHost::CreateBrowserSync(
info,
static_cast<CefRefPtr<CefClient> >(m_clientHandler),
create_url.ToStdString(),
browsersettings,
NULL
);
}
当我试图使m_widget
成为顶级GTK小部件之外的其他部件时(如上面Create
方法的代码注释部分所示),我在运行时会得到以下错误。
Gtk: IA__gtk_widget_realize: assertion 'GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Check failed: xwindow.
如何使此窗口显示在我的wxBoxSizer中,而不是作为它自己的GTK顶级窗口?
CEF需要X11窗口句柄。GtkWidget句柄在以前的CEF版本中是必需的。那个wiki页面上的文档似乎已经过时了。在将X11句柄传递给CEF之前,请确保它是有效的(显示窗口)。
我只能建议看看如何在cefclient示例应用程序中创建GTK窗口:
https://bitbucket.org/chromiumembedded/cef/src/98f59f47fd395c170f389eba36f2ef2e06a500a8/tests/cefclient/browser/root_window_gtk.cc?at=master&fileviewer=文件视图默认#root_window_gtk.cc-233
还可以看看CreateBrowser()-它使用GetXWindowForWidget():
https://bitbucket.org/chromiumembedded/cef/src/98f59f47fd395c170f389eba36f2ef2e06a500a8/tests/cefclient/browser/browser_window_std_gtk.cc?at=master&fileviewer=文件视图默认值#browser_window_std_gtk.cc-91