diff --git a/data/compositor.gschema.xml b/data/compositor.gschema.xml index 8cef571c..3b6fcd6c 100644 --- a/data/compositor.gschema.xml +++ b/data/compositor.gschema.xml @@ -6,11 +6,6 @@ Last selected user - - '' - Last selected session type - - diff --git a/src/Application.vala b/src/Application.vala index b4407717..38c3e005 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -20,6 +20,21 @@ */ public class Greeter.Application : Gtk.Application { + public unowned string default_session_type { + get { + if (lightdm_greeter.default_session_hint != null) { + return lightdm_greeter.default_session_hint; + } + + unowned var sessions = LightDM.get_sessions (); + if (sessions.length () > 0) { + sessions.first ().data.key; + } + + return ""; + } + } + private LightDM.Greeter lightdm_greeter; public Application () { @@ -68,69 +83,12 @@ public class Greeter.Application : Gtk.Application { gtk_settings.gtk_application_prefer_dark_theme = settings_portal.prefers_color_scheme == 1; }); - var settings = new GLib.Settings ("io.elementary.greeter"); - lightdm_greeter = new LightDM.Greeter (); try { lightdm_greeter.connect_to_daemon_sync (); } catch (Error e) { critical ("LightDM couldn't connect to daemon: %s", e.message); } - - unowned var sessions = LightDM.get_sessions (); - - var selected_session = ""; - if (settings.get_string ("last-session-type") != "") { - selected_session = settings.get_string ("last-session-type"); - } else if (lightdm_greeter.default_session_hint != null) { - selected_session = lightdm_greeter.default_session_hint; - } else if (sessions.length () > 0) { - selected_session = sessions.first ().data.key; - } - - var select_session_action = new GLib.SimpleAction.stateful ("select-session", GLib.VariantType.STRING, selected_session); - var vardict = new GLib.VariantDict (); - var has_pantheon_x11_session = false; - sessions.foreach ((session) => { - vardict.insert_value (session.name, new GLib.Variant.string (session.key)); - if (session.key == "pantheon") { - has_pantheon_x11_session = true; - } - }); - select_session_action.set_state_hint (vardict.end ()); - - select_session_action.activate.connect ((param) => { - if (!select_session_action.get_state ().equal (param)) { - select_session_action.set_state (param); - } - }); - - add_action (select_session_action); - - if (has_pantheon_x11_session) { - var a11y_settings = new GLib.Settings ("org.gnome.desktop.a11y.applications"); - a11y_settings.changed.connect ((key) => { - if (key != "screen-keyboard-enabled" && key != "screen-reader-enabled") { - return; - } - - if (!a11y_settings.get_boolean (key)) { - return; - } - - if (select_session_action.get_state ().get_string () != "pantheon-wayland") { - return; - } - - select_session_action.set_state (new Variant.string ("pantheon")); - - var notification = new Notification (_("Classic session automatically selected")); - notification.set_body (_("Accessibility features may be unavailable in the Secure session")); - notification.set_icon (new ThemedIcon ("preferences-desktop-accessibility")); - - send_notification ("session-type", notification); - }); - } } public override void activate () { diff --git a/src/Cards/BaseCard.vala b/src/Cards/BaseCard.vala index 2128e511..7437c168 100644 --- a/src/Cards/BaseCard.vala +++ b/src/Cards/BaseCard.vala @@ -12,16 +12,102 @@ public abstract class Greeter.BaseCard : Gtk.Bin { protected const int ERROR_SHAKE_DURATION = 450; + /* + * Unique identifier of the card. + * User card uses User + uid + * Manual card -- "manual" + * Guest card -- "guest" + */ + public string card_identifier { protected get; construct; } + public string selected_session { private get; construct; } + public bool connecting { get; set; default = false; } public bool need_password { get; set; default = false; } public bool use_fingerprint { get; set; default = false; } + public unowned string selected_session_type { + get { + return select_session_action.state.get_string (); + } + } + + protected SimpleAction select_session_action; + + private static bool has_pantheon_x11_session; + private static GLib.Settings a11y_settings; + private static bool sent_x11_a11y_notification = false; + + static construct { + LightDM.get_sessions ().foreach ((session) => { + if (session.key == "pantheon") { + has_pantheon_x11_session = true; + } + }); + + a11y_settings = new GLib.Settings ("org.gnome.desktop.a11y.applications"); + } + + protected BaseCard (string card_identifier, string selected_session) { + Object (card_identifier: card_identifier, selected_session: selected_session); + } + construct { + select_session_action = new GLib.SimpleAction.stateful ("select-session", GLib.VariantType.STRING, selected_session); + var vardict = new GLib.VariantDict (); + LightDM.get_sessions ().foreach ((session) => vardict.insert_value (session.name, new GLib.Variant.string (session.key))); + select_session_action.set_state_hint (vardict.end ()); + + var action_group = new SimpleActionGroup (); + action_group.add_action (select_session_action); + insert_action_group (card_identifier, action_group); + + select_session_action.change_state.connect ((value) => { + select_session_action.set_state (value); + + if (value.get_string () != "pantheon") { + sent_x11_a11y_notification = false; + } + }); + + if (has_pantheon_x11_session) { + a11y_settings.changed.connect ((key) => { + if (key != "screen-keyboard-enabled" && key != "screen-reader-enabled") { + return; + } + + if (!a11y_settings.get_boolean (key)) { + return; + } + + if (select_session_action.state.get_string () != "pantheon-wayland") { + return; + } + + select_session_action.set_state (new Variant.string ("pantheon")); + send_x11_a11y_notification (); + }); + } + halign = CENTER; valign = CENTER; width_request = 350; } + private static void send_x11_a11y_notification () { + // Avoid sending notification for every card + if (sent_x11_a11y_notification) { + return; + } + + sent_x11_a11y_notification = true; + + var notification = new Notification (_("Classic session automatically selected")); + notification.set_body (_("Accessibility features may be unavailable in the Secure session")); + notification.set_icon (new ThemedIcon ("preferences-desktop-accessibility")); + + GLib.Application.get_default ().send_notification ("session-type", notification); + } + public override bool focus (Gtk.DirectionType direction) { if (direction == LEFT) { go_left (); diff --git a/src/Cards/ManualCard.vala b/src/Cards/ManualCard.vala index cae3c34a..453784cf 100644 --- a/src/Cards/ManualCard.vala +++ b/src/Cards/ManualCard.vala @@ -10,6 +10,13 @@ public class Greeter.ManualCard : Greeter.BaseCard { private Gtk.Entry username_entry; private Gtk.Box main_box; + public ManualCard () { + Object ( + card_identifier: "manual", + selected_session: ((Greeter.Application) GLib.Application.get_default ()).default_session_type + ); + } + construct { width_request = 350; @@ -35,7 +42,7 @@ public class Greeter.ManualCard : Greeter.BaseCard { var caps_lock_revealer = new Greeter.CapsLockRevealer (); - var session_button = new Greeter.SessionButton (); + var session_button = new Greeter.SessionButton (card_identifier, select_session_action); var form_grid = new Gtk.Grid () { column_spacing = 6, diff --git a/src/Cards/UserCard.vala b/src/Cards/UserCard.vala index 1e1f9dff..48643e84 100644 --- a/src/Cards/UserCard.vala +++ b/src/Cards/UserCard.vala @@ -23,7 +23,13 @@ public class Greeter.UserCard : Greeter.BaseCard { private SelectionCheck logged_in; public UserCard (LightDM.User lightdm_user) { - Object (lightdm_user: lightdm_user); + unowned var default_session = ((Greeter.Application) GLib.Application.get_default ()).default_session_type; + + Object ( + lightdm_user: lightdm_user, + card_identifier: "User%u".printf ((uint) lightdm_user.uid), + selected_session: lightdm_user.session ?? default_session + ); } construct { @@ -46,7 +52,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 () { + var password_session_button = new Greeter.SessionButton (card_identifier, select_session_action) { vexpand = true }; lightdm_user.bind_property ("is-locked", password_session_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN); @@ -64,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 () { + var login_button_session_button = new Greeter.SessionButton (card_identifier, select_session_action) { vexpand = true }; lightdm_user.bind_property ("is-locked", login_button_session_button, "sensitive", SYNC_CREATE | INVERT_BOOLEAN); diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 7d8ae7fd..2a27ce7a 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -297,7 +297,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { if (lightdm_greeter.is_authenticated) { try { - unowned var session = application.get_action_state ("select-session").get_string (); + unowned var session = current_card.selected_session_type; // If the greeter is running on the install medium, check if the Installer has signalled // that it wants the greeter to launch the live (demo) session by means of touching a file @@ -311,7 +311,6 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { } } - gsettings.set_string ("last-session-type", session); lightdm_greeter.start_session_sync (session); return; diff --git a/src/Widgets/SessionButton.vala b/src/Widgets/SessionButton.vala index f21b5f52..933262a9 100644 --- a/src/Widgets/SessionButton.vala +++ b/src/Widgets/SessionButton.vala @@ -6,15 +6,15 @@ */ public class Greeter.SessionButton : Gtk.Bin { - construct { + public SessionButton (string action_group_prefix, Action select_session_action) { var menu = new GLib.Menu (); - unowned var application = (Gtk.Application) GLib.Application.get_default (); - var hint = application.get_action_state_hint ("select-session"); - var iter = hint.iterator (); + + var iter = select_session_action.get_state_hint ().iterator (); GLib.Variant? val = null; string? key = null; while (iter.next ("{sv}", out key, out val)) { - menu.append (key, Action.print_detailed_name ("app.select-session", val)); + var action_name = "%s.%s".printf (action_group_prefix, select_session_action.name); + menu.append (key, Action.print_detailed_name (action_name, val)); } var menu_button = new Gtk.MenuButton () {