{"id":211,"date":"2017-05-17T09:26:45","date_gmt":"2017-05-17T13:26:45","guid":{"rendered":"http:\/\/blogs.igalia.com\/tonikitoo\/?p=211"},"modified":"2017-05-19T15:15:24","modified_gmt":"2017-05-19T19:15:24","slug":"chromium-musozone-update-h12017-wayland-x11","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/tonikitoo\/2017\/05\/17\/chromium-musozone-update-h12017-wayland-x11\/","title":{"rendered":"Chromium Mus\/Ozone update (H1\/2017): wayland, x11"},"content":{"rendered":"<p>Since January, <a href=\"https:\/\/www.igalia.com\">Igalia<\/a> has been working on a project whose goal is to make the latest <a href=\"http:\/\/www.chromium.org\">Chromium Browser<\/a> able to run natively on Wayland-based environments. The project has various phases, requires us to carve out existing implementations and align our work with the direction Chromium&#8217;s mainline is taking.<\/p>\n<p>In this post I will provide an update on the progresses we have made over 2017\/H1, as well as our plans coming next.<\/p>\n<p>In order to jump straight to the latest results section (including videos) without the details, click <a href=\"#status\">here<\/a>.<\/p>\n<h4>Background<\/h4>\n<p>In 2016\/Q4, my fellow Igalian <a href=\"http:\/\/frederic-wang.fr\/\">Fr\u00e9d\u00e9ric Wang<\/a> and I ran a warm-up project to check the status of the existing <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ui\/ozone\/platform\/wayland\/\">Wayland support in Chromium&#8217;s mainline repository<\/a>, and estimate how much work was needed to get the full (and latest) Chromium browser running on Wayland.<\/p>\n<p>As part of this warm-up we <a href=\"https:\/\/codereview.chromium.org\/2408803002\/\">were<\/a> <a href=\"https:\/\/codereview.chromium.org\/2462423002\/\">able<\/a> to <a href=\"https:\/\/codereview.chromium.org\/2449103004\/\">build<\/a> <a href=\"https:\/\/codereview.chromium.org\/2457443004\/\">and<\/a> <a href=\"https:\/\/codereview.chromium.org\/2452063002\/\">launch<\/a> ChromeOS&#8217;s Chrome for both desktop and <a href=\"http:\/\/frederic-wang.fr\/chromium-on-r-car-m3.html\">embedded<\/a> Linux distributions, featuring either X11 or Wayland. <a href=\"https:\/\/www.automotivelinux.org\/\">Automotive Grade Linux<\/a>  running on the <a href=\"https:\/\/www.renesas.com\/en-us\/solutions\/automotive\/products\/rcar-m3.html\">Renesas&#8217; R-car M3<\/a> board is an example of the embedded environments we tested.<\/p>\n<figure style=\"width: 580px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/chrome_mash_ozone_wayland_non-chromeos-oct10-580x435.png\" width=\"435\" height=\"325\" alt=\"Mus+ash on LinuxOS (Nov\/2016).\" class=\"size-medium\" \/><figcaption class=\"wp-caption-text\">Mus+ash on LinuxOS (Nov\/2016)<\/figcaption><\/figure>\n<p>Although this was obviously not our end goal (some undesirable ChromeOS widgets were visible at the bottom), it allowed us to verify the overall performance of the build, and experiment with things a bit. Here is a brief summary of the most relevant findings:<\/p>\n<ul>\n<li>There is an ongoing effort to reimplement the Ash (aka &#8220;cash&#8221; or classic Ash) Window Manager on top of the new <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/\">UI Service<\/a> (aka Mus). It is the so called <a href=\"https:\/\/www.chromium.org\/developers\/mus-ash\">mus+ash project<\/a>, a <a href=\"https:\/\/www.chromium.org\/chromium-os\">ChromeOS<\/a> oriented effort that is the continuation of <a href=\"https:\/\/www.chromium.org\/developers\/mandoline\">Mandoline project<\/a>.<\/p>\n<\/li>\n<li>\n<p>It is possible to build <em>mus+ash<\/em> for various platforms including Linux, ChromeOS and Windows. On Linux specifically, it is possible to make off-device ChromeOS builds of <em>mus+ash<\/em>, and run it on desktop Linux for testing purposes. A more minimalistic Window Manager version is also available in \/\/mash\/simple_wm, and should run on regular Linux builds too.<\/p>\n<\/li>\n<li>\n<p><em>mus+ash<\/em> can be built with <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src\/+\/master\/docs\/ozone_overview.md\">Ozone<\/a> enabled. This means that it can run with the various backends Ozone has. It is worth saying that the upstream focus seems to be the <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ui\/ozone\/platform\/drm\/\">Ozone\/DRM-GBM<\/a> backend, for ChromeOS.<\/p>\n<\/li>\n<li>\n<p>Ozone itself has morphed over time from an abstraction layer underneath the <a href=\"https:\/\/www.chromium.org\/developers\/design-documents\/aura\">Aura toolkit<\/a>, to be a layer underneath Mus.<\/p>\n<\/li>\n<\/ul>\n<p>Last, we could publish some worth reading content:<\/p>\n<ul>\n<li><a href=\"http:\/\/frederic-wang.fr\/analysis-of-ozone-wayland.html\">Analysis of Ozone\/Wayland<\/a> &#8211; by <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/fwang\/\">fwang<\/a>.<\/li>\n<li><a href=\"https:\/\/blogs.igalia.com\/tonikitoo\/2016\/11\/14\/chromium-ozone-wayland-and-beyond\/\">Chromium, Ozone, Wayland and beyond<\/a> &#8211; by <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/agomes\/\">tonikitoo<\/a>.<\/li>\n<li><a href=\"http:\/\/frederic-wang.fr\/chromium-on-r-car-m3.html\">Chromium on R-car M3 (Renesas) board<\/a> &#8211; by <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/fwang\/\">fwang<\/a>.<\/li>\n<li><a href=\"http:\/\/frederic-wang.fr\/mus-window-system.html\">Mus window system<\/a> &#8211; by <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/fwang\/\">fwang<\/a>.<\/li>\n<\/ul>\n<h4>2017 developments<\/h4>\n<p>At the beginning of this new phase of the project, we knew we needed to work on two different levels, in order to have the Chromium browser running on desktop Linux, ideally without functionality losses if compared against the stock Chromium browser on X11: both <em>Mus<\/em> and <em>Ozone<\/em> needed to support &#8216;external window&#8217; mode.<\/p>\n<p>For the sake of completeness, the term <em>external window mode<\/em> above is the terminology we chose to represent a regular desktop application on Linux, where the host Window Manager takes care of windowing actions like <em>maximize<\/em>, <em>minimize<\/em>, <em>restore<\/em> and <em>fullscreen<\/em> the application window. Also, the application itself reacts to content size changes accordingly. Analogously, when we say an application runs in <em>internal window mode<\/em>, it runs within the (M)ash shell environment, the builtin Window Manager that powers ChromeOS builds. Applications in this mode do not interact with the host WM.<\/p>\n<p>A huge pro about how <em>mus+ash<\/em> is being implemented is that the Chrome browser itself already works as it ought to in non-ChromeOS Mus-based environments: either we are running Mus in internal or external window modes, Chrome will work just like Chrome for a Linux desktop ought to.<\/p>\n<p>That being said, we identified the following set of tasks, on both Ozone and Mus sides.<\/p>\n<p><strong>Ozone tasks<\/strong>:<\/p>\n<dl>\n<dt>Extend Ozone so that both Window Manager provided window decorations (like a regular X11 window on Ubuntu) and Chromium&#8217;s builtin window decoration work flawlessly.<\/dt>\n<dd>On Wayland, <a href=\"http:\/\/blog.martin-graesslin.com\/blog\/2013\/02\/client-side-window-decorations-and-wayland\/\">window decorations can be provided either by the client side (application), or by the Wayland server (compositor)<\/a>. The fact that <a href=\"https:\/\/github.com\/wayland-project\/weston\">Weston<\/a> does not provide window decorations by default, forces us to support Chromium&#8217;s builtin one for the good.<\/dd>\n<dt>In case of the Chromium&#8217;s builtin window decorations &#8230;<\/dt>\n<dd>&#8230; add support for basic windowing functionality like maximize, minimize, restore and fullscreen, as well as window dragging and resizing.<\/dd>\n<dt>Add support to &#8220;window close&#8221;.<\/dt>\n<dd>In internal window mode, there is no concept of window closing, because the outer\/native Ozone window represents the Window Manager display, which is not supposed to get closed. In external window mode, windows can be closed freely, as per the needs of the user.<\/dd>\n<dt>Add support for multi window browsing.<\/dt>\n<dd>Each browser window should be backed by its own <strong>acceleratedWidget<\/strong>. This also includes being able to draw widgets that on stock Linux\/X11 builds use native windows: tooltips, (nested and context) menus.<\/dd>\n<dt>Handle keyboard focus activation when switching windows.<\/dt>\n<dd>Again in &#8216;internal window&#8217; mode the outer\/native Ozone window is unique and represents the Window Manager display, not losing or gaining focus at any time. Focus switching of inner windows is handled by <em>mus+ash<\/em>. In &#8216;external window&#8217; mode, user can open as many Browser windows as he wants, and focus switches at the Window Manager level, should reflect on the application focus.<\/dd>\n<\/dl>\n<p><strong>Mus tasks<\/strong>:<\/p>\n<dl>\n<dt>Fix assumptions that make sense for <em>mus+ash<\/em> on ChromeOS only.<\/dt>\n<dd><a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=693081\">The fact that a display::Display instance mapped always to a single ui::ws::Display instance<\/a>.<\/dd>\n<dt>Ownership model<\/dt>\n<dd>Some Mus objects have slightly different ownership in external window mode: <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/display.h\">ws::Display<\/a>, <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/window_manager_state.h\">ws::WindowManagerState<\/a>, <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/window_manager_display_root.h\">ws::WindowManagerDisplayRoot<\/a> and <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/window_tree.h\">ws::WindowTree<\/a><\/dd>\n<\/dl>\n<h5>The plan<\/h5>\n<p>After meeting with <a href=\"https:\/\/codereview.chromium.org\/user\/rjkroege\">rjkroege@<\/a> at <a href=\"https:\/\/www.youtube.com\/playlist?list=PL9ioqAuyl6UL8vdrpzaYJANiUy8v4bw5k\">BlinkOn 7<\/a>, we <a href=\"https:\/\/docs.google.com\/presentation\/d\/13TV2sjLlO8Nqqm6jgaNLwM9v03QEA0idIOS8MRouXJU\/edit#slide=id.g1cd3a97327_0_45\">defined a highlevel plan<\/a> to tackle the project. These were the main action points:<\/p>\n<p>1) Extend the mus_demo to work in &#8216;external window&#8217; mode.<br \/>\n2)  Start fixing 1:1 assumptions in the code, e.g. <em>display::Display<\/em>  <em>ui::ws::Display<\/em>.<br \/>\n3)  Extend Mus to work on &#8216;external window&#8217; mode.<br \/>\n4)  Extend Ozone to work on &#8216;external window&#8217; mode.<br \/>\n5)  Make the code that handles the existing <strong>&#8211;mus<\/strong> command line parameter non-ChromeOS specific.<\/p>\n<p>With this 5 highlevel steps done, we would be able to get Chrome\/Mus running on desktop Linux, on the various Ozone backends.<\/p>\n<h5>The action<\/h5>\n<h6>Mus Demo<\/h6>\n<p><a href=\"https:\/\/codereview.chromium.org\/2679213003\/\">We<\/a> <a href=\"https:\/\/codereview.chromium.org\/2688013003\/\">were<\/a> <a href=\"https:\/\/codereview.chromium.org\/2688813003\/\">able<\/a> <a href=\"https:\/\/codereview.chromium.org\/2697013004\/\">to<\/a> <a href=\"https:\/\/codereview.chromium.org\/2692863007\/\">get<\/a> <a href=\"https:\/\/codereview.chromium.org\/2693923004\/\">mus_demo<\/a> <a href=\"https:\/\/codereview.chromium.org\/2700493005\/\">working<\/a> in <a href=\"https:\/\/codereview.chromium.org\/2622103004\/\">&#8216;external window&#8217; mode<\/a>, by making use of the existing <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/public\/interfaces\/window_tree_host.mojom\">WindowTreeHostFactory API<\/a>.<\/p>\n<p><iframe loading=\"lazy\" title=\"mus demo (external window mode)\" width=\"604\" height=\"453\" src=\"https:\/\/www.youtube.com\/embed\/KnUAoonYAko?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h6>1:1 assumptions<\/h6>\n<p>Although <em>WindowTreeHostFactory<\/em> was in place for the creation WindowTreeHost instances, both <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=693081\">Mus and Ozone still had assumptions that only applied in a ChromeOS context<\/a>. The Googler kylechar@ jumped in and <a href=\"https:\/\/codereview.chromium.org\/2696963003\">fixed<\/a> <a href=\"https:\/\/codereview.chromium.org\/2692863009\">some<\/a> of <a href=\"https:\/\/codereview.chromium.org\/2736943003\">them<\/a>, helping out on our effort.<\/p>\n<h6>Mus and Ozone carve out<\/h6>\n<p>In order to get the 3rd and 4th steps going, we decided to switch our main development repository to a <a href=\"https:\/\/github.com\/Igalia\/chromium\">GitHub fork<\/a>, so that we could expedite reviews and progresses. Given Igalia&#8217;s excellence in carrying downstream forks of large projects forward, we <a href=\"https:\/\/github.com\/igalia\/chromium#chromium-for-wayland\">established a contribution process and a rebase strategy<\/a> that would allow us to move at a good pace, and still stay as close as possible to Chromium&#8217;s tip of trunk.<\/p>\n<p>These are some of the main changes in our downstream repository:<\/p>\n<ul>\n<li>Mus and Aura\/Mus were changed to support an &#8216;external window&#8217; mode flow: there is a single <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ui\/aura\/mus\/window_tree_client.h\">WindowTreeClient<\/a> (Aura\/Mus) instance that maps to another single <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/window_tree.h\">WindowTree<\/a> instance (Mus). The relationship is invariable and is ensured by <a href=\"https:\/\/github.com\/Igalia\/chromium\/blob\/ozone-wayland-dev\/services\/ui\/ws\/window_tree_host_factory_registrar.h\">ui::ws::WindowTreeHostFactoryRegistrar<\/a> class.<\/p>\n<\/li>\n<li>\n<p>In this new set up, ui::ws::WindowTreeHostFactory::CreatePlatformWindow can create as many <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/public\/interfaces\/window_tree_host.mojom\">WindowTreeHost<\/a> \/ <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/display.h\">ui::ws::Display<\/a> instances as needed. ui::ws::Display triggers creation of <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/services\/ui\/ws\/platform_display.h\">PlatformDisplay<\/a> objects, which hold Ozone window handles. Hence, every Chromium window (and some browser widgets) gets backed by its own <strong>acceleratedWidget<\/strong>.<\/p>\n<\/li>\n<li>\n<p>In <em>mus+ash<\/em>, there are some operations accomplished through a cooperation between both Mus and Ash, or Mus and Aura\/Mus sides. For example, setting &#8220;frame decorations&#8221; values in <em>mus+ash<\/em> goes through the following path:<\/p>\n<p>1) <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ash\/mus\/window_manager.cc\">ash::mus::WindowManager<\/a> get frame decoration values as per the &#8220;material design&#8221; in use and passes it to <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ui\/aura\/mus\/window_tree_client.cc\">aura::WindowTreeClient::SetFrameDecorationValues<\/a>.<br \/>\n 2) WindowTree::WmSetFrameDecorationValues<br \/>\n 3) WindowManagerState::SetFrameDecorationValues<br \/>\n 4) UserDisplayManager::OnFrameDecorationValuesChanged<br \/>\n 5) ScreenMus::OnDisplays()<br \/>\n 6) These values are used later on to <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/chrome\/browser\/ui\/views\/frame\/browser_non_client_frame_view_mus.cc\">draw<\/a> &#8220;non client frame&#8221; area of the Browser window, which &#8220;frame&#8221; that contains the Web contents area.<\/p>\n<p>On Chrome\/Mus LinuxOS, we skip this round trip by using the same &#8220;non client frame view&#8221; as stock Linux\/X11 Chrome: <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/chrome\/browser\/ui\/views\/frame\/opaque_browser_frame_view.h\">OpaqueBrowserFrameView<\/a>.<\/p>\n<\/li>\n<li>\n<p>In <em>mus+ash<\/em> all Browser widgets creation take the <a href=\"https:\/\/cs.chromium.org\/chromium\/src\/ui\/views\/widget\/desktop_aura\/desktop_native_widget_aura.h\">DesktopNativeWidgetAura<\/a> path. This implies a new WindowPort and new WindowTreeHost instances per widget. Adding support for this in Mus and Ozone sides would require lots of work and refactory. Hence, we again decided to use the stock Linux\/X11 flow: for widgets currently backed by a native window (tooltips, menus) we use the NativeWidgetAura path, whereas for others widgets (bookmark banner and zoom in\/out banners, URL completion window, status bubble, etc) we use NativeWidgetAura. Also, this choice made extending Ozone accordingly simpler.<\/p>\n<\/li>\n<\/ul>\n<h4><a name=\"status\"><\/a> Status and next steps<\/h4>\n<p>We have reached a point where we can show Chrome Ozone\/Mus on desktop Linux, on using both X11 and Wayland backends,  and here is how it is looking like today:<\/p>\n<p>Wayland:<br \/>\n<iframe loading=\"lazy\" title=\"Chromium Browser (m60 - May\/15\/2017) on ozone\/wayland\" width=\"604\" height=\"453\" src=\"https:\/\/www.youtube.com\/embed\/D6jAucPocmg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>X11:<br \/>\n<iframe loading=\"lazy\" title=\"Chromium Browser (m60 - May\/10\/2017) ozone\/x11\" width=\"604\" height=\"453\" src=\"https:\/\/www.youtube.com\/embed\/tb027dDkg7E?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>The <strong>&#8211;mus<\/strong> and <strong>&#8211;ozone-platform={name}<\/strong> command line parameters control the Chrome configuration. Please note that the same Chrome binary is used.<\/p>\n<p>Some of our next steps for Chromium Mus\/Ozone are:<\/p>\n<ul>\n<li>Continue to fix the windowing features (namely window resize and dragging, as well as drag and drop) when Chromium&#8217;s builtin window decorations are used.<\/li>\n<li>Provide updated yocto builds on Igalia&#8217;s <a href=\"github.com\/Igalia\/meta-browser\">meta-browser fork<\/a>.<\/li>\n<li>Support newer shell protocols like <strong>XDG v6<\/strong>, supported by <a href=\"https:\/\/fedoraproject.org\/wiki\/Wayland_features\">Fedora 25<\/a>.<\/li>\n<li>Ensure no feature losses when compared to stock Chromium X11\/Linux.<\/li>\n<li>Ensure there is no performance penalties when compared to stock Chromium X11\/Linux.<\/li>\n<li>Start to upstream some of the changes.<\/li>\n<\/ul>\n<p>We are also considering providing prebuilt binaries, so that earlier adopters can test the status.<\/p>\n<p>This project is sponsored by Renesas Electronics &#8230;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-105\" src=\"http:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/renesas_logomark_l-1-580x99.jpg\" alt=\"renesas_logomark_l\" width=\"580\" height=\"99\" srcset=\"https:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/renesas_logomark_l-1-580x99.jpg 580w, https:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/renesas_logomark_l-1-768x131.jpg 768w, https:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/renesas_logomark_l-1-940x161.jpg 940w, https:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/renesas_logomark_l-1.jpg 1526w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/p>\n<p>&#8230; and is being performed by Igalian hacker <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/msisov\/\">Maksim Sisov<\/a> and <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/agomes\/\">Antonio Gomes (me)<\/a> on behalf of Igalia, being <a href=\"https:\/\/www.igalia.com\/nc\/igalia-247\/igalian\/item\/fwang\/\">Frederic Wang<\/a> an emeritus contributor.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-106\" src=\"http:\/\/blogs.igalia.com\/tonikitoo\/files\/2016\/11\/igalia-logo-364x130-2.png\" alt=\"igalia-logo-364x130\" width=\"364\" height=\"130\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since January, Igalia has been working on a project whose goal is to make the latest Chromium Browser able to run natively on Wayland-based environments. The project has various phases, requires us to carve out existing implementations and align our work with the direction Chromium&#8217;s mainline is taking. In this post I will provide an &hellip; <a href=\"https:\/\/blogs.igalia.com\/tonikitoo\/2017\/05\/17\/chromium-musozone-update-h12017-wayland-x11\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Chromium Mus\/Ozone update (H1\/2017): wayland, x11<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":38,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,17,8,13,18,11,10,12],"tags":[],"class_list":["post-211","post","type-post","status-publish","format-standard","hentry","category-browsers","category-chrome","category-chromium","category-igalia","category-mus","category-ozone","category-wayland","category-weston"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/posts\/211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/users\/38"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/comments?post=211"}],"version-history":[{"count":19,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/posts\/211\/revisions"}],"predecessor-version":[{"id":234,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/posts\/211\/revisions\/234"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/media?parent=211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/categories?post=211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/tonikitoo\/wp-json\/wp\/v2\/tags?post=211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}