diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ebb1076d..10a67f24 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,7 +31,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y desktop-file-utils libaccountsservice-dev libgdk-pixbuf2.0-dev libgnome-desktop-3-dev libgranite-dev libgtk-3-dev libhandy-1-dev liblightdm-gobject-1-dev ${{ matrix.mutter_pkg }} libx11-dev meson valac + apt install -y desktop-file-utils libaccountsservice-dev libgdk-pixbuf2.0-dev libgnome-desktop-3-dev libgranite-7-dev libgtk-4-dev libadwaita-1-dev liblightdm-gobject-1-dev ${{ matrix.mutter_pkg }} libx11-dev meson valac - name: Build env: DESTDIR: out diff --git a/data/Application.css b/data/Application.css index 300c9a92..9be995d3 100644 --- a/data/Application.css +++ b/data/Application.css @@ -4,6 +4,8 @@ */ .background { + background: transparent; + box-shadow: none; opacity: 0; transition: opacity 1s ease; } @@ -12,6 +14,7 @@ opacity: 1; } + .date, .time { color: #fff; diff --git a/po/POTFILES b/po/POTFILES index 47d1268b..1ee8320a 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -30,7 +30,6 @@ src/Settings.vala src/Cards/BaseCard.vala src/Cards/ManualCard.vala src/Cards/UserCard.vala -src/Widgets/BackgroundImage.vala src/Widgets/CapsLockRevealer.vala src/Widgets/DateTimeWidget.vala src/Widgets/PasswordEntry.vala diff --git a/src/Application.vala b/src/Application.vala index 20e9430c..fd4a7e2d 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -37,15 +37,12 @@ public class Greeter.Application : Gtk.Application { protected override void startup () { base.startup (); - var css_provider = new Gtk.CssProvider (); - css_provider.load_from_resource ("/io/elementary/greeter/Application.css"); - - Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + Granite.init (); } public override void activate () { add_window (new Greeter.MainWindow ()); - active_window.show_all (); + active_window.present (); } public static int main (string[] args) { diff --git a/src/Cards/BaseCard.vala b/src/Cards/BaseCard.vala index 66e14014..07e15c8a 100644 --- a/src/Cards/BaseCard.vala +++ b/src/Cards/BaseCard.vala @@ -22,8 +22,6 @@ public abstract class Greeter.BaseCard : Gtk.Box { public signal void do_connect (string? credential = null); - protected static Gtk.CssProvider css_provider; - public bool connecting { get; set; default = false; } public bool need_password { get; set; default = false; } public bool use_fingerprint { get; set; default = false; } @@ -38,11 +36,6 @@ public abstract class Greeter.BaseCard : Gtk.Box { protected Gtk.Revealer revealer; - static construct { - css_provider = new Gtk.CssProvider (); - css_provider.load_from_resource ("/io/elementary/greeter/Card.css"); - } - construct { revealer = new Gtk.Revealer () { halign = CENTER, @@ -52,8 +45,7 @@ public abstract class Greeter.BaseCard : Gtk.Box { width_request = 350 }; - add (revealer); - events |= Gdk.EventMask.BUTTON_RELEASE_MASK; + append (revealer); revealer.notify["child-revealed"].connect (() => { if (!revealer.child_revealed) { diff --git a/src/Cards/ManualCard.vala b/src/Cards/ManualCard.vala index 9d76f889..12e87636 100644 --- a/src/Cards/ManualCard.vala +++ b/src/Cards/ManualCard.vala @@ -22,7 +22,7 @@ public class Greeter.ManualCard : Greeter.BaseCard { hexpand = true, margin_bottom = 16 }; - label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); + label.add_css_class (Granite.STYLE_CLASS_H2_LABEL); username_entry = new Gtk.Entry () { hexpand = true, @@ -41,8 +41,8 @@ public class Greeter.ManualCard : Greeter.BaseCard { var caps_lock_revealer = new Greeter.CapsLockRevealer (); var password_box = new Gtk.Box (VERTICAL, 6); - password_box.add (password_entry); - password_box.add (caps_lock_revealer); + password_box.append (password_entry); + password_box.append (caps_lock_revealer); var session_button = new Greeter.SessionButton (); @@ -66,11 +66,9 @@ public class Greeter.ManualCard : Greeter.BaseCard { margin_start = 12, margin_end = 12 }; - main_box.add (form_grid); - - unowned var main_grid_style_context = main_box.get_style_context (); - main_grid_style_context.add_class (Granite.STYLE_CLASS_CARD); - main_grid_style_context.add_class (Granite.STYLE_CLASS_ROUNDED); + main_box.append (form_grid); + main_box.add_css_class (Granite.STYLE_CLASS_CARD); + main_box.add_css_class (Granite.STYLE_CLASS_ROUNDED); child = main_box; @@ -79,13 +77,19 @@ public class Greeter.ManualCard : Greeter.BaseCard { username_entry.activate.connect (() => do_connect_username (username_entry.text)); password_entry.activate.connect (on_login); - grab_focus.connect (() => { - if (username_entry.sensitive) { - username_entry.grab_focus_without_selecting (); - } else { - password_entry.grab_focus_without_selecting (); + + var focus_controller = new Gtk.EventControllerFocus (); + focus_controller.enter.connect (() => { + if (focus_controller.is_focus) { + if (username_entry.sensitive) { + username_entry.grab_focus_without_selecting (); + } else { + password_entry.grab_focus_without_selecting (); + } } }); + + add_controller (focus_controller); } private void on_login () { @@ -119,19 +123,14 @@ public class Greeter.ManualCard : Greeter.BaseCard { public override void wrong_credentials () { password_entry.text = ""; - unowned var username_entry_style_context = username_entry.get_style_context (); - username_entry_style_context.add_class (Gtk.STYLE_CLASS_ERROR); - - unowned var password_entry_style_context = password_entry.get_style_context (); - password_entry_style_context.add_class (Gtk.STYLE_CLASS_ERROR); - - unowned var grid_style_context = main_box.get_style_context (); - grid_style_context.add_class ("shake"); + username_entry.add_css_class (Granite.STYLE_CLASS_ERROR); + password_entry.add_css_class (Granite.STYLE_CLASS_ERROR); + main_box.add_css_class ("shake"); Timeout.add (ERROR_SHAKE_DURATION, () => { - grid_style_context.remove_class ("shake"); - username_entry_style_context.remove_class (Gtk.STYLE_CLASS_ERROR); - password_entry_style_context.remove_class (Gtk.STYLE_CLASS_ERROR); + main_box.remove_css_class ("shake"); + username_entry.remove_css_class (Granite.STYLE_CLASS_ERROR); + password_entry.remove_css_class (Granite.STYLE_CLASS_ERROR); connecting = false; focus_username_entry (); @@ -148,15 +147,12 @@ public class Greeter.ManualCard : Greeter.BaseCard { username_entry.secondary_icon_name = ""; username_entry.text = ""; - unowned var entry_style_context = username_entry.get_style_context (); - entry_style_context.add_class (Gtk.STYLE_CLASS_ERROR); - - unowned var grid_style_context = main_box.get_style_context (); - grid_style_context.add_class ("shake"); + username_entry.add_css_class (Granite.STYLE_CLASS_ERROR); + main_box.add_css_class ("shake"); Timeout.add (ERROR_SHAKE_DURATION, () => { - grid_style_context.remove_class ("shake"); - entry_style_context.remove_class (Gtk.STYLE_CLASS_ERROR); + main_box.remove_css_class ("shake"); + username_entry.remove_css_class (Granite.STYLE_CLASS_ERROR); return Source.REMOVE; }); diff --git a/src/Cards/UserCard.vala b/src/Cards/UserCard.vala index 40a5fffc..a2977f03 100644 --- a/src/Cards/UserCard.vala +++ b/src/Cards/UserCard.vala @@ -24,7 +24,7 @@ public class Greeter.UserCard : Greeter.BaseCard { private Pantheon.AccountsService greeter_act; private Pantheon.SettingsDaemon.AccountsService settings_act; - private Gtk.GestureMultiPress click_gesture; + private Gtk.GestureClick click_gesture; private Gtk.Revealer form_revealer; private Gtk.Stack login_stack; private Greeter.PasswordEntry password_entry; @@ -32,9 +32,6 @@ public class Greeter.UserCard : Greeter.BaseCard { private SelectionCheck logged_in; - private unowned Gtk.StyleContext main_box_style_context; - private unowned Gtk.StyleContext password_entry_context; - private bool needs_settings_set = false; public UserCard (LightDM.User lightdm_user) { @@ -52,11 +49,9 @@ public class Greeter.UserCard : Greeter.BaseCard { margin_end = 24, }; - unowned var username_label_context = username_label.get_style_context (); - username_label_context.add_class (Granite.STYLE_CLASS_H2_LABEL); + username_label.add_css_class (Granite.STYLE_CLASS_H2_LABEL); password_entry = new Greeter.PasswordEntry (); - password_entry_context = password_entry.get_style_context (); bind_property ( "connecting", @@ -65,10 +60,7 @@ public class Greeter.UserCard : Greeter.BaseCard { INVERT_BOOLEAN ); - var fingerprint_image = new Gtk.Image.from_icon_name ( - "fingerprint-symbolic", - BUTTON - ); + var fingerprint_image = new Gtk.Image.from_icon_name ("fingerprint-symbolic"); bind_property ( "use-fingerprint", @@ -103,7 +95,7 @@ public class Greeter.UserCard : Greeter.BaseCard { size_group.add_widget (session_button); var login_button = new Gtk.Button.with_label (_("Log In")); - login_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + login_button.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); bind_property ( "connecting", @@ -112,7 +104,7 @@ public class Greeter.UserCard : Greeter.BaseCard { INVERT_BOOLEAN ); - var disabled_icon = new Gtk.Image.from_icon_name ("changes-prevent-symbolic", MENU); + var disabled_icon = new Gtk.Image.from_icon_name ("changes-prevent-symbolic"); var disabled_message = new Gtk.Label (_("Account disabled")); @@ -120,9 +112,9 @@ public class Greeter.UserCard : Greeter.BaseCard { halign = Gtk.Align.CENTER, margin_top = 3 }; - disabled_box.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - disabled_box.add (disabled_icon); - disabled_box.add (disabled_message); + disabled_box.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + disabled_box.append (disabled_icon); + disabled_box.append (disabled_message); login_stack = new Gtk.Stack (); login_stack.add_named (password_grid, "password"); @@ -135,8 +127,8 @@ public class Greeter.UserCard : Greeter.BaseCard { margin_start = 24, margin_end = 24 }; - form_box.add (login_stack); - form_box.add (session_button); + form_box.append (login_stack); + form_box.append (session_button); form_revealer = new Gtk.Revealer () { margin_bottom = 12, @@ -153,31 +145,30 @@ public class Greeter.UserCard : Greeter.BaseCard { ); main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - margin_bottom = 48 + overflow = HIDDEN }; - // in reverse order because pack_end is used - main_box.pack_end (form_revealer); - main_box.pack_end (username_label); - - main_box_style_context = main_box.get_style_context (); - main_box_style_context.add_class (Granite.STYLE_CLASS_CARD); - main_box_style_context.add_class (Granite.STYLE_CLASS_ROUNDED); + main_box.append (username_label); + main_box.append (form_revealer); + main_box.add_css_class (Granite.STYLE_CLASS_CARD); + main_box.add_css_class (Granite.STYLE_CLASS_ROUNDED); update_collapsed_class (); - var avatar = new Hdy.Avatar (64, lightdm_user.display_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)) - }; + var avatar = new Adw.Avatar (64, lightdm_user.display_name, true); + + var user_icon_file = File.new_for_path (lightdm_user.image); + try { + avatar.custom_image = Gdk.Texture.from_file (user_icon_file ); + } catch (Error e) { + avatar.custom_image = null; + } var avatar_overlay = new Gtk.Overlay () { halign = CENTER, valign = START, margin_top = 100, - child = avatar + child = avatar, + overflow = VISIBLE }; logged_in = new SelectionCheck () { @@ -210,19 +201,15 @@ public class Greeter.UserCard : Greeter.BaseCard { on_act_user_loaded (); - card_overlay.focus.connect ((direction) => { + card_overlay.move_focus.connect ((direction) => { if (direction == LEFT) { go_left (); - return true; } else if (direction == RIGHT) { go_right (); - return true; } - - return false; }); - click_gesture = new Gtk.GestureMultiPress (this); + click_gesture = new Gtk.GestureClick (); click_gesture.pressed.connect ((n_press, x, y) => { if (!show_input) { focus_requested (); @@ -230,6 +217,8 @@ public class Greeter.UserCard : Greeter.BaseCard { } }); + add_controller (click_gesture); + notify["show-input"].connect (() => { update_collapsed_class (); }); @@ -245,18 +234,26 @@ public class Greeter.UserCard : Greeter.BaseCard { } }); - grab_focus.connect (() => { - password_entry.grab_focus_without_selecting (); + var focus_controller = new Gtk.EventControllerFocus (); + focus_controller.enter.connect (() => { + if (focus_controller.is_focus) { + password_entry.grab_focus_without_selecting (); + } }); + + add_controller (focus_controller); } 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 (prefers_accent_color)); + logged_in.add_css_class (accent_to_string (prefers_accent_color)); } private void set_background_image () { - Greeter.BackgroundImage background_image; + var background_picture = new Gtk.Picture () { + content_fit = COVER, + height_request = 150 + }; var background_path = lightdm_user.background; var background_exists = ( @@ -271,15 +268,29 @@ public class Greeter.UserCard : Greeter.BaseCard { } if (settings_act.picture_options != 0 && background_exists) { - background_image = new Greeter.BackgroundImage.from_path (background_path); + background_picture.set_filename (background_path); } else if (settings_act.picture_options == 0 && settings_act.primary_color != null) { - background_image = new Greeter.BackgroundImage.from_color (settings_act.primary_color); + Gdk.RGBA rgba_color = {}; + rgba_color.parse (settings_act.primary_color); + + uint32 f = 0x0; + f += (uint) Math.round (rgba_color.red * 255); + f <<= 8; + f += (uint) Math.round (rgba_color.green * 255); + f <<= 8; + f += (uint) Math.round (rgba_color.blue * 255); + f <<= 8; + f += 255; + + var pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, 1, 1); + pixbuf.fill (f); + + background_picture.paintable = (Gdk.Texture.for_pixbuf (pixbuf)); } else { - background_image = new Greeter.BackgroundImage.from_path (null); + background_picture.set_filename ("/usr/share/backgrounds/elementaryos-default"); } - main_box.pack_start (background_image); - main_box.show_all (); + main_box.prepend (background_picture); } private string accent_to_string (int i) { @@ -385,9 +396,9 @@ public class Greeter.UserCard : Greeter.BaseCard { private void update_collapsed_class () { if (show_input) { - main_box_style_context.remove_class ("collapsed"); + main_box.remove_css_class ("collapsed"); } else { - main_box_style_context.add_class ("collapsed"); + main_box.add_css_class ("collapsed"); } } @@ -506,14 +517,12 @@ public class Greeter.UserCard : Greeter.BaseCard { } public override void wrong_credentials () { - unowned var entry_style_context = password_entry.get_style_context (); - entry_style_context.add_class (Gtk.STYLE_CLASS_ERROR); - - main_box_style_context.add_class ("shake"); + password_entry.add_css_class (Granite.STYLE_CLASS_ERROR); + main_box.add_css_class ("shake"); Timeout.add (ERROR_SHAKE_DURATION, () => { - main_box_style_context.remove_class ("shake"); - entry_style_context.remove_class (Gtk.STYLE_CLASS_ERROR); + main_box.remove_css_class ("shake"); + password_entry.remove_css_class (Granite.STYLE_CLASS_ERROR); connecting = false; password_entry.grab_focus (); @@ -521,9 +530,9 @@ public class Greeter.UserCard : Greeter.BaseCard { }); } - private class SelectionCheck : Gtk.Spinner { + private class SelectionCheck : Gtk.Widget { class construct { - set_css_name (Gtk.STYLE_CLASS_CHECK); + set_css_name ("check"); } } } diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 3e14619d..d85f12a5 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -22,7 +22,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { private GLib.Queue user_cards; private Gtk.SizeGroup card_size_group; - private Hdy.Carousel carousel; + private Adw.Carousel carousel; private LightDM.Greeter lightdm_greeter; private Greeter.Settings settings; private Gtk.Button guest_login_button; @@ -36,8 +36,6 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { private bool installer_mode = false; - private Gtk.EventControllerKey key_controller; - private const uint[] NAVIGATION_KEYS = { Gdk.Key.Up, Gdk.Key.Down, @@ -47,15 +45,11 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { }; construct { - app_paintable = true; decorated = false; - type_hint = Gdk.WindowTypeHint.DESKTOP; settings = new Greeter.Settings (); create_session_selection_action (); - set_visual (get_screen ().get_rgba_visual ()); - guest_login_button = new Gtk.Button.with_label (_("Log in as Guest")); manual_login_button = new Gtk.ToggleButton.with_label (_("Manual Login…")); @@ -81,7 +75,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { var manual_card = new Greeter.ManualCard (); - carousel = new Hdy.Carousel () { + carousel = new Adw.Carousel () { allow_long_swipes = true, vexpand = true }; @@ -89,16 +83,16 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { var manual_login_stack = new Gtk.Stack () { transition_type = Gtk.StackTransitionType.CROSSFADE }; - manual_login_stack.add (carousel); - manual_login_stack.add (manual_card); + manual_login_stack.add_child (carousel); + manual_login_stack.add_child (manual_card); var main_box = new Gtk.Box (VERTICAL, 24) { margin_top = 24, margin_bottom = 24 }; - main_box.add (datetime_revealer); - main_box.add (manual_login_stack); - main_box.add (extra_login_grid); + main_box.append (datetime_revealer); + main_box.append (manual_login_stack); + main_box.append (extra_login_grid); child = main_box; @@ -169,7 +163,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { lightdm_greeter.bind_property ("hide-users-hint", manual_login_button, "active", GLib.BindingFlags.SYNC_CREATE); notify["scale-factor"].connect (() => { - maximize_window (); + maximize (); }); lightdm_user_list = LightDM.UserList.get_instance (); @@ -180,9 +174,12 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { manual_card.do_connect_username.connect (do_connect_username); manual_card.do_connect.connect (do_connect); - key_controller = new Gtk.EventControllerKey (this) { + var key_controller = new Gtk.EventControllerKey () { propagation_phase = CAPTURE }; + + ((Gtk.Widget) this).add_controller (key_controller); + key_controller.key_pressed.connect ((keyval, keycode, state) => { var mods = state & Gtk.accelerator_get_default_mod_mask (); @@ -222,28 +219,12 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { }); carousel.page_changed.connect ((index) => { - var children = carousel.get_children (); - - if (children.nth_data (index) is Greeter.UserCard) { + if (carousel.get_nth_page (index) is Greeter.UserCard) { current_user_card_index = (int) index; - switch_to_card ((Greeter.UserCard) children.nth_data (index)); + switch_to_card ((Greeter.UserCard) carousel.get_nth_page (index)); } }); - // regrab focus when dpi changed - get_screen ().monitors_changed.connect (() => { - maximize_and_focus (); - }); - - leave_notify_event.connect (() => { - maximize_and_focus (); - return false; - }); - - destroy.connect (() => { - Gtk.main_quit (); - }); - load_users.begin (() => { /* A significant delay is required in order for the window and card to be focused at * at boot. TODO: Find whether boot sequence can be tweaked to fix this. @@ -254,7 +235,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { }); }); - maximize_window (); + maximize (); if (settings.activate_numlock) { try { @@ -267,33 +248,16 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { private void maximize_and_focus () { present (); - maximize_window (); - get_style_context ().add_class ("initialized"); + maximize (); + add_css_class ("initialized"); + + // We can't move the window that probably need to go to compositor? if (current_card != null) { current_card.grab_focus (); } } - private void maximize_window () { - var display = Gdk.Display.get_default (); - unowned Gdk.Seat seat = display.get_default_seat (); - unowned Gdk.Device? pointer = seat.get_pointer (); - - Gdk.Monitor? monitor; - if (pointer != null) { - int x, y; - pointer.get_position (null, out x, out y); - monitor = display.get_monitor_at_point (x, y); - } else { - monitor = display.get_primary_monitor (); - } - - var rect = monitor.get_geometry (); - resize (rect.width, rect.height); - move (rect.x, rect.y); - } - private void create_session_selection_action () { unowned GLib.List sessions = LightDM.get_sessions (); weak LightDM.Session? first_session = sessions.nth_data (0); @@ -490,9 +454,8 @@ 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 (); - carousel.add (user_card); + carousel.append (user_card); user_card.focus_requested.connect (() => { switch_to_card (user_card); @@ -537,7 +500,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { current_card = user_card; - carousel.scroll_to (user_card); + carousel.scroll_to (user_card, true); user_card.set_settings (); user_card.show_input = true; @@ -588,7 +551,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { } carousel.interactive = false; - carousel.scroll_to (current_card); + carousel.scroll_to (current_card, true); } private void go_previous () { @@ -598,7 +561,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { unowned Greeter.UserCard? next_card = user_cards.peek_nth (current_user_card_index - 1); if (next_card != null) { - carousel.scroll_to (next_card); + carousel.scroll_to (next_card, true); } } @@ -609,7 +572,7 @@ public class Greeter.MainWindow : Gtk.ApplicationWindow { unowned Greeter.UserCard? next_card = user_cards.peek_nth (current_user_card_index + 1); if (next_card != null) { - carousel.scroll_to (next_card); + carousel.scroll_to (next_card, true); } } } diff --git a/src/Widgets/BackgroundImage.vala b/src/Widgets/BackgroundImage.vala deleted file mode 100644 index c52274ca..00000000 --- a/src/Widgets/BackgroundImage.vala +++ /dev/null @@ -1,89 +0,0 @@ -public class Greeter.BackgroundImage : Gtk.EventBox { - private uint last_size_hash = 0; - private Gdk.Pixbuf full_pixbuf; - private Gdk.Pixbuf fitting_pixbuf; - - construct { - height_request = 150; - } - - public BackgroundImage.from_path (string? path) { - if (path == null) { - path = "/usr/share/backgrounds/elementaryos-default"; - } - - try { - full_pixbuf = new Gdk.Pixbuf.from_file (path); - } catch (GLib.Error e) { - critical (e.message); - critical ("Fallback to default wallpaper"); - - try { - full_pixbuf = new Gdk.Pixbuf.from_file ("/usr/share/backgrounds/elementaryos-default"); - } catch (GLib.Error e) { - critical (e.message); - } - } - } - - public BackgroundImage.from_color (string color) { - full_pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, 1, 1); - - Gdk.RGBA rgba_color = {}; - rgba_color.parse (color); - - uint32 f = 0x0; - f += (uint) Math.round (rgba_color.red * 255); - f <<= 8; - f += (uint) Math.round (rgba_color.green * 255); - f <<= 8; - f += (uint) Math.round (rgba_color.blue * 255); - f <<= 8; - f += 255; - - full_pixbuf.fill (f); - } - - public override bool draw (Cairo.Context cr) { - var scale = get_scale_factor (); - var width = get_allocated_width () * scale; - var height = get_allocated_height () * scale; - var radius = 5 * scale; // Off-by-one to prevent light bleed - - var new_hash = GLib.int_hash (width) + GLib.int_hash (height); - if (new_hash != last_size_hash) { - last_size_hash = new_hash; - double full_ratio = (double)full_pixbuf.height / (double)full_pixbuf.width; - fitting_pixbuf = new Gdk.Pixbuf (full_pixbuf.colorspace, full_pixbuf.has_alpha, full_pixbuf.bits_per_sample, width, height); - - // Get a scaled pixbuf that preserves aspect ratio but is at least as big as the desired destination pixbuf - Gdk.Pixbuf scaled_pixbuf; - if ((int)(width * full_ratio) < height) { - scaled_pixbuf = full_pixbuf.scale_simple ((int)(width * (1 / full_ratio)), height, Gdk.InterpType.BILINEAR); - } else { - scaled_pixbuf = full_pixbuf.scale_simple (width, (int)(width * full_ratio), Gdk.InterpType.BILINEAR); - } - - // Find the offset we need to center the source pixbuf on the destination - int y = ((height - scaled_pixbuf.height) / 2).abs (); - int x = ((width - scaled_pixbuf.width) / 2).abs (); - - scaled_pixbuf.copy_area (x, y, width, height, fitting_pixbuf, 0, 0); - } - - cr.save (); - cr.scale (1.0 / scale, 1.0 / scale); - cr.new_sub_path (); - cr.arc (width - radius, radius, radius, -Math.PI_2, 0); - cr.line_to (width, height); - cr.line_to (0, height); - - cr.arc (radius, radius, radius, Math.PI, Math.PI + Math.PI_2); - cr.close_path (); - Gdk.cairo_set_source_pixbuf (cr, fitting_pixbuf, 0, 0); - cr.clip (); - cr.paint (); - cr.restore (); - return true; - } -} diff --git a/src/Widgets/CapsLockRevealer.vala b/src/Widgets/CapsLockRevealer.vala index bf2c2768..3de20207 100644 --- a/src/Widgets/CapsLockRevealer.vala +++ b/src/Widgets/CapsLockRevealer.vala @@ -3,8 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -public class Greeter.CapsLockRevealer : Gtk.Bin { - private weak Gdk.Keymap keymap; +public class Greeter.CapsLockRevealer : Adw.Bin { + private unowned Gdk.Device device; private Gtk.Image caps_lock_image; private Gtk.Image num_lock_image; @@ -12,26 +12,26 @@ public class Greeter.CapsLockRevealer : Gtk.Bin { private Gtk.Revealer revealer; construct { - caps_lock_image = new Gtk.Image.from_icon_name ("input-keyboard-capslock-symbolic", Gtk.IconSize.MENU) { + caps_lock_image = new Gtk.Image.from_icon_name ("input-keyboard-capslock-symbolic") { use_fallback = true, visible = false }; - num_lock_image = new Gtk.Image.from_icon_name ("input-keyboard-numlock-symbolic", Gtk.IconSize.MENU) { + num_lock_image = new Gtk.Image.from_icon_name ("input-keyboard-numlock-symbolic") { use_fallback = true, visible = false }; lock_label = new Gtk.Label (null); - lock_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL); + lock_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); var caps_lock_box = new Gtk.Box (HORIZONTAL, 3) { halign = CENTER }; - caps_lock_box.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - caps_lock_box.add (caps_lock_image); - caps_lock_box.add (num_lock_image); - caps_lock_box.add (lock_label); + caps_lock_box.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + caps_lock_box.append (caps_lock_image); + caps_lock_box.append (num_lock_image); + caps_lock_box.append (lock_label); revealer = new Gtk.Revealer () { child = caps_lock_box, @@ -40,20 +40,18 @@ public class Greeter.CapsLockRevealer : Gtk.Bin { child = revealer; - keymap = Gdk.Keymap.get_for_display (Gdk.Display.get_default ()); - keymap.state_changed.connect (update_visibility); + device = Gdk.Display.get_default ().get_default_seat ().get_keyboard (); + device.changed.connect (update_visibility); update_visibility (); } private void update_visibility () { - var caps_lock = keymap.get_caps_lock_state (); - var num_lock = keymap.get_num_lock_state (); + var caps_lock = device.caps_lock_state; + var num_lock = device.num_lock_state; revealer.reveal_child = caps_lock || num_lock; - caps_lock_image.no_show_all = !caps_lock; - num_lock_image.no_show_all = !num_lock; caps_lock_image.visible = caps_lock; num_lock_image.visible = num_lock; diff --git a/src/Widgets/DateTimeWidget.vala b/src/Widgets/DateTimeWidget.vala index 7b44d9dd..80428e5a 100644 --- a/src/Widgets/DateTimeWidget.vala +++ b/src/Widgets/DateTimeWidget.vala @@ -14,14 +14,14 @@ public class Greeter.DateTimeWidget : Gtk.Box { construct { time_label = new Gtk.Label (null); - time_label.get_style_context ().add_class ("time"); + time_label.add_css_class ("time"); date_label = new Gtk.Label (null); - date_label.get_style_context ().add_class ("date"); + date_label.add_css_class ("date"); orientation = VERTICAL; - add (time_label); - add (date_label); + append (time_label); + append (date_label); update_labels (); diff --git a/src/Widgets/PasswordEntry.vala b/src/Widgets/PasswordEntry.vala index f9bd6a26..83cb1d8b 100644 --- a/src/Widgets/PasswordEntry.vala +++ b/src/Widgets/PasswordEntry.vala @@ -29,8 +29,8 @@ public class Greeter.PasswordEntry : Gtk.Entry { visibility = false; input_purpose = Gtk.InputPurpose.PASSWORD; - icon_press.connect ((pos, event) => { - if (pos == Gtk.EntryIconPosition.SECONDARY) { + icon_press.connect ((pos) => { + if (pos == SECONDARY) { activate (); } }); diff --git a/src/Widgets/SessionButton.vala b/src/Widgets/SessionButton.vala index 3a2e60a9..37f3691c 100644 --- a/src/Widgets/SessionButton.vala +++ b/src/Widgets/SessionButton.vala @@ -19,33 +19,32 @@ * Authors: Corentin Noël */ -public class Greeter.SessionButton : Gtk.MenuButton { +public class Greeter.SessionButton : Adw.Bin { construct { var menu = new GLib.Menu (); - var cog_image = new Gtk.Image.from_icon_name ("open-menu-symbolic", Gtk.IconSize.BUTTON); + var menu_button = new Gtk.MenuButton () { + direction = DOWN, + has_frame = false, + icon_name = "open-menu-symbolic", + menu_model = menu + }; - direction = DOWN; - menu_model = menu; - get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); - add (cog_image); + child = menu_button; - // The session action is on the MainWindow toplevel, wait until it is accessible. - hierarchy_changed.connect ((previous_toplevel) => { - var main_window = (Gtk.ApplicationWindow) get_ancestor (typeof (Gtk.ApplicationWindow)); - if (main_window != null) { - var hint = main_window.get_action_state_hint ("select-session"); - var iter = hint.iterator (); - GLib.Variant? val = null; - string? key = null; - while (iter.next ("{sv}", out key, out val)) { - menu.append (key, Action.print_detailed_name ("win.select-session", val)); - } + var main_window = (Gtk.ApplicationWindow) get_ancestor (typeof (Gtk.ApplicationWindow)); + if (main_window != null) { + var hint = main_window.get_action_state_hint ("select-session"); + var iter = hint.iterator (); + GLib.Variant? val = null; + string? key = null; + while (iter.next ("{sv}", out key, out val)) { + menu.append (key, Action.print_detailed_name ("win.select-session", val)); + } - if (menu.get_n_items () == 0) { - destroy (); - } + if (menu.get_n_items () == 0) { + destroy (); } - }); + } } } diff --git a/src/meson.build b/src/meson.build index f3d33099..ba61bd62 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,9 +1,9 @@ actservice_dep = dependency('accountsservice') gobject_dep = dependency('gobject-2.0') glib_dep = dependency('glib-2.0') -gtk_dep = dependency('gtk+-3.0') -granite_dep = dependency('granite', version: '>= 5.5.0') -hdy_dep = dependency('libhandy-1', version: '>= 1.1.90') +gtk_dep = dependency('gtk4') +granite_dep = dependency('granite-7', version: '>= 7.0.0') +adw_dep = dependency('libadwaita-1', version: '>= 1.0.0') lightdm_dep = dependency('liblightdm-gobject-1') gnome_desktop_dep = dependency('gnome-desktop-3.0') m_dep = meson.get_compiler('c').find_library('m') @@ -22,13 +22,12 @@ executable( 'Cards/BaseCard.vala', 'Cards/ManualCard.vala', 'Cards/UserCard.vala', - 'Widgets/BackgroundImage.vala', 'Widgets/CapsLockRevealer.vala', 'Widgets/DateTimeWidget.vala', 'Widgets/PasswordEntry.vala', 'Widgets/SessionButton.vala', config_header, - dependencies: [ actservice_dep, gobject_dep, glib_dep, gtk_dep, granite_dep, hdy_dep, lightdm_dep, m_dep ], + dependencies: [ actservice_dep, gobject_dep, glib_dep, gtk_dep, granite_dep, adw_dep, lightdm_dep, m_dep ], install : true, install_dir: install_path )