Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
apt install -y desktop-file-utils libgdk-pixbuf-2.0-dev libgnome-desktop-3-dev libgranite-dev libgtk-3-dev libhandy-1-dev libjson-glib-dev liblightdm-gobject-1-dev ${{ matrix.mutter_pkg }} libsoup-3.0-dev libx11-dev ${{ matrix.lightdm_vala }} meson valac
apt install -y desktop-file-utils libaccountsservice-dev libgdk-pixbuf-2.0-dev libgnome-desktop-3-dev libgranite-dev libgtk-3-dev libhandy-1-dev libjson-glib-dev liblightdm-gobject-1-dev ${{ matrix.mutter_pkg }} libsoup-3.0-dev libx11-dev ${{ matrix.lightdm_vala }} meson valac
- name: Build
env:
DESTDIR: out
Expand All @@ -50,7 +50,7 @@ jobs:
- uses: actions/checkout@v7
- name: Install Dependencies
run: |
dnf install -y desktop-file-utils gdk-pixbuf2-devel gnome-desktop3-devel granite-devel gtk3-devel libhandy-devel lightdm-gobject-devel mutter-devel libX11-devel meson valac
dnf install -y accountsservice-devel desktop-file-utils gdk-pixbuf2-devel gnome-desktop3-devel granite-devel gtk3-devel libhandy-devel lightdm-gobject-devel mutter-devel libX11-devel meson valac
- name: Build
env:
DESTDIR: out
Expand All @@ -69,7 +69,7 @@ jobs:
run: |
zypper addrepo https://download.opensuse.org/repositories/X11:Pantheon/16.0/X11:Pantheon.repo
zypper --gpg-auto-import-keys refresh
zypper --non-interactive install tar git desktop-file-utils gdk-pixbuf-devel libgnome-desktop-3-devel granite6-devel gtk3-devel libhandy-devel lightdm-gobject-devel mutter-devel meson vala gcc
zypper --non-interactive install accountsservice-devel accountsservice-vala tar git desktop-file-utils gdk-pixbuf-devel libgnome-desktop-3-devel granite6-devel gtk3-devel libhandy-devel lightdm-gobject-devel mutter-devel meson vala gcc
- uses: actions/checkout@v7
- name: Build
env:
Expand Down
5 changes: 4 additions & 1 deletion src/Application.vala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2024 elementary, Inc. (https://elementary.io)
* Copyright 2018-2026 elementary, Inc. (https://elementary.io)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
Expand Down Expand Up @@ -111,6 +111,9 @@ public class Greeter.Application : Gtk.Application {
}

public static int main (string[] args) {
// Connect to UserManager as early as possible
Act.UserManager.get_default ();

return new Greeter.Application ().run (args);
}
}
107 changes: 62 additions & 45 deletions src/Cards/UserCard.vala
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
/*
* Copyright 2018-2025 elementary, Inc. (https://elementary.io)
* Copyright 2018-2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authors: Corentin Noël <corentin@elementary.io>
*/

public class Greeter.UserCard : Greeter.BaseCard {
public LightDM.User lightdm_user { get; construct; }
/**
* We use Act.User instead of LightDM.User because lightdm is unmaintained
* and lacks some fields from Act.User such as `password_mode`.
*/
public Act.User user { get; construct; }
Comment thread
lenemter marked this conversation as resolved.
public bool show_input { get; set; default = false; }
public bool is_24h { get; set; default = true; }
// TODO: In Gtk4 remove this gesture and move it to MainWindow
Expand All @@ -15,29 +19,32 @@ public class Greeter.UserCard : Greeter.BaseCard {
private Pantheon.AccountsService greeter_act;
private Pantheon.SettingsDaemon.AccountsService settings_act;

private Gtk.Label username_label;
private Gtk.Revealer form_revealer;
private Gtk.Stack login_stack;
private Greeter.PasswordEntry password_entry;
private Gtk.Box main_box;

private Greeter.SessionButton password_session_button;
private Greeter.SessionButton login_button_session_button;
private Gtk.Overlay avatar_overlay;
private SelectionCheck logged_in;

public UserCard (LightDM.User lightdm_user) {
Object (lightdm_user: lightdm_user);
public UserCard (Act.User user) requires (user.is_loaded) {
Object (user: user);
}

construct {
need_password = true;

username_label = new Gtk.Label (lightdm_user.display_name) {
var username_label = new Gtk.Label (user.real_name) {
hexpand = true,
margin_top = 24,
margin_bottom = 12,
margin_start = 24,
margin_end = 24,
};
username_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL);
user.bind_property ("locked", username_label, "sensitive", SYNC_CREATE);
Comment thread
lenemter marked this conversation as resolved.
Outdated

password_entry = new Greeter.PasswordEntry ();
bind_property ("connecting", password_entry, "sensitive", INVERT_BOOLEAN);
Expand All @@ -46,7 +53,7 @@ public class Greeter.UserCard : Greeter.BaseCard {
bind_property ("use-fingerprint", fingerprint_image, "no-show-all", SYNC_CREATE | INVERT_BOOLEAN);
bind_property ("use-fingerprint", fingerprint_image, "visible", SYNC_CREATE);

var password_session_button = new Greeter.SessionButton () {
password_session_button = new Greeter.SessionButton () {
vexpand = true
};

Expand All @@ -63,7 +70,7 @@ public class Greeter.UserCard : Greeter.BaseCard {
login_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
bind_property ("connecting", login_button, "sensitive", INVERT_BOOLEAN);

var login_button_session_button = new Greeter.SessionButton () {
login_button_session_button = new Greeter.SessionButton () {
vexpand = true
};

Expand Down Expand Up @@ -108,15 +115,15 @@ public class Greeter.UserCard : Greeter.BaseCard {

update_collapsed_class ();

var avatar = new Hdy.Avatar (64, lightdm_user.display_name, true) {
var avatar = new Hdy.Avatar (64, user.real_name, true) {
margin_top = 6,
margin_bottom = 6,
margin_start = 6,
margin_end = 6,
loadable_icon = new FileIcon (File.new_for_path (lightdm_user.image))
loadable_icon = new FileIcon (File.new_for_path (user.icon_file))
};

var avatar_overlay = new Gtk.Overlay () {
avatar_overlay = new Gtk.Overlay () {
halign = CENTER,
valign = START,
margin_top = 100,
Expand All @@ -128,16 +135,6 @@ public class Greeter.UserCard : Greeter.BaseCard {
valign = END
};

if (lightdm_user.logged_in) {
avatar_overlay.add_overlay (logged_in);

password_session_button.sensitive = false;
password_session_button.tooltip_text = (_("Session cannot be changed while user is logged in"));

login_button_session_button.sensitive = false;
login_button_session_button.tooltip_text = (_("Session cannot be changed while user is logged in"));
}

var card_overlay = new Gtk.Overlay () {
margin_top = 12,
margin_bottom = 12,
Expand All @@ -149,9 +146,12 @@ public class Greeter.UserCard : Greeter.BaseCard {

child = card_overlay;

connect_to_dbus_interfaces ();
lightdm_user.changed.connect (update_is_locked_ui);
user.changed.connect (update_is_locked_ui);
notify["need-password"].connect (update_is_locked_ui);
update_is_locked_ui ();

user.sessions_changed.connect (on_sessions_changed);
on_sessions_changed ();

click_gesture = new Gtk.GestureMultiPress (this);

Expand All @@ -161,31 +161,36 @@ public class Greeter.UserCard : Greeter.BaseCard {
login_button.clicked.connect (on_login);

grab_focus.connect (password_entry.grab_focus_without_selecting);

connect_to_dbus_interfaces ();
}

private void set_check_style () {
// Override check's accent_color so that it *always* uses user's preferred color
logged_in.get_style_context ().add_class (accent_to_string (settings_act.accent_color));
}

private string generate_background_image_path () {
if (settings_act.picture_options == 0) {
return "";
}

var path = Path.build_filename ("/", "var", "lib", "lightdm-data", user.user_name, "wallpaper");
if (FileUtils.test (path, EXISTS) && FileUtils.test (path, IS_REGULAR)) {
return path;
}

return "/usr/share/backgrounds/elementaryos-default";
}

private void set_background_image () {
Greeter.BackgroundImage background_image;

var background_path = lightdm_user.background;
var background_exists = (
background_path != null &&
FileUtils.test (background_path, EXISTS) &&
FileUtils.test (background_path, IS_REGULAR)
);

if (!background_exists) {
background_path = Path.build_filename ("/", "var", "lib", "lightdm-data", lightdm_user.name, "wallpaper");
background_exists = FileUtils.test (background_path, EXISTS) && FileUtils.test (background_path, IS_REGULAR);
}
var background_path = generate_background_image_path ();

if (settings_act.picture_options != 0 && background_exists) {
if (settings_act.picture_options != 0) {
background_image = new Greeter.BackgroundImage.from_path (background_path);
} else if (settings_act.picture_options == 0 && settings_act.primary_color != null) {
} else if (settings_act.primary_color != null) {
background_image = new Greeter.BackgroundImage.from_color (settings_act.primary_color);
} else {
background_image = new Greeter.BackgroundImage.from_path (null);
Expand Down Expand Up @@ -223,7 +228,7 @@ public class Greeter.UserCard : Greeter.BaseCard {
}

private void connect_to_dbus_interfaces () {
var account_path = "/org/freedesktop/Accounts/User%d".printf ((int )lightdm_user.uid);
var account_path = "/org/freedesktop/Accounts/User%d".printf (user.uid);
try {
greeter_act = Bus.get_proxy_sync (
SYSTEM,
Expand All @@ -246,16 +251,10 @@ public class Greeter.UserCard : Greeter.BaseCard {

set_background_image ();
set_check_style ();
update_is_locked_ui ();
}

private void update_is_locked_ui () {
// lightdm_user.is_locked prints warnings so let's use a getter method here
var is_locked = lightdm_user.get_is_locked ();

username_label.sensitive = !is_locked;

if (is_locked) {
if (user.locked) {
login_stack.visible_child_name = "disabled";
} else if (need_password) {
login_stack.visible_child_name = "password";
Expand All @@ -264,6 +263,24 @@ public class Greeter.UserCard : Greeter.BaseCard {
}
}

private void on_sessions_changed () {
var user_is_logged_in = user.is_logged_in ();

password_session_button.sensitive = !user_is_logged_in;
login_button_session_button.sensitive = user_is_logged_in;

var tooltip_text = user_is_logged_in ? (_("Session cannot be changed while user is logged in")) : "";
password_session_button.tooltip_text = tooltip_text;
login_button_session_button.tooltip_text = tooltip_text;

if (user_is_logged_in) {
avatar_overlay.add_overlay (logged_in);
logged_in.show_all ();
} else {
avatar_overlay.remove (logged_in);
}
}

private void on_login () {
if (connecting) {
return;
Expand Down Expand Up @@ -378,7 +395,7 @@ public class Greeter.UserCard : Greeter.BaseCard {

var background_settings = new GLib.Settings ("org.gnome.desktop.background");
background_settings.set_enum ("picture-options", settings_act.picture_options);
set_or_reset_settings_key (background_settings, "picture-uri", lightdm_user.background);
set_or_reset_settings_key (background_settings, "picture-uri", generate_background_image_path ());
set_or_reset_settings_key (background_settings, "primary-color", settings_act.primary_color);
}

Expand Down
Loading