Skip to content
Draft
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
63 changes: 63 additions & 0 deletions src/AuthenticationManager.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io)
*
* Authors: Leo "lenemter" <lenemter@gmail.com>
*/

private class Greeter.AuthenticationManager : Object {
public LightDM.Greeter lightdm_greeter { private get; construct; }

private bool waiting_for_authentication_to_complete = false;
private string queued_credential = "";

public AuthenticationManager (LightDM.Greeter lightdm_greeter) {
Object (lightdm_greeter: lightdm_greeter);
}

construct {
lightdm_greeter.show_prompt.connect (on_show_prompt);
}

private void on_show_prompt (string text, LightDM.PromptType type) {
if (type != SECRET ||
!waiting_for_authentication_to_complete
) {
return;
}

waiting_for_authentication_to_complete = false;

try {
lightdm_greeter.respond (queued_credential);
} catch (Error e) {
critical (e.message);
}

queued_credential = "";
}

public void cancel_authentication () {
if (!lightdm_greeter.in_authentication) {
return;
}

try {
lightdm_greeter.cancel_authentication ();
} catch (Error e) {
critical (e.message);
}
}

public void authenticate (string username, string credential) {
cancel_authentication ();

try {
lightdm_greeter.authenticate (username);
waiting_for_authentication_to_complete = true;
queued_credential = credential;
} catch (Error e) {
critical (e.message);
}
}
}
4 changes: 2 additions & 2 deletions src/Cards/BaseCard.vala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileCopyrightText: 2018-2025 elementary, Inc. (https://elementary.io)
* SPDX-FileCopyrightText: 2018-2026 elementary, Inc. (https://elementary.io)
*
* Authors: Corentin Noël <corentin@elementary.io>
*/

public abstract class Greeter.BaseCard : Gtk.Bin {
public signal void do_connect (string? credential = null);
public signal void authenticate (string username, string credential);
public signal void go_left ();
public signal void go_right ();

Expand Down
13 changes: 3 additions & 10 deletions src/Cards/ManualCard.vala
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/*
* Copyright 2018-2023 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileCopyrightText: 2018-2026 elementary, Inc. (https://elementary.io)
*/

public class Greeter.ManualCard : Greeter.BaseCard {
public signal void do_connect_username (string username);

private Greeter.PasswordEntry password_entry;
private Gtk.Entry username_entry;
private Gtk.Box main_box;
Expand Down Expand Up @@ -68,12 +66,7 @@ public class Greeter.ManualCard : Greeter.BaseCard {
bind_property ("connecting", username_entry, "sensitive", INVERT_BOOLEAN);
bind_property ("connecting", password_entry, "sensitive", INVERT_BOOLEAN);

username_entry.focus_out_event.connect (() => {
if (username_entry.text != "") {
do_connect_username (username_entry.text);
}
});

username_entry.activate.connect (on_login);
password_entry.activate.connect (on_login);
}

Expand All @@ -83,7 +76,7 @@ public class Greeter.ManualCard : Greeter.BaseCard {
}

connecting = true;
do_connect (password_entry.text);
authenticate (username_entry.text, password_entry.text);
}

public override void wrong_credentials () {
Expand Down
8 changes: 2 additions & 6 deletions src/Cards/UserCard.vala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright 2018-2025 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2018-2026 elementary, Inc. (https://elementary.io)
*
* Authors: Corentin Noël <corentin@elementary.io>
*/
Expand Down Expand Up @@ -270,11 +270,7 @@ public class Greeter.UserCard : Greeter.BaseCard {
}

connecting = true;
if (need_password) {
do_connect (password_entry.text);
} else {
do_connect ();
}
authenticate (lightdm_user.name, need_password ? password_entry.text : "");
}

private void update_collapsed_class () {
Expand Down
76 changes: 11 additions & 65 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/*
* SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileCopyrightText: 2018-2025 elementary, Inc. (https://elementary.io)
* SPDX-FileCopyrightText: 2018-2026 elementary, Inc. (https://elementary.io)
*
* Authors: Corentin Noël <corentin@elementary.io>
*/

public class Greeter.MainWindow : Gtk.ApplicationWindow {
public LightDM.Greeter lightdm_greeter { private get; construct; }

private AuthenticationManager authentication_manager;
private Pantheon.Desktop.Greeter? desktop_greeter;
private GLib.Queue<unowned Greeter.UserCard> user_cards;
private Gtk.SizeGroup card_size_group;
Expand All @@ -34,6 +35,8 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
decorated = false;
set_visual (get_screen ().get_rgba_visual ());

authentication_manager = new AuthenticationManager (lightdm_greeter);

gsettings = new GLib.Settings ("io.elementary.greeter");
settings = new Greeter.Settings ();

Expand Down Expand Up @@ -92,34 +95,14 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
child = main_box;

manual_login_button.toggled.connect (() => {
if (manual_login_button.active) {
if (lightdm_greeter.in_authentication) {
try {
lightdm_greeter.cancel_authentication ();
} catch (Error e) {
critical (e.message);
}
}
authentication_manager.cancel_authentication ();

if (manual_login_button.active) {
manual_login_stack.visible_child = manual_card;
current_card = manual_card;
} else {
if (lightdm_greeter.in_authentication) {
try {
lightdm_greeter.cancel_authentication ();
} catch (Error e) {
critical (e.message);
}
}

manual_login_stack.visible_child = carousel;
current_card = user_cards.peek_nth (current_user_card_index);

try {
lightdm_greeter.authenticate (((UserCard) current_card).lightdm_user.name);
} catch (Error e) {
critical (e.message);
}
}
});

Expand All @@ -143,8 +126,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
load_users.begin ();
});

manual_card.do_connect_username.connect (do_connect_username);
manual_card.do_connect.connect (do_connect);
manual_card.authenticate.connect (authenticate);

key_controller = new Gtk.EventControllerKey (this) {
propagation_phase = CAPTURE
Expand Down Expand Up @@ -278,7 +260,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
}
}

private void show_prompt (string text, LightDM.PromptType type = LightDM.PromptType.QUESTION) {
private void show_prompt (string text, LightDM.PromptType type) {
if (current_card is ManualCard) {
if (type == LightDM.PromptType.SECRET) {
((ManualCard) current_card).ask_password ();
Expand Down Expand Up @@ -402,7 +384,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
private void add_card (LightDM.User lightdm_user) {
var user_card = new Greeter.UserCard (lightdm_user);
user_card.show_all ();
user_card.do_connect.connect (do_connect);
user_card.authenticate.connect (authenticate);
user_card.click_gesture.pressed.connect ((gesture, n_press, x, y) => {
assert (gesture.widget is UserCard);

Expand Down Expand Up @@ -459,46 +441,10 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow {
if (user_card.lightdm_user.session != null) {
application.activate_action ("select-session", new GLib.Variant.string (user_card.lightdm_user.session));
}

if (lightdm_greeter.in_authentication) {
try {
lightdm_greeter.cancel_authentication ();
} catch (Error e) {
critical (e.message);
}
}

try {
lightdm_greeter.authenticate (user_card.lightdm_user.name);
} catch (Error e) {
critical (e.message);
}
}

private void do_connect_username (string username) {
if (lightdm_greeter.in_authentication) {
try {
lightdm_greeter.cancel_authentication ();
} catch (Error e) {
critical (e.message);
}
}

try {
lightdm_greeter.authenticate (username);
} catch (Error e) {
critical (e.message);
}
}

private void do_connect (string? credential) {
if (credential != null) {
try {
lightdm_greeter.respond (credential);
} catch (Error e) {
critical (e.message);
}
}
private void authenticate (string username, string credential) {
authentication_manager.authenticate (username, credential);

carousel.interactive = false;
carousel.scroll_to (current_card);
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ executable(
meson.project_name(),
greeter_resources,
'Application.vala',
'AuthenticationManager.vala',
'FPrintUtils.vala',
'MainWindow.vala',
'PantheonAccountsServicePlugin.vala',
Expand Down
Loading