コード例 #1
0
static void
xdg_surface_destructor (struct wl_resource *resource)
{
  MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource);
  MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);

  meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
                                                   surface);
  meta_wayland_surface_destroy_window (surface);
  xdg_surface->resource = NULL;
}
コード例 #2
0
static void
meta_wayland_wl_shell_surface_popup_dismiss (MetaWaylandPopupSurface *popup_surface)
{
  MetaWaylandWlShellSurface *wl_shell_surface =
    META_WAYLAND_WL_SHELL_SURFACE (popup_surface);
  MetaWaylandSurfaceRole *surface_role =
    META_WAYLAND_SURFACE_ROLE (popup_surface);
  MetaWaylandSurface *surface =
    meta_wayland_surface_role_get_surface (surface_role);

  wl_shell_surface->popup = NULL;

  meta_wayland_surface_destroy_window (surface);
}
コード例 #3
0
static void
handle_popup_parent_destroyed (struct wl_listener *listener,
                               void               *data)
{
  MetaWaylandXdgPopup *xdg_popup =
    wl_container_of (listener, xdg_popup, parent_destroy_listener);
  MetaWaylandSurfaceRole *surface_role =
    META_WAYLAND_SURFACE_ROLE (xdg_popup);
  MetaWaylandSurface *surface =
    meta_wayland_surface_role_get_surface (surface_role);

  wl_resource_post_error (xdg_popup->xdg_shell_resource,
                          XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
                          "destroyed popup not top most popup");
  xdg_popup->parent_surface = NULL;

  meta_wayland_surface_destroy_window (surface);
}
コード例 #4
0
static void
wl_shell_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
                              MetaWaylandPendingState *pending)
{
  MetaWaylandWlShellSurface *wl_shell_surface =
    META_WAYLAND_WL_SHELL_SURFACE (surface_role);
  MetaWaylandSurfaceRoleClass *surface_role_class;
  MetaWaylandSurface *surface =
    meta_wayland_surface_role_get_surface (surface_role);
  MetaWindow *window = surface->window;
  MetaRectangle geom = { 0 };

  surface_role_class =
    META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_wl_shell_surface_parent_class);
  surface_role_class->commit (surface_role, pending);

  /* For wl_shell, it's equivalent to an unmap. Semantics
   * are poorly defined, so we can choose some that are
   * convenient for us. */
  if (surface->buffer_ref.buffer && !window)
    {
      create_wl_shell_surface_window (surface);
    }
  else if (!surface->buffer_ref.buffer && window)
    {
      if (wl_shell_surface->popup)
        meta_wayland_popup_dismiss (wl_shell_surface->popup);
      else
        meta_wayland_surface_destroy_window (surface);
      return;
    }

  if (!window)
    return;

  if (!pending->newly_attached)
    return;

  meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0);
  meta_window_wayland_move_resize (window,
                                   NULL,
                                   geom, pending->dx, pending->dy);
}
コード例 #5
0
static void
meta_wayland_xdg_popup_dismiss (MetaWaylandPopupSurface *popup_surface)
{
  MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (popup_surface);
  MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup);
  MetaWaylandSurface *surface =
    meta_wayland_surface_role_get_surface (surface_role);
  MetaWaylandSurface *top_popup;

  top_popup = meta_wayland_popup_get_top_popup (xdg_popup->popup);
  if (surface != top_popup)
    {
      wl_resource_post_error (xdg_popup->xdg_shell_resource,
                              XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
                              "destroyed popup not top most popup");
    }

  xdg_popup->popup = NULL;

  meta_wayland_surface_destroy_window (surface);
}
コード例 #6
0
static void
xdg_shell_get_xdg_popup (struct wl_client   *client,
                         struct wl_resource *resource,
                         uint32_t            id,
                         struct wl_resource *surface_resource,
                         struct wl_resource *parent_resource,
                         struct wl_resource *seat_resource,
                         uint32_t            serial,
                         int32_t             x,
                         int32_t             y)
{
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
  MetaWaylandPopupSurface *popup_surface;
  MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource);
  MetaWaylandSurface *top_popup;
  MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
  MetaWindow *window;
  MetaDisplay *display = meta_get_display ();
  MetaWaylandXdgPopup *xdg_popup;
  MetaWaylandPopup *popup;

  if (META_IS_WAYLAND_XDG_POPUP (surface->role) &&
      META_WAYLAND_XDG_POPUP (surface->role)->resource)
    {
      wl_resource_post_error (surface_resource,
                              WL_DISPLAY_ERROR_INVALID_OBJECT,
                              "xdg_shell::get_xdg_popup already requested");
      return;
    }

  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_POPUP))
    {
      wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
                              "wl_surface@%d already has a different role",
                              wl_resource_get_id (surface->resource));
      return;
    }

  if (parent_surf == NULL ||
      parent_surf->window == NULL ||
      (!META_IS_WAYLAND_XDG_POPUP (parent_surf->role) &&
       !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role)))
    {
      wl_resource_post_error (resource,
                              XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
                              "invalid parent surface");
      return;
    }

  top_popup = meta_wayland_pointer_get_top_popup (&seat->pointer);
  if ((top_popup == NULL && !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role)) ||
      (top_popup != NULL && parent_surf != top_popup))
    {
      wl_resource_post_error (resource,
                              XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
                              "parent not top most surface");
      return;
    }

  xdg_popup = META_WAYLAND_XDG_POPUP (surface->role);
  xdg_popup->resource = wl_resource_create (client, &xdg_popup_interface,
                                            wl_resource_get_version (resource), id);
  wl_resource_set_implementation (xdg_popup->resource,
                                  &meta_wayland_xdg_popup_interface,
                                  xdg_popup,
                                  xdg_popup_destructor);

  xdg_popup->xdg_shell_resource = resource;

  if (!meta_wayland_seat_can_popup (seat, serial))
    {
      xdg_popup_send_popup_done (xdg_popup->resource);
      return;
    }

  xdg_popup->parent_surface = parent_surf;
  xdg_popup->parent_destroy_listener.notify = handle_popup_parent_destroyed;
  wl_resource_add_destroy_listener (parent_surf->resource,
                                    &xdg_popup->parent_destroy_listener);

  window = meta_window_wayland_new (display, surface);
  meta_window_wayland_place_relative_to (window, parent_surf->window, x, y);
  window->showing_for_first_time = FALSE;

  meta_wayland_surface_set_window (surface, window);

  meta_window_focus (window, meta_display_get_current_time (display));
  popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role);
  popup = meta_wayland_pointer_start_popup_grab (&seat->pointer,
                                                 popup_surface);
  if (popup == NULL)
    {
      xdg_popup_send_popup_done (xdg_popup->resource);
      meta_wayland_surface_destroy_window (surface);
      return;
    }

  xdg_popup->popup = popup;
}