Original report by Maksim Sisov (Bitbucket: Maksim Sisov).
Hi Marshall,
I have already contacted you about Ozone/Wayland/X11 support via e-mail as you remember, but I think it’s better to move the discussion here.
As we discussed, Ozone/Wayland/X11 can only be used with views framework now, but it does not allow to embed host windows into client windows.
Whereas adding support for Ozone/X11 is trivial, the Ozone/Wayland requires some design changes. That is, you proposed to start with cefclient application and here is what I think: the cefclient has two main window classes - RootWindowGtk that uses the GTK toolkit to create windows and BrowserWindowStdGtk (I don’t take osr here as it does not look like there are any changes needed to make it work with Wayland as it is going to be the client hosting the top level window without any need to embed a CEF window into that).
The RootWindowGtk receives callback events from GTK (window state changes, focus changes, bounds changes and etc) and calls the BrowserWindowStdGtk to say it to make changes to a CEF native window. The BrowserWindowStdGtk may either call to the CEF native window through browser_->GetHost()->Blah() or through X11 native APIs like XChangeProperty, XConfigureWindow and etc.
The first approach (browser_->GetHost()->Blah()) results in calling the WindowX11, which then uses X11 native APIs to change own properties and the properties of its child window, which is a Chromium window (either via changing properties of the child window directly or via changing own properties first… and when ConfigureNotify or any other event comes, it does the same change via X11 native APIs for its child (chromium) window. Then, the chromium’s X11 window receives events from X11 and passes all core stuff for processing to PlatformWindowDelegate to aura/views/blink and etc…).
The second approach (through X11 native APIs) does pretty much the same except the fact that it's the client who uses X11 APIs to change properties of the CEF native window, which then receives X11 messages from the X server and does the same changes for it’s child via the same X11 APis.
I haven’t really checked mac or win and might be mistaken, but it seems like they do the same.
However, it is not the case for Wayland… And embedding will look different for that. I analyzed different approaches and it seems like wl_subsurface is the way to go.
In case of Wayland, clients should take a wl_surface that they created (either via gdk, native Wayland or qt toolkit or whatever) and a wl_display they used and pass them to CEF. Depending on whether a parent wl_surface is passed or not, the CEF either will create a toplevel window or a subsurface that it will parent with the passed parent wl_surface. Then, it will also pass own wl_surface that it created along with a wl_subsurface, which Chromium will use to associate own wl_subsurface with.
The mechanism, which X11 uses for property changes (XChangeProperty or XConfigureWindow) to manipulate the state of any X11 windows, won’t work with Wayland. Instead, a client will always manipulate the CEF browser window via browser_->GetHost()->DoSmth(Args…). However, one must realizethat the calls that manipulate the state of the window (such as SetBounds(), Hide(), Show() and etc) may not result in actual Wayland calls as a subsurface should be treated as an overlay above a parent surface that cannot be really hidden, shown or placed to some arbitrary area in respect to parent’s local coordinates. Instead, the state changes must be propagated through calls to views::Widget or whatever mechanism content api provides.
What do you think about that?
Original report by Maksim Sisov (Bitbucket: Maksim Sisov).
Hi Marshall,
I have already contacted you about Ozone/Wayland/X11 support via e-mail as you remember, but I think it’s better to move the discussion here.
As we discussed, Ozone/Wayland/X11 can only be used with views framework now, but it does not allow to embed host windows into client windows.
Whereas adding support for Ozone/X11 is trivial, the Ozone/Wayland requires some design changes. That is, you proposed to start with cefclient application and here is what I think: the cefclient has two main window classes - RootWindowGtk that uses the GTK toolkit to create windows and BrowserWindowStdGtk (I don’t take osr here as it does not look like there are any changes needed to make it work with Wayland as it is going to be the client hosting the top level window without any need to embed a CEF window into that).
The RootWindowGtk receives callback events from GTK (window state changes, focus changes, bounds changes and etc) and calls the BrowserWindowStdGtk to say it to make changes to a CEF native window. The BrowserWindowStdGtk may either call to the CEF native window through browser_->GetHost()->Blah() or through X11 native APIs like XChangeProperty, XConfigureWindow and etc.
The first approach (browser_->GetHost()->Blah()) results in calling the WindowX11, which then uses X11 native APIs to change own properties and the properties of its child window, which is a Chromium window (either via changing properties of the child window directly or via changing own properties first… and when ConfigureNotify or any other event comes, it does the same change via X11 native APIs for its child (chromium) window. Then, the chromium’s X11 window receives events from X11 and passes all core stuff for processing to PlatformWindowDelegate to aura/views/blink and etc…).
The second approach (through X11 native APIs) does pretty much the same except the fact that it's the client who uses X11 APIs to change properties of the CEF native window, which then receives X11 messages from the X server and does the same changes for it’s child via the same X11 APis.
I haven’t really checked mac or win and might be mistaken, but it seems like they do the same.
However, it is not the case for Wayland… And embedding will look different for that. I analyzed different approaches and it seems like wl_subsurface is the way to go.
In case of Wayland, clients should take a wl_surface that they created (either via gdk, native Wayland or qt toolkit or whatever) and a wl_display they used and pass them to CEF. Depending on whether a parent wl_surface is passed or not, the CEF either will create a toplevel window or a subsurface that it will parent with the passed parent wl_surface. Then, it will also pass own wl_surface that it created along with a wl_subsurface, which Chromium will use to associate own wl_subsurface with.
The mechanism, which X11 uses for property changes (XChangeProperty or XConfigureWindow) to manipulate the state of any X11 windows, won’t work with Wayland. Instead, a client will always manipulate the CEF browser window via browser_->GetHost()->DoSmth(Args…). However, one must realizethat the calls that manipulate the state of the window (such as SetBounds(), Hide(), Show() and etc) may not result in actual Wayland calls as a subsurface should be treated as an overlay above a parent surface that cannot be really hidden, shown or placed to some arbitrary area in respect to parent’s local coordinates. Instead, the state changes must be propagated through calls to views::Widget or whatever mechanism content api provides.
What do you think about that?