From a71c39b8648f000ac2b867d358205e72018bde50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org> Date: Tue, 17 Apr 2018 15:51:21 +0200 Subject: [PATCH] lockscreen: limit input to shell using input-inhibitor --- protocol/wlr-input-inhibitor-unstable-v1.xml | 67 ++++++++++++++++++++ src/meson.build | 1 + src/phosh.c | 26 ++++++-- 3 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 protocol/wlr-input-inhibitor-unstable-v1.xml diff --git a/protocol/wlr-input-inhibitor-unstable-v1.xml b/protocol/wlr-input-inhibitor-unstable-v1.xml new file mode 100644 index 0000000..b62d1bb --- /dev/null +++ b/protocol/wlr-input-inhibitor-unstable-v1.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="wlr_input_inhibit_unstable_v1"> + <copyright> + Copyright © 2018 Drew DeVault + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + </copyright> + + <interface name="zwlr_input_inhibit_manager_v1" version="1"> + <description summary="inhibits input events to other clients"> + Clients can use this interface to prevent input events from being sent to + any surfaces but its own, which is useful for example in lock screen + software. It is assumed that access to this interface will be locked down + to whitelisted clients by the compositor. + </description> + + <request name="get_inhibitor"> + <description summary="inhibit input to other clients"> + Activates the input inhibitor. As long as the inhibitor is active, the + compositor will not send input events to other clients. + </description> + <arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/> + </request> + + <enum name="error"> + <entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/> + </enum> + </interface> + + <interface name="zwlr_input_inhibitor_v1" version="1"> + <description summary="inhibits input to other clients"> + While this resource exists, input to clients other than the owner of the + inhibitor resource will not receive input events. The client that owns + this resource will receive all input events normally. The compositor will + also disable all of its own input processing (such as keyboard shortcuts) + while the inhibitor is active. + + The compositor may continue to send input events to selected clients, + such as an on-screen keyboard (via the input-method protocol). + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the input inhibitor object"> + Destroy the inhibitor and allow other clients to receive input. + </description> + </request> + </interface> +</protocol> diff --git a/src/meson.build b/src/meson.build index 18db653..673283f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -21,6 +21,7 @@ wl_protos = [ '/'.join([wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml']), '../protocol/idle.xml', '../protocol/phosh-mobile-shell.xml', + '../protocol/wlr-input-inhibitor-unstable-v1.xml', '../protocol/wlr-layer-shell-unstable-v1.xml', ] wl_proto_deps = [] diff --git a/src/phosh.c b/src/phosh.c index d8022f3..63b6e2f 100644 --- a/src/phosh.c +++ b/src/phosh.c @@ -21,6 +21,7 @@ #include "idle-client-protocol.h" #include "phosh-mobile-shell-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" +#include "wlr-input-inhibitor-unstable-v1-client-protocol.h" #include "phosh.h" #include "background.h" @@ -52,6 +53,8 @@ typedef struct struct phosh_mobile_shell *mshell; struct zwlr_layer_shell_v1 *layer_shell; struct org_kde_kwin_idle *idle_manager; + struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager; + struct zwlr_input_inhibitor_v1 *input_inhibitor; struct wl_output *output; GdkDisplay *gdk_display; @@ -122,9 +125,9 @@ lockscreen_unlock_cb (PhoshShell *self, PhoshLockscreen *window) zwlr_layer_surface_v1_destroy(priv->lockscreen->layer_surface); g_free (priv->lockscreen); priv->lockscreen = NULL; -#if 0 - phosh_mobile_shell_unlock(priv->mshell); -#endif + + zwlr_input_inhibitor_v1_destroy(priv->input_inhibitor); + priv->input_inhibitor = NULL; } @@ -239,6 +242,9 @@ lockscreen_create (PhoshShell *self) lockscreen = g_malloc0 (sizeof *lockscreen); lockscreen->window = phosh_lockscreen_new (); + priv->input_inhibitor = + zwlr_input_inhibit_manager_v1_get_inhibitor(priv->input_inhibit_manager); + gdk_window = gtk_widget_get_window (lockscreen->window); gdk_wayland_window_set_use_custom_surface (gdk_window); @@ -452,6 +458,12 @@ registry_handle_global (void *data, #if 0 /* FIXME: this breaks GTK+ input since GTK+ binds it as well */ priv->seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); #endif + } else if (!strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name)) { + priv->input_inhibit_manager = wl_registry_bind( + registry, + name, + &zwlr_input_inhibit_manager_v1_interface, + 1); } } @@ -536,12 +548,12 @@ phosh_shell_constructed (GObject *object) /* Wait until we have been notified about the compositor, * shell, and shell helper objects */ - if (!priv->output || !priv->layer_shell || !priv->idle_manager) + if (!priv->output || !priv->layer_shell || !priv->idle_manager || !priv->input_inhibit_manager) wl_display_roundtrip (priv->display); - if (!priv->output || !priv->layer_shell || !priv->idle_manager) { + if (!priv->output || !priv->layer_shell || !priv->idle_manager || !priv->input_inhibit_manager) { g_error ("Could not find needed globals\n" - "output: %p, layer_shell: %p, seat: %p\n", - priv->output, priv->mshell, priv->idle_manager); + "output: %p, layer_shell: %p, seat: %p, inhibit: %p\n", + priv->output, priv->mshell, priv->idle_manager, priv->input_inhibit_manager); } env_setup (); -- GitLab