[mutter] wayland: Unmap popup windows when a popup chain is dismissed
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland: Unmap popup windows when a popup chain is dismissed
- Date: Tue, 17 Feb 2015 14:17:22 +0000 (UTC)
commit be77874ec92dd7ff936955ac89ce67db5edc2a08
Author: Jonas Ådahl <jadahl gmail com>
Date: Thu Feb 12 11:13:55 2015 +0800
wayland: Unmap popup windows when a popup chain is dismissed
When dismissing a popup grab, always unmap every popup window in the
chain, instead of relying on the surfaces and xdg_popups being
destroyed.
https://bugzilla.gnome.org/show_bug.cgi?id=744452
src/wayland/meta-wayland-pointer.c | 9 +++------
src/wayland/meta-wayland-pointer.h | 4 ++--
src/wayland/meta-wayland-popup.c | 10 ++++++++++
src/wayland/meta-wayland-popup.h | 2 ++
src/wayland/meta-wayland-surface.c | 28 ++++++++++++++++++++++++++--
src/wayland/meta-wayland-surface.h | 6 ++++++
6 files changed, 49 insertions(+), 10 deletions(-)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index b9d7f66..5905cb9 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -581,7 +581,7 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
meta_wayland_popup_grab_destroy (popup_grab);
}
-gboolean
+MetaWaylandPopup *
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
@@ -589,7 +589,7 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
if (pointer->grab != &pointer->default_grab &&
!meta_wayland_pointer_grab_is_popup_grab (pointer->grab))
- return FALSE;
+ return NULL;
if (pointer->grab == &pointer->default_grab)
{
@@ -601,10 +601,7 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
else
grab = (MetaWaylandPopupGrab*)pointer->grab;
- if (meta_wayland_popup_create (surface, grab) == NULL)
- return FALSE;
-
- return TRUE;
+ return meta_wayland_popup_create (surface, grab);
}
void
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 5dadd5f..60125ac 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -99,8 +99,8 @@ void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
void meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer);
-gboolean meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
- MetaWaylandSurface *popup);
+MetaWaylandPopup *meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
+ MetaWaylandSurface *popup);
void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
diff --git a/src/wayland/meta-wayland-popup.c b/src/wayland/meta-wayland-popup.c
index 9a70ce3..cc8b4bd 100644
--- a/src/wayland/meta-wayland-popup.c
+++ b/src/wayland/meta-wayland-popup.c
@@ -61,6 +61,7 @@ struct _MetaWaylandPopup
MetaWaylandPopupGrab *grab;
MetaWaylandSurface *surface;
struct wl_listener surface_destroy_listener;
+ struct wl_signal destroy_signal;
struct wl_list link;
};
@@ -180,6 +181,8 @@ meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab)
void
meta_wayland_popup_destroy (MetaWaylandPopup *popup)
{
+ wl_signal_emit (&popup->destroy_signal, popup);
+
wl_list_remove (&popup->surface_destroy_listener.link);
wl_list_remove (&popup->link);
g_slice_free (MetaWaylandPopup, popup);
@@ -196,6 +199,12 @@ meta_wayland_popup_dismiss (MetaWaylandPopup *popup)
meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer);
}
+struct wl_signal *
+meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup)
+{
+ return &popup->destroy_signal;
+}
+
static void
on_popup_surface_destroy (struct wl_listener *listener,
void *data)
@@ -220,6 +229,7 @@ meta_wayland_popup_create (MetaWaylandSurface *surface,
popup->grab = grab;
popup->surface = surface;
popup->surface_destroy_listener.notify = on_popup_surface_destroy;
+ wl_signal_init (&popup->destroy_signal);
if (surface->xdg_popup)
{
diff --git a/src/wayland/meta-wayland-popup.h b/src/wayland/meta-wayland-popup.h
index bba6d56..7082225 100644
--- a/src/wayland/meta-wayland-popup.h
+++ b/src/wayland/meta-wayland-popup.h
@@ -46,4 +46,6 @@ void meta_wayland_popup_destroy (MetaWaylandPopup *popup);
void meta_wayland_popup_dismiss (MetaWaylandPopup *popup);
+struct wl_signal *meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup);
+
#endif /* META_WAYLAND_POPUP_H */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index b7c888d..6751301 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1021,7 +1021,9 @@ xdg_popup_destructor (struct wl_resource *resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- destroy_window (surface);
+ if (surface->popup.popup)
+ meta_wayland_popup_dismiss (surface->popup.popup);
+
surface->xdg_popup = NULL;
}
@@ -1037,6 +1039,17 @@ static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = {
};
static void
+handle_popup_destroyed (struct wl_listener *listener, void *data)
+{
+ MetaWaylandSurface *surface =
+ wl_container_of (listener, surface, popup.destroy_listener);
+
+ surface->popup.popup = NULL;
+
+ destroy_window (surface);
+}
+
+static void
xdg_shell_get_xdg_popup (struct wl_client *client,
struct wl_resource *resource,
uint32_t id,
@@ -1053,6 +1066,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
MetaWindow *window;
MetaDisplay *display = meta_get_display ();
+ MetaWaylandPopup *popup;
if (parent_surf == NULL || parent_surf->window == NULL)
return;
@@ -1107,7 +1121,17 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
meta_wayland_surface_set_window (surface, window);
meta_window_focus (window, meta_display_get_current_time (display));
- meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
+ popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
+ if (popup == NULL)
+ {
+ destroy_window (surface);
+ return;
+ }
+
+ surface->popup.destroy_listener.notify = handle_popup_destroyed;
+ surface->popup.popup = popup;
+ wl_signal_add (meta_wayland_popup_get_destroy_signal (popup),
+ &surface->popup.destroy_listener);
}
static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = {
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index dd8497a..0f13dfd 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -100,6 +100,12 @@ struct _MetaWaylandSurface
MetaWaylandSerial acked_configure_serial;
gboolean has_set_geometry;
+ /* xdg_popup */
+ struct {
+ MetaWaylandPopup *popup;
+ struct wl_listener destroy_listener;
+ } popup;
+
/* wl_subsurface stuff. */
struct {
MetaWaylandSurface *parent;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]