Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add finish behavior #369

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ config_init (Configuration *config)
g_hash_table_insert (config->priv->seat_keys, "greeter-allow-guest", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "greeter-show-manual-login", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "greeter-show-remote-login", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "greeter-grace-timeout", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "user-session", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "allow-user-switching", GINT_TO_POINTER (KEY_SUPPORTED));
g_hash_table_insert (config->priv->seat_keys, "allow-guest", GINT_TO_POINTER (KEY_SUPPORTED));
Expand Down
2 changes: 2 additions & 0 deletions data/lightdm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
# greeter-allow-guest = True if the greeter should show a guest login option
# greeter-show-manual-login = True if the greeter should offer a manual login option
# greeter-show-remote-login = True if the greeter should offer a remote login option
# greeter-grace-timeout = Number of seconds to wait before killing the greeter
# user-session = Session to load for users
# allow-user-switching = True if allowed to switch users
# allow-guest = True if guest login is allowed
Expand Down Expand Up @@ -104,6 +105,7 @@
#greeter-allow-guest=true
#greeter-show-manual-login=false
#greeter-show-remote-login=true
#greeter-grace-timeout=0
#user-session=default
#allow-user-switching=true
#allow-guest=true
Expand Down
1 change: 1 addition & 0 deletions debian/liblightdm-gobject-1-0.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ liblightdm-gobject-1.so.0 liblightdm-gobject-1-0 #MINVER#
lightdm_greeter_respond@Base 0.9.2
lightdm_greeter_set_language@Base 0.9.8
lightdm_greeter_set_resettable@Base 1.11.1
lightdm_greeter_set_finish_behavior@Base 1.33.0
lightdm_greeter_start_session@Base 1.11.1
lightdm_greeter_start_session_finish@Base 1.11.1
lightdm_greeter_start_session_sync@Base 0.9.2
Expand Down
1 change: 1 addition & 0 deletions doc/lightdm-gobject-1-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ LightDMGreeterError
lightdm_greeter_error_quark
lightdm_greeter_new
lightdm_greeter_set_resettable
lightdm_greeter_set_finish_behavior
lightdm_greeter_connect_to_daemon
lightdm_greeter_connect_to_daemon_finish
lightdm_greeter_connect_to_daemon_sync
Expand Down
34 changes: 27 additions & 7 deletions liblightdm-gobject/greeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ typedef struct
/* API version the daemon is using */
guint32 api_version;

/* TRUE if the daemon can reuse this greeter */
gboolean resettable;
/* Defines the finish behavior for the greeter; either to be resettable, killed immediately or terminated gracefully */
LightDMGreeterFinishBehavior finish_behavior;

/* Socket connection to daemon */
GSocket *socket;
Expand Down Expand Up @@ -297,6 +297,7 @@ lightdm_greeter_new (void)
* @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.
* Use lightdm_greeter_set_finish_behavior to set more behaviors after logged in.
* This must be called before lightdm_greeter_connect is called.
**/
void
Expand All @@ -307,7 +308,26 @@ lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable)
LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);

g_return_if_fail (!priv->connected);
priv->resettable = resettable;
priv->finish_behavior = resettable ? LIGHTDM_GREETER_FINISH_BEHAVIOR_RESETTABLE : LIGHTDM_GREETER_FINISH_BEHAVIOR_IMMEDIATE;
}

/**
* lightdm_greeter_set_finish_behavior:
* @greeter: A #LightDMGreeter
* @finish_behavior: The finish behavior of the greeter when the user logs in
*
* Set whether the greeter will be reset, killed immediately or terminated gracefully.
* This must be called before lightdm_greeter_connect is called.
**/
void
lightdm_greeter_set_finish_behavior (LightDMGreeter *greeter, LightDMGreeterFinishBehavior finish_behavior)
{
g_return_if_fail (LIGHTDM_IS_GREETER (greeter));

LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);

g_return_if_fail (!priv->connected);
priv->finish_behavior = finish_behavior;
}

static Request *
Expand Down Expand Up @@ -921,14 +941,14 @@ from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
}

static gboolean
send_connect (LightDMGreeter *greeter, gboolean resettable, GError **error)
send_connect (LightDMGreeter *greeter, LightDMGreeterFinishBehavior finish_behavior, GError **error)
{
g_debug ("Connecting to display manager...");
guint8 message[MAX_MESSAGE_LENGTH];
gsize offset = 0;
return write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length () * 2, &offset, error) &&
write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset, error) &&
write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset, error) &&
write_int (message, MAX_MESSAGE_LENGTH, finish_behavior, &offset, error) &&
write_int (message, MAX_MESSAGE_LENGTH, API_VERSION, &offset, error) &&
send_message (greeter, message, offset, error);
}
Expand Down Expand Up @@ -982,7 +1002,7 @@ lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancel

Request *request = request_new (greeter, cancellable, callback, user_data);
GError *error = NULL;
if (send_connect (greeter, priv->resettable, &error))
if (send_connect (greeter, priv->finish_behavior, &error))
priv->connect_requests = g_list_append (priv->connect_requests, request);
else
{
Expand Down Expand Up @@ -1030,7 +1050,7 @@ lightdm_greeter_connect_to_daemon_sync (LightDMGreeter *greeter, GError **error)
LightDMGreeterPrivate *priv = lightdm_greeter_get_instance_private (greeter);

/* Read until we are connected */
if (!send_connect (greeter, priv->resettable, error))
if (!send_connect (greeter, priv->finish_behavior, error))
return FALSE;
Request *request = request_new (greeter, NULL, NULL, NULL);
priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request));
Expand Down
15 changes: 15 additions & 0 deletions liblightdm-gobject/lightdm/greeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ typedef enum
LIGHTDM_GREETER_ERROR_INVALID_USER
} LightDMGreeterError;

/**
* LightDMGreeterFinishBehavior:
* @LIGHTDM_GREETER_FINISH_BEHAVIOR_IMMEDIATE: greeter is killed immediately.
* @LIGHTDM_GREETER_FINISH_BEHAVIOR_RESETTABLE: greeter can be reset.
* @LIGHTDM_GREETER_FINISH_BEHAVIOR_GRACEFUL: greeter is terminated gracefully.
*/
typedef enum
{
LIGHTDM_GREETER_FINISH_BEHAVIOR_IMMEDIATE,
LIGHTDM_GREETER_FINISH_BEHAVIOR_RESETTABLE,
LIGHTDM_GREETER_FINISH_BEHAVIOR_GRACEFUL,
} LightDMGreeterFinishBehavior;

GQuark lightdm_greeter_error_quark (void);

GType lightdm_greeter_error_get_type (void);
Expand All @@ -124,6 +137,8 @@ LightDMGreeter *lightdm_greeter_new (void);

void lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable);

void lightdm_greeter_set_finish_behavior (LightDMGreeter *greeter, LightDMGreeterFinishBehavior finish_behavior);

void lightdm_greeter_connect_to_daemon (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);

gboolean lightdm_greeter_connect_to_daemon_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error);
Expand Down
7 changes: 7 additions & 0 deletions liblightdm-qt/QLightDM/greeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class Q_DECL_EXPORT Greeter : public QObject
MessageTypeError
};

enum FinishBehavior {
BehaviorImmediate,
BehaviorResettable,
BehaviorGraceful
};

explicit Greeter(QObject* parent=0);
virtual ~Greeter();

Expand Down Expand Up @@ -93,6 +99,7 @@ public Q_SLOTS:
void cancelAutologin();
void setLanguage (const QString &language);
void setResettable (bool resettable);
void setFinishBehavior (QLightDM::Greeter::FinishBehavior finishBehavior);
bool startSessionSync(const QString &session=QString());
QString ensureSharedDataDirSync(const QString &username);

Expand Down
24 changes: 24 additions & 0 deletions liblightdm-qt/greeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


#include "QLightDM/greeter.h"
#include "lightdm/greeter.h"

#include <QtCore/QDebug>
#include <QtCore/QDir>
Expand Down Expand Up @@ -202,6 +203,29 @@ void Greeter::setResettable (bool resettable)
lightdm_greeter_set_resettable(d->ldmGreeter, resettable);
}

void Greeter::setFinishBehavior (QLightDM::Greeter::FinishBehavior finishBehavior)
{
Q_D(Greeter);
LightDMGreeterFinishBehavior behavior;

switch (finishBehavior)
{
case BehaviorResettable:
behavior = LIGHTDM_GREETER_FINISH_BEHAVIOR_RESETTABLE;
break;
case BehaviorGraceful:
behavior = LIGHTDM_GREETER_FINISH_BEHAVIOR_GRACEFUL;
break;
break;
case BehaviorImmediate:
default:
behavior = LIGHTDM_GREETER_FINISH_BEHAVIOR_IMMEDIATE;
break;
}

lightdm_greeter_set_finish_behavior(d->ldmGreeter, behavior);
}

bool Greeter::startSessionSync(const QString &session)
{
Q_D(Greeter);
Expand Down
24 changes: 13 additions & 11 deletions src/greeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ typedef struct
/* TRUE if the PAM session is being cancelled */
gboolean cancelling;

/* TRUE if a the greeter can handle a reset; else we will just kill it instead */
gboolean resettable;
/* Defines the finish behavior for the greeter; either to be resettable, killed immediately or terminated gracefully */
FinishBehavior finish_behavior;

/* TRUE if a user has been authenticated and the session requested to start */
gboolean start_session;
Expand Down Expand Up @@ -327,14 +327,14 @@ string_length (const gchar *value)
}

static void
handle_connect (Greeter *greeter, const gchar *version, gboolean resettable, guint32 api_version)
handle_connect (Greeter *greeter, const gchar *version, FinishBehavior finish_behavior, guint32 api_version)
{
GreeterPrivate *priv = greeter_get_instance_private (greeter);

g_debug ("Greeter connected version=%s api=%u resettable=%s", version, api_version, resettable ? "true" : "false");
g_debug ("Greeter connected version=%s api=%u finish_behavior=%d", version, api_version, finish_behavior);

priv->api_version = api_version;
priv->resettable = resettable;
priv->finish_behavior = finish_behavior;

guint32 env_length = 0;
GHashTableIter iter;
Expand Down Expand Up @@ -941,13 +941,15 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
case GREETER_MESSAGE_CONNECT:
{
g_autofree gchar *version = read_string (greeter, &offset);
gboolean resettable = FALSE;
FinishBehavior finish_behavior = BEHAVIOR_IMMEDIATE;
if (offset < length)
resettable = read_int (greeter, &offset) != 0;
finish_behavior = read_int (greeter, &offset);
if (finish_behavior >= LAST_BEHAVIOR)
finish_behavior = BEHAVIOR_IMMEDIATE;
guint32 api_version = 0;
if (offset < length)
api_version = read_int (greeter, &offset);
handle_connect (greeter, version, resettable, api_version);
handle_connect (greeter, version, finish_behavior, api_version);
}
break;
case GREETER_MESSAGE_AUTHENTICATE:
Expand Down Expand Up @@ -1044,12 +1046,12 @@ greeter_take_authentication_session (Greeter *greeter)
return session;
}

gboolean
greeter_get_resettable (Greeter *greeter)
FinishBehavior
greeter_get_finish_behavior (Greeter *greeter)
{
GreeterPrivate *priv = greeter_get_instance_private (greeter);
g_return_val_if_fail (greeter != NULL, FALSE);
return priv->resettable;
return priv->finish_behavior;
}

gboolean
Expand Down
10 changes: 9 additions & 1 deletion src/greeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ typedef struct
gboolean (*start_session)(Greeter *greeter, SessionType type, const gchar *session);
} GreeterClass;

typedef enum
{
BEHAVIOR_IMMEDIATE,
BEHAVIOR_RESETTABLE,
BEHAVIOR_GRACEFUL,
LAST_BEHAVIOR,
} FinishBehavior;

G_DEFINE_AUTOPTR_CLEANUP_FUNC (Greeter, g_object_unref)

GType greeter_get_type (void);
Expand Down Expand Up @@ -74,7 +82,7 @@ Session *greeter_take_authentication_session (Greeter *greeter);

gboolean greeter_get_start_session (Greeter *greeter);

gboolean greeter_get_resettable (Greeter *greeter);
FinishBehavior greeter_get_finish_behavior (Greeter *greeter);

const gchar *greeter_get_active_username (Greeter *greeter);

Expand Down
39 changes: 34 additions & 5 deletions src/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

#include "seat.h"
#include "configuration.h"
#include "greeter.h"
#include "guest-account.h"
#include "greeter-session.h"
#include "session-config.h"
#include "session.h"

enum {
SESSION_ADDED,
Expand Down Expand Up @@ -267,7 +269,8 @@ seat_set_active_session (Seat *seat, Session *session)
if (IS_GREETER_SESSION (s))
{
Greeter *greeter = greeter_session_get_greeter (GREETER_SESSION (s));
if (greeter_get_resettable (greeter))
FinishBehavior finish_behavior = greeter_get_finish_behavior(greeter);
if (finish_behavior == BEHAVIOR_RESETTABLE)
{
if (priv->active_session == s)
{
Expand Down Expand Up @@ -563,7 +566,7 @@ find_resettable_greeter (Seat *seat)
{
Session *session = link->data;
if (!session_get_is_stopping (session) && IS_GREETER_SESSION (session) &&
greeter_get_resettable (greeter_session_get_greeter (GREETER_SESSION (session))))
greeter_get_finish_behavior (greeter_session_get_greeter (GREETER_SESSION (session))) == BEHAVIOR_RESETTABLE)
return GREETER_SESSION (session);
}

Expand Down Expand Up @@ -1128,6 +1131,18 @@ greeter_create_session_cb (Greeter *greeter, Seat *seat)
return g_object_ref (session);
}

static void
greeter_grace_timeout_cb (gpointer data)
{
Session *session = data;

if (!session_get_is_started(session))
return;

l_debug (session, "Greeter timed out");
session_stop (session);
}

static gboolean
greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *session_name, Seat *seat)
{
Expand Down Expand Up @@ -1214,7 +1229,7 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
{
DisplayServer *display_server = session_get_display_server (greeter_session);
if (display_server &&
!greeter_get_resettable (greeter) &&
greeter_get_finish_behavior (greeter) != BEHAVIOR_RESETTABLE &&
can_share_display_server (seat, display_server) &&
strcmp (display_server_get_session_type (display_server), session_get_session_type (session)) == 0)
{
Expand All @@ -1223,8 +1238,22 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
/* Run on the same display server after the greeter has stopped */
session_set_display_server (session, display_server);

/* Stop the greeter */
session_stop (greeter_session);
FinishBehavior finish_behavior = greeter_get_finish_behavior(greeter);
if (finish_behavior == BEHAVIOR_GRACEFUL)
{
l_debug (seat, "Waiting for greeter to terminate");
int timeout = seat_get_integer_property (seat, "greeter-grace-timeout");
if (timeout > 0) {
g_timeout_add_seconds_once(timeout, greeter_grace_timeout_cb, greeter_session);
}

session_wait_for_finish(greeter_session);
}
else
{
/* Stop the greeter */
session_stop (greeter_session);
}

return TRUE;
}
Expand Down
Loading
Loading