New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTK+ 3.22 Port #9

Closed
fenryxo opened this Issue Nov 11, 2017 · 18 comments

Comments

Projects
None yet
2 participants
@fenryxo
Contributor

fenryxo commented Nov 11, 2017

gcc -std=c99 -Wall -Werror -o Release/cefcapi.out -I. -I.. -Wl,-rpath,. -L./Release examples/main_linux.c -lX11 -lcef `pkg-config --libs --cflags gtk+-3.0`
cd Release/ && ./cefcapi.out && cd ../

Process args: none (Main process)

initialize_cef_app
initialize_cef_base_ref_counted
cef_base_ref_counted_t.size = 72
cef_execute_process, argc=1
cef_base_ref_counted_t.add_ref
cef_base_ref_counted_t.release
cef_initialize
on_before_command_line_processing
on_register_custom_schemes
get_browser_process_handler

Process args: --type=zygote --no-sandbox --lang=en-US --log-file=/home/fenryxo/dev/projects/cef/cefcapi/Release/debug.log --log-severity=warning 

initialize_cef_app
initialize_cef_base_ref_counted
cef_base_ref_counted_t.size = 72
cef_execute_process, argc=6
cef_base_ref_counted_t.add_ref
cef_base_ref_counted_t.release
on_before_command_line_processing
on_register_custom_schemes
get_resource_bundle_handler
initialize_gtk
[1111/165611.209405:ERROR:nss_util.cc(747)] After loading Root Certs, loaded==false: NSS error code: -8018
create_gtk_window
initialize_client_handler
initialize_cef_base_ref_counted
cef_base_ref_counted_t.size = 152
cef_browser_host_create_browser
cef_run_message_loop
X11 error: type=0, serial=200, code=8
X11 error: type=0, serial=202, code=3
X11 error: type=0, serial=203, code=3
X11 error: type=0, serial=204, code=3
X11 error: type=0, serial=205, code=3
X11 error: type=0, serial=206, code=3
X11 error: type=0, serial=207, code=3
X11 error: type=0, serial=208, code=3
X11 error: type=0, serial=219, code=3
X11 error: type=0, serial=221, code=3
X11 error: type=0, serial=222, code=3
X11 error: type=0, serial=223, code=3
X11 error: type=0, serial=224, code=3
X11 error: type=0, serial=228, code=3
X11 error: type=0, serial=229, code=3
Segmentation fault

It would be great if we managed to make CEF work with GTK+ 3. I'm afraid I don't have enough experience with CEF to do it on my own.

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 11, 2017

Owner

Do these x11 errors also appear when using GTK 2?
Looks like window handle may be invalid. Make sure that the GTK window is realized and that xid is valid.

Owner

cztomczak commented Nov 11, 2017

Do these x11 errors also appear when using GTK 2?
Looks like window handle may be invalid. Make sure that the GTK window is realized and that xid is valid.

@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Nov 11, 2017

Contributor

Do these x11 errors also appear when using GTK 2?

No, only with GTK+ 3.

Looks like window handle may be invalid. Make sure that the GTK window is realized and that xid is valid.

The window handle is valid. The window is realized in examples/gtk.h:58. Also, the very first error is BadMatch (8), not BadWindow (3).

Contributor

fenryxo commented Nov 11, 2017

Do these x11 errors also appear when using GTK 2?

No, only with GTK+ 3.

Looks like window handle may be invalid. Make sure that the GTK window is realized and that xid is valid.

The window handle is valid. The window is realized in examples/gtk.h:58. Also, the very first error is BadMatch (8), not BadWindow (3).

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 11, 2017

Owner

You can set parent window to NULL and CEF will create a window of its own such case. Set here NULL instead of xid:

window_info.parent_window = NULL;

Does it work then?

Owner

cztomczak commented Nov 11, 2017

You can set parent window to NULL and CEF will create a window of its own such case. Set here NULL instead of xid:

window_info.parent_window = NULL;

Does it work then?

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 11, 2017

Owner

Take a look at hello world examples for GTK 3. Things might work a bit differently there. See for example here: https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
Window is being created during "activate" event. In CEF Python gtk3 example works fine and has a similar structure as official GTK 3 examples, window is created in "startup" event and realized/shown in "activate" event along with embedding of browser.

Owner

cztomczak commented Nov 11, 2017

Take a look at hello world examples for GTK 3. Things might work a bit differently there. See for example here: https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
Window is being created during "activate" event. In CEF Python gtk3 example works fine and has a similar structure as official GTK 3 examples, window is created in "startup" event and realized/shown in "activate" event along with embedding of browser.

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Nov 11, 2017

Contributor

The result is the same with the GTK+ 3 Hello World exmaple. Both the original and the new example

  • crash with X errors when a valid xid is passed - the printed xid is not zero and I can see the window on the screen if I delay cef_do_message_loop_work().
  • show an extra fully functional CEF window when 0 is passed as window_info.parent_window.

So, for whatever reason, CEF seems not to like a valid window id.

Cefpython uses C++ API and its window_info.SetAsChild(xid) method. I'm wondering whether this method does something extra except for setting window_info members.

Contributor

fenryxo commented Nov 11, 2017

The result is the same with the GTK+ 3 Hello World exmaple. Both the original and the new example

  • crash with X errors when a valid xid is passed - the printed xid is not zero and I can see the window on the screen if I delay cef_do_message_loop_work().
  • show an extra fully functional CEF window when 0 is passed as window_info.parent_window.

So, for whatever reason, CEF seems not to like a valid window id.

Cefpython uses C++ API and its window_info.SetAsChild(xid) method. I'm wondering whether this method does something extra except for setting window_info members.

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 12, 2017

Owner

What OS and gtk3 version are you using?

Owner

cztomczak commented Nov 12, 2017

What OS and gtk3 version are you using?

@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Nov 12, 2017

Contributor

Debian 9 Stretch, GTK+ 3.22.11.

Contributor

fenryxo commented Nov 12, 2017

Debian 9 Stretch, GTK+ 3.22.11.

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 12, 2017

Owner

Can you try with GTK 3.10?

Owner

cztomczak commented Nov 12, 2017

Can you try with GTK 3.10?

@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Nov 12, 2017

Contributor

Can you try with GTK 3.10?

Sure, I need to download Ubuntu 14.04 first.

Anyway, there are some experiments I tried yesterday.

Tracebacks from gdb:

Both logs contain

XSync
CefWindowX11::CefWindowX11 w 85983235, x 0, y 0, w 800, h 600 => 81788929
XSync

which comes from my modifications of CefWindowX11::CefWindowX11() (libcef/browser/native/window_x11.cc)

...
XSync(xdisplay_, 0);
printf("XSync\n");
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
swa.background_pixmap = None;
swa.override_redirect = false;
xwindow_ = XCreateWindow(xdisplay_, parent_xwindow_, bounds.x(), bounds.y(),
                           bounds.width(), bounds.height(),
                           0,               // border width
                           CopyFromParent,  // depth
                           InputOutput,
                           CopyFromParent,  // visual
                           CWBackPixmap | CWOverrideRedirect, &swa);
printf("CefWindowX11::CefWindowX11 w %u, x %d, y %d, w %u, h %u => %u\n",
(unsigned) parent_xwindow_,
bounds.x(), bounds.y(), bounds.width(), bounds.height(), (unsigned) xwindow_);
XSync(xdisplay_, 0);
printf("XSync\n");
...

and that means that the very first child window of the passed parent window has been created without any issues (no X errors emitted).

Contributor

fenryxo commented Nov 12, 2017

Can you try with GTK 3.10?

Sure, I need to download Ubuntu 14.04 first.

Anyway, there are some experiments I tried yesterday.

Tracebacks from gdb:

Both logs contain

XSync
CefWindowX11::CefWindowX11 w 85983235, x 0, y 0, w 800, h 600 => 81788929
XSync

which comes from my modifications of CefWindowX11::CefWindowX11() (libcef/browser/native/window_x11.cc)

...
XSync(xdisplay_, 0);
printf("XSync\n");
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
swa.background_pixmap = None;
swa.override_redirect = false;
xwindow_ = XCreateWindow(xdisplay_, parent_xwindow_, bounds.x(), bounds.y(),
                           bounds.width(), bounds.height(),
                           0,               // border width
                           CopyFromParent,  // depth
                           InputOutput,
                           CopyFromParent,  // visual
                           CWBackPixmap | CWOverrideRedirect, &swa);
printf("CefWindowX11::CefWindowX11 w %u, x %d, y %d, w %u, h %u => %u\n",
(unsigned) parent_xwindow_,
bounds.x(), bounds.y(), bounds.width(), bounds.height(), (unsigned) xwindow_);
XSync(xdisplay_, 0);
printf("XSync\n");
...

and that means that the very first child window of the passed parent window has been created without any issues (no X errors emitted).

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Nov 12, 2017

Owner

Looks to me there is an issue with embedding with newer GTK / XLib. Try these to workaround the issue:

  1. Try a different gtk widget structure. For example create GTK container in the window and embed CEF inside that container, see gtk_container_add.
  2. Call gtk_plug_new(xid) before embedding CEF
  3. Set window_info.parent_window to NULL and then after CEF is embedded reparent windows (using maybe XReparentWindow).
Owner

cztomczak commented Nov 12, 2017

Looks to me there is an issue with embedding with newer GTK / XLib. Try these to workaround the issue:

  1. Try a different gtk widget structure. For example create GTK container in the window and embed CEF inside that container, see gtk_container_add.
  2. Call gtk_plug_new(xid) before embedding CEF
  3. Set window_info.parent_window to NULL and then after CEF is embedded reparent windows (using maybe XReparentWindow).
@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Nov 19, 2017

Contributor

Can you try with GTK 3.10?

Sure, I need to download Ubuntu 14.04 first.

It indeed does work with GTK+ 3.10.8-0ubuntu1.6 (Ubuntu 14.04). I'll now go up from 3.10 to find the first GTK+ release that does not work. I hope I will then understand the issue better and will try the suggested workarounds. Thanks for your tips.

Contributor

fenryxo commented Nov 19, 2017

Can you try with GTK 3.10?

Sure, I need to download Ubuntu 14.04 first.

It indeed does work with GTK+ 3.10.8-0ubuntu1.6 (Ubuntu 14.04). I'll now go up from 3.10 to find the first GTK+ release that does not work. I hope I will then understand the issue better and will try the suggested workarounds. Thanks for your tips.

@fenryxo fenryxo changed the title from GTK+ 3 Port to GTK+ 3.22 Port Nov 19, 2017

@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Dec 3, 2017

Contributor

@cztomczak, I've identified the very first failing revision - GNOME/gtk@dae4477 between GTK+ 3.15.1 and 3.15.2. GTK+ changed the selection of default window visuals (need to study more what that means) and I guess that CEF uses incompatible visuals somewhere (hence the BadMatch X error).

Contributor

fenryxo commented Dec 3, 2017

@cztomczak, I've identified the very first failing revision - GNOME/gtk@dae4477 between GTK+ 3.15.1 and 3.15.2. GTK+ changed the selection of default window visuals (need to study more what that means) and I guess that CEF uses incompatible visuals somewhere (hence the BadMatch X error).

@cztomczak

This comment has been minimized.

Show comment
Hide comment
@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Dec 5, 2017

Contributor
  • Disabling GPU does not help.
  • But using the default X visual instead of the GTK+'s blessed one works (at least with GTK+ revid dae447728d and 3.22.11):
GtkWidget* create_gtk_window(char* title, int width, int height) {
    printf("create_gtk_window\n");
    // Create window.
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    ...
    // GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
    // since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
    // However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9
    // Let's use the default X11 visual instead the GTK's blessed one.
    GdkScreen* screen = gdk_screen_get_default();
    GList* visuals = gdk_screen_list_visuals(screen);
    printf("n visuals: %u\n", g_list_length(visuals));
    GdkX11Screen* x11_screen = GDK_X11_SCREEN(screen);
    g_assert(x11_screen != NULL);
    Visual* default_xvisual = DefaultVisual(GDK_SCREEN_XDISPLAY(x11_screen),
        GDK_SCREEN_XNUMBER(x11_screen));
    GdkVisual* default_visual = NULL;
    int i = 0;
    while (visuals != NULL) {
	GdkVisual* visual = GDK_X11_VISUAL (visuals->data);
        if (default_xvisual->visualid == gdk_x11_visual_get_xvisual(
           GDK_X11_VISUAL (visuals->data))->visualid) {
           printf("Default visual %d\n", i);
           default_visual = visual;
        }
        i++;
        visuals = visuals->next;
    }
    gtk_widget_set_visual(GTK_WIDGET(window), default_visual);
    gtk_widget_show_all(window);
    return vbox;
}
  • I'm going to prepare pull requests to add a working GTK+ 3 example here.
Contributor

fenryxo commented Dec 5, 2017

  • Disabling GPU does not help.
  • But using the default X visual instead of the GTK+'s blessed one works (at least with GTK+ revid dae447728d and 3.22.11):
GtkWidget* create_gtk_window(char* title, int width, int height) {
    printf("create_gtk_window\n");
    // Create window.
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    ...
    // GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
    // since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
    // However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9
    // Let's use the default X11 visual instead the GTK's blessed one.
    GdkScreen* screen = gdk_screen_get_default();
    GList* visuals = gdk_screen_list_visuals(screen);
    printf("n visuals: %u\n", g_list_length(visuals));
    GdkX11Screen* x11_screen = GDK_X11_SCREEN(screen);
    g_assert(x11_screen != NULL);
    Visual* default_xvisual = DefaultVisual(GDK_SCREEN_XDISPLAY(x11_screen),
        GDK_SCREEN_XNUMBER(x11_screen));
    GdkVisual* default_visual = NULL;
    int i = 0;
    while (visuals != NULL) {
	GdkVisual* visual = GDK_X11_VISUAL (visuals->data);
        if (default_xvisual->visualid == gdk_x11_visual_get_xvisual(
           GDK_X11_VISUAL (visuals->data))->visualid) {
           printf("Default visual %d\n", i);
           default_visual = visual;
        }
        i++;
        visuals = visuals->next;
    }
    gtk_widget_set_visual(GTK_WIDGET(window), default_visual);
    gtk_widget_show_all(window);
    return vbox;
}
  • I'm going to prepare pull requests to add a working GTK+ 3 example here.
@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Dec 5, 2017

Contributor

So, I'm proposing following changes. Should I submit them as 5 separate pull requests or combine them somewhow?

  1. Update CEF headers to the latest stable CEF.
  2. Add some useful debug info (window xid, GTK version).
  3. Add a gtk3 target to the linux Makefile and modify the linux example to be buildable with both GTK+ 2 & 3 (using GTK_CHECK_VERSION macro).
  4. Add the X11 visual workaround for the GTK+ 3 example.
  5. Add a "modern" GTK+ 3 example that uses GtkApplication stuff.
Contributor

fenryxo commented Dec 5, 2017

So, I'm proposing following changes. Should I submit them as 5 separate pull requests or combine them somewhow?

  1. Update CEF headers to the latest stable CEF.
  2. Add some useful debug info (window xid, GTK version).
  3. Add a gtk3 target to the linux Makefile and modify the linux example to be buildable with both GTK+ 2 & 3 (using GTK_CHECK_VERSION macro).
  4. Add the X11 visual workaround for the GTK+ 3 example.
  5. Add a "modern" GTK+ 3 example that uses GtkApplication stuff.
@cztomczak

This comment has been minimized.

Show comment
Hide comment
@cztomczak

cztomczak Dec 5, 2017

Owner

Great progress Fenryxo! Updating CEF should be a separate PR. Others changes I would divide into two PRs: update old example + add new example.

Owner

cztomczak commented Dec 5, 2017

Great progress Fenryxo! Updating CEF should be a separate PR. Others changes I would divide into two PRs: update old example + add new example.

@fenryxo

This comment has been minimized.

Show comment
Hide comment
@fenryxo

fenryxo Dec 6, 2017

Contributor
  1. Add a "modern" GTK+ 3 example that uses GtkApplication stuff.

This can be made later. Closing as the main issue has been addressed.

Contributor

fenryxo commented Dec 6, 2017

  1. Add a "modern" GTK+ 3 example that uses GtkApplication stuff.

This can be made later. Closing as the main issue has been addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment