mirror of
https://github.com/brl/mutter.git
synced 2025-01-07 18:22:14 +00:00
wayland: Port popup grabs to MetaWaylandEventInterface
This is again a grab interface that mostly wants to meddle with focus, logically setting a NULL surface if the surface client does not match the popup client. Since popups are meant to naturally work with any input device, the code has been refactored to not involve the MetaWaylandPointer directly in MetaWaylandPopup creation or getting the top popup surface (memory management was shuffled), or compressing multiple grabbing xdg_popups together (the existing grab maintains a single MetaWaylandEventHandler for all). Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
parent
125ba92169
commit
5ade2060a7
@ -1139,32 +1139,6 @@ meta_wayland_pointer_cancel_grab (MetaWaylandPointer *pointer)
|
||||
pointer->grab->interface->cancel (pointer->grab);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
|
||||
meta_wayland_popup_grab_destroy (popup_grab);
|
||||
}
|
||||
|
||||
MetaWaylandPopup *
|
||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
MetaWaylandPopupGrab *grab;
|
||||
|
||||
if (pointer->grab != &pointer->default_grab &&
|
||||
!meta_wayland_pointer_grab_is_popup_grab (pointer->grab))
|
||||
return NULL;
|
||||
|
||||
if (pointer->grab == &pointer->default_grab)
|
||||
grab = meta_wayland_popup_grab_create (pointer, popup_surface);
|
||||
else
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
|
||||
return meta_wayland_popup_create (popup_surface, grab);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
@ -1384,18 +1358,6 @@ meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer, uint32_t serial)
|
||||
return pointer->grab_serial == serial;
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPopupGrab *grab;
|
||||
|
||||
if (!meta_wayland_pointer_grab_is_popup_grab (pointer->grab))
|
||||
return NULL;
|
||||
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
return meta_wayland_popup_grab_get_top_popup(grab);
|
||||
}
|
||||
|
||||
static void
|
||||
relative_pointer_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
|
@ -122,11 +122,6 @@ void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
|
||||
void meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer);
|
||||
|
||||
MetaWaylandPopup *meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandPopupSurface *popup_surface);
|
||||
|
||||
void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
|
||||
|
||||
void meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t *x,
|
||||
@ -144,8 +139,6 @@ gboolean meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
||||
gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer,
|
||||
uint32_t serial);
|
||||
|
||||
MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer);
|
||||
|
||||
MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
|
||||
struct wl_client *client);
|
||||
void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource);
|
||||
|
@ -53,7 +53,10 @@ G_DEFINE_INTERFACE (MetaWaylandPopupSurface, meta_wayland_popup_surface,
|
||||
|
||||
struct _MetaWaylandPopupGrab
|
||||
{
|
||||
MetaWaylandPointerGrab generic;
|
||||
MetaWaylandSeat *seat;
|
||||
MetaWaylandEventHandler *handler;
|
||||
|
||||
int press_count;
|
||||
|
||||
struct wl_client *grab_client;
|
||||
struct wl_list all_popups;
|
||||
@ -66,12 +69,7 @@ struct _MetaWaylandPopup
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
static void
|
||||
meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
static void
|
||||
meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab);
|
||||
static void meta_wayland_popup_grab_finish (MetaWaylandPopupGrab *grab);
|
||||
|
||||
static void
|
||||
meta_wayland_popup_surface_default_init (MetaWaylandPopupSurfaceInterface *iface)
|
||||
@ -90,121 +88,165 @@ meta_wayland_popup_surface_dismiss (MetaWaylandPopupSurface *popup_surface)
|
||||
META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->dismiss (popup_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_popup_surface_finish (MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->finish (popup_surface);
|
||||
}
|
||||
|
||||
static MetaWaylandSurface *
|
||||
meta_wayland_popup_surface_get_surface (MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
return META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->get_surface (popup_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface)
|
||||
static MetaWaylandSurface *
|
||||
popup_grab_get_focus_surface (MetaWaylandEventHandler *handler,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab;
|
||||
MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (grab->pointer);
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
MetaWaylandPopupGrab *popup_grab = user_data;
|
||||
ClutterSeat *clutter_seat = clutter_input_device_get_seat (device);
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
/*
|
||||
* We rely on having a pointer grab even when the seat doesn't have
|
||||
* the pointer capability. In this case, we shouldn't update any pointer focus
|
||||
* since there is no such thing when the seat doesn't have the pointer
|
||||
* capability.
|
||||
*/
|
||||
if (!meta_wayland_seat_has_pointer (seat))
|
||||
return;
|
||||
if (device == clutter_seat_get_keyboard (clutter_seat) &&
|
||||
!wl_list_empty (&popup_grab->all_popups))
|
||||
{
|
||||
/* Keyboard focus must always go to the topmost surface */
|
||||
return meta_wayland_popup_grab_get_top_popup (popup_grab);
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = meta_wayland_event_handler_chain_up_get_focus_surface (handler,
|
||||
device,
|
||||
sequence);
|
||||
|
||||
/* Popup grabs are in owner-events mode (ie, events for the same client
|
||||
are reported as normal) */
|
||||
if (surface &&
|
||||
wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
meta_wayland_pointer_set_focus (grab->pointer, surface);
|
||||
else if (pointer->button_count == 0)
|
||||
meta_wayland_pointer_set_focus (grab->pointer, NULL);
|
||||
if (surface &&
|
||||
wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
return surface;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
popup_grab_focus (MetaWaylandEventHandler *handler,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaWaylandSurface *surface,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_wayland_pointer_send_motion (grab->pointer, event);
|
||||
meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
static gboolean
|
||||
popup_grab_press (MetaWaylandEventHandler *handler,
|
||||
const ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
MetaWaylandPopupGrab *popup_grab = user_data;
|
||||
|
||||
if (pointer->focus_surface)
|
||||
meta_wayland_pointer_send_button (grab->pointer, event);
|
||||
else if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE &&
|
||||
pointer->button_count == 0)
|
||||
meta_wayland_pointer_end_popup_grab (grab->pointer);
|
||||
popup_grab->press_count++;
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_cancel (MetaWaylandPointerGrab *grab)
|
||||
static gboolean
|
||||
popup_grab_release (MetaWaylandEventHandler *handler,
|
||||
const ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_wayland_pointer_end_popup_grab (grab->pointer);
|
||||
MetaWaylandPopupGrab *popup_grab = user_data;
|
||||
ClutterInputDevice *device = clutter_event_get_source_device (event);
|
||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
popup_grab->press_count = MAX (0, popup_grab->press_count - 1);
|
||||
|
||||
if (popup_grab->press_count == 0)
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
surface = meta_wayland_event_handler_chain_up_get_focus_surface (popup_grab->handler,
|
||||
device,
|
||||
sequence);
|
||||
if (!surface ||
|
||||
wl_resource_get_client (surface->resource) != popup_grab->grab_client)
|
||||
{
|
||||
meta_wayland_popup_grab_finish (popup_grab);
|
||||
return CLUTTER_EVENT_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static MetaWaylandPointerGrabInterface popup_grab_interface = {
|
||||
static MetaWaylandEventInterface popup_event_interface = {
|
||||
popup_grab_get_focus_surface,
|
||||
popup_grab_focus,
|
||||
popup_grab_motion,
|
||||
popup_grab_button,
|
||||
popup_grab_cancel
|
||||
NULL, /* motion */
|
||||
popup_grab_press,
|
||||
popup_grab_release,
|
||||
};
|
||||
|
||||
MetaWaylandPopupGrab *
|
||||
meta_wayland_popup_grab_create (MetaWaylandPointer *pointer,
|
||||
meta_wayland_popup_grab_create (MetaWaylandSeat *seat,
|
||||
MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_popup_surface_get_surface (popup_surface);
|
||||
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||
MetaWaylandInput *input = meta_wayland_seat_get_input (seat);
|
||||
MetaWaylandPopupGrab *grab;
|
||||
|
||||
grab = g_new0 (MetaWaylandPopupGrab, 1);
|
||||
grab->generic.interface = &popup_grab_interface;
|
||||
grab->generic.pointer = pointer;
|
||||
grab->seat = seat;
|
||||
grab->grab_client = client;
|
||||
wl_list_init (&grab->all_popups);
|
||||
|
||||
meta_wayland_popup_grab_begin (grab, surface);
|
||||
grab->handler =
|
||||
meta_wayland_input_attach_event_handler (input,
|
||||
&popup_event_interface,
|
||||
grab);
|
||||
|
||||
return grab;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab)
|
||||
{
|
||||
meta_wayland_popup_grab_end (grab);
|
||||
g_free (grab);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandPointer *pointer = grab->generic.pointer;
|
||||
|
||||
meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab)
|
||||
meta_wayland_popup_grab_finish (MetaWaylandPopupGrab *grab)
|
||||
{
|
||||
MetaWaylandPopup *popup, *tmp;
|
||||
|
||||
g_assert (grab->generic.interface == &popup_grab_interface);
|
||||
|
||||
wl_list_for_each_safe (popup, tmp, &grab->all_popups, link)
|
||||
{
|
||||
meta_wayland_popup_surface_done (popup->popup_surface);
|
||||
MetaWaylandPopupSurface *popup_surface = popup->popup_surface;
|
||||
|
||||
meta_wayland_popup_surface_done (popup_surface);
|
||||
meta_wayland_popup_destroy (popup);
|
||||
meta_wayland_popup_surface_finish (popup_surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab)
|
||||
{
|
||||
g_assert (wl_list_empty (&grab->all_popups));
|
||||
|
||||
if (grab->handler)
|
||||
{
|
||||
MetaWaylandInput *input = meta_wayland_seat_get_input (grab->seat);
|
||||
|
||||
meta_wayland_input_detach_event_handler (input, grab->handler);
|
||||
grab->handler = NULL;
|
||||
}
|
||||
|
||||
meta_wayland_pointer_end_grab (grab->generic.pointer);
|
||||
g_free (grab);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_popup_grab_has_popups (MetaWaylandPopupGrab *grab)
|
||||
{
|
||||
return !wl_list_empty (&grab->all_popups);
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
@ -218,41 +260,45 @@ meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab)
|
||||
return meta_wayland_popup_surface_get_surface (popup->popup_surface);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab)
|
||||
{
|
||||
return grab->interface == &popup_grab_interface;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_popup_destroy (MetaWaylandPopup *popup)
|
||||
{
|
||||
meta_wayland_popup_surface_dismiss (popup->popup_surface);
|
||||
|
||||
wl_list_remove (&popup->link);
|
||||
g_free (popup);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_popup_grab_repick_keyboard_focus (MetaWaylandPopupGrab *popup_grab)
|
||||
{
|
||||
MetaWaylandSeat *seat = popup_grab->seat;
|
||||
MetaContext *context =
|
||||
meta_wayland_compositor_get_context (seat->compositor);
|
||||
MetaBackend *backend = meta_context_get_backend (context);
|
||||
ClutterBackend *clutter_backend =
|
||||
meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *clutter_seat =
|
||||
clutter_backend_get_default_seat (clutter_backend);
|
||||
MetaWaylandInput *input;
|
||||
|
||||
input = meta_wayland_seat_get_input (seat);
|
||||
meta_wayland_input_invalidate_focus (input,
|
||||
clutter_seat_get_keyboard (clutter_seat),
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_popup_dismiss (MetaWaylandPopup *popup)
|
||||
{
|
||||
MetaWaylandPopupSurface *popup_surface = popup->popup_surface;
|
||||
MetaWaylandPopupGrab *popup_grab = popup->grab;
|
||||
|
||||
meta_wayland_popup_destroy (popup);
|
||||
|
||||
if (wl_list_empty (&popup_grab->all_popups))
|
||||
{
|
||||
meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer);
|
||||
}
|
||||
meta_wayland_popup_surface_finish (popup_surface);
|
||||
else
|
||||
{
|
||||
MetaWaylandSurface *top_popup_surface;
|
||||
MetaWaylandSeat *seat;
|
||||
|
||||
top_popup_surface = meta_wayland_popup_grab_get_top_popup (popup_grab);
|
||||
seat = meta_wayland_pointer_get_seat (popup_grab->generic.pointer);
|
||||
meta_wayland_seat_set_input_focus (seat, top_popup_surface);
|
||||
}
|
||||
meta_wayland_popup_grab_repick_keyboard_focus (popup_grab);
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
@ -268,7 +314,6 @@ meta_wayland_popup_create (MetaWaylandPopupSurface *popup_surface,
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_popup_surface_get_surface (popup_surface);
|
||||
MetaWaylandPopup *popup;
|
||||
MetaWaylandSeat *seat;
|
||||
|
||||
/* Don't allow creating popups if the grab has a different client. */
|
||||
if (grab->grab_client != wl_resource_get_client (surface->resource))
|
||||
@ -280,8 +325,7 @@ meta_wayland_popup_create (MetaWaylandPopupSurface *popup_surface,
|
||||
|
||||
wl_list_insert (&grab->all_popups, &popup->link);
|
||||
|
||||
seat = meta_wayland_pointer_get_seat (grab->generic.pointer);
|
||||
meta_wayland_seat_set_input_focus (seat, surface);
|
||||
meta_wayland_popup_grab_repick_keyboard_focus (grab);
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
@ -37,17 +37,18 @@ struct _MetaWaylandPopupSurfaceInterface
|
||||
|
||||
void (*done) (MetaWaylandPopupSurface *popup_surface);
|
||||
void (*dismiss) (MetaWaylandPopupSurface *popup_surface);
|
||||
void (*finish) (MetaWaylandPopupSurface *popup_surface);
|
||||
MetaWaylandSurface *(*get_surface) (MetaWaylandPopupSurface *popup_surface);
|
||||
};
|
||||
|
||||
MetaWaylandPopupGrab *meta_wayland_popup_grab_create (MetaWaylandPointer *pointer,
|
||||
MetaWaylandPopupGrab *meta_wayland_popup_grab_create (MetaWaylandSeat *seat,
|
||||
MetaWaylandPopupSurface *popup_surface);
|
||||
|
||||
void meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab);
|
||||
|
||||
MetaWaylandSurface *meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab);
|
||||
gboolean meta_wayland_popup_grab_has_popups (MetaWaylandPopupGrab *grab);
|
||||
|
||||
gboolean meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab);
|
||||
MetaWaylandSurface *meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab);
|
||||
|
||||
MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandPopupSurface *surface,
|
||||
MetaWaylandPopupGrab *grab);
|
||||
|
@ -55,6 +55,7 @@ typedef struct _MetaWaylandXdgShellClient
|
||||
struct wl_resource *resource;
|
||||
GList *surfaces;
|
||||
GList *surface_constructors;
|
||||
MetaWaylandPopupGrab *popup_grab;
|
||||
} MetaWaylandXdgShellClient;
|
||||
|
||||
struct _MetaWaylandXdgPositioner
|
||||
@ -1125,6 +1126,9 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||
MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup);
|
||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandXdgShellClient *xdg_shell_client = xdg_surface_priv->shell_client;
|
||||
struct wl_resource *xdg_wm_base_resource =
|
||||
meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
@ -1153,7 +1157,7 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
|
||||
if (seat)
|
||||
{
|
||||
MetaWaylandSurface *top_popup;
|
||||
MetaWaylandSurface *top_popup = NULL;
|
||||
|
||||
if (!meta_wayland_seat_can_popup (seat, serial))
|
||||
{
|
||||
@ -1161,7 +1165,9 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
return;
|
||||
}
|
||||
|
||||
top_popup = meta_wayland_pointer_get_top_popup (seat->pointer);
|
||||
if (xdg_shell_client->popup_grab)
|
||||
top_popup = meta_wayland_popup_grab_get_top_popup (xdg_shell_client->popup_grab);
|
||||
|
||||
if (top_popup && parent_surface != top_popup)
|
||||
{
|
||||
wl_resource_post_error (xdg_wm_base_resource,
|
||||
@ -1193,8 +1199,16 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
|
||||
|
||||
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 (!xdg_shell_client->popup_grab)
|
||||
{
|
||||
xdg_shell_client->popup_grab =
|
||||
meta_wayland_popup_grab_create (seat, popup_surface);
|
||||
}
|
||||
|
||||
popup = meta_wayland_popup_create (popup_surface,
|
||||
xdg_shell_client->popup_grab);
|
||||
|
||||
if (popup == NULL)
|
||||
{
|
||||
xdg_popup_send_popup_done (xdg_popup->resource);
|
||||
@ -1506,6 +1520,23 @@ meta_wayland_xdg_popup_dismiss (MetaWaylandPopupSurface *popup_surface)
|
||||
meta_wayland_xdg_popup_unmap (xdg_popup);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_popup_finish (MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (popup_surface);
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup);
|
||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandXdgShellClient *xdg_shell_client = xdg_surface_priv->shell_client;
|
||||
|
||||
if (xdg_shell_client->popup_grab &&
|
||||
!meta_wayland_popup_grab_has_popups (xdg_shell_client->popup_grab))
|
||||
{
|
||||
meta_wayland_popup_grab_destroy (xdg_shell_client->popup_grab);
|
||||
xdg_shell_client->popup_grab = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaWaylandSurface *
|
||||
meta_wayland_xdg_popup_get_surface (MetaWaylandPopupSurface *popup_surface)
|
||||
{
|
||||
@ -1520,6 +1551,7 @@ popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface)
|
||||
{
|
||||
iface->done = meta_wayland_xdg_popup_done;
|
||||
iface->dismiss = meta_wayland_xdg_popup_dismiss;
|
||||
iface->finish = meta_wayland_xdg_popup_finish;
|
||||
iface->get_surface = meta_wayland_xdg_popup_get_surface;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user