diff options
-rw-r--r-- | src/logind-dbus.c | 22 | ||||
-rw-r--r-- | src/logind-seat-dbus.c | 28 | ||||
-rw-r--r-- | src/logind-seat.c | 53 | ||||
-rw-r--r-- | src/logind-seat.h | 2 | ||||
-rw-r--r-- | src/logind-session-dbus.c | 28 | ||||
-rw-r--r-- | src/logind-session.c | 59 | ||||
-rw-r--r-- | src/logind-session.h | 2 | ||||
-rw-r--r-- | src/logind-user-dbus.c | 28 | ||||
-rw-r--r-- | src/logind-user.c | 10 | ||||
-rw-r--r-- | src/logind-user.h | 2 | ||||
-rw-r--r-- | src/logind.c | 1 | ||||
-rw-r--r-- | src/logind.h | 2 |
12 files changed, 217 insertions, 20 deletions
diff --git a/src/logind-dbus.c b/src/logind-dbus.c index f9ee7e5553..f73307f806 100644 --- a/src/logind-dbus.c +++ b/src/logind-dbus.c @@ -604,3 +604,25 @@ oom: const DBusObjectPathVTable bus_manager_vtable = { .message_function = manager_message_handler }; + +int manager_send_changed(Manager *manager, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + + assert(manager); + + m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + return r; +} diff --git a/src/logind-seat-dbus.c b/src/logind-seat-dbus.c index 33eafe5ee5..1895fe6cc3 100644 --- a/src/logind-seat-dbus.c +++ b/src/logind-seat-dbus.c @@ -370,3 +370,31 @@ finish: return r; } + +int seat_send_changed(Seat *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + p = seat_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Seat", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/logind-seat.c b/src/logind-seat.c index 95c66dd712..09356b6b09 100644 --- a/src/logind-seat.c +++ b/src/logind-seat.c @@ -226,8 +226,33 @@ int seat_apply_acls(Seat *s, Session *old_active) { return r; } +int seat_set_active(Seat *s, Session *session) { + Session *old_active; + + assert(s); + assert(session); + assert(session->seat == s); + + if (session == s->active) + return 0; + + old_active = s->active; + s->active = session; + + seat_apply_acls(s, old_active); + + if (session && session->started) + session_send_changed(session, "Active\0"); + + if (!session || session->started) + seat_send_changed(s, "ActiveSession\0"); + + return 0; +} + int seat_active_vt_changed(Seat *s, int vtnr) { - Session *i, *new_active = NULL, *old_active; + Session *i, *new_active = NULL; + int r; assert(s); assert(vtnr >= 1); @@ -243,16 +268,10 @@ int seat_active_vt_changed(Seat *s, int vtnr) { break; } - if (new_active == s->active) - return 0; - - old_active = s->active; - s->active = new_active; - - seat_apply_acls(s, old_active); + r = seat_set_active(s, new_active); manager_spawn_autovt(s->manager, vtnr); - return 0; + return r; } int seat_read_active_vt(Seat *s) { @@ -361,17 +380,19 @@ int seat_attach_session(Seat *s, Session *session) { assert(session); assert(!session->seat); - if (!seat_is_vtconsole(s)) { - if (s->sessions) - return -EEXIST; - - assert(!s->active); - s->active = session; - } + if (!seat_is_vtconsole(s) && s->sessions) + return -EEXIST; session->seat = s; LIST_PREPEND(Session, sessions_by_seat, s->sessions, session); + seat_send_changed(s, "Sessions\0"); + + if (!seat_is_vtconsole(s)) { + assert(!s->active); + seat_set_active(s, session); + } + return 0; } diff --git a/src/logind-seat.h b/src/logind-seat.h index a7cd6c7e47..275939e176 100644 --- a/src/logind-seat.h +++ b/src/logind-seat.h @@ -54,6 +54,7 @@ int seat_save(Seat *s); int seat_load(Seat *s); int seat_apply_acls(Seat *s, Session *old_active); +int seat_set_active(Seat *s, Session *session); int seat_active_vt_changed(Seat *s, int vtnr); int seat_read_active_vt(Seat *s); @@ -75,5 +76,6 @@ char *seat_bus_path(Seat *s); extern const DBusObjectPathVTable bus_seat_vtable; int seat_send_signal(Seat *s, bool new_seat); +int seat_send_changed(Seat *s, const char *properties); #endif diff --git a/src/logind-session-dbus.c b/src/logind-session-dbus.c index edc96dd644..0ce880c590 100644 --- a/src/logind-session-dbus.c +++ b/src/logind-session-dbus.c @@ -419,3 +419,31 @@ finish: return r; } + +int session_send_changed(Session *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + p = session_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Session", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/logind-session.c b/src/logind-session.c index 26f857dc39..5ba6b21eeb 100644 --- a/src/logind-session.c +++ b/src/logind-session.c @@ -76,8 +76,12 @@ void session_free(Session *s) { s->user->display = NULL; } - if (s->seat) + if (s->seat) { + if (s->seat->active == s) + s->seat->active = NULL; + LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); + } free(s->cgroup_path); strv_free(s->controllers); @@ -229,7 +233,7 @@ int session_load(Session *s) { s->kill_processes = k; } - if (seat) { + if (seat && !s->seat) { Seat *o; o = hashmap_get(s->manager->seats, seat); @@ -430,6 +434,9 @@ int session_start(Session *s) { assert(s); assert(s->user); + if (s->started) + return 0; + /* Create cgroup */ r = session_create_cgroup(s); if (r < 0) @@ -443,8 +450,19 @@ int session_start(Session *s) { dual_timestamp_get(&s->timestamp); + s->started = true; + session_send_signal(s, true); + if (s->seat) { + if (s->seat->active == s) + seat_send_changed(s->seat, "Sessions\0ActiveSession\0"); + else + seat_send_changed(s->seat, "Sessions\0"); + } + + user_send_changed(s->user, "Sessions\0"); + return 0; } @@ -521,7 +539,8 @@ int session_stop(Session *s) { assert(s); - session_send_signal(s, false); + if (!s->started) + return 0; /* Kill cgroup */ k = session_kill_cgroup(s); @@ -534,6 +553,19 @@ int session_stop(Session *s) { unlink(s->state_file); session_add_to_gc_queue(s); + session_send_signal(s, false); + + if (s->seat) { + if (s->seat->active == s) + seat_set_active(s->seat, NULL); + + seat_send_changed(s->seat, "Sessions\0"); + } + + user_send_changed(s->user, "Sessions\0"); + + s->started = false; + return r; } @@ -607,6 +639,27 @@ void session_set_idle_hint(Session *s, bool b) { s->idle_hint = b; dual_timestamp_get(&s->idle_hint_timestamp); + + session_send_changed(s, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + if (s->seat) + seat_send_changed(s->seat, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + user_send_changed(s->user, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + manager_send_changed(s->manager, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); } int session_check_gc(Session *s) { diff --git a/src/logind-session.h b/src/logind-session.h index a30c3e727e..d2f25523ec 100644 --- a/src/logind-session.h +++ b/src/logind-session.h @@ -72,6 +72,7 @@ struct Session { bool kill_processes; bool in_gc_queue:1; + bool started:1; LIST_FIELDS(Session, sessions_by_user); LIST_FIELDS(Session, sessions_by_seat); @@ -97,6 +98,7 @@ char *session_bus_path(Session *s); extern const DBusObjectPathVTable bus_session_vtable; int session_send_signal(Session *s, bool new_session); +int session_send_changed(Session *s, const char *properties); const char* session_type_to_string(SessionType t); SessionType session_type_from_string(const char *s); diff --git a/src/logind-user-dbus.c b/src/logind-user-dbus.c index c8d47de0e7..623f2c9c24 100644 --- a/src/logind-user-dbus.c +++ b/src/logind-user-dbus.c @@ -353,3 +353,31 @@ finish: return r; } + +int user_send_changed(User *u, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(u); + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/logind-user.c b/src/logind-user.c index 70d6a9a524..cb3e44197f 100644 --- a/src/logind-user.c +++ b/src/logind-user.c @@ -260,6 +260,9 @@ int user_start(User *u) { assert(u); + if (u->started) + return 0; + /* Make XDG_RUNTIME_DIR */ r = user_mkdir_runtime_path(u); if (r < 0) @@ -280,6 +283,8 @@ int user_start(User *u) { dual_timestamp_get(&u->timestamp); + u->started = true; + user_send_signal(u, true); return 0; @@ -361,6 +366,9 @@ int user_stop(User *u) { int r = 0, k; assert(u); + if (!u->started) + return 0; + LIST_FOREACH(sessions_by_user, s, u->sessions) { k = session_stop(s); if (k < 0) @@ -387,6 +395,8 @@ int user_stop(User *u) { unlink(u->state_file); user_add_to_gc_queue(u); + u->started = false; + return r; } diff --git a/src/logind-user.h b/src/logind-user.h index c6f1401109..dd0dcad9cf 100644 --- a/src/logind-user.h +++ b/src/logind-user.h @@ -55,6 +55,7 @@ struct User { dual_timestamp timestamp; bool in_gc_queue:1; + bool started:1; LIST_HEAD(Session, sessions); LIST_FIELDS(User, gc_queue); @@ -76,6 +77,7 @@ char *user_bus_path(User *s); extern const DBusObjectPathVTable bus_user_vtable; int user_send_signal(User *u, bool new_user); +int user_send_changed(User *u, const char *properties); const char* user_state_to_string(UserState s); UserState user_state_from_string(const char *s); diff --git a/src/logind.c b/src/logind.c index d72a5bfa8b..cdb4da7f25 100644 --- a/src/logind.c +++ b/src/logind.c @@ -890,7 +890,6 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) { return idle_hint; } - int manager_startup(Manager *m) { int r; Seat *seat; diff --git a/src/logind.h b/src/logind.h index e18a357c9a..1b7a2b2398 100644 --- a/src/logind.h +++ b/src/logind.h @@ -114,4 +114,6 @@ bool x11_display_is_local(const char *display); extern const DBusObjectPathVTable bus_manager_vtable; +int manager_send_changed(Manager *manager, const char *properties); + #endif |