// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sommelier-window.h"  // NOLINT(build/include_directory)

#include <algorithm>
#include <climits>
#include <fstream>
#include <assert.h>
#include <cstdint>
#include <wayland-client-protocol.h>

#include "sommelier.h"            // NOLINT(build/include_directory)
#include "sommelier-logging.h"    // NOLINT(build/include_directory)
#include "sommelier-tracing.h"    // NOLINT(build/include_directory)
#include "sommelier-transform.h"  // NOLINT(build/include_directory)
#include "viewporter-shim.h"      // NOLINT(build/include_directory)
#include "xcb/xcb-shim.h"

#include "aura-shell-client-protocol.h"  // NOLINT(build/include_directory)
#include "viewporter-client-protocol.h"  // NOLINT(build/include_directory)
#include "xdg-shell-client-protocol.h"   // NOLINT(build/include_directory)

#ifdef QUIRKS_SUPPORT
#include "quirks/sommelier-quirks.h"
#endif

#define XID_APPLICATION_ID_FORMAT APPLICATION_ID_FORMAT_PREFIX ".xid.%d"
#define WM_CLIENT_LEADER_APPLICATION_ID_FORMAT \
  APPLICATION_ID_FORMAT_PREFIX ".wmclientleader.%d"
#define WM_CLASS_APPLICATION_ID_FORMAT \
  APPLICATION_ID_FORMAT_PREFIX ".wmclass.%s"
#define X11_PROPERTY_APPLICATION_ID_FORMAT \
  APPLICATION_ID_FORMAT_PREFIX ".xprop.%s"
sl_window::sl_window(struct sl_context* ctx,
                     xcb_window_t id,
                     int x,
                     int y,
                     int width,
                     int height,
                     int border_width)
    : ctx(ctx),
      id(id),
      x(x),
      y(y),
      width(width),
      height(height),
      border_width(border_width) {
  wl_list_insert(&ctx->unpaired_windows, &link);
  pixman_region32_init(&shape_rectangles);
}

sl_window::~sl_window() {
  if (this == ctx->host_focus_window) {
    ctx->host_focus_window = nullptr;
    ctx->needs_set_input_focus = 1;
  }

  free(name);
  free(clazz);
  free(startup_id);
  wl_list_remove(&link);
  pixman_region32_fini(&shape_rectangles);
}

void sl_configure_window(struct sl_window* window) {
  TRACE_EVENT("surface", "sl_configure_window", "id", window->id);
  assert(!window->pending_config.serial);

  if (window->next_config.mask) {
    int x = window->x;
    int y = window->y;
    int i = 0;

    xcb()->configure_window(window->ctx->connection, window->frame_id,
                            window->next_config.mask,
                            window->next_config.values);

    if (window->next_config.mask & XCB_CONFIG_WINDOW_X) {
      x = window->next_config.values[i++];
    }
    if (window->next_config.mask & XCB_CONFIG_WINDOW_Y) {
      y = window->next_config.values[i++];
    }
    if (window->next_config.mask & XCB_CONFIG_WINDOW_WIDTH) {
      window->width = window->next_config.values[i++];
    }
    if (window->next_config.mask & XCB_CONFIG_WINDOW_HEIGHT) {
      window->height = window->next_config.values[i++];
    }
    if (window->next_config.mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
      window->border_width = window->next_config.values[i++];
    }

    // Set x/y to origin in case window gravity is not northwest as expected.
    assert(window->managed);

    uint32_t values[5];
    // Populate values[0~3] with x,y,w,h
    // x and y need to be 0. We are configuring the child window, not the frame
    // window, and the child window should always have a zero offset from its
    // frame (parent) window. See
    // https://en.wikipedia.org/wiki/Re-parenting_window_manager
    values[0] = 0;
    values[1] = 0;
    sl_window_get_width_height(window, &values[2], &values[3]);

    values[4] = window->border_width;
    xcb()->configure_window(
        window->ctx->connection, window->id,
        XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH |
            XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_BORDER_WIDTH,
        values);

    if (x != window->x || y != window->y) {
      window->x = x;
      window->y = y;
      sl_send_configure_notify(window);
    }
  }

  if (window->managed) {
    xcb()->change_property(
        window->ctx->connection, XCB_PROP_MODE_REPLACE, window->id,
        window->ctx->atoms[ATOM_NET_WM_STATE].value, XCB_ATOM_ATOM, 32,
        window->next_config.states_length, window->next_config.states);
  }

  window->pending_config = window->next_config;
  window->next_config.serial = 0;
  window->next_config.mask = 0;
  window->next_config.states_length = 0;
}

void sl_send_configure_notify(struct sl_window* window) {
  // Send a "synthetic" ConfigureNotify event.
  xcb_configure_notify_event_t event = {};
  event.response_type = XCB_CONFIGURE_NOTIFY;
  event.pad0 = 0;
  event.event = window->id;
  event.window = window->id;
  event.above_sibling = XCB_WINDOW_NONE;

  // Per ICCCM, synthetic ConfigureNotify events use root coordinates
  // even if the window has been reparented.
  uint32_t xywh[4];
  sl_window_get_x_y(window, &xywh[0], &xywh[1]);
  sl_window_get_width_height(window, &xywh[2], &xywh[3]);
  event.x = static_cast<int16_t>(xywh[0]);
  event.y = static_cast<int16_t>(xywh[1]);
  event.width = static_cast<uint16_t>(xywh[2]);
  event.height = static_cast<uint16_t>(xywh[3]);

  event.border_width = static_cast<uint16_t>(window->border_width);
  event.override_redirect = 0;
  event.pad1 = 0;

  xcb()->send_event(window->ctx->connection, 0, window->id,
                    XCB_EVENT_MASK_STRUCTURE_NOTIFY,
                    reinterpret_cast<char*>(&event));
}

int sl_process_pending_configure_acks(struct sl_window* window,
                                      struct sl_host_surface* host_surface) {
  if (!window->pending_config.serial) {
    return 0;
  }

#ifdef COMMIT_LOOP_FIX
  // Do not commit/ack if there is nothing to change.
  //
  // TODO(b/181077580): we should never do this, but avoiding it requires a
  // more systemic fix
  if (!window->pending_config.mask &&
      window->pending_config.states_length == 0) {
    return 0;
  }
#endif

  if (window->managed && host_surface) {
    if (window->viewport_override) {
      // If viewport override is set, only check viewport size and completely
      // ignore window size for containerized windows.
      if (sl_window_is_containerized(window) &&
          (window->viewport_height != window->viewport_height_realized ||
           window->viewport_width != window->viewport_width_realized)) {
        return 0;
      }
    } else {
      uint32_t width = window->width + window->border_width * 2;
      uint32_t height = window->height + window->border_width * 2;
      // Early out if we expect contents to match window size at some point in
      // the future.
      if ((width != host_surface->contents_width ||
           height != host_surface->contents_height)) {
        return 0;
      }
    }
  }

  if (window->xdg_surface) {
    xdg_surface_ack_configure(window->xdg_surface,
                              window->pending_config.serial);
  }
  window->pending_config.serial = 0;

  if (window->next_config.serial) {
    sl_configure_window(window);
  }

  return 1;
}

void sl_commit(struct sl_window* window, struct sl_host_surface* host_surface) {
  if (sl_process_pending_configure_acks(window, host_surface)) {
    if (host_surface) {
      wl_surface_commit(host_surface->proxy);
    }
  }
}

static const struct xdg_popup_listener sl_internal_xdg_popup_listener = {
    /*configure=*/DoNothing, /*done=*/DoNothing};

static void sl_internal_xdg_surface_configure(void* data,
                                              struct xdg_surface* xdg_surface,
                                              uint32_t serial) {
  TRACE_EVENT("surface", "sl_internal_xdg_surface_configure");
  struct sl_window* window =
      static_cast<sl_window*>(xdg_surface_get_user_data(xdg_surface));

  window->next_config.serial = serial;

  if (window->configure_event_barrier) {
    window->coalesced_next_config = window->next_config;
    window->next_config.serial = 0;
  } else if (!window->pending_config.serial) {
    struct wl_resource* host_resource;
    struct sl_host_surface* host_surface = nullptr;

    host_resource =
        wl_client_get_object(window->ctx->client, window->host_surface_id);
    if (host_resource) {
      host_surface = static_cast<sl_host_surface*>(
          wl_resource_get_user_data(host_resource));
    }

    sl_configure_window(window);
    sl_commit(window, host_surface);
  }
}

static const struct xdg_surface_listener sl_internal_xdg_surface_listener = {
    sl_internal_xdg_surface_configure};

static void sl_internal_xdg_surface_configure_barrier_done(
    void* data, struct wl_callback* callback, uint32_t serial) {
  struct sl_window* window =
      static_cast<sl_window*>(wl_callback_get_user_data(callback));

  window->configure_event_barrier = nullptr;

  if (window->coalesced_next_config.serial) {
    window->next_config = window->coalesced_next_config;
    window->coalesced_next_config.serial = 0;
    sl_internal_xdg_surface_configure(data, window->xdg_surface,
                                      window->next_config.serial);
  }
}

////////////////////////////////////////////////////////////////////////////////
// common toplevel code

static const int32_t kUnspecifiedCoord = INT32_MIN;

void sl_window_update_should_be_containerized_from_pid(
    struct sl_window* window) {
  bool quirk_enabled = false;
#ifdef QUIRKS_SUPPORT
  quirk_enabled = window->ctx->quirks.IsEnabled(
      window, quirks::FEATURE_CONTAINERIZE_WINDOWS);
#endif
  if (!quirk_enabled || !window->pid) {
    return;
  }

  // If the binary name contains certain keywords, it is probably not actually a
  // game.
  char comm_file_path[50];
  snprintf(comm_file_path, sizeof(comm_file_path), "/proc/%d/comm",
           window->pid);
  std::ifstream proc_comm_file(comm_file_path);
  if (proc_comm_file.is_open()) {
    std::string process_name;
    if (getline(proc_comm_file, process_name)) {
      std::transform(process_name.begin(), process_name.end(),
                     process_name.begin(), tolower);
      window->should_be_containerized_from_pid =
          (process_name.find("launcher") == std::string::npos &&
           process_name.find("easyanticheat") == std::string::npos &&
           process_name.find("battleeye") == std::string::npos &&
           process_name.find("nprotect") == std::string::npos);
    }
    proc_comm_file.close();
  }

  // TODO(endlesspring): Consider other aspects of the process - memory
  // usage, library usage, etc to determine.
}

bool sl_window_is_containerized(struct sl_window* window) {
  bool window_containerized = false;
#ifdef QUIRKS_SUPPORT
  bool probably_game_window =
      // Steam game ID property is set
      window->steam_game_id &&
      // Window type is normal
      window->type ==
          window->ctx->atoms[ATOM_NET_WM_WINDOW_TYPE_NORMAL].value &&
      // Based on the PID and derived information, the window is probably a game
      // window.
      window->should_be_containerized_from_pid &&
      // Window max dimensions are either not set or if set, bigger (in
      // half-perimeter) than specified value.
      ((window->max_width + window->max_height == 0) ||
       (window->max_width + window->max_height >= 400));
  if (window_containerized && !probably_game_window) {
    LOG(VERBOSE) << window
                 << " is not a game window! max_width=" << window->max_width;
  }
  window_containerized =
      probably_game_window && window->ctx->quirks.IsEnabled(
                                  window, quirks::FEATURE_CONTAINERIZE_WINDOWS);
#endif
  return window_containerized;
}

void sl_window_reset_viewport(struct sl_window* window) {
  LOG(VERBOSE) << window << " viewport override unset";
  window->viewport_width = -1;
  window->viewport_height = -1;
  window->viewport_override = false;
  // Note that viewport destination is reset during surface_commit.
}

// Handle a configure event on a toplevel object from the compositor.
//
// window: The window being configured.
// x: The configured X coordinate in host logical space, or kUnspecifiedCoord
//    for toplevel objects that don't send positions.
// y: The configured Y coordinate in host logical space, or kUnspecifiedCoord
//    for toplevel objects that don't send positions.
// width, height: Configured size in host logical space.
// states: Array of XDG_TOPLEVEL_STATE_* enum values.
void sl_internal_toplevel_configure(struct sl_window* window,
                                    int32_t x,
                                    int32_t y,
                                    int32_t width,
                                    int32_t height,
                                    struct wl_array* states) {
  if (!window->managed ||
      (window->ctx->ignore_stateless_toplevel_configure && states->size == 0)) {
    // Ignore requests for non-managed windows.
    // Ignore requests with no states if --ignore-stateless-toplevel-configure
    // is set.
    return;
  }

  bool window_containerized = sl_window_is_containerized(window);

  if (window_containerized) {
    // Process window states first, so that window position and size can be
    // configured based on the states. If the window is not containerized, we
    // process the states last.
    sl_internal_toplevel_configure_state_containerized(window, states);
  }

  if (width && height) {
    int32_t width_in_pixels = width;
    int32_t height_in_pixels = height;

    // We are receiving a request to resize a window (in logical dimensions)
    // If the request is equal to the cached values we used to make adjustments
    // do not recalculate the values
    // However, if the request is not equal to the cached values, try
    // and keep the buffer same size as what was previously set
    // by the application.
    struct sl_host_surface* paired_surface = window->paired_surface;

    if (paired_surface && paired_surface->has_own_scale) {
      if (width != paired_surface->cached_logical_width ||
          height != paired_surface->cached_logical_height) {
        sl_transform_try_window_scale(window->ctx, paired_surface,
                                      window->width, window->height);
      }
    }
    sl_transform_host_to_guest(window->ctx, window->paired_surface,
                               &width_in_pixels, &height_in_pixels);

    int config_idx = 0;
    window->next_config.mask = 0;
    // Refer to enum xcb_config_window_t for the order of configuration,
    // position must be done before size.
    sl_internal_toplevel_configure_position(window, x, y, width_in_pixels,
                                            height_in_pixels, config_idx);

    // We don't need to resize windows using viewports that are windowed and
    // resizble.
    if (window_containerized) {
      sl_internal_toplevel_configure_size_containerized(
          window, x, y, width, height, width_in_pixels, height_in_pixels,
          config_idx);
    } else {
      sl_internal_toplevel_configure_size(window, x, y, width, height,
                                          width_in_pixels, height_in_pixels,
                                          config_idx);
    }
  }

  if (!window_containerized) {
    sl_internal_toplevel_configure_state(window, states);
  }
}

void sl_internal_toplevel_configure_size_containerized(struct sl_window* window,
                                                       int32_t x,
                                                       int32_t y,
                                                       int32_t host_width,
                                                       int32_t host_height,
                                                       int32_t width_in_pixels,
                                                       int32_t height_in_pixels,
                                                       int& mut_config_idx) {
  // Check the game is windowed (with decorations, indicating that this is not
  // borderless windowed), and has hinted that it can be resized to the size
  // that Exo requested. Note that max size 0 means no limits. Note that min&max
  // dimensions are strictly set by the X11 client only (and forwarded to Exo
  // immediately).
  bool windowed_and_resizable =
      (!window->fullscreen && window->decorated) &&
      (window->max_width >= width_in_pixels || !window->max_width) &&
      window->min_width <= width_in_pixels &&
      (window->max_height >= height_in_pixels || !window->max_height) &&
      window->min_height <= height_in_pixels;
  // Forward resizes to the client if requested size fits within the min&max
  // dimensions.
  if (windowed_and_resizable && !window->use_emulated_rects) {
    // TODO(b/330639760): Consider unset aspect ratio every frame in
    // surface_commit.
    zaura_surface_set_aspect_ratio(window->aura_surface, -1, -1);
    sl_window_reset_viewport(window);
    window->next_config.mask |= XCB_CONFIG_WINDOW_WIDTH |
                                XCB_CONFIG_WINDOW_HEIGHT |
                                XCB_CONFIG_WINDOW_BORDER_WIDTH;
    window->next_config.values[mut_config_idx++] = width_in_pixels;
    window->next_config.values[mut_config_idx++] = height_in_pixels;
    window->next_config.values[mut_config_idx++] = 0;
    LOG(VERBOSE) << window << " size set to " << width_in_pixels << "x"
                 << height_in_pixels;
    return;
  }

  auto output = window->paired_surface->output.get();

  // Set the window size to be either max or min window size, set by the X11
  // client. If width/height min and max are 0, set the window size to the size
  // of the screen. If the window is fullscreen (by the client), ignore size
  // hints and set it to the size of the screen.
  // We are effectively maximizing the window as much as we can within the
  // specified range, then down-scaling. This is to have consistent window
  // rendering experience with the most-expected use-case (fullscreen game,
  // user hits fullscreen toggle key). However, once we have better upscaling
  // algorithm, we should consider minimizing the size (or average?) then
  // upscaling in viewports instead.
  int safe_window_width =
      window->max_width ? window->max_width : window->min_width;
  int safe_window_height =
      window->max_height ? window->max_height : window->min_height;
  if (window->use_emulated_rects) {
    LOG(VERBOSE) << "using emulated rects " << window->emulated_width << "x"
                 << window->emulated_height;
    // If screen size emulation is set by XWayland, set the window size to the
    // emulated size and adjust the viewport size as Exo had requested it to be.
    safe_window_width = window->emulated_width;
    safe_window_height = window->emulated_height;
  } else if (!safe_window_width || !safe_window_height ||
             window->max_width > output->width ||
             window->max_height > output->height || window->fullscreen) {
    safe_window_width = output->width;
    safe_window_height = output->height;
  }

  window->next_config.mask |= XCB_CONFIG_WINDOW_WIDTH |
                              XCB_CONFIG_WINDOW_HEIGHT |
                              XCB_CONFIG_WINDOW_BORDER_WIDTH;
  window->next_config.values[mut_config_idx++] = safe_window_width;
  window->next_config.values[mut_config_idx++] = safe_window_height;
  window->next_config.values[mut_config_idx++] = 0;
  LOG(VERBOSE) << window << " size(safe) set to " << safe_window_width << "x"
               << safe_window_height;

  if (window->use_emulated_rects && window->compositor_fullscreen) {
    // Some games using emulated rects have xwayland send the wrong viewport
    // destination, causing the game to render in a small box. This overrides
    // that via quirk to set the destination to the size of the screen.
    if (sl_window_should_fix_randr_emu(window)) {
      window->viewport_override = true;
      window->viewport_width = host_width;
      window->viewport_height = host_height;
      window->viewport_pointer_scale =
          static_cast<float>(output->logical_width) / window->viewport_width;
      return;
    }
    // If we are using emulated rects and the window is fullscreen in
    // compositor, we only have to report the emulated size (done above). Aspect
    // ratio changes are moot (since compositor fullscreen). We don't have to
    // set viewport overrides since we can fully rely on viewport setup by
    // Xwayland.
    // If the window is windowed in compositor, then we have to do additional
    // viewport operations to make the window fit into the size that compositor
    // wants it to be, without disrupting the emulation. This has identical code
    // path as non-emulated mode, except pointer movement scaling (see below).
    sl_window_reset_viewport(window);
    return;
  }

  // Use viewport to resize surface as per Exo request if we are not using
  // emulated rects, or window is not fullscreen in Exo (and using emulated
  // rects).
  window->viewport_override = true;

  int32_t safe_window_width_in_wl = safe_window_width;
  int32_t safe_window_height_in_wl = safe_window_height;
  sl_transform_guest_to_host(window->ctx, window->paired_surface,
                             &safe_window_width_in_wl,
                             &safe_window_height_in_wl);
  // TODO(endlesspring): consider ignoring aspect ratio and filling the entire
  // screen if Exo wants the window to be fullscreen. This wills require having
  // pointer scale in x and y, instead of one.
  // if (window->compositor_fullscreen) {
  //   window->viewport_width = output->logical_width;
  //   window->viewport_height = output->logical_height;
  //   window->viewport_pointer_scale =
  //       static_cast<float>(safe_window_width_in_wl) / window->viewport_width;
  //   return;
  // }

  // TODO(b/330639760): Once aspect ratio is working correctly, we can entirely
  // get rid of this ratio calculation, in theory.
  // Adjust viewport while maintaining aspect ratio
  float width_ratio = static_cast<float>(safe_window_width) / width_in_pixels;
  float height_ratio =
      static_cast<float>(safe_window_height) / height_in_pixels;
  if (std::abs(width_ratio - height_ratio) < 0.005) {
    window->viewport_width = host_width;
    window->viewport_height = host_height;
    // If Exo sets a size that is of a different aspect ratio we shrink
    // the window to maintain aspect ratio. We do this by always shrinking
    // the side that is now proportionally larger as if we expand the
    // smaller side it might result in the window becoming larger than the
    // allowed bounds of the screen.
  } else if (width_ratio < height_ratio) {
    window->viewport_width =
        (static_cast<float>(safe_window_width) * host_height) /
        safe_window_height;
    window->viewport_height = host_height;

  } else if (width_ratio > height_ratio) {
    window->viewport_height =
        (static_cast<float>(safe_window_height) * host_width) /
        safe_window_width;
    window->viewport_width = host_width;
  }
  LOG(VERBOSE) << window << " viewport set to " << window->viewport_width << "x"
               << window->viewport_height;

  // TODO(b/330639760): For some reason, set_aspect_ratio includes the title
  // bar in the surface ratio. Figure out a way to mitigate this.
  // Also consider setting aspect ratio every frame in surface_commit.
  zaura_surface_set_aspect_ratio(
      window->aura_surface, window->viewport_width,
      window->viewport_height + (window->compositor_fullscreen ? 0 : 32));

  if (window->use_emulated_rects) {
    // Pointer scaling is being done in XWayland as well, assuming the viewport
    // is the size of the screen. Map the movement from viewport to logical
    // width of the screen (which XWayland is expecting).
    window->viewport_pointer_scale =
        static_cast<float>(output->logical_width) / window->viewport_width;
  } else {
    // Map movement from viewport to the window's space.
    window->viewport_pointer_scale =
        static_cast<float>(safe_window_width_in_wl) / window->viewport_width;
  }

  if (window->xdg_toplevel) {
    // Override X11 client-defined min and max size to a value relative to
    // display screen size.
    // When client client updates min/max, window->min/max_width/height values
    // are updated, then xdg_toplevel calls are made (see
    // sl_handle_property_notify for details). This results in Exo adjusting
    // the window size appropriately, resulting in this snippet
    // (part of toplevel_configure) to run and override the max/min again. This
    // allows the X11 client to continue resize itself but also allow the user
    // to resize the window at will within the constraints.
    xdg_toplevel_set_max_size(window->xdg_toplevel, output->logical_width * 0.8,
                              output->logical_height * 0.8);
    xdg_toplevel_set_min_size(window->xdg_toplevel, output->logical_width * 0.4,
                              output->logical_height * 0.4);
  }
}

void sl_internal_toplevel_configure_size(struct sl_window* window,
                                         int32_t x,
                                         int32_t y,
                                         int32_t host_width,
                                         int32_t host_height,
                                         int32_t width_in_pixels,
                                         int32_t height_in_pixels,
                                         int& mut_config_idx) {
  // For games with issues with incorrect viewport destination when using randr
  // emulation, this will override the viewport destination with the screen size
  // when in fullscreen mode.
  if (window->use_emulated_rects && window->compositor_fullscreen &&
      sl_window_should_fix_randr_emu(window)) {
    window->viewport_override = true;
    window->viewport_width = host_width;
    window->viewport_height = host_height;
    window->viewport_pointer_scale =
        static_cast<float>(window->width) / window->viewport_width;
    // Workaround using viewport for when Exo sets sizes that are not
    // within the bounds the client requested.
    // TODO(b/316990641): Implement resizing via viewports if
    // window->fullscreen==true but window->compositor_fullscreen==false.
    // Only do this when --only-client-can-exit-fullscreen is set.
  } else if (window->ctx->viewport_resize &&
             ((window->max_width != 0 && width_in_pixels > window->max_width) ||
              (window->min_width != 0 && width_in_pixels < window->min_width) ||
              (window->max_height != 0 &&
               height_in_pixels > window->max_height) ||
              (window->min_height != 0 &&
               height_in_pixels < window->min_height))) {
    window->viewport_override = true;
    float width_ratio = static_cast<float>(window->width) / width_in_pixels;
    float height_ratio = static_cast<float>(window->height) / height_in_pixels;
    if (std::abs(width_ratio - height_ratio) < 0.01) {
      window->viewport_override = true;
      window->viewport_width = host_width;
      window->viewport_height = host_height;
      // If Exo sets a size that is of a different aspect ratio we shrink
      // the window to maintain aspect ratio. We do this by always shrinking
      // the side that is now proportionally larger as if we expand the
      // smaller side it might result in the window becoming larger than the
      // allowed bounds of the screen.
    } else if (width_ratio < height_ratio) {
      window->viewport_width =
          (static_cast<float>(window->width) * host_height) / window->height;
      window->viewport_height = host_height;

    } else if (width_ratio > height_ratio) {
      window->viewport_height =
          (static_cast<float>(window->height) * host_width) / window->width;
      window->viewport_width = host_width;
    }

    int32_t window_width = window->width;
    int32_t window_height = window->height;
    sl_transform_guest_to_host(window->ctx, window->paired_surface,
                               &window_width, &window_height);
    window->viewport_pointer_scale =
        static_cast<float>(window_width) / window->viewport_width;
    xdg_toplevel_set_min_size(window->xdg_toplevel, window->viewport_width,
                              window->viewport_height);
    xdg_toplevel_set_max_size(window->xdg_toplevel, window->viewport_width,
                              window->viewport_height);
  } else if (window->viewport_override) {
    sl_window_reset_viewport(window);
    wp_viewport_shim()->set_destination(window->paired_surface->viewport,
                                        window->viewport_width,
                                        window->viewport_height);
  }

  window->next_config.mask |= XCB_CONFIG_WINDOW_WIDTH |
                              XCB_CONFIG_WINDOW_HEIGHT |
                              XCB_CONFIG_WINDOW_BORDER_WIDTH;
  if (window->viewport_override) {
    LOG(VERBOSE) << window << " viewport override, size set to "
                 << window->width << "x" << window->height;
    window->next_config.values[mut_config_idx++] = window->width;
    window->next_config.values[mut_config_idx++] = window->height;
    window->next_config.values[mut_config_idx++] = 0;
  } else if (window->use_emulated_rects) {
    LOG(VERBOSE) << window << " emulated, size set to "
                 << window->emulated_width << "x" << window->emulated_height;
    window->next_config.values[mut_config_idx++] = window->emulated_width;
    window->next_config.values[mut_config_idx++] = window->emulated_height;
    window->next_config.values[mut_config_idx++] = 0;
  } else {
    LOG(VERBOSE) << window << " size set to " << width_in_pixels << "x"
                 << height_in_pixels;
    window->next_config.values[mut_config_idx++] = width_in_pixels;
    window->next_config.values[mut_config_idx++] = height_in_pixels;
    window->next_config.values[mut_config_idx++] = 0;
  }
}

void sl_internal_toplevel_configure_position(struct sl_window* window,
                                             uint32_t x,
                                             uint32_t y,
                                             int32_t width_in_pixels,
                                             int32_t height_in_pixels,
                                             int& mut_config_idx) {
  if (window->use_emulated_rects) {
    // Ignore requests from the compositor and set the coordinates as emulation
    // requested.
    window->next_config.mask |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
    window->next_config.values[mut_config_idx++] = window->emulated_x;
    window->next_config.values[mut_config_idx++] = window->emulated_y;
    LOG(VERBOSE) << window << " position set to emulated " << window->emulated_x
                 << "," << window->emulated_y;

  } else if (x != kUnspecifiedCoord && y != kUnspecifiedCoord) {
    // Convert to virtual coordinates
    int32_t guest_x = x;
    int32_t guest_y = y;

    sl_transform_host_position_to_guest_position(
        window->ctx, window->paired_surface, &guest_x, &guest_y);

    window->next_config.mask |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
    window->next_config.values[mut_config_idx++] = guest_x;
    window->next_config.values[mut_config_idx++] = guest_y;
    LOG(VERBOSE) << window << " position set to specified " << guest_x << ","
                 << guest_y;

  } else if (!(window->size_flags & (US_POSITION | P_POSITION))) {
    uint32_t new_x = 0;
    uint32_t new_y = 0;

    const sl_host_output* output =
        window->paired_surface ? window->paired_surface->output.get() : nullptr;
    if (output) {
      if (sl_window_is_containerized(window) && window->viewport_override &&
          window->fullscreen && !window->compositor_fullscreen) {
        new_x = output->virt_x;
        new_y = output->virt_y;
      } else {
        new_x =
            output->virt_x + (output->virt_rotated_width - width_in_pixels) / 2;
        new_y = (output->virt_rotated_height - height_in_pixels) / 2;
      }
    } else {
      new_x = window->ctx->screen->width_in_pixels / 2 - width_in_pixels / 2;
      new_y = window->ctx->screen->height_in_pixels / 2 - height_in_pixels / 2;
    }

    window->next_config.mask |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
    window->next_config.values[mut_config_idx++] = new_x;
    window->next_config.values[mut_config_idx++] = new_y;
    LOG(VERBOSE) << window << " position set to new " << new_x << "," << new_y;
  }
}

void sl_internal_toplevel_configure_set_activated(struct sl_window* window,
                                                  bool activated) {
  if (activated != window->activated) {
    if (activated != (window->ctx->host_focus_window == window)) {
      window->ctx->host_focus_window = activated ? window : nullptr;
      window->ctx->needs_set_input_focus = 1;
    }
    window->activated = activated;
  }
}

void sl_internal_toplevel_configure_state(struct sl_window* window,
                                          struct wl_array* states) {
  // States: https://wayland.app/protocols/xdg-shell#xdg_toplevel:enum:state
  // Note that if there are no states specified, it is not-maximized,
  // not-fullscreen, not-currently-being-resized and not-activated window.
  bool activated = false;
  window->allow_resize = 1;
  window->compositor_fullscreen = 0;

  uint32_t* state;
  int state_idx = 0;

  if (window->ctx->only_client_can_exit_fullscreen && window->fullscreen) {
    // If the window has been set to full screen by the client, do not try to
    // revert it back. Many games and applications fail to adapt to changes
    // enforced by the WM (ie. the fullscreen state must be toggled via the
    // game's UI).
    window->next_config.states[state_idx++] =
        window->ctx->atoms[ATOM_NET_WM_STATE_FULLSCREEN].value;
    window->allow_resize = 0;
  }

  sl_array_for_each(state, states) {
    if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
      if (state_idx == 0) {
        // Only add fullscreen state if it was previously not added by
        // --only-client-can-exit-fullscreen
        window->next_config.states[state_idx++] =
            window->ctx->atoms[ATOM_NET_WM_STATE_FULLSCREEN].value;
      }
      window->allow_resize = 0;
      window->compositor_fullscreen = 1;
    }
    if (*state == XDG_TOPLEVEL_STATE_MAXIMIZED) {
      bool force_x11_unmaximize = false;
#ifdef QUIRKS_SUPPORT
      force_x11_unmaximize = window->ctx->quirks.IsEnabled(
          window, quirks::FEATURE_FORCE_X11_UNMAXIMIZE);
#endif
      window->allow_resize = 0;
      if (!force_x11_unmaximize) {
        window->next_config.states[state_idx++] =
            window->ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT].value;
        window->next_config.states[state_idx++] =
            window->ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ].value;
      }
    }
    if (*state == XDG_TOPLEVEL_STATE_ACTIVATED) {
      activated = true;
      window->next_config.states[state_idx++] =
          window->ctx->atoms[ATOM_NET_WM_STATE_FOCUSED].value;
    }
    if (*state == XDG_TOPLEVEL_STATE_RESIZING) {
      window->allow_resize = 0;
    }
  }

  sl_internal_toplevel_configure_set_activated(window, activated);

  LOG(VERBOSE) << window << " state change, fullscreen=" << window->fullscreen
               << " compositor_fullscreen=" << window->compositor_fullscreen;
  // Override previous state definitions
  window->next_config.states_length = state_idx;
}

void sl_internal_toplevel_configure_state_containerized(
    struct sl_window* window, struct wl_array* states) {
  // States: https://wayland.app/protocols/xdg-shell#xdg_toplevel:enum:state
  // Note that if there are no states specified, it is not-maximized,
  // not-fullscreen, not-currently-being-resized and not-activated window.
  bool activated = false;
  window->allow_resize = 1;
  window->compositor_fullscreen = 0;

  uint32_t* state;
  int state_idx = 0;

  // Keep the fullscreen state if X11 client decided to be fullscreen. Ignore
  // compositor's request.
  if (window->fullscreen) {
    window->allow_resize = 0;
    window->next_config.states[state_idx++] =
        window->ctx->atoms[ATOM_NET_WM_STATE_FULLSCREEN].value;
  }

  // Ditto as above, but maximize state.
  if (window->maximized) {
    bool force_x11_unmaximize = false;
#ifdef QUIRKS_SUPPORT
    force_x11_unmaximize = window->ctx->quirks.IsEnabled(
        window, quirks::FEATURE_FORCE_X11_UNMAXIMIZE);
#endif
    window->allow_resize = 0;
    if (!force_x11_unmaximize) {
      window->next_config.states[state_idx++] =
          window->ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT].value;
      window->next_config.states[state_idx++] =
          window->ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ].value;
    }
  }

  sl_array_for_each(state, states) {
    // Note that we are ignoring maximized state for reasons specified above. We
    // are not even taking note of what the compositor wants since we don't have
    // to for window containerization.
    if (*state == XDG_TOPLEVEL_STATE_FULLSCREEN) {
      // Mark as compositor request to be fullscreen, so that other sizing
      // operations can operate to fulfill Exo's request.
      window->compositor_fullscreen = 1;
    }
    if (*state == XDG_TOPLEVEL_STATE_ACTIVATED) {
      activated = true;
      window->next_config.states[state_idx++] =
          window->ctx->atoms[ATOM_NET_WM_STATE_FOCUSED].value;
    }
    if (*state == XDG_TOPLEVEL_STATE_RESIZING) {
      window->allow_resize = 0;
    }
  }

  // Set focus appropriately.
  sl_internal_toplevel_configure_set_activated(window, activated);

  if (!window->compositor_fullscreen) {
    // Ignore the window decoration settings done by the X11 client, and show
    // frame decorations if Exo treats the surface as non-fullscreen.
    zaura_surface_set_frame(window->aura_surface,
                            ZAURA_SURFACE_FRAME_TYPE_NORMAL);
  }

  LOG(VERBOSE) << window << " state change, fullscreen=" << window->fullscreen
               << " compositor_fullscreen=" << window->compositor_fullscreen;
  // Override previous state definitions
  window->next_config.states_length = state_idx;
}

////////////////////////////////////////////////////////////////////////////////
// xdg_toplevel event listeners
//
// https://crsrc.org/s/?q=f:sommelier/protocol/xdg-shell.xml%20name=\"xdg_toplevel
//
// In Exo, this is sent from
// https://crsrc.org/s/?q=f:exo%2Fwayland.*cc%20xdg_toplevel_send_configure
static void sl_internal_xdg_toplevel_configure(
    void* unused_data,
    struct xdg_toplevel* xdg_toplevel,
    int32_t width,
    int32_t height,
    struct wl_array* states) {
  TRACE_EVENT("other", "sl_internal_xdg_toplevel_configure");
  struct sl_window* window =
      static_cast<sl_window*>(xdg_toplevel_get_user_data(xdg_toplevel));
  sl_internal_toplevel_configure(window, kUnspecifiedCoord, kUnspecifiedCoord,
                                 width, height, states);
}

// In Exo, this is sent from
// https://crsrc.org/s/?q=f:exo%2Fwayland.*cc%20xdg_toplevel_send_close
static void sl_internal_xdg_toplevel_close(void* data,
                                           struct xdg_toplevel* xdg_toplevel) {
  TRACE_EVENT("other", "sl_internal_xdg_toplevel_close");
  struct sl_window* window =
      static_cast<sl_window*>(xdg_toplevel_get_user_data(xdg_toplevel));
  xcb_client_message_event_t event = {};
  event.response_type = XCB_CLIENT_MESSAGE;
  event.format = 32;
  event.window = window->id;
  event.type = window->ctx->atoms[ATOM_WM_PROTOCOLS].value;
  event.data.data32[0] = window->ctx->atoms[ATOM_WM_DELETE_WINDOW].value;
  event.data.data32[1] = XCB_CURRENT_TIME;

  xcb_send_event(window->ctx->connection, 0, window->id,
                 XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
}

static const struct xdg_toplevel_listener sl_internal_xdg_toplevel_listener = {
    sl_internal_xdg_toplevel_configure, sl_internal_xdg_toplevel_close};

////////////////////////////////////////////////////////////////////////////////
// zaura_toplevel event listeners
//
// https://crsrc.org/s/?q=f:sommelier/protocol/aura-shell.xml%20name=\"zaura_toplevel

// Sent from Exo here:
// https://crsrc.org/s/?q=f:exo%2Fwayland.*cc%20zaura_toplevel_send_configure
static void sl_internal_zaura_toplevel_configure(
    void* unused_data,
    struct zaura_toplevel* zaura_toplevel,
    int32_t x,
    int32_t y,
    int32_t width,
    int32_t height,
    struct wl_array* states) {
  TRACE_EVENT("other", "sl_internal_zaura_toplevel_configure");
  struct sl_window* window =
      static_cast<sl_window*>(zaura_toplevel_get_user_data(zaura_toplevel));

  // aura_toplevel.configure replaces xdg_toplevel.configure for surfaces on
  // which zaura_toplevel_set_supports_screen_coordinates() has been called.
  // So we shouldn't get duplicate events.
  //
  // TODO(cpelling): Handle aura-specific states.
  sl_internal_toplevel_configure(window, x, y, width, height, states);
}

// Sent from Exo here:
// https://crsrc.org/s/?q=f:exo%2Fwayland.*cc%20zaura_toplevel_send_origin_change
static void sl_internal_zaura_toplevel_origin_change(
    void* data, struct zaura_toplevel* zaura_toplevel, int32_t x, int32_t y) {
  // aura_toplevel.origin_change is not part of the normal configuration
  // lifecycle, and is not followed by xdg_surface.configure. So just apply
  // this change immediately.
  sl_window* window =
      static_cast<sl_window*>(zaura_toplevel_get_user_data(zaura_toplevel));

  if (window->configure_event_barrier) {
    // TODO(cpelling): Coalesce origin_change events instead of dropping them.
    return;
  }

  int32_t guest_x = x;
  int32_t guest_y = y;
  sl_transform_host_position_to_guest_position(
      window->ctx, window->paired_surface, &guest_x, &guest_y);
  window->x = guest_x;
  window->y = guest_y;

  uint32_t values[2];
  sl_window_get_x_y(window, &values[0], &values[1]);
  xcb()->configure_window(window->ctx->connection, window->frame_id,
                          XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
}

static const struct zaura_toplevel_listener
    sl_internal_zaura_toplevel_listener = {
        sl_internal_zaura_toplevel_configure,
        sl_internal_zaura_toplevel_origin_change};

static const struct wl_callback_listener configure_event_barrier_listener = {
    sl_internal_xdg_surface_configure_barrier_done};

void sl_toplevel_send_window_bounds_to_host(struct sl_window* window) {
  // Don't send window bounds if fullscreen/maximized/resizing,
  // or if the feature is unsupported by the host or disabled by flag.
  if (!window->allow_resize || !sl_window_is_client_positioned(window) ||
      !window->ctx->aura_shell ||
      window->ctx->aura_shell->version <
          ZAURA_TOPLEVEL_SET_WINDOW_BOUNDS_SINCE_VERSION ||
      !window->aura_toplevel) {
    return;
  }
  int32_t x = window->x;
  int32_t y = window->y;
  int32_t w = window->width;
  int32_t h = window->height;
  if (window->size_flags & P_MIN_SIZE) {
    if (w < window->min_width) {
      w = window->min_width;
    }
    if (h < window->min_height) {
      h = window->min_height;
    }
  }
  if (window->size_flags & P_MAX_SIZE) {
    if (w > window->max_width) {
      w = window->max_width;
    }
    if (h > window->max_height) {
      h = window->max_height;
    }
  }

  sl_host_output* output = sl_transform_guest_position_to_host_position(
      window->ctx, window->paired_surface, &x, &y);
  sl_transform_guest_to_host(window->ctx, window->paired_surface, &w, &h);

  zaura_toplevel_set_window_bounds(window->aura_toplevel, x, y, w, h,
                                   output->proxy);

  if (window->configure_event_barrier) {
    wl_callback_destroy(window->configure_event_barrier);
  }
  window->configure_event_barrier = wl_display_sync(window->ctx->display);
  wl_callback_add_listener(window->configure_event_barrier,
                           &configure_event_barrier_listener, window);
}

////////////////////////////////////////////////////////////////////////////////

void sl_update_application_id(struct sl_context* ctx,
                              struct sl_window* window) {
  TRACE_EVENT("other", "sl_update_application_id");
  if (!window->aura_surface) {
    return;
  }
  if (ctx->application_id) {
    zaura_surface_set_application_id(window->aura_surface, ctx->application_id);
    return;
  }
  // Don't set application id for X11 override redirect. This prevents
  // aura shell from thinking that these are regular application windows
  // that should appear in application lists.
  if (!ctx->xwayland || window->managed) {
    char* application_id_str;
    if (!window->app_id_property.empty()) {
      application_id_str =
          sl_xasprintf(X11_PROPERTY_APPLICATION_ID_FORMAT, ctx->vm_id,
                       window->app_id_property.c_str());
    } else if (window->clazz) {
      application_id_str = sl_xasprintf(WM_CLASS_APPLICATION_ID_FORMAT,
                                        ctx->vm_id, window->clazz);
    } else if (window->client_leader != XCB_WINDOW_NONE) {
      application_id_str = sl_xasprintf(WM_CLIENT_LEADER_APPLICATION_ID_FORMAT,
                                        ctx->vm_id, window->client_leader);
    } else {
      application_id_str =
          sl_xasprintf(XID_APPLICATION_ID_FORMAT, ctx->vm_id, window->id);
    }

    zaura_surface_set_application_id(window->aura_surface, application_id_str);
    free(application_id_str);
  }
}

void sl_window_update(struct sl_window* window) {
  TRACE_EVENT("surface", "sl_window_update", "id", window->id);
  struct wl_resource* host_resource = nullptr;
  struct sl_host_surface* host_surface;
  struct sl_context* ctx = window->ctx;
  struct sl_window* parent = nullptr;

  if (window->host_surface_id) {
    host_resource = wl_client_get_object(ctx->client, window->host_surface_id);
    if (host_resource && window->unpaired) {
      wl_list_remove(&window->link);
      wl_list_insert(&ctx->windows, &window->link);
      window->unpaired = 0;
    }
  } else if (!window->unpaired) {
    wl_list_remove(&window->link);
    wl_list_insert(&ctx->unpaired_windows, &window->link);
    window->unpaired = 1;
    window->paired_surface->window = nullptr;
    window->paired_surface = nullptr;
  }

  if (!host_resource) {
    if (window->aura_surface) {
      zaura_surface_destroy(window->aura_surface);
      window->aura_surface = nullptr;
    }
    if (window->xdg_toplevel) {
      xdg_toplevel_destroy(window->xdg_toplevel);
      window->xdg_toplevel = nullptr;
    }
    if (window->xdg_popup) {
      xdg_popup_destroy(window->xdg_popup);
      window->xdg_popup = nullptr;
    }
    if (window->xdg_surface) {
      xdg_surface_destroy(window->xdg_surface);
      window->xdg_surface = nullptr;
    }
    window->realized = 0;
    return;
  }

  host_surface =
      static_cast<sl_host_surface*>(wl_resource_get_user_data(host_resource));
  assert(host_surface);
  assert(!host_surface->has_role);

  if (!window->unpaired) {
    window->paired_surface = host_surface;
    host_surface->window = window;
    sl_transform_try_window_scale(ctx, host_surface, window->width,
                                  window->height);
  }

  assert(ctx->xdg_shell);
  assert(ctx->xdg_shell->internal);

  if (window->managed) {
    if (window->transient_for != XCB_WINDOW_NONE) {
      struct sl_window* sibling;

      wl_list_for_each(sibling, &ctx->windows, link) {
        if (sibling->id == window->transient_for) {
          if (sibling->xdg_toplevel) {
            parent = sibling;
          }
          break;
        }
      }
    }
  }

  // If we have a transient parent, but could not find it in the list of
  // realized windows, then pick the window that had the last event for the
  // parent.  We update this again when we gain focus, so if we picked the wrong
  // one it can get corrected at that point (but it's also possible the parent
  // will never be realized, which is why selecting one here is important).
  if (!window->managed ||
      (!parent && window->transient_for != XCB_WINDOW_NONE)) {
    struct sl_window* sibling;
    uint32_t parent_last_event_serial = 0;

    wl_list_for_each(sibling, &ctx->windows, link) {
      struct wl_resource* sibling_host_resource;
      struct sl_host_surface* sibling_host_surface;

      if (!sibling->realized) {
        continue;
      }

      sibling_host_resource =
          wl_client_get_object(ctx->client, sibling->host_surface_id);
      if (!sibling_host_resource) {
        continue;
      }

      // Any parent will do but prefer last event window.
      sibling_host_surface = static_cast<sl_host_surface*>(
          wl_resource_get_user_data(sibling_host_resource));
      if (parent_last_event_serial > sibling_host_surface->last_event_serial) {
        continue;
      }

      // Do not use ourselves as the parent.
      if (sibling->host_surface_id == window->host_surface_id) {
        continue;
      }

      parent = sibling;
      parent_last_event_serial = sibling_host_surface->last_event_serial;
    }
  }

  if (!window->depth) {
    xcb_get_geometry_reply_t* geometry_reply = xcb()->get_geometry_reply(
        ctx->connection, xcb()->get_geometry(ctx->connection, window->id),
        nullptr);
    if (geometry_reply) {
      window->depth = geometry_reply->depth;
      free(geometry_reply);
    }
  }

  if (!window->xdg_surface) {
    window->xdg_surface = xdg_wm_base_get_xdg_surface(ctx->xdg_shell->internal,
                                                      host_surface->proxy);
    xdg_surface_add_listener(window->xdg_surface,
                             &sl_internal_xdg_surface_listener, window);
  }

  if (ctx->aura_shell) {
    uint32_t frame_color;

    if (!window->aura_surface) {
      window->aura_surface = zaura_shell_get_aura_surface(
          ctx->aura_shell->internal, host_surface->proxy);
    }

    zaura_surface_set_frame(window->aura_surface,
                            window->decorated ? ZAURA_SURFACE_FRAME_TYPE_NORMAL
                            : window->depth == 32
                                ? ZAURA_SURFACE_FRAME_TYPE_NONE
                                : ZAURA_SURFACE_FRAME_TYPE_SHADOW);

    frame_color = window->dark_frame ? ctx->dark_frame_color : ctx->frame_color;
    zaura_surface_set_frame_colors(window->aura_surface, frame_color,
                                   frame_color);
    zaura_surface_set_startup_id(window->aura_surface, window->startup_id);
    sl_update_application_id(ctx, window);

    if (ctx->aura_shell->version >=
        ZAURA_SURFACE_SET_FULLSCREEN_MODE_SINCE_VERSION) {
      zaura_surface_set_fullscreen_mode(window->aura_surface,
                                        ctx->fullscreen_mode);
    }
  }

  // Always use top-level surface for X11 windows as we can't control when the
  // window is closed.
  if (ctx->xwayland || !parent) {
    if (!window->xdg_toplevel) {
      window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface);
      xdg_toplevel_add_listener(window->xdg_toplevel,
                                &sl_internal_xdg_toplevel_listener, window);
    }

    // Right now, aura_toplevel is only needed for windows positioned by the
    // client (which is all windows if --enable-x11-move-windows is passed).
    // Setting it up means we get x and y coordinates in configure
    // events (aura_toplevel.configure replaces xdg_toplevel.configure), which
    // changes how windows are positioned in the X server's coordinate space. If
    // windows end up partially offscreen in that space, we get bugs like
    // b/269053427.
    //
    // Bottom line: If --enable-x11-move-windows is enabled, apps are
    // responsible for keeping themselves onscreen within X space. If not,
    // Sommelier is; in which case it should ignore the host compositor's
    // positioning decisions, since those are made without reference to X space.
    // Sommelier could listen to aura_toplevel.configure and ignore the x and y
    // coordinates, but for now the most conservative approach is to avoid using
    // aura_toplevel entirely. This can be revisited later if we need
    // aura_toplevel for anything else.
    if (sl_window_is_client_positioned(window) && ctx->aura_shell &&
        window->xdg_toplevel && !window->aura_toplevel) {
      window->aura_toplevel = zaura_shell_get_aura_toplevel_for_xdg_toplevel(
          ctx->aura_shell->internal, window->xdg_toplevel);
      zaura_toplevel_set_supports_screen_coordinates(window->aura_toplevel);
      zaura_toplevel_add_listener(window->aura_toplevel,
                                  &sl_internal_zaura_toplevel_listener, window);
    }

    if (parent) {
      xdg_toplevel_set_parent(window->xdg_toplevel, parent->xdg_toplevel);
    }
    if (window->name) {
      xdg_toplevel_set_title(window->xdg_toplevel, window->name);
    }
    if (window->size_flags & P_MIN_SIZE) {
      int32_t minw = window->min_width;
      int32_t minh = window->min_height;

      sl_transform_guest_to_host(window->ctx, window->paired_surface, &minw,
                                 &minh);
      xdg_toplevel_set_min_size(window->xdg_toplevel, minw, minh);
    }
    if (window->size_flags & P_MAX_SIZE) {
      int32_t maxw = window->max_width;
      int32_t maxh = window->max_height;

      sl_transform_guest_to_host(window->ctx, window->paired_surface, &maxw,
                                 &maxh);
      xdg_toplevel_set_max_size(window->xdg_toplevel, maxw, maxh);
    }
    if (window->maximized) {
      xdg_toplevel_set_maximized(window->xdg_toplevel);
    }
    if (window->fullscreen) {
      xdg_toplevel_set_fullscreen(window->xdg_toplevel, nullptr);
    }
  } else if (!window->xdg_popup) {
    struct xdg_positioner* positioner;
    int32_t diffx = window->x - parent->x;
    int32_t diffy = window->y - parent->y;

    positioner = xdg_wm_base_create_positioner(ctx->xdg_shell->internal);
    assert(positioner);

    sl_transform_guest_to_host(window->ctx, window->paired_surface, &diffx,
                               &diffy);
    xdg_positioner_set_anchor(positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
    xdg_positioner_set_gravity(positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
    xdg_positioner_set_anchor_rect(positioner, diffx, diffy, 1, 1);

    window->xdg_popup = xdg_surface_get_popup(window->xdg_surface,
                                              parent->xdg_surface, positioner);
    xdg_popup_add_listener(window->xdg_popup, &sl_internal_xdg_popup_listener,
                           window);

    xdg_positioner_destroy(positioner);
  }

  if ((window->size_flags & (US_POSITION | P_POSITION)) && parent &&
      ctx->aura_shell) {
    int32_t diffx = window->x - parent->x;
    int32_t diffy = window->y - parent->y;

    sl_transform_guest_to_host(window->ctx, window->paired_surface, &diffx,
                               &diffy);
    zaura_surface_set_parent(window->aura_surface, parent->aura_surface, diffx,
                             diffy);
  }

#ifdef COMMIT_LOOP_FIX
  sl_commit(window, host_surface);
#else
  wl_surface_commit(host_surface->proxy);
#endif

  if (host_surface->contents_width && host_surface->contents_height) {
    window->realized = 1;
  }
}

#ifdef QUIRKS_SUPPORT
bool sl_window_should_log_quirk(struct sl_window* window, int feature_enum) {
  return window->logged_quirks.insert(feature_enum).second;
}

std::set<int> sl_window_logged_quirks(struct sl_window* window) {
  return window->logged_quirks;
}
#endif

bool sl_window_is_client_positioned(struct sl_window* window) {
#ifdef QUIRKS_SUPPORT
  if (window->ctx->quirks.IsEnabled(window, quirks::FEATURE_X11_MOVE_WINDOWS)) {
    return true;
  }
#endif
  return window->ctx->enable_x11_move_windows;
}

bool sl_window_should_fix_randr_emu(struct sl_window* window) {
#ifdef QUIRKS_SUPPORT
  if (window->ctx->quirks.IsEnabled(window, quirks::FEATURE_RANDR_EMU_FIX)) {
    return true;
  }
#endif
  return false;
}

void sl_window_get_x_y(struct sl_window* window, uint32_t* x, uint32_t* y) {
  if (x != nullptr) {
    *x = window->x;
  }
  if (y != nullptr) {
    *y = window->y;
  }
}

void sl_window_get_width_height(struct sl_window* window,
                                uint32_t* w,
                                uint32_t* h) {
  if (window->use_emulated_rects) {
    if (w != nullptr) {
      *w = window->emulated_width;
    }
    if (h != nullptr) {
      *h = window->emulated_height;
    }
  } else {
    if (w != nullptr) {
      *w = window->width;
    }
    if (h != nullptr) {
      *h = window->height;
    }
  }
}

bool sl_window_get_output_virt_position(struct sl_window* window,
                                        uint32_t& mut_x,
                                        uint32_t& mut_y) {
  for (auto output : window->ctx->host_outputs) {
    if (window->x >= output->virt_x &&
        window->x < output->virt_x + output->virt_width &&
        window->y >= output->virt_y &&
        window->y < output->virt_y + output->virt_height) {
      mut_x = output->virt_x;
      mut_y = output->virt_y;
      return true;
    }
  }
  return false;
}
