Qt+Cef integration on Linux

  • I'm trying to create Qt application with Cef browser working on Linux (Debian Wheezy)
    Versions: Qt 5.5, Cef 1547
    Basically, I have QWidget with following browser initialization code:

    CefwindowInfo info;
    QWindow* win = new QWindow();
    CefBrowserHost::CreateBrowser(info, ...);

    This code causes Segmentation fault exception with following callstack

    0> g_type_check_instance_cast
    1> CefBrowserHostImpl::PlatformCreateWindow()
    2> ??

    If I comment out the line with info.SetAsChild(..) , everything works as expected save that Cef is launched in separate window, while I need it to be integrated in my Qt application.

    Any ideas what am I doing wrong?

  • Qt Champions 2017

    You're probably passing a nullptr to the SetAsChild method. You should check that as a first step. Secondly, if you're dealing with widgets then the widget may not have a window handle at all (if it's a child to another widget) as Qt optimizes the number of handles used and only root-level widgets get a X window, although a handle should be created when the call is made. And lastly, depending on where you call this code (the snippet) Qt may have not yet created the handle (if at all).

    Kind regards.

  • Thank you, kshegunov, for you replies.
    SetAsChild receives valid handle. QWindow in Qt was designed specifically to be the point of integration between different windows. I'm running the code in debug mode, so no optimizations are applied. The above code itself is executed without exceptions. The problem happens somewhere inside CefDoMessageLoopWork() later.

  • Qt Champions 2017

    Just to be sure.
    Its not CefwindowInfo info;
    running out of scope?

  • No, mrjj, it is not "out-of-scope" issue. The problem is in some kind of validation of QWindow->winId() handle by gnome g_type_check_instance_cast. As if QWindow->winId() returns not the type of object expected by Cef. Should it be GtkWindow*?

  • Qt Champions 2017

    That could be as
    Seems to want a cef_window_handle_t and not the Wld (even u cast it)
    Its unclear if it wants one of its own windows or can accept platform "ID"

  • @mrjj, you've hit the point. The problem is to pass to SetAsChild() something it will be happy with... But what it is?

  • Qt Champions 2017

    Well is it make for linux?
    Really seems windows-ish for me using HWND and DWORD
    Also on the download page
    I see no linux?
    Of Course it works on linux too but if u check out the
    cef_window_handle_t ( right click and go to definition)
    is that also using DWORD and HWND or what is the internals in your version?

  • @mrjj
    Yes, it fully supports Linux. Moreover, it is even embeddable into Qt. But unfortunately there are no open examples.
    Here https://bitbucket.org/chromiumembedded/cef/src/master/tests/cefclient/cefclient_gtk.cc?at=master&fileviewer=file-view-default you could find an example how to do it with Gtk+. Now, I need to somehow connect Qt and Cef with or without Gtk+ intermediate layer.

  • Qt Champions 2017

    Ok, but since you are using the
    That will give you the native handle for a window for the display/deskop manager you are using. ( AFAIK)
    So if NOT gtk as your desktop, will it then work with Cef ?
    Are you on KDE or what linux ?

  • Qt Champions 2017

    @antofik said in Qt+Cef integration on Linux:

    The problem happens somewhere inside CefDoMessageLoopWork() later.

    Pull a trace out of that. And also bear in mind Qt very much dislikes sharing the (system) event loop with other things, so I'm still not convinced that integration is possible between these two libraries.

  • Actually, I've managed to make it work.
    Just in case, if someone will need it in future:

      GtkWidget* gtkWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      GtkWidget* parentView = gtk_vbox_new(FALSE, 0);
      GtkContainer* container = (GTK_CONTAINER(gtkWin));
      gtk_container_add(container, parentView);
      gtk_window_set_position(GTK_WINDOW(gtkWin), GTK_WIN_POS_CENTER);
      GdkWindow* w = gtk_widget_get_window(parentView);
      XID t = gdk_x11_drawable_get_xid(w);
      WId wid = (WId) t;
      QWindow* win = QWindow::fromWinId(wid);
      setLayout(new QGridLayout());
      QWidget* widget = QWidget::createWindowContainer(win);

    Basically, I've created my own GTK window, passed the reference on this window to CEF, and placed it into Qt widget using QWindow::fromWinId().

  • Qt Champions 2017

    So would it be fair to conclude that it really
    wants a gtk windows handle and not what ever comes out of
    winId() ?

  • Yes @mrjj, Cef is built on Gtk2, so it requires gtk handle, not the winId().

    Anyhow, it is possible to integrate Cef with Qt on linux, and that is what matters :-)

  • is there somewhere a more complete example of mixing qt/gtk/cef?

  • Qt Champions 2017

    Not that i have stumbled upon.
    Have you asked on the forum ?

    You cannot use http://doc.qt.io/qt-5/qtwebengine-index.html
    or webkit ?

  • @mrjj i am wondering if it can be done with cef due to (my) project restrictions ..
    I have found several git repos with qt+cef, but only for windows. Also i managed to combine gtk with cef successfully, but i cant find anything about qt+cef@linux (maybe because qt+gtk is not a happy combination?). The code snippet from @antofik does not build (gtkwidget with qwidget is it even possible) or i am missing something?

  • Qt Champions 2017

    Well mixing Gtk and Qt is pretty rare use case as far as I know. Both being Widgets libraries.
    And there is always the issue of the event loop.
    So as far as integration it will not be funny.

    @antofik sample wraps a gtk window using native Gtk calls +Qt and is apparently supported by
    createWindowContainer so in this case it works.

    I have not seen much info about this. sorry.

  • @mrjj thanks for your time+replies

  • Qt Champions 2017

    Just as a note.
    Webkit been revived

    So you might be able to use that?

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.