mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-09-06 09:56:14 +00:00
compositor: Hide surfaces by setting surface->output to NULL
This way we can still use surface->link when a surface is not in the main compositor surface list and don't need the hidden_surface wrapper object. Also, setting surface->output to NULL will block the surface frame callback until we put the surface back into the main list. This has the effect of blocking animations while a surface isn't visible.
This commit is contained in:
parent
bfbb26bdb2
commit
1ec0c31596
|
@ -398,8 +398,9 @@ unlock_dialog_item_focus_handler(struct window *window,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct unlock_dialog *
|
static struct unlock_dialog *
|
||||||
unlock_dialog_create(struct display *display)
|
unlock_dialog_create(struct desktop *desktop)
|
||||||
{
|
{
|
||||||
|
struct display *display = desktop->display;
|
||||||
struct unlock_dialog *dialog;
|
struct unlock_dialog *dialog;
|
||||||
|
|
||||||
dialog = malloc(sizeof *dialog);
|
dialog = malloc(sizeof *dialog);
|
||||||
|
@ -419,6 +420,9 @@ unlock_dialog_create(struct display *display)
|
||||||
unlock_dialog_item_focus_handler);
|
unlock_dialog_item_focus_handler);
|
||||||
dialog->button = window_add_item(dialog->window, NULL);
|
dialog->button = window_add_item(dialog->window, NULL);
|
||||||
|
|
||||||
|
desktop_shell_set_lock_surface(desktop->shell,
|
||||||
|
window_get_wl_surface(dialog->window));
|
||||||
|
|
||||||
unlock_dialog_draw(dialog);
|
unlock_dialog_draw(dialog);
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
|
@ -467,13 +471,9 @@ desktop_shell_prepare_lock_surface(void *data,
|
||||||
struct desktop *desktop = data;
|
struct desktop *desktop = data;
|
||||||
|
|
||||||
if (!desktop->unlock_dialog) {
|
if (!desktop->unlock_dialog) {
|
||||||
desktop->unlock_dialog =
|
desktop->unlock_dialog = unlock_dialog_create(desktop);
|
||||||
unlock_dialog_create(desktop->display);
|
|
||||||
desktop->unlock_dialog->desktop = desktop;
|
desktop->unlock_dialog->desktop = desktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
desktop_shell_set_lock_surface(desktop_shell,
|
|
||||||
window_get_wl_surface(desktop->unlock_dialog->window));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct desktop_shell_listener listener = {
|
static const struct desktop_shell_listener listener = {
|
||||||
|
|
|
@ -313,7 +313,7 @@ wlsc_surface_damage_below(struct wlsc_surface *surface)
|
||||||
{
|
{
|
||||||
struct wlsc_surface *below;
|
struct wlsc_surface *below;
|
||||||
|
|
||||||
if (wl_list_empty(&surface->link))
|
if (surface->output == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (surface->link.next == &surface->compositor->surface_list)
|
if (surface->link.next == &surface->compositor->surface_list)
|
||||||
|
@ -369,6 +369,9 @@ wlsc_compositor_repick(struct wlsc_compositor *compositor)
|
||||||
int32_t sx, sy;
|
int32_t sx, sy;
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
|
|
||||||
|
if (!compositor->focus)
|
||||||
|
return;
|
||||||
|
|
||||||
time = wlsc_compositor_get_time();
|
time = wlsc_compositor_get_time();
|
||||||
wl_list_for_each(device, &compositor->input_device_list, link) {
|
wl_list_for_each(device, &compositor->input_device_list, link) {
|
||||||
if (device->input_device.grab)
|
if (device->input_device.grab)
|
||||||
|
|
|
@ -53,25 +53,11 @@ struct wl_shell {
|
||||||
bool locked;
|
bool locked;
|
||||||
bool prepare_event_sent;
|
bool prepare_event_sent;
|
||||||
|
|
||||||
|
struct wlsc_surface *lock_surface;
|
||||||
|
struct wl_listener lock_surface_listener;
|
||||||
struct wl_list hidden_surface_list;
|
struct wl_list hidden_surface_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hidden_surface {
|
|
||||||
struct wlsc_surface *surface;
|
|
||||||
struct wl_listener destroy_listener;
|
|
||||||
struct wl_shell *shell;
|
|
||||||
|
|
||||||
struct wl_list link;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
hidden_surface_destroy(struct hidden_surface *hidden)
|
|
||||||
{
|
|
||||||
wl_list_remove(&hidden->link);
|
|
||||||
wl_list_remove(&hidden->destroy_listener.link);
|
|
||||||
free(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlsc_move_grab {
|
struct wlsc_move_grab {
|
||||||
struct wl_grab grab;
|
struct wl_grab grab;
|
||||||
struct wlsc_surface *surface;
|
struct wlsc_surface *surface;
|
||||||
|
@ -843,59 +829,51 @@ desktop_shell_set_panel(struct wl_client *client,
|
||||||
output->current->height);
|
output->current->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_lock_surface_destroy(struct wl_listener *listener,
|
||||||
|
struct wl_resource *resource, uint32_t time)
|
||||||
|
{
|
||||||
|
struct wl_shell *shell =
|
||||||
|
container_of(listener, struct wl_shell, panel_listener);
|
||||||
|
|
||||||
|
fprintf(stderr, "lock surface gone\n");
|
||||||
|
shell->lock_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
desktop_shell_set_lock_surface(struct wl_client *client,
|
desktop_shell_set_lock_surface(struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
struct wl_resource *surface_resource)
|
struct wl_resource *surface_resource)
|
||||||
{
|
{
|
||||||
struct wl_shell *shell = resource->data;
|
struct wl_shell *shell = resource->data;
|
||||||
struct wlsc_surface *es = surface_resource->data;
|
|
||||||
|
|
||||||
shell->prepare_event_sent = false;
|
shell->prepare_event_sent = false;
|
||||||
|
|
||||||
if (!shell->locked)
|
if (!shell->locked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wl_list_remove(&es->link);
|
shell->lock_surface = surface_resource->data;
|
||||||
wl_list_insert(&shell->compositor->surface_list, &es->link);
|
|
||||||
|
|
||||||
wlsc_compositor_repick(shell->compositor);
|
shell->lock_surface_listener.func = handle_lock_surface_destroy;
|
||||||
wlsc_compositor_wake(shell->compositor);
|
wl_list_insert(&surface_resource->destroy_listener_list,
|
||||||
|
&shell->lock_surface_listener.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resume_desktop(struct wl_shell *shell)
|
resume_desktop(struct wl_shell *shell)
|
||||||
{
|
{
|
||||||
struct hidden_surface *hidden;
|
struct wlsc_surface *surface;
|
||||||
struct hidden_surface *tmp;
|
|
||||||
struct wl_list *elem;
|
|
||||||
struct wl_list *put = &shell->compositor->surface_list;
|
|
||||||
|
|
||||||
wl_list_for_each_safe(hidden, tmp, &shell->hidden_surface_list, link) {
|
wl_list_for_each(surface, &shell->hidden_surface_list, link)
|
||||||
elem = &hidden->surface->link;
|
wlsc_surface_configure(surface, surface->x, surface->y,
|
||||||
wl_list_remove(elem);
|
surface->width, surface->height);
|
||||||
|
|
||||||
if (hidden->surface == shell->panel) {
|
wl_list_insert_list(shell->background->link.prev,
|
||||||
wl_list_insert(&shell->compositor->surface_list, elem);
|
&shell->hidden_surface_list);
|
||||||
if (put == &shell->compositor->surface_list)
|
wl_list_init(&shell->hidden_surface_list);
|
||||||
put = elem;
|
|
||||||
} else {
|
|
||||||
wl_list_insert(put, elem);
|
|
||||||
put = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
hidden_surface_destroy(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wl_list_empty(&shell->hidden_surface_list)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: Assertion failed: hidden_surface_list is not empty.\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
shell->locked = false;
|
shell->locked = false;
|
||||||
wlsc_compositor_repick(shell->compositor);
|
wlsc_compositor_repick(shell->compositor);
|
||||||
wlsc_compositor_damage_all(shell->compositor);
|
|
||||||
wlsc_compositor_wake(shell->compositor);
|
wlsc_compositor_wake(shell->compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,34 +958,6 @@ resize_binding(struct wl_input_device *device, uint32_t time,
|
||||||
time, edges, resource);
|
time, edges, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
handle_hidden_surface_destroy(struct wl_listener *listener,
|
|
||||||
struct wl_resource *resource, uint32_t time)
|
|
||||||
{
|
|
||||||
struct hidden_surface *hidden =
|
|
||||||
container_of(listener, struct hidden_surface, destroy_listener);
|
|
||||||
|
|
||||||
hidden_surface_destroy(hidden);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct hidden_surface *
|
|
||||||
hidden_surface_create(struct wl_shell *shell, struct wlsc_surface *surface)
|
|
||||||
{
|
|
||||||
struct hidden_surface *hidden;
|
|
||||||
|
|
||||||
hidden = malloc(sizeof *hidden);
|
|
||||||
if (!hidden)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hidden->surface = surface;
|
|
||||||
hidden->shell = shell;
|
|
||||||
hidden->destroy_listener.func = handle_hidden_surface_destroy;
|
|
||||||
wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
|
|
||||||
&hidden->destroy_listener.link);
|
|
||||||
|
|
||||||
return hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
activate(struct wlsc_shell *base, struct wlsc_surface *es,
|
activate(struct wlsc_shell *base, struct wlsc_surface *es,
|
||||||
struct wlsc_input_device *device, uint32_t time)
|
struct wlsc_input_device *device, uint32_t time)
|
||||||
|
@ -1036,7 +986,6 @@ lock(struct wlsc_shell *base)
|
||||||
struct wl_list *surface_list = &shell->compositor->surface_list;
|
struct wl_list *surface_list = &shell->compositor->surface_list;
|
||||||
struct wlsc_surface *cur;
|
struct wlsc_surface *cur;
|
||||||
struct wlsc_surface *tmp;
|
struct wlsc_surface *tmp;
|
||||||
struct hidden_surface *hidden;
|
|
||||||
struct wlsc_input_device *device;
|
struct wlsc_input_device *device;
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
|
|
||||||
|
@ -1063,13 +1012,9 @@ lock(struct wlsc_shell *base)
|
||||||
if (cur == shell->background)
|
if (cur == shell->background)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
hidden = hidden_surface_create(shell, cur);
|
cur->output = NULL;
|
||||||
if (!hidden)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wl_list_insert(shell->hidden_surface_list.prev, &hidden->link);
|
|
||||||
wl_list_remove(&cur->link);
|
wl_list_remove(&cur->link);
|
||||||
wl_list_init(&cur->link);
|
wl_list_insert(shell->hidden_surface_list.prev, &cur->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset pointer foci */
|
/* reset pointer foci */
|
||||||
|
@ -1117,37 +1062,37 @@ map(struct wlsc_shell *base,
|
||||||
{
|
{
|
||||||
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
||||||
struct wlsc_compositor *compositor = shell->compositor;
|
struct wlsc_compositor *compositor = shell->compositor;
|
||||||
struct hidden_surface *hidden;
|
struct wl_list *list;
|
||||||
|
|
||||||
|
if (shell->locked)
|
||||||
|
list = &shell->hidden_surface_list;
|
||||||
|
else
|
||||||
|
list = &compositor->surface_list;
|
||||||
|
|
||||||
/* Map background at the bottom of the stack, panel on top,
|
/* Map background at the bottom of the stack, panel on top,
|
||||||
everything else just below panel. */
|
everything else just below panel. */
|
||||||
if (surface == shell->background) {
|
if (surface == shell->background) {
|
||||||
wl_list_insert(compositor->surface_list.prev, &surface->link);
|
wl_list_insert(compositor->surface_list.prev, &surface->link);
|
||||||
|
} else if (surface == shell->panel) {
|
||||||
} else if (shell->locked) {
|
wl_list_insert(list, &surface->link);
|
||||||
wl_list_init(&surface->link);
|
} else if (surface == shell->lock_surface) {
|
||||||
|
wl_list_insert(&compositor->surface_list, &surface->link);
|
||||||
hidden = hidden_surface_create(shell, surface);
|
wlsc_compositor_repick(compositor);
|
||||||
if (!hidden)
|
wlsc_compositor_wake(compositor);
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* panel positioning is fixed on resume */
|
|
||||||
wl_list_insert(&shell->hidden_surface_list, &hidden->link);
|
|
||||||
} else {
|
} else {
|
||||||
if (surface == shell->panel)
|
wl_list_insert(&shell->panel->link, &surface->link);
|
||||||
wl_list_insert(&compositor->surface_list,
|
|
||||||
&surface->link);
|
|
||||||
else
|
|
||||||
wl_list_insert(&shell->panel->link, &surface->link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) {
|
if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) {
|
||||||
surface->x = 10 + random() % 400;
|
surface->x = 10 + random() % 400;
|
||||||
surface->y = 10 + random() % 400;
|
surface->y = 10 + random() % 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlsc_surface_configure(surface, surface->x, surface->y, width, height);
|
surface->width = width;
|
||||||
|
surface->height = height;
|
||||||
|
if (!shell->locked)
|
||||||
|
wlsc_surface_configure(surface,
|
||||||
|
surface->x, surface->y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1233,6 +1178,10 @@ static void
|
||||||
unbind_desktop_shell(struct wl_resource *resource)
|
unbind_desktop_shell(struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
struct wl_shell *shell = resource->data;
|
struct wl_shell *shell = resource->data;
|
||||||
|
|
||||||
|
if (shell->locked)
|
||||||
|
resume_desktop(shell);
|
||||||
|
|
||||||
shell->child.desktop_shell = NULL;
|
shell->child.desktop_shell = NULL;
|
||||||
shell->prepare_event_sent = false;
|
shell->prepare_event_sent = false;
|
||||||
free(resource);
|
free(resource);
|
||||||
|
|
Loading…
Reference in a new issue