[gnome-boxes] express-install: Port express-install configuration UI to libhandy
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes] express-install: Port express-install configuration UI to libhandy
- Date: Fri, 11 Feb 2022 12:42:37 +0000 (UTC)
commit 9e8af77be85336158a336acd8acae070f3aca3f4
Author: Felipe Borges <felipeborges gnome org>
Date: Fri Feb 11 12:39:17 2022 +0100
express-install: Port express-install configuration UI to libhandy
We also drop the Avatar injection since this feature is not very
used and requires AccountsService on the host.
build-aux/flatpak/org.gnome.Boxes.json | 2 -
data/ui/assistant/pages/setup-page.ui | 7 --
data/ui/unattended-setup-box.ui | 224 +++++++--------------------------
src/assistant/review-page.vala | 12 +-
src/unattended-file.vala | 75 -----------
src/unattended-installer.vala | 39 ------
src/unattended-setup-box.vala | 50 ++------
src/util-app.vala | 40 ------
src/util.vala | 53 --------
9 files changed, 62 insertions(+), 440 deletions(-)
---
diff --git a/build-aux/flatpak/org.gnome.Boxes.json b/build-aux/flatpak/org.gnome.Boxes.json
index 48741a66..23b593b0 100644
--- a/build-aux/flatpak/org.gnome.Boxes.json
+++ b/build-aux/flatpak/org.gnome.Boxes.json
@@ -14,8 +14,6 @@
"--share=network",
"--device=all",
"--system-talk-name=org.freedesktop.timedate1",
- "--system-talk-name=org.freedesktop.Accounts",
- "--filesystem=/var/lib/AccountsService/icons:ro",
"--talk-name=org.gnome.ControlCenter",
"--talk-name=org.freedesktop.secrets",
"--filesystem=xdg-run/dconf",
diff --git a/data/ui/assistant/pages/setup-page.ui b/data/ui/assistant/pages/setup-page.ui
index f5425b7a..fd9ecf35 100644
--- a/data/ui/assistant/pages/setup-page.ui
+++ b/data/ui/assistant/pages/setup-page.ui
@@ -3,19 +3,12 @@
<template class="BoxesAssistantSetupPage" parent="BoxesAssistantPage">
<property name="visible">True</property>
<property name="title" translatable="yes">Express Installation</property>
- <property name="expand">True</property>
<child>
<object class="GtkBox" id="setup_box">
<property name="visible">True</property>
- <property name="expand">True</property>
<property name="orientation">vertical</property>
- <property name="spacing">0</property>
- <property name="margin-start">10</property>
- <property name="margin-end">10</property>
- <property name="valign">center</property>
</object>
</child>
-
</template>
</interface>
diff --git a/data/ui/unattended-setup-box.ui b/data/ui/unattended-setup-box.ui
index c50d1db4..03d96ec4 100644
--- a/data/ui/unattended-setup-box.ui
+++ b/data/ui/unattended-setup-box.ui
@@ -6,8 +6,6 @@
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">30</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
<child>
<object class="GtkInfoBar" id="needs_internet_bar">
<property name="visible">False</property>
@@ -38,221 +36,93 @@
</child>
</object>
</child>
+
<child>
- <object class="GtkLabel" id="setup_label">
- <property name="label" translatable="yes">Choose express install to automatically preconfigure the
box with optimal settings.</property>
- <property name="visible">True</property>
- <property name="wrap">True</property>
- <property name="halign">start</property>
- <property name="width-chars">30</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="setup_hbox">
+ <object class="HdyPreferencesPage">
<property name="visible">True</property>
- <property name="valign">start</property>
- <property name="margin">24</property>
- <property name="orientation">horizontal</property>
- <property name="spacing">0</property>
+
<child>
- <object class="GtkGrid" id="setup_grid">
+ <object class="HdyPreferencesGroup">
<property name="visible">True</property>
- <property name="column-homogeneous">False</property>
- <property name="row-homogeneous">False</property>
- <property name="column-spacing">0</property>
- <property name="row-spacing">0</property>
+ <property name="description" translatable="yes">Choose express install to automatically
preconfigure the box with optimal settings.</property>
- <!-- First row -->
<child>
- <object class="GtkLabel" id="express_label">
- <property name="label" translatable="yes" comments="Translators: 'Express Install' means
that the new box installation will be fully automated, the user won't be asked anything while it's
performed.">Express Install</property>
+ <object class="HdyActionRow">
<property name="visible">True</property>
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="margin-end">10</property>
- <property name="margin-bottom">15</property>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">0</property>
- <property name="width">2</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkSwitch" id="express_toggle">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="valign">center</property>
- <property name="margin-bottom">15</property>
- <signal name="notify::active" handler="on_mandatory_input_changed"/>
- </object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
+ <property name="title" translatable="yes" comments="Translators: 'Express Install' means
that the new box installation will be fully automated, the user won't be asked anything while it's
performed.">Express Install</property>
- <!-- 2nd row (while user avatar spans over 2 rows) -->
- <child>
- <object class="GtkImage" id="user_avatar">
- <property name="visible">True</property>
- <property name="icon-name">avatar-default</property>
- <property name="icon-size">0</property>
- <property name="pixel-size">64</property>
- <property name="margin-end">15</property>
- <property name="valign">center</property>
- <property name="halign">center</property>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">1</property>
- <property name="width">1</property>
- <property name="height">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="username_label">
- <property name="label" translatable="yes">Username</property>
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="valign">baseline</property>
- <property name="margin-end">10</property>
- <property name="margin-bottom">10</property>
- </object>
- <packing>
- <property name="left-attach">1</property>
- <property name="top-attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="username_entry">
- <property name="visible">True</property>
- <property name="visibility">True</property>
- <property name="halign">fill</property>
- <property name="valign">baseline</property>
- <property name="margin-bottom">10</property>
- <signal name="activate" handler="on_username_entry_activated"/>
- <signal name="notify::text" handler="on_mandatory_input_changed"/>
+ <child>
+ <object class="GtkSwitch" id="express_toggle">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <signal name="notify::active" handler="on_mandatory_input_changed"/>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
- <!-- 3rd row -->
- <child>
- <object class="GtkLabel" id="password_label">
- <property name="label" translatable="yes">Password</property>
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="valign">baseline</property>
- <property name="margin-end">10</property>
- </object>
- <packing>
- <property name="left-attach">1</property>
- <property name="top-attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
<child>
- <object class="GtkNotebook" id="password_notebook">
+ <object class="HdyActionRow" id="username_row">
<property name="visible">True</property>
- <property name="show-tabs">False</property>
- <property name="show-border">False</property>
- <property name="halign">fill</property>
- <property name="valign">center</property>
+ <property name="title" translatable="yes">Username</property>
+
<child>
- <object class="GtkButton" id="password_button">
- <property name="label" translatable="yes">_Add Password</property>
+ <object class="GtkEntry" id="username_entry">
<property name="visible">True</property>
- <property name="use-underline">True</property>
- <property name="valign">baseline</property>
- <signal name="clicked" handler="on_password_button_clicked"/>
+ <property name="valign">center</property>
+ <signal name="activate" handler="on_username_entry_activated"/>
+ <signal name="notify::text" handler="on_mandatory_input_changed"/>
</object>
</child>
+ </object>
+ </child>
+
+ <child>
+ <object class="HdyActionRow" id="password_row">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Password</property>
+
<child>
<object class="GtkEntry" id="password_entry">
<property name="text"></property>
<property name="visible">True</property>
+ <property name="valign">center</property>
<property name="visibility">False</property>
<property name="secondary-icon-activatable">True</property>
<property name="secondary-icon-name">eye-not-looking-symbolic</property>
<signal name="icon-release" handler="on_secondary_icon_clicked"/>
<signal name="changed" handler="on_password_entry_changed"/>
- <signal name="focus-out-event" handler="on_password_entry_focus_out"/>
<signal name="activate" handler="on_password_entry_activated"/>
<signal name="notify::text" handler="on_mandatory_input_changed"/>
</object>
</child>
</object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
- <!-- 4th row -->
- <child>
- <object class="GtkLabel" id="product_key_label">
- <property name="visible">False</property>
- <property name="label" translatable="yes">Product Key</property>
- <property name="margin-top">15</property>
- <property name="margin-end">10</property>
- <property name="halign">end</property>
- <property name="valign">center</property>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">3</property>
- <property name="width">2</property>
- <property name="height">1</property>
- </packing>
- </child>
<child>
- <object class="GtkEntry" id="product_key_entry">
+ <object class="HdyActionRow" id="product_key_row">
<property name="visible">False</property>
- <property name="visibility">True</property>
- <property name="halign">fill</property>
- <property name="valign">center</property>
- <property name="margin-top">15</property>
- <style>
- <class name="boxes-product-key-entry"/>
- </style>
- <signal name="activate" handler="on_key_entry_activated"/>
- <signal name="insert-text" handler="on_key_text_inserted"/>
- <signal name="notify::text" handler="on_mandatory_input_changed"/>
+ <property name="title" translatable="yes">Product Key</property>
+
+ <child>
+ <object class="GtkEntry" id="product_key_entry">
+ <property name="visible">True</property>
+ <property name="visibility">True</property>
+ <property name="valign">center</property>
+ <signal name="activate" handler="on_key_entry_activated"/>
+ <signal name="insert-text" handler="on_key_text_inserted"/>
+ <signal name="notify::text" handler="on_mandatory_input_changed"/>
+ <style>
+ <class name="boxes-product-key-entry"/>
+ </style>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left-attach">2</property>
- <property name="top-attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="padding">0</property>
- </packing>
</child>
</template>
</interface>
diff --git a/src/assistant/review-page.vala b/src/assistant/review-page.vala
index f449a53d..acb56a36 100644
--- a/src/assistant/review-page.vala
+++ b/src/assistant/review-page.vala
@@ -57,18 +57,18 @@ public async void populate (LibvirtMachine machine) {
ram_row.setup (machine);
storage_row.setup (machine);
- var install_media = machine.vm_creator.install_media;
bool show_unattended_rows = false;
+ var install_media = machine.vm_creator.install_media;
if (install_media is Boxes.UnattendedInstaller) {
var installer = install_media as Boxes.UnattendedInstaller;
show_unattended_rows = installer.setup_box.express_toggle.active;
- if (!show_unattended_rows)
- return;
-
- username_label.label = installer.setup_box.username;
- password_label.label = installer.setup_box.hidden_password;
+ if (show_unattended_rows) {
+ username_label.label = installer.setup_box.username;
+ password_label.label = installer.setup_box.hidden_password;
+ }
}
+
unattended_username_row.visible = unattended_password_row.visible = show_unattended_rows;
if (App.app.supports_uefi_installs ()) {
uefi_row.visible = install_media.supports_efi && !install_media.requires_efi;
diff --git a/src/unattended-file.vala b/src/unattended-file.vala
index 43c9a704..630370ae 100644
--- a/src/unattended-file.vala
+++ b/src/unattended-file.vala
@@ -156,78 +156,3 @@ protected async File get_source_file (Cancellable? cancellable) throws GLib.Err
return unattended_tmp;
}
}
-
-private class Boxes.UnattendedAvatarFile : GLib.Object, Boxes.UnattendedFile {
- public string dest_name { get; set; }
- public string src_path { get; set; }
-
- protected UnattendedInstaller installer { get; set; }
-
- private File unattended_tmp;
-
- private AvatarFormat? avatar_format;
- private Gdk.PixbufFormat pixbuf_format;
-
- public UnattendedAvatarFile (UnattendedInstaller installer, string src_path, AvatarFormat? avatar_format)
- throws Boxes.Error {
- this.installer = installer;
- this.src_path = src_path;
-
- this.avatar_format = avatar_format;
-
- foreach (var format in Gdk.Pixbuf.get_formats ()) {
- if (avatar_format != null) {
- foreach (var mime_type in avatar_format.mime_types) {
- if (mime_type in format.get_mime_types ()) {
- pixbuf_format = format;
-
- break;
- }
- }
- } else if (format.get_name () == "png")
- pixbuf_format = format; // Fallback to PNG if supported
-
- if (pixbuf_format != null)
- break;
- }
-
- if (pixbuf_format == null)
- throw new Boxes.Error.INVALID ("Failed to find suitable format to save user avatar file in.");
-
- dest_name = installer.setup_box.username + "." + pixbuf_format.get_extensions ()[0];
- }
-
- ~UnattendedAvatarFile () {
- if (unattended_tmp == null)
- return;
-
- try {
- delete_file (unattended_tmp);
- } catch (GLib.Error e) {
- warning ("Error deleting %s: %s", unattended_tmp.get_path (), e.message);
- }
- }
-
- protected async File get_source_file (Cancellable? cancellable) throws GLib.Error {
- var destination_path = installer.get_user_unattended (dest_name);
-
- try {
- var width = (avatar_format != null)? avatar_format.width : -1;
- var height = (avatar_format != null)? avatar_format.height : -1;
- var pixbuf = new Gdk.Pixbuf.from_file_at_scale (src_path, width, height, true);
-
- if (avatar_format != null && !avatar_format.alpha && pixbuf.get_has_alpha ())
- pixbuf = remove_alpha (pixbuf);
-
- debug ("Saving user avatar file at '%s'..", destination_path);
- pixbuf.save (destination_path, pixbuf_format.get_name ());
- debug ("Saved user avatar file at '%s'.", destination_path);
- } catch (GLib.Error error) {
- warning ("Failed to save user avatar: %s.", error.message);
- }
-
- unattended_tmp = File.new_for_path (destination_path);
-
- return unattended_tmp;
- }
-}
diff --git a/src/unattended-installer.vala b/src/unattended-installer.vala
index c176a50b..cac5f1c4 100644
--- a/src/unattended-installer.vala
+++ b/src/unattended-installer.vala
@@ -78,7 +78,6 @@
private GLib.List<UnattendedFile> unattended_files;
private GLib.List<UnattendedFile> secondary_unattended_files;
- private UnattendedAvatarFile avatar_file;
private string? timezone;
private string lang;
@@ -145,8 +144,6 @@ private static string escape_genisoimage_path (string path) {
setup_box.user_wants_to_create.connect (() => {
user_wants_to_create ();
});
-
- fetch_user_avatar.begin ();
}
public override void prepare_to_continue_installation (string vm_name) {
@@ -246,11 +243,6 @@ public void configure_install_script (InstallScript script) {
// case and is not that costly in the end.
script.set_preferred_injection_method (injection_method);
- if (avatar_file != null) {
- var location = ((script.path_format == PathFormat.UNIX)? "/" : "\\") + avatar_file.dest_name;
- config.set_avatar_location (location);
- }
-
config.set_driver_signing (driver_signing);
}
@@ -402,37 +394,6 @@ private async void create_iso (Cancellable? cancellable) throws GLib.Error {
yield exec (argv, cancellable);
}
- private async void fetch_user_avatar () {
- var username = Environment.get_user_name ();
- string avatar_path = "/var/lib/AccountsService/icons/" + username;
-
- try {
- avatar_path = yield get_user_avatar_from_accountsservice (username);
- } catch (GLib.Error error) {
- warning ("Failed to retrieve information about user '%s': %s", username, error.message);
- }
-
- if (!FileUtils.test (avatar_path, FileTest.EXISTS))
- return;
-
- setup_box.avatar_path = avatar_path;
-
- try {
- AvatarFormat avatar_format = null;
- foreach (var s in scripts.get_elements ()) {
- var script = s as InstallScript;
- avatar_format = script.avatar_format;
- if (avatar_format != null)
- break;
- }
-
- avatar_file = new UnattendedAvatarFile (this, avatar_path, avatar_format);
- add_unattended_file (avatar_file);
- } catch (GLib.Error error) {
- debug ("Failed to load user avatar file '%s': %s", avatar_path, error.message);
- }
- }
-
private async void extract_boot_files (ISOExtractor extractor, Cancellable? cancellable) throws
GLib.Error {
yield extractor.extract (os_media.kernel_path, kernel_file.get_path (), cancellable);
yield extractor.extract (os_media.initrd_path, initrd_file.get_path (), cancellable);
diff --git a/src/unattended-setup-box.vala b/src/unattended-setup-box.vala
index b5f2479c..8fb99296 100644
--- a/src/unattended-setup-box.vala
+++ b/src/unattended-setup-box.vala
@@ -60,17 +60,6 @@
}
}
- public string avatar_path {
- set {
- try {
- var pixbuf = new Gdk.Pixbuf.from_file_at_scale (value, 64, 64, true);
- user_avatar.pixbuf = round_image (pixbuf);
- } catch (GLib.Error error) {
- debug ("Failed to load user avatar file '%s': %s", value, error.message);
- }
- }
- }
-
public signal void user_wants_to_create (); // User wants to already create the VM
private bool _needs_password;
@@ -92,21 +81,17 @@
[GtkChild]
private unowned Gtk.Label needs_internet_label;
[GtkChild]
- private unowned Gtk.Grid setup_grid;
- [GtkChild]
- private unowned Gtk.Label express_label;
- [GtkChild]
public unowned Gtk.Switch express_toggle;
[GtkChild]
- private unowned Gtk.Image user_avatar;
+ private unowned Hdy.ActionRow username_row;
[GtkChild]
private unowned Gtk.Entry username_entry;
[GtkChild]
- private unowned Gtk.Notebook password_notebook;
+ private unowned Hdy.ActionRow password_row;
[GtkChild]
private unowned Gtk.Entry password_entry;
[GtkChild]
- private unowned Gtk.Label product_key_label;
+ private unowned Hdy.ActionRow product_key_row;
[GtkChild]
private unowned Gtk.Entry product_key_entry;
@@ -140,9 +125,7 @@ public UnattendedSetupBox (InstallerMedia media, string? product_key_format, boo
set_entry_text_from_key (password_entry, PASSWORD_KEY);
set_entry_text_from_key (product_key_entry, PRODUCTKEY_KEY);
- if (password != "") {
- password_notebook.next_page ();
- } else {
+ if (password == "") {
Secret.password_lookup.begin (secret_password_schema, cancellable, (obj, res) => {
try {
var credentials_str = Secret.password_lookup.end (res);
@@ -157,7 +140,6 @@ public UnattendedSetupBox (InstallerMedia media, string? product_key_format, boo
if (password_str != null && password_str != "") {
password_entry.text = password_str;
- password_notebook.next_page ();
}
} catch (GLib.Error error) {
warning ("Failed to parse password from the keyring: %s", error.message);
@@ -183,16 +165,11 @@ public UnattendedSetupBox (InstallerMedia media, string? product_key_format, boo
setup_express_toggle (media.os_media.live, needs_internet);
if (product_key_format != null) {
- product_key_label.visible = true;
+ product_key_row.visible = true;
- product_key_entry.visible = true;
product_key_entry.width_chars = product_key_format.length;
product_key_entry.max_length = product_key_format.length;
}
-
- foreach (var child in setup_grid.get_children ())
- if (child != express_label && child != express_toggle)
- express_toggle.bind_property ("active", child, "sensitive", BindingFlags.SYNC_CREATE);
}
public override void dispose () {
@@ -286,6 +263,10 @@ else if (default_value != null)
[GtkCallback]
private void on_mandatory_input_changed () {
notify_property ("ready-to-create");
+
+ username_row.sensitive = express_toggle.active;
+ password_row.sensitive = express_toggle.active;
+ product_key_row.sensitive = express_toggle.active;
}
[GtkCallback]
@@ -296,25 +277,12 @@ else if (username != "" && product_key_format != null)
product_key_entry.grab_focus (); // If username is provided, must be product key thats still not
provided
}
- [GtkCallback]
- private void on_password_button_clicked () {
- password_notebook.next_page ();
- password_entry.grab_focus ();
- }
-
[GtkCallback]
private void on_password_entry_changed () {
cancellable.cancel ();
cancellable = new Cancellable ();
}
- [GtkCallback]
- private bool on_password_entry_focus_out () {
- if (password_entry.text_length == 0)
- password_notebook.prev_page ();
- return false;
- }
-
[GtkCallback]
private void on_password_entry_activated () {
if (ready_for_express)
diff --git a/src/util-app.vala b/src/util-app.vala
index 4d6ac519..690354b5 100644
--- a/src/util-app.vala
+++ b/src/util-app.vala
@@ -462,46 +462,6 @@ public async bool check_storage_pool (out string diagnosis) {
return true;
}
-
- // FIXME: Better ways to remove alpha more than welcome
- private Gdk.Pixbuf remove_alpha (Gdk.Pixbuf pixbuf) {
- const uint8 ALPHA_TRESHOLD = 50;
-
- return_val_if_fail (pixbuf.get_n_channels () == 4 && pixbuf.get_bits_per_sample () == 8, pixbuf);
-
- var width = pixbuf.get_width ();
- var height = pixbuf.get_height ();
- var rowstride = pixbuf.get_rowstride ();
- unowned uint8[] orig_pixels = pixbuf.get_pixels ();
- var pixels = new uint8[rowstride * height];
-
- for (var i = 0; i < height; i++) {
- for (var j = 0, k = 0; j < width * 4; j += 4, k += 3) {
- var orig_index = rowstride * i + j;
- var index = rowstride * i + k;
-
- if (orig_pixels[orig_index + 3] < ALPHA_TRESHOLD) {
- pixels[index] = 0xFF;
- pixels[index + 1] = 0xFF;
- pixels[index + 2] = 0xFF;
- } else {
- pixels[index] = orig_pixels[orig_index];
- pixels[index + 1] = orig_pixels[orig_index + 1];
- pixels[index + 2] = orig_pixels[orig_index + 2];
- }
- }
- }
-
- return new Gdk.Pixbuf.from_data (pixels,
- pixbuf.get_colorspace (),
- false,
- 8,
- width,
- height,
- rowstride,
- null);
- }
-
public void draw_as_css_box (Widget widget) {
widget.draw.connect ((cr) => {
var context = widget.get_style_context ();
diff --git a/src/util.vala b/src/util.vala
index 49016ac8..00ff156c 100644
--- a/src/util.vala
+++ b/src/util.vala
@@ -433,57 +433,4 @@ public static string canonicalize_for_search (string str) {
}
return res.str;
}
-
- [DBus (name = "org.freedesktop.Accounts")]
- public interface Fdo.Accounts : Object {
- public abstract async string FindUserByName(string name) throws GLib.Error;
- }
-
- private async Fdo.Accounts? get_accountsservice_accounts_manager () throws GLib.Error {
- Fdo.Accounts? accounts = yield Bus.get_proxy (BusType.SYSTEM,
- "org.freedesktop.Accounts",
- "/org/freedesktop/Accounts");
-
- if (accounts == null)
- throw new Boxes.Error.INVALID ("Failed to connect to AccountsService D-Bus service");
-
- return accounts;
- }
-
- [DBus (name = "org.freedesktop.Accounts.User")]
- public interface Fdo.AccountsUser : Object {
- public abstract bool AutomaticLogin { get; }
- public abstract bool Locked { get; }
- public abstract bool SystemAccount { get; }
- public abstract int32 AccountType { get; }
- public abstract int32 PasswordMode { get; }
- public abstract string Email { owned get; }
- public abstract string HomeDirectory { owned get; }
- public abstract string IconFile { owned get; }
- public abstract string Language { owned get; }
- public abstract string Location { owned get; }
- public abstract string RealName { owned get; }
- public abstract string Shell { owned get; }
- public abstract string UserName { owned get; }
- public abstract string XSession { owned get; }
- }
-
- private async Fdo.AccountsUser? get_accountsservice_accounts_user (string object_path) throws GLib.Error
{
- Fdo.AccountsUser? user = yield Bus.get_proxy (BusType.SYSTEM,
- "org.freedesktop.Accounts",
- object_path);
-
- if (user == null)
- throw new Boxes.Error.INVALID ("Failed to retrieve information about user");
-
- return user;
- }
-
- public async string? get_user_avatar_from_accountsservice (string username) throws GLib.Error {
- Fdo.Accounts accounts = yield get_accountsservice_accounts_manager ();
- var path = yield accounts.FindUserByName (username);
- Fdo.AccountsUser user = yield get_accountsservice_accounts_user (path);
-
- return user.IconFile;
- }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]