Skip to content
Snippets Groups Projects
Commit b14c09aa authored by Guido Gunther's avatar Guido Gunther :zzz:
Browse files

Lockscreen: use pin to unlock

The lock screen now shows the current time and on upward drag it
switches to the lock screen. The lock screen then shows a keypad to
unlock the screen.

Validating the entered pin will be done in a follow up patch.

TODO in future patches:
 - slide up lock surface when swiping
 - wiggle pane a little if swipe is too soft
 - alpha blend out lock screen surface
parent e3813ad1
No related branches found
No related tags found
No related merge requests found
......@@ -5,5 +5,6 @@ src/menu.c
src/panel.c
src/phosh.c
src/settings.c
src/ui/lockscreen.ui
src/ui/settings-menu.ui
src/ui/top-panel.ui
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: phosh\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-01 18:31+0200\n"
"POT-Creation-Date: 2018-04-02 11:39+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -5,9 +5,21 @@
*/
#include "config.h"
#include "lockscreen.h"
#include <string.h>
#include <glib/gi18n.h>
#include <math.h>
#define HANDY_USE_UNSTABLE_API
#include <libhandy-0.0/handy.h>
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-wall-clock.h>
#define TEST_PIN "1234"
#define LOCKSCREEN_IDLE_SECONDS 5
enum {
LOCKSCREEN_UNLOCK,
N_SIGNALS
......@@ -22,18 +34,138 @@ typedef struct _PhoshLockscreen
typedef struct PhoshLockscreen {
gint _dummy;
GtkWidget *stack;
/* info page */
GtkWidget *ebox_info;
GtkWidget *grid_info;
GtkWidget *lbl_clock;
GtkGesture *ebox_pan_gesture;
/* unlock page */
GtkWidget *grid_unlock;
GtkWidget *dialer_keypad;
GtkWidget *lbl_keypad;
GtkWidget *lbl_unlock_status;
guint idle_timer;
gint64 last_input;
GnomeWallClock *wall_clock;
} PhoshLockscreenPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (PhoshLockscreen, phosh_lockscreen, GTK_TYPE_WINDOW)
/* FIXME: Temporarily add a button until we interface with pam */
static void
btn_clicked (PhoshLockscreen *lockscreen,
GtkButton *btn)
show_info_page (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
hdy_dialer_clear_number (HDY_DIALER (priv->dialer_keypad));
gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->ebox_info);
}
static gboolean
keypad_check_idle (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
gint64 now = g_get_monotonic_time ();
g_assert (PHOSH_IS_LOCKSCREEN (self));
if (now - priv->last_input > LOCKSCREEN_IDLE_SECONDS * 1000 * 1000) {
show_info_page (self);
priv->idle_timer = 0;
return FALSE;
}
return TRUE;
}
static void
show_unlock_page (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->grid_unlock);
hdy_dialer_set_show_action_buttons (HDY_DIALER (priv->dialer_keypad), FALSE);
if (!priv->idle_timer) {
priv->last_input = g_get_monotonic_time ();
priv->idle_timer = g_timeout_add_seconds (LOCKSCREEN_IDLE_SECONDS,
(GSourceFunc) keypad_check_idle,
self);
}
}
static void
keypad_update_labels (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
const gchar *number;
g_autofree gchar *stars = NULL;
number = hdy_dialer_get_number (HDY_DIALER (priv->dialer_keypad));
stars = g_strnfill (strlen(number), '*');
gtk_label_set_label (GTK_LABEL (priv->lbl_keypad), stars);
gtk_label_set_label (GTK_LABEL (priv->lbl_unlock_status), _("Enter PIN to unlock"));
}
static void
keypad_number_notified_cb (PhoshLockscreen *self)
{
PhoshLockscreenPrivate *priv;
const gchar *number;
g_assert (PHOSH_IS_LOCKSCREEN (self));
priv = phosh_lockscreen_get_instance_private (self);
number = hdy_dialer_get_number (HDY_DIALER (priv->dialer_keypad));
if (strlen (number) == strlen (TEST_PIN)) {
if (!g_strcmp0 (number, TEST_PIN)) {
/* FIXME: compare to real PIN */
g_signal_emit(self, signals[LOCKSCREEN_UNLOCK], 0);
} else {
gtk_label_set_label (GTK_LABEL (priv->lbl_unlock_status), _("Wrong PIN"));
hdy_dialer_clear_number (HDY_DIALER (priv->dialer_keypad));
}
}
priv->last_input = g_get_monotonic_time ();
}
static void
keypad_symbol_clicked_cb (PhoshLockscreen *self, gchar symbol, HdyDialer *keypad)
{
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
g_assert (PHOSH_IS_LOCKSCREEN (self));
g_assert (HDY_IS_DIALER (keypad));
keypad_update_labels (self);
priv->last_input = g_get_monotonic_time ();
}
static void
info_pan_cb (PhoshLockscreen *self, GtkPanDirection dir, gdouble offset, GtkGesturePan *pan)
{
if (dir == GTK_PAN_DIRECTION_UP)
show_unlock_page (self);
}
static void
wall_clock_notify_cb (PhoshLockscreen *self,
GParamSpec *pspec,
GnomeWallClock *wall_clock)
{
g_signal_emit(lockscreen, signals[LOCKSCREEN_UNLOCK], 0);
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
const gchar *str;
str = gnome_wall_clock_get_clock(wall_clock);
gtk_label_set_text (GTK_LABEL (priv->lbl_clock), str);
}
......@@ -41,9 +173,7 @@ static void
phosh_lockscreen_constructed (GObject *object)
{
PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
GtkWidget *grid;
GtkWidget *button;
GtkWidget *label;
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
GdkDisplay *display = gdk_display_get_default ();
/* There's no primary monitor on nested wayland so just use the
......@@ -66,15 +196,37 @@ phosh_lockscreen_constructed (GObject *object)
gtk_widget_get_style_context (GTK_WIDGET (self)),
"phosh-lockscreen");
grid = gtk_widget_new (GTK_TYPE_GRID, "halign", GTK_ALIGN_CENTER, "valign", GTK_ALIGN_CENTER, NULL);
gtk_container_add (GTK_CONTAINER (self), grid);
gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->ebox_info);
priv->ebox_pan_gesture = gtk_gesture_pan_new (GTK_WIDGET (priv->ebox_info),
GTK_ORIENTATION_VERTICAL);
g_signal_connect_swapped (priv->ebox_pan_gesture,
"pan",
G_CALLBACK (info_pan_cb),
self);
priv->wall_clock = g_object_new (GNOME_TYPE_WALL_CLOCK, NULL);
g_signal_connect_swapped (priv->wall_clock,
"notify::clock",
G_CALLBACK (wall_clock_notify_cb),
self);
wall_clock_notify_cb (self, NULL, priv->wall_clock);
}
static void
phosh_lockscreen_dispose (GObject *object)
{
PhoshLockscreen *self = PHOSH_LOCKSCREEN (object);
PhoshLockscreenPrivate *priv = phosh_lockscreen_get_instance_private (self);
g_clear_object (&priv->wall_clock);
if (priv->idle_timer) {
g_source_remove (priv->idle_timer);
priv->idle_timer = 0;
}
/* FIXME: just a button for now */
label = gtk_label_new("Click to unlock desktop");
button = gtk_button_new_from_icon_name ("face-surprise-symbolic", GTK_ICON_SIZE_DIALOG);
gtk_grid_attach (GTK_GRID (grid), label, 2, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), button, 2, 3, 1, 1);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (btn_clicked), self);
G_OBJECT_CLASS (phosh_lockscreen_parent_class)->dispose (object);
}
......@@ -82,18 +234,43 @@ static void
phosh_lockscreen_class_init (PhoshLockscreenClass *klass)
{
GObjectClass *object_class = (GObjectClass *)klass;
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->constructed = phosh_lockscreen_constructed;
object_class->dispose = phosh_lockscreen_dispose;
signals[LOCKSCREEN_UNLOCK] = g_signal_new ("lockscreen-unlock",
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
NULL, G_TYPE_NONE, 0);
gtk_widget_class_set_template_from_resource (widget_class,
"/sm/puri/phosh/ui/lockscreen.ui");
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, stack);
/* unlock page */
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, grid_unlock);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, dialer_keypad);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, lbl_keypad);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, lbl_unlock_status);
gtk_widget_class_bind_template_callback_full (widget_class,
"keypad_symbol_clicked_cb",
G_CALLBACK(keypad_symbol_clicked_cb));
gtk_widget_class_bind_template_callback_full (widget_class,
"keypad_number_notified_cb",
G_CALLBACK(keypad_number_notified_cb));
/* info page */
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, ebox_info);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, grid_info);
gtk_widget_class_bind_template_child_private (widget_class, PhoshLockscreen, lbl_clock);
}
static void
phosh_lockscreen_init (PhoshLockscreen *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
......
......@@ -51,6 +51,7 @@ phosh_deps = [
dependency('gtk+-3.0'),
dependency('gtk+-wayland-3.0'),
dependency('wayland-client'),
dependency('libhandy-0.0'),
cc.find_library('m', required: false),
cc.find_library('rt', required: false),
]
......
......@@ -32,7 +32,7 @@
#include "settings.h"
/* FIXME: use org.gnome.desktop.session.idle-delay */
#define LOCKSCREEN_TIMEOUT 60 * 1000
#define LOCKSCREEN_TIMEOUT 300 * 1000
enum {
PHOSH_SHELL_PROP_0,
......@@ -837,7 +837,6 @@ int main(int argc, char *argv[])
textdomain (GETTEXT_PACKAGE);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
gtk_init (&argc, &argv);
g_object_new (PHOSH_TYPE_SHELL, NULL);
......
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/sm/puri/phosh">
<file preprocess="xml-stripblanks">ui/top-panel.ui</file>
<file preprocess="xml-stripblanks">ui/lockscreen.ui</file>
<file preprocess="xml-stripblanks">ui/settings-menu.ui</file>
<file preprocess="xml-stripblanks">ui/top-panel.ui</file>
<file compressed="true">style.css</file>
</gresource>
</gresources>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="0.0"/>
<template class="PhoshLockscreen" parent="GtkWindow">
<property name="can_focus">False</property>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_duration">500</property>
<property name="transition_type">slide-up</property>
<child>
<object class="GtkGrid" id="grid_unlock">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">False</property>
<property name="vexpand">False</property>
<child>
<object class="GtkLabel" id="lbl_keypad">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<attributes>
<attribute name="font-desc" value="Cantarell Bold 16"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="HdyDialer" id="dialer_keypad">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<signal name="symbol-clicked" handler="keypad_symbol_clicked_cb" swapped="yes"/>
<signal name="notify::number" handler="keypad_number_notified_cb" swapped="yes"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbl_unlock_status">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="label" translatable="yes">Enter PIN to unlock</property>
<attributes>
<attribute name="font-desc" value="Cantarell 16"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="name">unlock</property>
<property name="title">unlock</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="ebox_info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="above_child">True</property>
<child>
<object class="GtkGrid" id="grid_info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="lbl_clock">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="label">00:00</property>
<property name="single_line_mode">True</property>
<property name="track_visited_links">False</property>
<attributes>
<attribute name="font-desc" value="Cantarell 64"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Slide up to unlock</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="name">info</property>
<property name="title">info</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</template>
</interface>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment