diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index d1b1d7d4..b437ed8c 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -311,8 +311,17 @@ desktop_shell_configure(void *data, } } +static void +desktop_shell_prepare_lock_surface(void *data, + struct desktop_shell *desktop_shell) +{ + /* no-op for now */ + desktop_shell_unlock(desktop_shell); +} + static const struct desktop_shell_listener listener = { - desktop_shell_configure + desktop_shell_configure, + desktop_shell_prepare_lock_surface }; static void diff --git a/compositor/compositor.c b/compositor/compositor.c index eab0a373..bba12e5c 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -1334,6 +1334,9 @@ wlsc_compositor_wake(struct wlsc_compositor *compositor) if (compositor->idle_inhibit) return; + if (compositor->state == WLSC_COMPOSITOR_SLEEPING) + compositor->shell->unlock(compositor->shell); + wlsc_compositor_fade(compositor, 0.0); compositor->state = WLSC_COMPOSITOR_ACTIVE; diff --git a/compositor/compositor.h b/compositor/compositor.h index 50ccdb57..12820bf6 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -162,6 +162,7 @@ struct wlsc_shell { struct wlsc_surface *es, struct wlsc_input_device *device, uint32_t time); void (*lock)(struct wlsc_shell *shell); + void (*unlock)(struct wlsc_shell *shell); void (*map)(struct wlsc_shell *shell, struct wlsc_surface *surface, int32_t width, int32_t height); void (*configure)(struct wlsc_shell *shell, diff --git a/compositor/shell.c b/compositor/shell.c index 19362356..9d22cde3 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -1,5 +1,6 @@ /* * Copyright © 2010 Intel Corporation + * Copyright © 2011 Collabora, Ltd. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -44,7 +46,11 @@ struct wl_shell { struct { struct wlsc_process process; struct wl_client *client; + struct wl_resource *desktop_shell; } child; + + bool locked; + bool prepare_event_sent; }; struct wlsc_move_grab { @@ -818,9 +824,28 @@ desktop_shell_set_panel(struct wl_client *client, output->current->height); } +static void +desktop_shell_set_lock_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ +} + +static void +desktop_shell_unlock(struct wl_client *client, + struct wl_resource *resource) +{ + struct wl_shell *shell = resource->data; + + shell->locked = false; + shell->prepare_event_sent = false; +} + static const struct desktop_shell_interface desktop_shell_implementation = { desktop_shell_set_background, - desktop_shell_set_panel + desktop_shell_set_panel, + desktop_shell_set_lock_surface, + desktop_shell_unlock }; static void @@ -907,8 +932,35 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es, } static void -lock(struct wlsc_shell *shell) +lock(struct wlsc_shell *base) { + struct wl_shell *shell = container_of(base, struct wl_shell, shell); + + shell->locked = true; +} + +static void +unlock(struct wlsc_shell *base) +{ + struct wl_shell *shell = container_of(base, struct wl_shell, shell); + + if (!shell->locked) { + wlsc_compositor_wake(shell->compositor); + return; + } + + /* If desktop-shell client has gone away, unlock immediately. */ + if (!shell->child.desktop_shell) { + shell->locked = false; + return; + } + + if (shell->prepare_event_sent) + return; + + wl_resource_post_event(shell->child.desktop_shell, + DESKTOP_SHELL_PREPARE_LOCK_SURFACE); + shell->prepare_event_sent = true; } static void @@ -1014,6 +1066,15 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) &shell_interface, id, shell); } +static void +unbind_desktop_shell(struct wl_resource *resource) +{ + struct wl_shell *shell = resource->data; + shell->child.desktop_shell = NULL; + shell->prepare_event_sent = false; + free(resource); +} + static void bind_desktop_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) @@ -1025,8 +1086,11 @@ bind_desktop_shell(struct wl_client *client, &desktop_shell_implementation, id, shell); - if (client == shell->child.client) + if (client == shell->child.client) { + resource->destroy = unbind_desktop_shell; + shell->child.desktop_shell = resource; return; + } wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "permission to bind desktop_shell denied"); @@ -1049,6 +1113,7 @@ shell_init(struct wlsc_compositor *ec) shell->compositor = ec; shell->shell.activate = activate; shell->shell.lock = lock; + shell->shell.unlock = unlock; shell->shell.map = map; shell->shell.configure = configure; shell->shell.set_selection_focus = wlsc_selection_set_focus; diff --git a/compositor/tablet-shell.c b/compositor/tablet-shell.c index 504adc07..21786a2c 100644 --- a/compositor/tablet-shell.c +++ b/compositor/tablet-shell.c @@ -553,6 +553,11 @@ tablet_shell_lock(struct wlsc_shell *base) tablet_shell_set_state(shell, STATE_LOCKED); } +static void +tablet_shell_unlock(struct wlsc_shell *base) +{ +} + static void go_home(struct tablet_shell *shell) { @@ -687,6 +692,7 @@ shell_init(struct wlsc_compositor *compositor) compositor->shell = &shell->shell; shell->shell.lock = tablet_shell_lock; + shell->shell.unlock = tablet_shell_unlock; shell->shell.map = tablet_shell_map; shell->shell.configure = tablet_shell_configure; shell->shell.set_selection_focus = diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml index 438773dd..d099925f 100644 --- a/protocol/desktop-shell.xml +++ b/protocol/desktop-shell.xml @@ -9,6 +9,12 @@ + + + + + + @@ -19,6 +25,12 @@ + +