Skip to content
Merged
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
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 | INVERT_BOOLEAN);

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