surface: add wlr_surface_role.precommit
This allows to emit the unmap event before the surface becomes actually unmapped for most shells.
This commit is contained in:
parent
4984ea49ee
commit
16d7e09d99
|
@ -19,7 +19,8 @@ struct wlr_xdg_surface *create_xdg_surface(
|
||||||
uint32_t id);
|
uint32_t id);
|
||||||
void unmap_xdg_surface(struct wlr_xdg_surface *surface);
|
void unmap_xdg_surface(struct wlr_xdg_surface *surface);
|
||||||
void destroy_xdg_surface(struct wlr_xdg_surface *surface);
|
void destroy_xdg_surface(struct wlr_xdg_surface *surface);
|
||||||
void handle_xdg_surface_committed(struct wlr_surface *wlr_surface);
|
void handle_xdg_surface_commit(struct wlr_surface *wlr_surface);
|
||||||
|
void handle_xdg_surface_precommit(struct wlr_surface *wlr_surface);
|
||||||
|
|
||||||
void create_xdg_positioner(struct wlr_xdg_client *client, uint32_t id);
|
void create_xdg_positioner(struct wlr_xdg_client *client, uint32_t id);
|
||||||
struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource(
|
struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource(
|
||||||
|
|
|
@ -19,7 +19,8 @@ struct wlr_xdg_surface_v6 *create_xdg_surface_v6(
|
||||||
uint32_t id);
|
uint32_t id);
|
||||||
void unmap_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
|
void unmap_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
|
||||||
void destroy_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
|
void destroy_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
|
||||||
void handle_xdg_surface_v6_committed(struct wlr_surface *wlr_surface);
|
void handle_xdg_surface_v6_commit(struct wlr_surface *wlr_surface);
|
||||||
|
void handle_xdg_surface_v6_precommit(struct wlr_surface *wlr_surface);
|
||||||
|
|
||||||
void create_xdg_positioner_v6(struct wlr_xdg_client_v6 *client, uint32_t id);
|
void create_xdg_positioner_v6(struct wlr_xdg_client_v6 *client, uint32_t id);
|
||||||
struct wlr_xdg_positioner_v6_resource *get_xdg_positioner_v6_from_resource(
|
struct wlr_xdg_positioner_v6_resource *get_xdg_positioner_v6_from_resource(
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct wlr_surface_state {
|
||||||
struct wlr_surface_role {
|
struct wlr_surface_role {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*commit)(struct wlr_surface *surface);
|
void (*commit)(struct wlr_surface *surface);
|
||||||
|
void (*precommit)(struct wlr_surface *surface);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_surface {
|
struct wlr_surface {
|
||||||
|
|
|
@ -360,10 +360,14 @@ static void surface_update_opaque_region(struct wlr_surface *surface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_commit_pending(struct wlr_surface *surface) {
|
static void surface_commit_pending(struct wlr_surface *surface) {
|
||||||
bool invalid_buffer = surface->pending.committed & WLR_SURFACE_STATE_BUFFER;
|
|
||||||
|
|
||||||
surface_state_finalize(surface, &surface->pending);
|
surface_state_finalize(surface, &surface->pending);
|
||||||
|
|
||||||
|
if (surface->role && surface->role->precommit) {
|
||||||
|
surface->role->precommit(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool invalid_buffer = surface->pending.committed & WLR_SURFACE_STATE_BUFFER;
|
||||||
|
|
||||||
surface->sx += surface->pending.dx;
|
surface->sx += surface->pending.dx;
|
||||||
surface->sy += surface->pending.dy;
|
surface->sy += surface->pending.dy;
|
||||||
surface_update_damage(&surface->buffer_damage,
|
surface_update_damage(&surface->buffer_damage,
|
||||||
|
|
|
@ -214,7 +214,8 @@ static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
|
|
||||||
const struct wlr_surface_role xdg_popup_surface_role = {
|
const struct wlr_surface_role xdg_popup_surface_role = {
|
||||||
.name = "xdg_popup",
|
.name = "xdg_popup",
|
||||||
.commit = handle_xdg_surface_committed,
|
.commit = handle_xdg_surface_commit,
|
||||||
|
.precommit = handle_xdg_surface_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
void create_xdg_popup(struct wlr_xdg_surface *xdg_surface,
|
void create_xdg_popup(struct wlr_xdg_surface *xdg_surface,
|
||||||
|
|
|
@ -313,7 +313,7 @@ static void xdg_surface_handle_surface_commit(struct wl_listener *listener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_xdg_surface_committed(struct wlr_surface *wlr_surface) {
|
void handle_xdg_surface_commit(struct wlr_surface *wlr_surface) {
|
||||||
struct wlr_xdg_surface *surface =
|
struct wlr_xdg_surface *surface =
|
||||||
wlr_xdg_surface_from_wlr_surface(wlr_surface);
|
wlr_xdg_surface_from_wlr_surface(wlr_surface);
|
||||||
if (surface == NULL) {
|
if (surface == NULL) {
|
||||||
|
@ -355,6 +355,22 @@ void handle_xdg_surface_committed(struct wlr_surface *wlr_surface) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_xdg_surface_precommit(struct wlr_surface *wlr_surface) {
|
||||||
|
struct wlr_xdg_surface *surface =
|
||||||
|
wlr_xdg_surface_from_wlr_surface(wlr_surface);
|
||||||
|
if (surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface->pending.committed & WLR_SURFACE_STATE_BUFFER &&
|
||||||
|
wlr_surface->pending.buffer_resource == NULL) {
|
||||||
|
// This is a NULL commit
|
||||||
|
if (surface->configured && surface->mapped) {
|
||||||
|
unmap_xdg_surface(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void xdg_surface_handle_surface_destroy(struct wl_listener *listener,
|
static void xdg_surface_handle_surface_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_xdg_surface *xdg_surface =
|
struct wlr_xdg_surface *xdg_surface =
|
||||||
|
|
|
@ -449,7 +449,8 @@ static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
|
|
||||||
const struct wlr_surface_role xdg_toplevel_surface_role = {
|
const struct wlr_surface_role xdg_toplevel_surface_role = {
|
||||||
.name = "xdg_toplevel",
|
.name = "xdg_toplevel",
|
||||||
.commit = handle_xdg_surface_committed,
|
.commit = handle_xdg_surface_commit,
|
||||||
|
.precommit = handle_xdg_surface_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface,
|
void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface,
|
||||||
|
|
|
@ -251,7 +251,8 @@ void handle_xdg_surface_v6_popup_committed(struct wlr_xdg_surface_v6 *surface) {
|
||||||
|
|
||||||
const struct wlr_surface_role xdg_popup_v6_surface_role = {
|
const struct wlr_surface_role xdg_popup_v6_surface_role = {
|
||||||
.name = "xdg_popup_v6",
|
.name = "xdg_popup_v6",
|
||||||
.commit = handle_xdg_surface_v6_committed,
|
.commit = handle_xdg_surface_v6_commit,
|
||||||
|
.precommit = handle_xdg_surface_v6_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
void create_xdg_popup_v6(struct wlr_xdg_surface_v6 *xdg_surface,
|
void create_xdg_popup_v6(struct wlr_xdg_surface_v6 *xdg_surface,
|
||||||
|
|
|
@ -371,7 +371,7 @@ static void xdg_surface_handle_surface_commit(struct wl_listener *listener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_xdg_surface_v6_committed(struct wlr_surface *wlr_surface) {
|
void handle_xdg_surface_v6_commit(struct wlr_surface *wlr_surface) {
|
||||||
struct wlr_xdg_surface_v6 *surface =
|
struct wlr_xdg_surface_v6 *surface =
|
||||||
wlr_xdg_surface_v6_from_wlr_surface(wlr_surface);
|
wlr_xdg_surface_v6_from_wlr_surface(wlr_surface);
|
||||||
if (surface == NULL) {
|
if (surface == NULL) {
|
||||||
|
@ -407,11 +407,23 @@ void handle_xdg_surface_v6_committed(struct wlr_surface *wlr_surface) {
|
||||||
surface->mapped = true;
|
surface->mapped = true;
|
||||||
wlr_signal_emit_safe(&surface->events.map, surface);
|
wlr_signal_emit_safe(&surface->events.map, surface);
|
||||||
}
|
}
|
||||||
if (surface->configured && !wlr_surface_has_buffer(surface->surface) &&
|
}
|
||||||
surface->mapped) {
|
|
||||||
|
void handle_xdg_surface_v6_precommit(struct wlr_surface *wlr_surface) {
|
||||||
|
struct wlr_xdg_surface_v6 *surface =
|
||||||
|
wlr_xdg_surface_v6_from_wlr_surface(wlr_surface);
|
||||||
|
if (surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface->pending.committed & WLR_SURFACE_STATE_BUFFER &&
|
||||||
|
wlr_surface->pending.buffer_resource == NULL) {
|
||||||
|
// This is a NULL commit
|
||||||
|
if (surface->configured && surface->mapped) {
|
||||||
unmap_xdg_surface_v6(surface);
|
unmap_xdg_surface_v6(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void xdg_surface_handle_resource_destroy(struct wl_resource *resource) {
|
static void xdg_surface_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
struct wlr_xdg_surface_v6 *surface = xdg_surface_from_resource(resource);
|
struct wlr_xdg_surface_v6 *surface = xdg_surface_from_resource(resource);
|
||||||
|
|
|
@ -419,7 +419,8 @@ static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
|
|
||||||
const struct wlr_surface_role xdg_toplevel_v6_surface_role = {
|
const struct wlr_surface_role xdg_toplevel_v6_surface_role = {
|
||||||
.name = "xdg_toplevel_v6",
|
.name = "xdg_toplevel_v6",
|
||||||
.commit = handle_xdg_surface_v6_committed,
|
.commit = handle_xdg_surface_v6_commit,
|
||||||
|
.precommit = handle_xdg_surface_v6_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
void create_xdg_toplevel_v6(struct wlr_xdg_surface_v6 *xdg_surface,
|
void create_xdg_toplevel_v6(struct wlr_xdg_surface_v6 *xdg_surface,
|
||||||
|
|
|
@ -652,9 +652,27 @@ static void xwayland_surface_role_commit(struct wlr_surface *wlr_surface) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xwayland_surface_role_precommit(struct wlr_surface *wlr_surface) {
|
||||||
|
assert(wlr_surface->role == &xwayland_surface_role);
|
||||||
|
struct wlr_xwayland_surface *surface = wlr_surface->role_data;
|
||||||
|
if (surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface->pending.committed & WLR_SURFACE_STATE_BUFFER &&
|
||||||
|
wlr_surface->pending.buffer_resource == NULL) {
|
||||||
|
// This is a NULL commit
|
||||||
|
if (surface->mapped) {
|
||||||
|
wlr_signal_emit_safe(&surface->events.unmap, surface);
|
||||||
|
surface->mapped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wlr_surface_role xwayland_surface_role = {
|
static const struct wlr_surface_role xwayland_surface_role = {
|
||||||
.name = "wlr_xwayland_surface",
|
.name = "wlr_xwayland_surface",
|
||||||
.commit = xwayland_surface_role_commit,
|
.commit = xwayland_surface_role_commit,
|
||||||
|
.precommit = xwayland_surface_role_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
|
Loading…
Reference in New Issue