logind: fix Display property of user objects

When we dropped support for creating a per-user to the "main" X11
display we stopped returning useful data in the "Display" user property.
With this change this is fixed and we again expose an appropriate
(graphical session) in the property that is useful as the "main" one, if
one is needed.
This commit is contained in:
Lennart Poettering 2014-05-19 09:03:20 +09:00
parent 2be6107255
commit 952d32609f
5 changed files with 47 additions and 3 deletions

View file

@ -545,6 +545,8 @@ int session_start(Session *s) {
s->started = true;
user_elect_display(s->user);
/* Save data */
session_save(s);
user_save(s->user);
@ -553,7 +555,7 @@ int session_start(Session *s) {
/* Send signals */
session_send_signal(s, true);
user_send_changed(s->user, "Sessions", NULL);
user_send_changed(s->user, "Sessions", "Display", NULL);
if (s->seat) {
if (s->seat->active == s)
seat_send_changed(s->seat, "Sessions", "ActiveSession", NULL);
@ -612,6 +614,8 @@ int session_stop(Session *s, bool force) {
s->stopping = true;
user_elect_display(s->user);
session_save(s);
user_save(s->user);
@ -660,7 +664,7 @@ int session_finalize(Session *s) {
}
user_save(s->user);
user_send_changed(s->user, "Sessions", NULL);
user_send_changed(s->user, "Sessions", "Display", NULL);
return r;
}

View file

@ -60,6 +60,8 @@ typedef enum SessionType {
_SESSION_TYPE_INVALID = -1
} SessionType;
#define SESSION_TYPE_IS_GRAPHICAL(type) IN_SET(type, SESSION_X11, SESSION_WAYLAND, SESSION_MIR)
enum KillWho {
KILL_LEADER,
KILL_ALL,

View file

@ -220,7 +220,7 @@ const sd_bus_vtable user_vtable[] = {
SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),

View file

@ -713,6 +713,43 @@ int user_kill(User *u, int signo) {
return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL);
}
void user_elect_display(User *u) {
Session *graphical = NULL, *text = NULL, *s;
assert(u);
/* This elects a primary session for each user, which we call
* the "display". We try to keep the assignment stable, but we
* "upgrade" to better choices. */
LIST_FOREACH(sessions_by_user, s, u->sessions) {
if (s->class != SESSION_USER)
continue;
if (s->stopping)
continue;
if (SESSION_TYPE_IS_GRAPHICAL(s->type))
graphical = s;
else
text = s;
}
if (graphical &&
(!u->display ||
u->display->class != SESSION_USER ||
u->display->stopping ||
!SESSION_TYPE_IS_GRAPHICAL(u->display->type)))
u->display = graphical;
if (text &&
(!u->display ||
u->display->class != SESSION_USER ||
u->display->stopping))
u->display = text;
}
static const char* const user_state_table[_USER_STATE_MAX] = {
[USER_OFFLINE] = "offline",
[USER_OPENING] = "opening",

View file

@ -80,6 +80,7 @@ int user_save(User *u);
int user_load(User *u);
int user_kill(User *u, int signo);
int user_check_linger_file(User *u);
void user_elect_display(User *u);
extern const sd_bus_vtable user_vtable[];
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);