static MetaWaylandSurface * meta_wayland_wl_shell_surface_popup_get_surface (MetaWaylandPopupSurface *popup_surface) { MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (popup_surface); return meta_wayland_surface_role_get_surface (surface_role); }
static MetaWaylandSurface * surface_from_xdg_popup_resource (struct wl_resource *resource) { MetaWaylandXdgPopup *xdg_popup = wl_resource_get_user_data (resource); MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); return meta_wayland_surface_role_get_surface (surface_role); }
static MetaWaylandSurface * surface_from_wl_shell_surface_resource (struct wl_resource *resource) { MetaWaylandWlShellSurface *wl_shell_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (wl_shell_surface); return meta_wayland_surface_role_get_surface (surface_role); }
static MetaWaylandSurface * wl_shell_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role) { MetaWaylandWlShellSurface *wl_shell_surface = META_WAYLAND_WL_SHELL_SURFACE (surface_role); if (wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_POPUP && wl_shell_surface->parent_surface) return meta_wayland_surface_get_toplevel (wl_shell_surface->parent_surface); else return meta_wayland_surface_role_get_surface (surface_role); }
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); }
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); }
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); }
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); }
static void xdg_popup_role_commit (MetaWaylandSurfaceRole *surface_role, MetaWaylandPendingState *pending) { 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_xdg_popup_parent_class); surface_role_class->commit (surface_role, pending); if (surface->buffer_ref.buffer == NULL) { /* XDG surfaces can't commit NULL buffers */ wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "Cannot commit a NULL buffer to an xdg_popup"); return; } if (!pending->newly_attached) return; /* If the window disappeared the surface is not coming back. */ if (!window) return; meta_wayland_surface_apply_window_state (surface, pending); meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0); meta_window_wayland_move_resize (window, NULL, geom, pending->dx, pending->dy); }
static void xdg_surface_role_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, int new_width, int new_height, MetaWaylandSerial *sent_serial) { MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (shell_surface_role); MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (shell_surface_role); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); struct wl_client *client = wl_resource_get_client (xdg_surface->resource); struct wl_display *display = wl_client_get_display (client); uint32_t serial = wl_display_next_serial (display); struct wl_array states; if (!xdg_surface->resource) return; wl_array_init (&states); fill_states (&states, surface->window); xdg_surface_send_configure (xdg_surface->resource, new_width, new_height, &states, serial); wl_array_release (&states); if (sent_serial) { sent_serial->set = TRUE; sent_serial->value = serial; } }
static MetaWaylandSurface * xdg_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role) { return meta_wayland_surface_role_get_surface (surface_role); }
static void xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role, MetaWaylandPendingState *pending) { MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_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_xdg_surface_parent_class); surface_role_class->commit (surface_role, pending); if (surface->buffer_ref.buffer == NULL) { /* XDG surfaces can't commit NULL buffers */ wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "Cannot commit a NULL buffer to an xdg_surface"); return; } if (!pending->newly_attached) return; /* If the window disappeared the surface is not coming back. */ if (!window) return; meta_wayland_surface_apply_window_state (surface, pending); if (pending->has_new_geometry) { /* If we have new geometry, use it. */ geom = pending->new_geometry; xdg_surface->has_set_geometry = TRUE; } else if (!xdg_surface->has_set_geometry) { /* If the surface has never set any geometry, calculate * a default one unioning the surface and all subsurfaces together. */ meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0); } else { /* Otherwise, keep the geometry the same. */ /* XXX: We don't store the geometry in any consistent place * right now, so we can't re-fetch it. We should change * meta_window_wayland_move_resize. */ /* XXX: This is the common case. Recognize it to prevent * a warning. */ if (pending->dx == 0 && pending->dy == 0) return; g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now."); return; } meta_window_wayland_move_resize (window, &xdg_surface->acked_configure_serial, geom, pending->dx, pending->dy); xdg_surface->acked_configure_serial.set = FALSE; }