diff --git a/protocol/idle.xml b/protocol/idle.xml new file mode 100644 index 0000000000000000000000000000000000000000..92d9989c749746edd3ff276418690f693b7b3cc5 --- /dev/null +++ b/protocol/idle.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="idle"> + <copyright><![CDATA[ + Copyright (C) 2015 Martin Gräßlin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + ]]></copyright> + <interface name="org_kde_kwin_idle" version="1"> + <description summary="User idle time manager"> + This interface allows to monitor user idle time on a given seat. The interface + allows to register timers which trigger after no user activity was registered + on the seat for a given interval. It notifies when user activity resumes. + + This is useful for applications wanting to perform actions when the user is not + interacting with the system, e.g. chat applications setting the user as away, power + management features to dim screen, etc.. + </description> + <request name="get_idle_timeout"> + <arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/> + <arg name="seat" type="object" interface="wl_seat"/> + <arg name="timeout" type="uint" summary="The idle timeout in msec"/> + </request> + </interface> + <interface name="org_kde_kwin_idle_timeout" version="1"> + <request name="release" type="destructor"> + <description summary="release the timeout object"/> + </request> + <request name="simulate_user_activity"> + <description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/> + </request> + <event name="idle"> + <description summary="Triggered when there has not been any user activity in the requested idle time interval"/> + </event> + <event name="resumed"> + <description summary="Triggered on the first user activity after an idle event"/> + </event> + </interface> +</protocol> diff --git a/src/meson.build b/src/meson.build index f39de3e334425c85ed2ff6c559f4be6360e58570..18db65369d2b209255742cbe346c92b9266caeac 100644 --- a/src/meson.build +++ b/src/meson.build @@ -19,6 +19,7 @@ phosh_resources = gnome.compile_resources( wl_protos = [ '/'.join([wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml']), + '../protocol/idle.xml', '../protocol/phosh-mobile-shell.xml', '../protocol/wlr-layer-shell-unstable-v1.xml', ] diff --git a/src/phosh.c b/src/phosh.c index fac7c2c3d5b984a46b97fbb4cecb86c28152d4e3..d150ed56908bd5555178b61c1ad5578c2d48cabb 100644 --- a/src/phosh.c +++ b/src/phosh.c @@ -18,6 +18,7 @@ #include "config.h" +#include "idle-client-protocol.h" #include "phosh-mobile-shell-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" @@ -28,6 +29,9 @@ #include "favorites.h" #include "settings.h" +/* FIXME: use org.gnome.desktop.session.idle-delay */ +#define LOCKSCREEN_TIMEOUT 60 * 1000 + enum { PHOSH_SHELL_PROP_0, PHOSH_SHELL_PROP_ROTATION, @@ -47,13 +51,12 @@ typedef struct struct wl_registry *registry; struct phosh_mobile_shell *mshell; struct zwlr_layer_shell_v1 *layer_shell; + struct org_kde_kwin_idle *idle_manager; struct wl_output *output; - struct wl_seat *seat; - struct wl_pointer *pointer; - GdkDisplay *gdk_display; gint rotation; + struct wl_seat *seat; /* Top panel */ struct elem *panel; @@ -64,6 +67,7 @@ typedef struct /* Lockscreen */ struct elem *lockscreen; gulong unlock_handler_id; + struct org_kde_kwin_idle_timeout *lock_timer; /* Favorites menu */ struct elem *favorites; @@ -116,6 +120,7 @@ lockscreen_unlock_cb (PhoshShell *self, PhoshLockscreen *window) g_signal_handler_disconnect (window, priv->unlock_handler_id); gtk_widget_destroy (GTK_WIDGET (window)); + zwlr_layer_surface_v1_destroy(priv->lockscreen->layer_surface); g_free (priv->lockscreen); priv->lockscreen = NULL; #if 0 @@ -264,6 +269,49 @@ lockscreen_create (PhoshShell *self) } +static void lock_idle_cb(void* data, struct org_kde_kwin_idle_timeout *timer) +{ + PhoshShell *self = data; + PhoshShellPrivate *priv = phosh_shell_get_instance_private (self); + + g_return_if_fail (PHOSH_IS_SHELL (data)); + if (!priv->lockscreen) + lockscreen_create(self); +} + + +static void lock_resume_cb(void* data, struct org_kde_kwin_idle_timeout *timer) +{ +} + + +static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = { + .idle = lock_idle_cb, + .resumed = lock_resume_cb, +}; + + +static void +lockscreen_prepare (PhoshShell *self) +{ + PhoshShellPrivate *priv = phosh_shell_get_instance_private (self); + + g_return_if_fail(priv->seat); + g_return_if_fail(priv->idle_manager); + + priv->lock_timer = org_kde_kwin_idle_get_idle_timeout( + priv->idle_manager, + priv->seat, + LOCKSCREEN_TIMEOUT); + + g_return_if_fail (priv->lock_timer); + + org_kde_kwin_idle_timeout_add_listener(priv->lock_timer, + &idle_timer_listener, + self); +} + + static void panel_create (PhoshShell *self) { @@ -368,18 +416,6 @@ env_setup () } -static void -phosh_mobile_shell_prepare_lock_surface (void *data, - struct phosh_mobile_shell *phosh_mobile_shell) -{ - PhoshShell *self = data; - PhoshShellPrivate *priv = phosh_shell_get_instance_private (self); - - if (!priv->lockscreen) - lockscreen_create(self); -} - - static void registry_handle_global (void *data, struct wl_registry *registry, @@ -405,6 +441,12 @@ registry_handle_global (void *data, /* TODO: create multiple outputs */ priv->output = wl_registry_bind (registry, name, &wl_output_interface, 1); + } else if (!strcmp (interface, "org_kde_kwin_idle")) { + priv->idle_manager = wl_registry_bind (registry, + name, + &org_kde_kwin_idle_interface, 1); + } else if (!strcmp(interface, "wl_seat")) { + priv->seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); } } @@ -414,6 +456,7 @@ registry_handle_global_remove (void *data, struct wl_registry *registry, uint32_t name) { + // TODO } @@ -500,6 +543,7 @@ phosh_shell_constructed (GObject *object) panel_create (self); /* Create background after panel since it needs the panel's size */ background_create (self); + lockscreen_prepare (self); }