mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-23 18:39:48 +01:00
Merge pull request #857 from emersion/shell-always-unmap
Always unmap before destroying surface
This commit is contained in:
commit
65903d2677
4 changed files with 59 additions and 25 deletions
|
@ -102,6 +102,16 @@ struct wlr_xdg_surface_configure {
|
||||||
struct wlr_xdg_toplevel_state *toplevel_state;
|
struct wlr_xdg_toplevel_state *toplevel_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An xdg-surface is a user interface element requiring management by the
|
||||||
|
* compositor. An xdg-surface alone isn't useful, a role should be assigned to
|
||||||
|
* it in order to map it.
|
||||||
|
*
|
||||||
|
* When a surface has a role and is ready to be displayed, the `map` event is
|
||||||
|
* emitted. When a surface should no longer be displayed, the `unmap` event is
|
||||||
|
* emitted. The `unmap` event is guaranted to be emitted before the `destroy`
|
||||||
|
* event if the view is destroyed when mapped.
|
||||||
|
*/
|
||||||
struct wlr_xdg_surface {
|
struct wlr_xdg_surface {
|
||||||
struct wlr_xdg_client *client;
|
struct wlr_xdg_client *client;
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
|
|
@ -90,6 +90,16 @@ struct wlr_xdg_toplevel_v6_state {
|
||||||
uint32_t min_width, min_height;
|
uint32_t min_width, min_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An xdg-surface is a user interface element requiring management by the
|
||||||
|
* compositor. An xdg-surface alone isn't useful, a role should be assigned to
|
||||||
|
* it in order to map it.
|
||||||
|
*
|
||||||
|
* When a surface has a role and is ready to be displayed, the `map` event is
|
||||||
|
* emitted. When a surface should no longer be displayed, the `unmap` event is
|
||||||
|
* emitted. The `unmap` event is guaranted to be emitted before the `destroy`
|
||||||
|
* event if the view is destroyed when mapped.
|
||||||
|
*/
|
||||||
struct wlr_xdg_toplevel_v6 {
|
struct wlr_xdg_toplevel_v6 {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wlr_xdg_surface_v6 *base;
|
struct wlr_xdg_surface_v6 *base;
|
||||||
|
|
|
@ -75,6 +75,15 @@ struct wlr_xwayland_surface_size_hints {
|
||||||
uint32_t win_gravity;
|
uint32_t win_gravity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Xwayland user interface component. It has an absolute position in
|
||||||
|
* layout-local coordinates.
|
||||||
|
*
|
||||||
|
* When a surface is ready to be displayed, the `map` event is emitted. When a
|
||||||
|
* surface should no longer be displayed, the `unmap` event is emitted. The
|
||||||
|
* `unmap` event is guaranted to be emitted before the `destroy` event if the
|
||||||
|
* view is destroyed when mapped.
|
||||||
|
*/
|
||||||
struct wlr_xwayland_surface {
|
struct wlr_xwayland_surface {
|
||||||
xcb_window_t window_id;
|
xcb_window_t window_id;
|
||||||
struct wlr_xwm *xwm;
|
struct wlr_xwm *xwm;
|
||||||
|
@ -116,8 +125,7 @@ struct wlr_xwayland_surface {
|
||||||
|
|
||||||
// _NET_WM_STATE
|
// _NET_WM_STATE
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool maximized_vert;
|
bool maximized_vert, maximized_horz;
|
||||||
bool maximized_horz;
|
|
||||||
|
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
|
|
||||||
|
|
|
@ -273,8 +273,12 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
|
||||||
i, property);
|
i, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xsurface_unmap(struct wlr_xwayland_surface *surface);
|
||||||
|
|
||||||
static void wlr_xwayland_surface_destroy(
|
static void wlr_xwayland_surface_destroy(
|
||||||
struct wlr_xwayland_surface *xsurface) {
|
struct wlr_xwayland_surface *xsurface) {
|
||||||
|
xsurface_unmap(xsurface);
|
||||||
|
|
||||||
wlr_signal_emit_safe(&xsurface->events.destroy, xsurface);
|
wlr_signal_emit_safe(&xsurface->events.destroy, xsurface);
|
||||||
|
|
||||||
if (xsurface == xsurface->xwm->focus_surface) {
|
if (xsurface == xsurface->xwm->focus_surface) {
|
||||||
|
@ -618,7 +622,8 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface,
|
||||||
if (!xsurface->added &&
|
if (!xsurface->added &&
|
||||||
wlr_surface_has_buffer(xsurface->surface) &&
|
wlr_surface_has_buffer(xsurface->surface) &&
|
||||||
xsurface->mapped) {
|
xsurface->mapped) {
|
||||||
wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface, xsurface);
|
wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface,
|
||||||
|
xsurface);
|
||||||
xsurface->added = true;
|
xsurface->added = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,9 +631,7 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface,
|
||||||
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xwayland_surface *xsurface =
|
struct wlr_xwayland_surface *xsurface =
|
||||||
wl_container_of(listener, xsurface, surface_destroy);
|
wl_container_of(listener, xsurface, surface_destroy);
|
||||||
|
xsurface_unmap(xsurface);
|
||||||
xsurface->surface = NULL;
|
|
||||||
// TODO destroy xwayland surface?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xwm_map_shell_surface(struct wlr_xwm *xwm,
|
static void xwm_map_shell_surface(struct wlr_xwm *xwm,
|
||||||
|
@ -665,6 +668,27 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm,
|
||||||
wlr_signal_emit_safe(&xsurface->events.map, xsurface);
|
wlr_signal_emit_safe(&xsurface->events.map, xsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xsurface_unmap(struct wlr_xwayland_surface *surface) {
|
||||||
|
if (surface->mapped) {
|
||||||
|
surface->mapped = false;
|
||||||
|
wlr_signal_emit_safe(&surface->events.unmap, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surface->surface_id) {
|
||||||
|
// Make sure we're not on the unpaired surface list or we
|
||||||
|
// could be assigned a surface during surface creation that
|
||||||
|
// was mapped before this unmap request.
|
||||||
|
wl_list_remove(&surface->unpaired_link);
|
||||||
|
surface->surface_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surface->surface) {
|
||||||
|
wlr_surface_set_role_committed(surface->surface, NULL, NULL);
|
||||||
|
wl_list_remove(&surface->surface_destroy.link);
|
||||||
|
surface->surface = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void xwm_handle_create_notify(struct wlr_xwm *xwm,
|
static void xwm_handle_create_notify(struct wlr_xwm *xwm,
|
||||||
xcb_create_notify_event_t *ev) {
|
xcb_create_notify_event_t *ev) {
|
||||||
wlr_log(L_DEBUG, "XCB_CREATE_NOTIFY (%u)", ev->window);
|
wlr_log(L_DEBUG, "XCB_CREATE_NOTIFY (%u)", ev->window);
|
||||||
|
@ -778,25 +802,7 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xsurface->mapped) {
|
xsurface_unmap(xsurface);
|
||||||
xsurface->mapped = false;
|
|
||||||
wlr_signal_emit_safe(&xsurface->events.unmap, xsurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xsurface->surface_id) {
|
|
||||||
// Make sure we're not on the unpaired surface list or we
|
|
||||||
// could be assigned a surface during surface creation that
|
|
||||||
// was mapped before this unmap request.
|
|
||||||
wl_list_remove(&xsurface->unpaired_link);
|
|
||||||
xsurface->surface_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xsurface->surface) {
|
|
||||||
wlr_surface_set_role_committed(xsurface->surface, NULL, NULL);
|
|
||||||
wl_list_remove(&xsurface->surface_destroy.link);
|
|
||||||
}
|
|
||||||
xsurface->surface = NULL;
|
|
||||||
|
|
||||||
xsurface_set_wm_state(xsurface, ICCCM_WITHDRAWN_STATE);
|
xsurface_set_wm_state(xsurface, ICCCM_WITHDRAWN_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue