wayland: Fail clients who try to create or destroy a not-top-most popup
If a client creates an xdg_popup given a parent that is a xdg_popup that is not the most top one in the grab chain, send the not_the_topmost_popup error. Also fail a client who destroys a popup that is not the top most one. https://bugzilla.gnome.org/show_bug.cgi?id=744452
This commit is contained in:
parent
be77874ec9
commit
9a99a80710
@ -741,3 +741,15 @@ meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer, uint32_t serial)
|
|||||||
{
|
{
|
||||||
return pointer->grab_serial == 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);
|
||||||
|
}
|
||||||
|
@ -125,4 +125,6 @@ gboolean meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer,
|
|||||||
gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer,
|
gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer,
|
||||||
uint32_t serial);
|
uint32_t serial);
|
||||||
|
|
||||||
|
MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_POINTER_H */
|
#endif /* META_WAYLAND_POINTER_H */
|
||||||
|
@ -172,6 +172,17 @@ meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab)
|
|||||||
meta_wayland_pointer_end_grab (grab->generic.pointer);
|
meta_wayland_pointer_end_grab (grab->generic.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWaylandSurface *
|
||||||
|
meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab)
|
||||||
|
{
|
||||||
|
MetaWaylandPopup *popup;
|
||||||
|
|
||||||
|
g_assert (!wl_list_empty (&grab->all_popups));
|
||||||
|
popup = wl_container_of (grab->all_popups.next, popup, link);
|
||||||
|
|
||||||
|
return popup->surface;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab)
|
meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab)
|
||||||
{
|
{
|
||||||
@ -199,6 +210,12 @@ meta_wayland_popup_dismiss (MetaWaylandPopup *popup)
|
|||||||
meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer);
|
meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWaylandSurface *
|
||||||
|
meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup)
|
||||||
|
{
|
||||||
|
return meta_wayland_popup_grab_get_top_popup (popup->grab);
|
||||||
|
}
|
||||||
|
|
||||||
struct wl_signal *
|
struct wl_signal *
|
||||||
meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup)
|
meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +37,8 @@ void meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab,
|
|||||||
|
|
||||||
void meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab);
|
void meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab);
|
||||||
|
|
||||||
|
MetaWaylandSurface *meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab);
|
||||||
|
|
||||||
gboolean meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab);
|
gboolean meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab);
|
||||||
|
|
||||||
MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandSurface *surface,
|
MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandSurface *surface,
|
||||||
@ -46,6 +48,8 @@ void meta_wayland_popup_destroy (MetaWaylandPopup *popup);
|
|||||||
|
|
||||||
void meta_wayland_popup_dismiss (MetaWaylandPopup *popup);
|
void meta_wayland_popup_dismiss (MetaWaylandPopup *popup);
|
||||||
|
|
||||||
|
MetaWaylandSurface *meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup);
|
||||||
|
|
||||||
struct wl_signal *meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup);
|
struct wl_signal *meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_POPUP_H */
|
#endif /* META_WAYLAND_POPUP_H */
|
||||||
|
@ -1041,9 +1041,19 @@ static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = {
|
|||||||
static void
|
static void
|
||||||
handle_popup_destroyed (struct wl_listener *listener, void *data)
|
handle_popup_destroyed (struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
MetaWaylandPopup *popup = data;
|
||||||
|
MetaWaylandSurface *top_popup;
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
wl_container_of (listener, surface, popup.destroy_listener);
|
wl_container_of (listener, surface, popup.destroy_listener);
|
||||||
|
|
||||||
|
top_popup = meta_wayland_popup_get_top_popup (popup);
|
||||||
|
if (surface != top_popup)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (surface->xdg_popup,
|
||||||
|
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||||
|
"destroyed popup not top most popup");
|
||||||
|
}
|
||||||
|
|
||||||
surface->popup.popup = NULL;
|
surface->popup.popup = NULL;
|
||||||
|
|
||||||
destroy_window (surface);
|
destroy_window (surface);
|
||||||
@ -1063,6 +1073,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
|||||||
struct wl_resource *popup_resource;
|
struct wl_resource *popup_resource;
|
||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||||
MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource);
|
MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource);
|
||||||
|
MetaWaylandSurface *top_popup;
|
||||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaDisplay *display = meta_get_display ();
|
MetaDisplay *display = meta_get_display ();
|
||||||
@ -1093,6 +1104,16 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
top_popup = meta_wayland_pointer_get_top_popup (&seat->pointer);
|
||||||
|
if ((top_popup == NULL && parent_surf->xdg_surface == NULL) ||
|
||||||
|
(top_popup != NULL && parent_surf != top_popup))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource,
|
||||||
|
XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
|
||||||
|
"parent not top most surface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
popup_resource = wl_resource_create (client, &xdg_popup_interface,
|
popup_resource = wl_resource_create (client, &xdg_popup_interface,
|
||||||
wl_resource_get_version (resource), id);
|
wl_resource_get_version (resource), id);
|
||||||
wl_resource_set_implementation (popup_resource,
|
wl_resource_set_implementation (popup_resource,
|
||||||
|
Loading…
Reference in New Issue
Block a user