Skip to content
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
2 changes: 1 addition & 1 deletion data/lightdm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
# session-wrapper = Wrapper script to run session with
# greeter-wrapper = Wrapper script to run greeter with
# guest-wrapper = Wrapper script to run guest sessions with
# display-setup-script = Script to run when starting a greeter session (runs as root)
# display-setup-script = Script to run when starting a greeter session (runs as root); also re-run on resume from sleep
# display-stopped-script = Script to run after stopping the display server (runs as root)
# greeter-setup-script = Script to run when starting a greeter (runs as root)
# session-setup-script = Script to run when starting a user session (runs as root)
Expand Down
16 changes: 16 additions & 0 deletions src/lightdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,18 @@ login1_service_seat_attention_key_cb (Login1Service *service, Login1Seat *login1
seat_switch_to_greeter (seat);
}

static void
login1_service_prepare_for_sleep_cb (Login1Service *service, gboolean active)
{
/* active=TRUE means the system is about to sleep; FALSE means it resumed. */
if (active)
return;

g_debug ("System resumed from sleep, re-running display setup scripts");
for (GList *link = display_manager_get_seats (display_manager); link; link = link->next)
seat_run_display_setup_scripts (link->data);
}

int
main (int argc, char **argv)
{
Expand Down Expand Up @@ -894,6 +906,10 @@ main (int argc, char **argv)
/* Load dynamic seats from logind */
g_debug ("Monitoring logind for seats");

/* Resume is system-wide; re-run display-setup even when seats are not
* started from logind's default seat list. */
g_signal_connect (login1_service_get_instance (), LOGIN1_SERVICE_SIGNAL_PREPARE_FOR_SLEEP, G_CALLBACK (login1_service_prepare_for_sleep_cb), NULL);

if (config_get_boolean (config_get_instance (), "LightDM", "start-default-seat"))
{
g_signal_connect (login1_service_get_instance (), LOGIN1_SERVICE_SIGNAL_SEAT_ADDED, G_CALLBACK (login1_service_seat_added_cb), NULL);
Expand Down
15 changes: 15 additions & 0 deletions src/login1.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ enum {
SEAT_ADDED,
SEAT_REMOVED,
SEAT_ATTENTION_KEY,
PREPARE_FOR_SLEEP,
LAST_SERVICE_SIGNAL
};
static guint service_signals[LAST_SERVICE_SIGNAL] = { 0 };
Expand Down Expand Up @@ -257,6 +258,12 @@ signal_cb (GDBusConnection *connection,
}

}
else if (strcmp (signal_name, "PrepareForSleep") == 0)
{
gboolean active;
g_variant_get (parameters, "(b)", &active);
g_signal_emit (service, service_signals[PREPARE_FOR_SLEEP], 0, active);
}
}

gboolean
Expand Down Expand Up @@ -515,6 +522,14 @@ login1_service_class_init (Login1ServiceClass *klass)
NULL, NULL,
NULL,
G_TYPE_NONE, 1, LOGIN1_SEAT_TYPE);
service_signals[PREPARE_FOR_SLEEP] =
g_signal_new (LOGIN1_SERVICE_SIGNAL_PREPARE_FOR_SLEEP,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (Login1ServiceClass, prepare_for_sleep),
NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}

const gchar *
Expand Down
2 changes: 2 additions & 0 deletions src/login1.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ G_BEGIN_DECLS
#define LOGIN1_SERVICE_SIGNAL_SEAT_ADDED "seat-added"
#define LOGIN1_SERVICE_SIGNAL_SEAT_REMOVED "seat-removed"
#define LOGIN1_SERVICE_SIGNAL_SEAT_ATTENTION_KEY "seat-attention-key"
#define LOGIN1_SERVICE_SIGNAL_PREPARE_FOR_SLEEP "prepare-for-sleep"

#define LOGIN1_SEAT_SIGNAL_CAN_GRAPHICAL_CHANGED "can-graphical-changed"
#define LOGIN1_SIGNAL_ACTIVE_SESION_CHANGED "active-session-changed"
Expand Down Expand Up @@ -52,6 +53,7 @@ typedef struct
void (*seat_added)(Login1Service *service, Login1Seat *seat);
void (*seat_removed)(Login1Service *service, Login1Seat *seat);
void (*seat_attention_key)(Login1Service *service, Login1Seat *seat);
void (*prepare_for_sleep)(Login1Service *service, gboolean active);
} Login1ServiceClass;

GType login1_service_get_type (void);
Expand Down
26 changes: 26 additions & 0 deletions src/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,32 @@ find_session_for_display_server (Seat *seat, DisplayServer *display_server)
return NULL;
}

void
seat_run_display_setup_scripts (Seat *seat)
{
SeatPrivate *priv = seat_get_instance_private (seat);
const gchar *script;

g_return_if_fail (seat != NULL);

script = seat_get_string_property (seat, "display-setup-script");
if (!script)
return;

for (GList *link = priv->display_servers; link; link = link->next)
{
DisplayServer *display_server = link->data;

if (!display_server_get_is_ready (display_server) ||
display_server_get_is_stopping (display_server))
continue;

l_debug (seat, "Running display setup script %s", script);
if (!run_script (seat, display_server, script, NULL, NULL))
l_debug (seat, "Display setup script failed");
}
}

static void
display_server_ready_cb (DisplayServer *display_server, Seat *seat)
{
Expand Down
3 changes: 3 additions & 0 deletions src/seat.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ void seat_set_can_tty (Seat *seat, gboolean can_tty);

gboolean seat_start (Seat *seat);

/* Re-run display-setup-script for ready display servers (e.g. after resume). */
void seat_run_display_setup_scripts (Seat *seat);

GList *seat_get_sessions (Seat *seat);

void seat_set_active_session (Seat *seat, Session *session);
Expand Down
2 changes: 2 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ TESTS = \
test-script-hooks \
test-script-hook-display-setup-fail \
test-script-hook-display-setup-missing \
test-script-hook-display-setup-resume \
test-script-hook-greeter-setup-fail \
test-script-hook-greeter-setup-missing \
test-script-hook-session-setup-fail \
Expand Down Expand Up @@ -544,6 +545,7 @@ EXTRA_DIST = \
scripts/script-hooks.conf \
scripts/script-hook-display-setup-fail.conf \
scripts/script-hook-display-setup-missing.conf \
scripts/script-hook-display-setup-resume.conf \
scripts/script-hook-greeter-setup-fail.conf \
scripts/script-hook-greeter-setup-missing.conf \
scripts/script-hook-session-setup-fail.conf \
Expand Down
40 changes: 40 additions & 0 deletions tests/scripts/script-hook-display-setup-resume.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#
# Check display-setup-script is re-run when resuming from sleep (issue #428)
#

[Seat:*]
display-setup-script=test-script-hook DISPLAY-SETUP

#?*START-DAEMON
#?RUNNER DAEMON-START

# X server starts
#?XSERVER-0 START VT=7 SEAT=seat0

# Daemon connects when X server is ready
#?*XSERVER-0 INDICATE-READY
#?XSERVER-0 INDICATE-READY
#?XSERVER-0 ACCEPT-CONNECT

# Display setup runs when the display server becomes ready
#?SCRIPT-HOOK DISPLAY-SETUP XDG_SEAT=seat0

# Greeter starts
#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
#?LOGIN1 ACTIVATE-SESSION SESSION=c0
#?XSERVER-0 ACCEPT-CONNECT
#?GREETER-X-0 CONNECT-XSERVER
#?GREETER-X-0 CONNECT-TO-DAEMON
#?GREETER-X-0 CONNECTED-TO-DAEMON

# Simulate resume from sleep (PrepareForSleep active=false)
#?*LOGIN1-PREPARE-FOR-SLEEP ACTIVE=FALSE

# Display setup must run again so greeter DPMS / layout scripts apply
#?SCRIPT-HOOK DISPLAY-SETUP XDG_SEAT=seat0

# Cleanup
#?*STOP-DAEMON
#?GREETER-X-0 TERMINATE SIGNAL=15
#?XSERVER-0 TERMINATE SIGNAL=15
#?RUNNER DAEMON-EXIT STATUS=0
17 changes: 17 additions & 0 deletions tests/src/test-runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,20 @@ handle_command (const gchar *command)
const gchar *id = g_hash_table_lookup (params, "ID");
remove_login1_seat (dbus_conn, id);
}
else if (strcmp (name, "LOGIN1-PREPARE-FOR-SLEEP") == 0)
{
const gchar *v = g_hash_table_lookup (params, "ACTIVE");
gboolean active = v && strcmp (v, "TRUE") == 0;
g_autoptr(GError) error = NULL;
if (!g_dbus_connection_emit_signal (dbus_conn,
NULL,
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"PrepareForSleep",
g_variant_new ("(b)", active),
&error))
g_warning ("Failed to emit PrepareForSleep: %s", error->message);
}
else if (strcmp (name, "LIST-SEATS") == 0)
{
g_autoptr(GError) error = NULL;
Expand Down Expand Up @@ -1933,6 +1947,9 @@ login1_name_acquired_cb (GDBusConnection *connection,
" <signal name='SeatRemoved'>"
" <arg name='seat' type='so'/>"
" </signal>"
" <signal name='PrepareForSleep'>"
" <arg name='start' type='b'/>"
" </signal>"
" </interface>"
"</node>";
g_autoptr(GError) error = NULL;
Expand Down
2 changes: 2 additions & 0 deletions tests/test-script-hook-display-setup-resume
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
./src/dbus-env ./src/test-runner script-hook-display-setup-resume test-gobject-greeter