diff --git a/src/AuthenticationManager.vala b/src/AuthenticationManager.vala new file mode 100644 index 00000000..e9fd9255 --- /dev/null +++ b/src/AuthenticationManager.vala @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io) + * + * Authors: Leo "lenemter" + */ + +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); + } + } +} diff --git a/src/Cards/BaseCard.vala b/src/Cards/BaseCard.vala index 2128e511..7ac72561 100644 --- a/src/Cards/BaseCard.vala +++ b/src/Cards/BaseCard.vala @@ -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 */ 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 (); diff --git a/src/Cards/ManualCard.vala b/src/Cards/ManualCard.vala index cae3c34a..4a7cc713 100644 --- a/src/Cards/ManualCard.vala +++ b/src/Cards/ManualCard.vala @@ -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; @@ -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); } @@ -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 () { diff --git a/src/Cards/UserCard.vala b/src/Cards/UserCard.vala index d60d00cd..badcf539 100644 --- a/src/Cards/UserCard.vala +++ b/src/Cards/UserCard.vala @@ -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 */ @@ -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 () { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 616ae938..088ac595 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1,6 +1,6 @@ /* * 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 */ @@ -8,6 +8,7 @@ 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 user_cards; private Gtk.SizeGroup card_size_group; @@ -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 (); @@ -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); - } } }); @@ -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 @@ -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 (); @@ -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); @@ -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); diff --git a/src/meson.build b/src/meson.build index 4b5059d6..c495cbd0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,6 +17,7 @@ executable( meson.project_name(), greeter_resources, 'Application.vala', + 'AuthenticationManager.vala', 'FPrintUtils.vala', 'MainWindow.vala', 'PantheonAccountsServicePlugin.vala',