summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Terry <michael.terry@canonical.com>2014-04-24 14:36:40 -0400
committerMichael Terry <michael.terry@canonical.com>2014-04-24 14:36:40 -0400
commitec0b529210d4a9d6a99dea07b06731d63b9d0815 (patch)
treeee6c86caa613d9a518d54ace0dc9481f7a582f69
parent695964bb9c1a92f1e3a78c5850451abcc8900b63 (diff)
downloadlightdm-ec0b529210d4a9d6a99dea07b06731d63b9d0815.tar.gz
First pass at reset support
-rw-r--r--configure.ac2
-rw-r--r--debian/changelog6
-rw-r--r--debian/liblightdm-gobject-1-0.symbols1
-rw-r--r--liblightdm-gobject/greeter.c99
-rw-r--r--liblightdm-gobject/lightdm/greeter.h6
-rw-r--r--liblightdm-qt/QLightDM/greeter.h3
-rw-r--r--liblightdm-qt/greeter.cpp24
-rw-r--r--src/greeter.c53
-rw-r--r--src/greeter.h8
-rw-r--r--src/seat.c194
-rw-r--r--tests/src/test-gobject-greeter.c54
-rwxr-xr-xtests/src/test-python-greeter46
-rw-r--r--tests/src/test-qt-greeter.cpp52
-rw-r--r--tests/src/test-qt-greeter.h4
14 files changed, 447 insertions, 105 deletions
diff --git a/configure.ac b/configure.ac
index 9ded6cad..0de08ad3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(lightdm, 1.10.0)
+AC_INIT(lightdm, 1.10.1)
AC_CONFIG_MACRO_DIR(m4)
AC_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz foreign])
diff --git a/debian/changelog b/debian/changelog
index f8c1d2e0..c558ccf9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+lightdm (1.10.1-0ubuntu1) UNRELEASED; urgency=medium
+
+ * Add lightdm_greeter_set_resettable
+
+ -- Michael Terry <mterry@ubuntu.com> Wed, 23 Apr 2014 19:21:30 -0400
+
lightdm (1.10.0-0ubuntu3) trusty; urgency=medium
* debian/patches/06_apparmor_chromium_updates.patch: allow oxide based
diff --git a/debian/liblightdm-gobject-1-0.symbols b/debian/liblightdm-gobject-1-0.symbols
index e9afdffa..770e824e 100644
--- a/debian/liblightdm-gobject-1-0.symbols
+++ b/debian/liblightdm-gobject-1-0.symbols
@@ -37,6 +37,7 @@ liblightdm-gobject-1.so.0 liblightdm-gobject-1-0 #MINVER#
lightdm_greeter_new@Base 0.9.2
lightdm_greeter_respond@Base 0.9.2
lightdm_greeter_set_language@Base 0.9.8
+ lightdm_greeter_set_resettable@Base 1.10.1
lightdm_greeter_start_session_sync@Base 0.9.2
lightdm_hibernate@Base 0.9.2
lightdm_language_get_code@Base 0.9.2
diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c
index c02f73ef..2f28464b 100644
--- a/liblightdm-gobject/greeter.c
+++ b/liblightdm-gobject/greeter.c
@@ -39,6 +39,8 @@ enum {
SHOW_MESSAGE,
AUTHENTICATION_COMPLETE,
AUTOLOGIN_TIMER_EXPIRED,
+ IDLE,
+ RESET,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -83,6 +85,7 @@ typedef enum
GREETER_MESSAGE_SET_LANGUAGE,
GREETER_MESSAGE_AUTHENTICATE_REMOTE,
GREETER_MESSAGE_ENSURE_SHARED_DIR,
+ GREETER_MESSAGE_SET_RESETTABLE,
} GreeterMessage;
/* Messages from the server to the greeter */
@@ -93,6 +96,8 @@ typedef enum
SERVER_MESSAGE_END_AUTHENTICATION,
SERVER_MESSAGE_SESSION_RESULT,
SERVER_MESSAGE_SHARED_DIR_RESULT,
+ SERVER_MESSAGE_IDLE,
+ SERVER_MESSAGE_RESET,
} ServerMessage;
/**
@@ -381,6 +386,31 @@ handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize messa
g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
}
+static void
+handle_reset (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
+{
+ LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ GString *hint_string;
+
+ g_hash_table_remove_all (priv->hints);
+
+ hint_string = g_string_new ("");
+ while (*offset < message_length)
+ {
+ gchar *name, *value;
+
+ name = read_string (message, message_length, offset);
+ value = read_string (message, message_length, offset);
+ g_hash_table_insert (priv->hints, name, value);
+ g_string_append_printf (hint_string, " %s=%s", name, value);
+ }
+
+ g_debug ("Reset%s", hint_string->str);
+ g_string_free (hint_string, TRUE);
+
+ g_signal_emit (G_OBJECT (greeter), signals[RESET], 0);
+}
+
static guint8 *
read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
{
@@ -460,6 +490,12 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
case SERVER_MESSAGE_END_AUTHENTICATION:
handle_end_authentication (greeter, message, message_length, &offset);
break;
+ case SERVER_MESSAGE_IDLE:
+ g_signal_emit (G_OBJECT (greeter), signals[IDLE], 0);
+ break;
+ case SERVER_MESSAGE_RESET:
+ handle_reset (greeter, message, message_length, &offset);
+ break;
default:
g_warning ("Unknown message from server: %d", id);
break;
@@ -1057,6 +1093,31 @@ lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language)
}
/**
+ * lightdm_greeter_set_resettable:
+ * @greeter: A #LightDMGreeter
+ * @resettable: Whether the greeter wants to be reset instead of killed after the user logs in
+ *
+ * Set whether the greeter will be reset instead of killed after the user logs in.
+ **/
+void
+lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
+{
+ LightDMGreeterPrivate *priv;
+ guint8 message[MAX_MESSAGE_LENGTH];
+ gsize offset = 0;
+
+ g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
+
+ priv = GET_PRIVATE (greeter);
+
+ g_return_if_fail (priv->connected);
+
+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_RESETTABLE, int_length (), &offset);
+ write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset);
+ write_message (greeter, message, offset);
+}
+
+/**
* lightdm_greeter_start_session_sync:
* @greeter: A #LightDMGreeter
* @session: (allow-none): The session to log into or #NULL to use the default.
@@ -1460,4 +1521,42 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
+
+ /**
+ * LightDMGreeter::idle:
+ * @greeter: A #LightDMGreeter
+ *
+ * The ::idle signal gets emitted when the user has logged in and the
+ * greeter is no longer needed.
+ *
+ * This signal only matters if the greeter has marked itself as
+ * resettable using lightdm_greeter_set_resettable().
+ **/
+ signals[IDLE] =
+ g_signal_new ("idle",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LightDMGreeterClass, idle),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * LightDMGreeter::reset:
+ * @greeter: A #LightDMGreeter
+ *
+ * The ::reset signal gets emitted when the user is returning to a greeter
+ * that was previously marked idle.
+ *
+ * This signal only matters if the greeter has marked itself as
+ * resettable using lightdm_greeter_set_resettable().
+ **/
+ signals[RESET] =
+ g_signal_new ("reset",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LightDMGreeterClass, reset),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
}
diff --git a/liblightdm-gobject/lightdm/greeter.h b/liblightdm-gobject/lightdm/greeter.h
index ca1b26fb..438fb755 100644
--- a/liblightdm-gobject/lightdm/greeter.h
+++ b/liblightdm-gobject/lightdm/greeter.h
@@ -57,14 +57,14 @@ typedef struct
void (*show_prompt)(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type);
void (*authentication_complete)(LightDMGreeter *greeter);
void (*autologin_timer_expired)(LightDMGreeter *greeter);
+ void (*idle)(LightDMGreeter *greeter);
+ void (*reset)(LightDMGreeter *greeter);
/* Reserved */
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
- void (*reserved5) (void);
- void (*reserved6) (void);
} LightDMGreeterClass;
GType lightdm_greeter_get_type (void);
@@ -119,6 +119,8 @@ const gchar *lightdm_greeter_get_authentication_user (LightDMGreeter *greeter);
void lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language);
+void lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable);
+
gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error);
gchar *lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username);
diff --git a/liblightdm-qt/QLightDM/greeter.h b/liblightdm-qt/QLightDM/greeter.h
index 82916d00..8abf5e92 100644
--- a/liblightdm-qt/QLightDM/greeter.h
+++ b/liblightdm-qt/QLightDM/greeter.h
@@ -79,6 +79,7 @@ public Q_SLOTS:
void respond(const QString &response);
void cancelAuthentication();
void setLanguage (const QString &language);
+ void setResettable (bool resettable);
bool startSessionSync(const QString &session=QString());
QString ensureSharedDataDirSync(const QString &username);
@@ -87,6 +88,8 @@ Q_SIGNALS:
void showPrompt(QString text, QLightDM::Greeter::PromptType type);
void authenticationComplete();
void autologinTimerExpired();
+ void idle();
+ void reset();
private:
GreeterPrivate *d_ptr;
diff --git a/liblightdm-qt/greeter.cpp b/liblightdm-qt/greeter.cpp
index 12e2db4c..406a6321 100644
--- a/liblightdm-qt/greeter.cpp
+++ b/liblightdm-qt/greeter.cpp
@@ -33,6 +33,8 @@ protected:
static void cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data);
static void cb_authenticationComplete(LightDMGreeter *greeter, gpointer data);
static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);
+ static void cb_idle(LightDMGreeter *greeter, gpointer data);
+ static void cb_reset(LightDMGreeter *greeter, gpointer data);
private:
Q_DECLARE_PUBLIC(Greeter)
@@ -50,6 +52,8 @@ GreeterPrivate::GreeterPrivate(Greeter *parent) :
g_signal_connect (ldmGreeter, "show-message", G_CALLBACK (cb_showMessage), this);
g_signal_connect (ldmGreeter, "authentication-complete", G_CALLBACK (cb_authenticationComplete), this);
g_signal_connect (ldmGreeter, "autologin-timer-expired", G_CALLBACK (cb_autoLoginExpired), this);
+ g_signal_connect (ldmGreeter, "idle", G_CALLBACK (cb_idle), this);
+ g_signal_connect (ldmGreeter, "reset", G_CALLBACK (cb_reset), this);
}
void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)
@@ -88,6 +92,20 @@ void GreeterPrivate::cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data)
Q_EMIT that->q_func()->autologinTimerExpired();
}
+void GreeterPrivate::cb_idle(LightDMGreeter *greeter, gpointer data)
+{
+ Q_UNUSED(greeter);
+ GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
+ Q_EMIT that->q_func()->idle();
+}
+
+void GreeterPrivate::cb_reset(LightDMGreeter *greeter, gpointer data)
+{
+ Q_UNUSED(greeter);
+ GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
+ Q_EMIT that->q_func()->reset();
+}
+
Greeter::Greeter(QObject *parent) :
QObject(parent),
d_ptr(new GreeterPrivate(this))
@@ -166,6 +184,12 @@ void Greeter::setLanguage (const QString &language)
lightdm_greeter_set_language(d->ldmGreeter, language.toLocal8Bit().constData());
}
+void Greeter::setResettable (bool resettable)
+{
+ Q_D(Greeter);
+ lightdm_greeter_set_resettable(d->ldmGreeter, resettable);
+}
+
bool Greeter::startSessionSync(const QString &session)
{
Q_D(Greeter);
diff --git a/src/greeter.c b/src/greeter.c
index 9c68556a..7643fb53 100644
--- a/src/greeter.c
+++ b/src/greeter.c
@@ -63,6 +63,9 @@ struct GreeterPrivate
/* PAM session being constructed by the greeter */
Session *authentication_session;
+ /* TRUE if a the greeter can handle a reset; else we will just kill it instead */
+ gboolean resettable;
+
/* TRUE if a user has been authenticated and the session requested to start */
gboolean start_session;
@@ -92,6 +95,7 @@ typedef enum
GREETER_MESSAGE_SET_LANGUAGE,
GREETER_MESSAGE_AUTHENTICATE_REMOTE,
GREETER_MESSAGE_ENSURE_SHARED_DIR,
+ GREETER_MESSAGE_SET_RESETTABLE,
} GreeterMessage;
/* Messages from the server to the greeter */
@@ -102,6 +106,8 @@ typedef enum
SERVER_MESSAGE_END_AUTHENTICATION,
SERVER_MESSAGE_SESSION_RESULT,
SERVER_MESSAGE_SHARED_DIR_RESULT,
+ SERVER_MESSAGE_IDLE,
+ SERVER_MESSAGE_RESET,
} ServerMessage;
static gboolean read_cb (GIOChannel *source, GIOCondition condition, gpointer data);
@@ -128,6 +134,12 @@ greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest)
}
void
+greeter_clear_hints (Greeter *greeter)
+{
+ g_hash_table_remove_all (greeter->priv->hints);
+}
+
+void
greeter_set_hint (Greeter *greeter, const gchar *name, const gchar *value)
{
g_hash_table_insert (greeter->priv->hints, g_strdup (name), g_strdup (value));
@@ -315,6 +327,37 @@ send_end_authentication (Greeter *greeter, guint32 sequence_number, const gchar
write_message (greeter, message, offset);
}
+void greeter_idle (Greeter *greeter)
+{
+ guint8 message[MAX_MESSAGE_LENGTH];
+ gsize offset = 0;
+
+ write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_IDLE, 0, &offset);
+ write_message (greeter, message, offset);
+}
+
+void greeter_reset (Greeter *greeter)
+{
+ guint8 message[MAX_MESSAGE_LENGTH];
+ gsize offset = 0;
+ guint32 length = 0;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, greeter->priv->hints);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ length += string_length (key) + string_length (value);
+
+ write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_RESET, length, &offset);
+ g_hash_table_iter_init (&iter, greeter->priv->hints);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ write_string (message, MAX_MESSAGE_LENGTH, key, &offset);
+ write_string (message, MAX_MESSAGE_LENGTH, value, &offset);
+ }
+ write_message (greeter, message, offset);
+}
+
static void
authentication_complete_cb (Session *session, Greeter *greeter)
{
@@ -837,6 +880,9 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
handle_ensure_shared_dir (greeter, username);
g_free (username);
break;
+ case GREETER_MESSAGE_SET_RESETTABLE:
+ greeter->priv->resettable = read_int (greeter, &offset);
+ break;
default:
l_warning (greeter, "Unknown message from greeter: %d", id);
break;
@@ -862,6 +908,13 @@ greeter_get_authentication_session (Greeter *greeter)
}
gboolean
+greeter_get_resettable (Greeter *greeter)
+{
+ g_return_val_if_fail (greeter != NULL, FALSE);
+ return greeter->priv->resettable;
+}
+
+gboolean
greeter_get_start_session (Greeter *greeter)
{
g_return_val_if_fail (greeter != NULL, FALSE);
diff --git a/src/greeter.h b/src/greeter.h
index 5fae00e4..3aa126d6 100644
--- a/src/greeter.h
+++ b/src/greeter.h
@@ -46,14 +46,22 @@ void greeter_set_pam_services (Greeter *greeter, const gchar *pam_service, const
void greeter_set_allow_guest (Greeter *greeter, gboolean allow_guest);
+void greeter_clear_hints (Greeter *greeter);
+
void greeter_set_hint (Greeter *greeter, const gchar *name, const gchar *value);
+void greeter_idle (Greeter *greeter);
+
+void greeter_reset (Greeter *greeter);
+
gboolean greeter_get_guest_authenticated (Greeter *greeter);
Session *greeter_get_authentication_session (Greeter *greeter);
gboolean greeter_get_start_session (Greeter *greeter);
+gboolean greeter_get_resettable (Greeter *greeter);
+
const gchar *greeter_get_active_username (Greeter *greeter);
G_END_DECLS
diff --git a/src/seat.c b/src/seat.c
index cd8373c7..10ec7a06 100644
--- a/src/seat.c
+++ b/src/seat.c
@@ -220,8 +220,17 @@ seat_set_active_session (Seat *seat, Session *session)
if (IS_GREETER (s))
{
- l_debug (seat, "Stopping greeter");
- session_stop (s);
+ Greeter *greeter = GREETER (s);
+ if (greeter_get_resettable (greeter))
+ {
+ l_debug (seat, "Idling greeter");
+ greeter_idle (greeter);
+ }
+ else
+ {
+ l_debug (seat, "Stopping greeter");
+ session_stop (s);
+ }
}
}
@@ -430,36 +439,84 @@ can_share_display_server (Seat *seat, DisplayServer *display_server)
return seat->priv->share_display_server && display_server_get_can_share (display_server);
}
+static Greeter *
+find_greeter_session (Seat *seat)
+{
+ GList *link;
+
+ for (link = seat->priv->sessions; link; link = link->next)
+ {
+ Session *session = link->data;
+ if (!session_get_is_stopping (session) && IS_GREETER (session))
+ return GREETER (session);
+ }
+
+ return NULL;
+}
+
+static void
+reset_greeter_hints (Seat *seat, Greeter *greeter_session)
+{
+ greeter_clear_hints (greeter_session);
+ greeter_set_hint (greeter_session, "default-session", seat_get_string_property (seat, "user-session"));
+ greeter_set_hint (greeter_session, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
+ greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
+ greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
+ greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
+}
+
static void
switch_to_greeter_from_failed_session (Seat *seat, Session *session)
{
Greeter *greeter_session;
+ gboolean existing = FALSE;
+
+ /* Switch to greeter if one open */
+ greeter_session = find_greeter_session (seat);
+ if (greeter_session)
+ {
+ l_debug (seat, "Switching to existing greeter");
+ reset_greeter_hints (seat, greeter_session);
+ existing = TRUE;
+ }
+ else
+ {
+ greeter_session = create_greeter_session (seat);
+ }
- greeter_session = create_greeter_session (seat);
if (session_get_is_guest (session))
greeter_set_hint (greeter_session, "select-guest", "true");
else
greeter_set_hint (greeter_session, "select-user", session_get_username (session));
- if (seat->priv->session_to_activate)
- g_object_unref (seat->priv->session_to_activate);
- seat->priv->session_to_activate = g_object_ref (greeter_session);
- if (can_share_display_server (seat, session_get_display_server (session)))
- session_set_display_server (SESSION (greeter_session), session_get_display_server (session));
+ if (existing)
+ {
+ greeter_reset (greeter_session);
+ seat_set_active_session (seat, SESSION (greeter_session));
+ }
else
{
- DisplayServer *display_server;
+ if (seat->priv->session_to_activate)
+ g_object_unref (seat->priv->session_to_activate);
+ seat->priv->session_to_activate = g_object_ref (greeter_session);
- display_server = create_display_server (seat, session_get_session_type (session));
- session_set_display_server (session, display_server);
- if (!display_server_start (display_server))
+ if (can_share_display_server (seat, session_get_display_server (session)))
+ session_set_display_server (SESSION (greeter_session), session_get_display_server (session));
+ else
{
- l_debug (seat, "Failed to start display server for greeter");
- seat_stop (seat);
+ DisplayServer *display_server;
+
+ display_server = create_display_server (seat, session_get_session_type (session));
+ session_set_display_server (session, display_server);
+ if (!display_server_start (display_server))
+ {
+ l_debug (seat, "Failed to start display server for greeter");
+ seat_stop (seat);
+ }
}
- }
- start_session (seat, SESSION (greeter_session));
+ start_session (seat, SESSION (greeter_session));
+ }
/* Stop failed session */
session_stop (session);
@@ -1160,12 +1217,8 @@ create_greeter_session (Seat *seat)
g_signal_connect (greeter_session, "start-session", G_CALLBACK (greeter_start_session_cb), seat);
/* Set hints to greeter */
- greeter_set_hint (greeter_session, "default-session", seat_get_string_property (seat, "user-session"));
greeter_set_allow_guest (greeter_session, seat_get_allow_guest (seat));
- greeter_set_hint (greeter_session, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
- greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
- greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
- greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
+ reset_greeter_hints (seat, greeter_session);
g_object_unref (session_config);
@@ -1248,21 +1301,6 @@ create_display_server (Seat *seat, const gchar *session_type)
return display_server;
}
-static Greeter *
-find_greeter_session (Seat *seat)
-{
- GList *link;
-
- for (link = seat->priv->sessions; link; link = link->next)
- {
- Session *session = link->data;
- if (!session_get_is_stopping (session) && IS_GREETER (session))
- return GREETER (session);
- }
-
- return NULL;
-}
-
gboolean
seat_switch_to_greeter (Seat *seat)
{
@@ -1274,7 +1312,7 @@ seat_switch_to_greeter (Seat *seat)
if (!seat->priv->can_switch)
return FALSE;
- /* Switch to greeter if one open (shouldn't be though) */
+ /* Switch to greeter if one open */
greeter_session = find_greeter_session (seat);
if (greeter_session)
{
@@ -1304,6 +1342,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
{
Greeter *greeter_session;
DisplayServer *display_server;
+ gboolean existing = FALSE;
/* If authenticated, then unlock existing session or start new one */
if (session_get_is_authenticated (session))
@@ -1332,22 +1371,44 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
return;
}
- l_debug (seat, "Switching to greeter to authenticate session");
-
session_stop (session);
- greeter_session = create_greeter_session (seat);
+ /* See if we already have a greeter up and reuse it if so. Which will only
+ happen if the greeter marked itself as resettable and we thus didn't
+ kill it when a user session started */
+ greeter_session = find_greeter_session (seat);
+ if (greeter_session)
+ {
+ l_debug (seat, "Switching to existing greeter to authenticate session");
+ reset_greeter_hints (seat, greeter_session);
+ existing = TRUE;
+ }
+ else
+ {
+ l_debug (seat, "Starting greeter to authenticate session");
+ greeter_session = create_greeter_session (seat);
+ }
+
if (session_get_is_guest (session))
greeter_set_hint (greeter_session, "select-guest", "true");
else
greeter_set_hint (greeter_session, "select-user", session_get_username (session));
- if (seat->priv->session_to_activate)
- g_object_unref (seat->priv->session_to_activate);
- seat->priv->session_to_activate = g_object_ref (greeter_session);
- display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
- session_set_display_server (SESSION (greeter_session), display_server);
- display_server_start (display_server);
+ if (existing)
+ {
+ greeter_reset (greeter_session);
+ seat_set_active_session (seat, SESSION (greeter_session));
+ }
+ else
+ {
+ if (seat->priv->session_to_activate)
+ g_object_unref (seat->priv->session_to_activate);
+ seat->priv->session_to_activate = g_object_ref (greeter_session);
+
+ display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+ session_set_display_server (SESSION (greeter_session), display_server);
+ display_server_start (display_server);
+ }
}
gboolean
@@ -1432,6 +1493,7 @@ seat_lock (Seat *seat, const gchar *username)
{
Greeter *greeter_session;
DisplayServer *display_server;
+ gboolean existing = FALSE;
g_return_val_if_fail (seat != NULL, FALSE);
@@ -1440,30 +1502,42 @@ seat_lock (Seat *seat, const gchar *username)
l_debug (seat, "Locking");
- /* Switch to greeter if one open (shouldn't be though) */
+ /* Switch to greeter if one open (only true if it's a resettable greeter) */
greeter_session = find_greeter_session (seat);
if (greeter_session)
{
l_debug (seat, "Switching to existing greeter");
- seat_set_active_session (seat, SESSION (greeter_session));
- return TRUE;
+ reset_greeter_hints (seat, greeter_session);
+ existing = TRUE;
+ }
+ else
+ {
+ greeter_session = create_greeter_session (seat);
+ if (!greeter_session)
+ return FALSE;
}
- greeter_session = create_greeter_session (seat);
- if (!greeter_session)
- return FALSE;
-
- display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
-
- if (seat->priv->session_to_activate)
- g_object_unref (seat->priv->session_to_activate);
- seat->priv->session_to_activate = g_object_ref (greeter_session);
greeter_set_hint (greeter_session, "lock-screen", "true");
if (username)
greeter_set_hint (greeter_session, "select-user", username);
- session_set_display_server (SESSION (greeter_session), display_server);
- return display_server_start (display_server);
+ if (existing)
+ {
+ greeter_reset (greeter_session);
+ seat_set_active_session (seat, SESSION (greeter_session));
+ return TRUE;
+ }
+ else
+ {
+ display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+
+ if (seat->priv->session_to_activate)
+ g_object_unref (seat->priv->session_to_activate);
+ seat->priv->session_to_activate = g_object_ref (greeter_session);
+ session_set_display_server (SESSION (greeter_session), display_server);
+
+ return display_server_start (display_server);
+ }
}
void
diff --git a/tests/src/test-gobject-greeter.c b/tests/src/test-gobject-greeter.c
index 233df5c0..0be56c0b 100644
--- a/tests/src/test-gobject-greeter.c
+++ b/tests/src/test-gobject-greeter.c
@@ -65,6 +65,38 @@ sigterm_cb (gpointer user_data)
}
static void
+print_hints (LightDMGreeter *greeter)
+{
+ if (lightdm_greeter_get_select_user_hint (greeter))
+ status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, lightdm_greeter_get_select_user_hint (greeter));
+ if (lightdm_greeter_get_select_guest_hint (greeter))
+ status_notify ("%s SELECT-GUEST-HINT", greeter_id);
+ if (lightdm_greeter_get_lock_hint (greeter))
+ status_notify ("%s LOCK-HINT", greeter_id);
+ if (!lightdm_greeter_get_has_guest_account_hint (greeter))
+ status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
+ if (lightdm_greeter_get_hide_users_hint (greeter))
+ status_notify ("%s HIDE-USERS-HINT", greeter_id);
+ if (lightdm_greeter_get_show_manual_login_hint (greeter))
+ status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
+ if (!lightdm_greeter_get_show_remote_login_hint (greeter))
+ status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+}
+
+static void
+idle_cb (LightDMGreeter *greeter)
+{
+ status_notify ("%s IDLE", greeter_id);
+}
+
+static void
+reset_cb (LightDMGreeter *greeter)
+{
+ status_notify ("%s RESET", greeter_id);
+ print_hints (greeter);
+}
+
+static void
user_changed_cb (LightDMUser *user)
{
status_notify ("%s USER-CHANGED USERNAME=%s", greeter_id, lightdm_user_get_name (user));
@@ -405,6 +437,13 @@ main (int argc, char **argv)
g_signal_connect (lightdm_user_list_get_instance (), "user-removed", G_CALLBACK (user_removed_cb), NULL);
}
+ if (g_key_file_get_boolean (config, "test-greeter-config", "resettable", NULL))
+ {
+ lightdm_greeter_set_resettable (greeter, TRUE);
+ g_signal_connect (greeter, "idle", G_CALLBACK (idle_cb), NULL);
+ g_signal_connect (greeter, "reset", G_CALLBACK (reset_cb), NULL);
+ }
+
status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
if (!lightdm_greeter_connect_sync (greeter, NULL))
{
@@ -414,20 +453,7 @@ main (int argc, char **argv)
status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
- if (lightdm_greeter_get_select_user_hint (greeter))
- status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, lightdm_greeter_get_select_user_hint (greeter));
- if (lightdm_greeter_get_select_guest_hint (greeter))
- status_notify ("%s SELECT-GUEST-HINT", greeter_id);
- if (lightdm_greeter_get_lock_hint (greeter))
- status_notify ("%s LOCK-HINT", greeter_id);
- if (!lightdm_greeter_get_has_guest_account_hint (greeter))
- status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
- if (lightdm_greeter_get_hide_users_hint (greeter))
- status_notify ("%s HIDE-USERS-HINT", greeter_id);
- if (lightdm_greeter_get_show_manual_login_hint (greeter))
- status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
- if (!lightdm_greeter_get_show_remote_login_hint (greeter))
- status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+ print_hints (greeter);
g_main_loop_run (loop);
diff --git a/tests/src/test-python-greeter b/tests/src/test-python-greeter
index f8e5c373..2bc80e3e 100755
--- a/tests/src/test-python-greeter
+++ b/tests/src/test-python-greeter
@@ -185,6 +185,22 @@ def request_cb (channel, condition):
return True
+def print_hints (greeter):
+ if greeter.get_select_user_hint () is not None:
+ status_notify ('%s SELECT-USER-HINT USERNAME=%s' % (greeter_id, greeter.get_select_user_hint ()))
+ if greeter.get_select_guest_hint ():
+ status_notify ('%s SELECT-GUEST-HINT' % greeter_id)
+ if greeter.get_lock_hint ():
+ status_notify ('%s LOCK-HINT' % greeter_id)
+ if not greeter.get_has_guest_account_hint ():
+ status_notify ('%s HAS-GUEST-ACCOUNT-HINT=FALSE' % greeter_id)
+ if greeter.get_hide_users_hint ():
+ status_notify ('%s HIDE-USERS-HINT' % greeter_id)
+ if greeter.get_show_manual_login_hint ():
+ status_notify ('%s SHOW-MANUAL-LOGIN-HINT' % greeter_id)
+ if not greeter.get_show_remote_login_hint ():
+ status_notify ('%s SHOW-REMOTE-LOGIN-HINT=FALSE' % greeter_id)
+
path = os.getenv ('LIGHTDM_TEST_ROOT') + '/.s'
status_socket = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM)
status_socket.connect (path)
@@ -254,6 +270,21 @@ if log_user_changes:
LightDM.UserList.get_instance ().connect ('user-added', user_added_cb)
LightDM.UserList.get_instance ().connect ('user-removed', user_removed_cb)
+def idle_cb (greeter):
+ status_notify ('%s IDLE' % (greeter_id))
+def reset_cb (greeter):
+ status_notify ('%s RESET' % (greeter_id))
+ print_hints (greeter)
+resettable = False
+try:
+ resettable = config.get_boolean ('test-greeter-config', 'resettable')
+except:
+ pass
+if resettable:
+ LightDM.Greeter.get_instance ().set_resettable (True)
+ LightDM.Greeter.get_instance ().connect ('idle', idle_cb)
+ LightDM.Greeter.get_instance ().connect ('reset', reset_cb)
+
status_notify ('%s CONNECT-TO-DAEMON' % greeter_id)
if not greeter.connect_sync ():
status_notify ('%s FAIL-CONNECT-DAEMON' % greeter_id)
@@ -261,19 +292,6 @@ if not greeter.connect_sync ():
status_notify ('%s CONNECTED-TO-DAEMON' % greeter_id)
-if greeter.get_select_user_hint () is not None:
- status_notify ('%s SELECT-USER-HINT USERNAME=%s' % (greeter_id, greeter.get_select_user_hint ()))
-if greeter.get_select_guest_hint ():
- status_notify ('%s SELECT-GUEST-HINT' % greeter_id)
-if greeter.get_lock_hint ():
- status_notify ('%s LOCK-HINT' % greeter_id)
-if not greeter.get_has_guest_account_hint ():
- status_notify ('%s HAS-GUEST-ACCOUNT-HINT=FALSE' % greeter_id)
-if greeter.get_hide_users_hint ():
- status_notify ('%s HIDE-USERS-HINT' % greeter_id)
-if greeter.get_show_manual_login_hint ():
- status_notify ('%s SHOW-MANUAL-LOGIN-HINT' % greeter_id)
-if not greeter.get_show_remote_login_hint ():
- status_notify ('%s SHOW-REMOTE-LOGIN-HINT=FALSE' % greeter_id)
+print_hints (greeter)
loop.run ()
diff --git a/tests/src/test-qt-greeter.cpp b/tests/src/test-qt-greeter.cpp
index 29434c7b..bac1fea8 100644
--- a/tests/src/test-qt-greeter.cpp
+++ b/tests/src/test-qt-greeter.cpp
@@ -54,6 +54,36 @@ void TestGreeter::autologinTimerExpired ()
status_notify ("%s AUTOLOGIN-TIMER-EXPIRED", greeter_id);
}
+void TestGreeter::printHints ()
+{
+ if (selectUserHint() != "")
+ status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, greeter->selectUserHint ().toAscii ().constData ());
+ if (selectGuestHint())
+ status_notify ("%s SELECT-GUEST-HINT", greeter_id);
+ if (lockHint())
+ status_notify ("%s LOCK-HINT", greeter_id);
+ if (!hasGuestAccountHint ())
+ status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
+ if (hideUsersHint ())
+ status_notify ("%s HIDE-USERS-HINT", greeter_id);
+ if (showManualLoginHint ())
+ status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
+ if (!showRemoteLoginHint ())
+ status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+
+}
+
+void TestGreeter::idle ()
+{
+ status_notify ("%s IDLE", greeter_id);
+}
+
+void TestGreeter::reset ()
+{
+ status_notify ("%s RESET", greeter_id);
+ printHints ();
+}
+
void TestGreeter::userRowsInserted (const QModelIndex & parent, int start, int end)
{
for (int i = start; i <= end; i++)
@@ -268,6 +298,13 @@ main(int argc, char *argv[])
QObject::connect (users_model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), greeter, SLOT(userRowsRemoved(const QModelIndex&, int, int)));
}
+ if (config->value ("test-greeter-config/resettable", "false") == "true")
+ {
+ greeter->setResettable (true);
+ QObject::connect (greeter, SIGNAL(idle()), greeter, SLOT(idle()));
+ QObject::connect (greeter, SIGNAL(reset()), greeter, SLOT(reset()));
+ }
+
status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
if (!greeter->connectSync())
{
@@ -277,20 +314,7 @@ main(int argc, char *argv[])
status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
- if (greeter->selectUserHint() != "")
- status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, greeter->selectUserHint ().toAscii ().constData ());
- if (greeter->selectGuestHint())
- status_notify ("%s SELECT-GUEST-HINT", greeter_id);
- if (greeter->lockHint())
- status_notify ("%s LOCK-HINT", greeter_id);
- if (!greeter->hasGuestAccountHint ())
- status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
- if (greeter->hideUsersHint ())
- status_notify ("%s HIDE-USERS-HINT", greeter_id);
- if (greeter->showManualLoginHint ())
- status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
- if (!greeter->showRemoteLoginHint ())
- status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
+ greeter->printHints();
return app->exec();
}
diff --git a/tests/src/test-qt-greeter.h b/tests/src/test-qt-greeter.h
index 10a10db0..b6ff1270 100644
--- a/tests/src/test-qt-greeter.h
+++ b/tests/src/test-qt-greeter.h
@@ -8,6 +8,8 @@ class TestGreeter : public QLightDM::Greeter
public:
TestGreeter ();
+ void printHints();
+
private Q_SLOTS:
void showMessage(QString text, QLightDM::Greeter::MessageType type);
void showPrompt(QString text, QLightDM::Greeter::PromptType type);
@@ -15,4 +17,6 @@ private Q_SLOTS:
void autologinTimerExpired();
void userRowsInserted(const QModelIndex & parent, int start, int end);
void userRowsRemoved(const QModelIndex & parent, int start, int end);
+ void idle();
+ void reset();
};