[gnome-control-center/wip/feborges/new-users-panel-gtk4: 8/8] user-accounts: Port to gtk4/libadwaita implementing the new design
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/feborges/new-users-panel-gtk4: 8/8] user-accounts: Port to gtk4/libadwaita implementing the new design
- Date: Tue, 8 Feb 2022 13:29:57 +0000 (UTC)
commit 7f8e90a96689d8358c3a8e9f6c2757257a344926
Author: Felipe Borges <felipeborges gnome org>
Date: Wed Jan 26 10:13:58 2022 +0100
user-accounts: Port to gtk4/libadwaita implementing the new design
https://gitlab.gnome.org/Teams/Design/settings-mockups/-/raw/master/users/users.png
panels/meson.build | 2 +-
panels/user-accounts/cc-add-user-dialog.c | 247 ++---
panels/user-accounts/cc-add-user-dialog.ui | 944 +++++-----------
panels/user-accounts/cc-avatar-chooser.c | 305 +-----
panels/user-accounts/cc-avatar-chooser.h | 2 +-
panels/user-accounts/cc-avatar-chooser.ui | 23 +-
panels/user-accounts/cc-carousel.c | 434 --------
panels/user-accounts/cc-carousel.h | 50 -
panels/user-accounts/cc-carousel.ui | 118 --
panels/user-accounts/cc-crop-area.c | 1257 ++++++++++------------
panels/user-accounts/cc-crop-area.h | 24 +-
panels/user-accounts/cc-fingerprint-dialog.c | 130 ++-
panels/user-accounts/cc-fingerprint-dialog.ui | 114 +-
panels/user-accounts/cc-login-history-dialog.c | 40 +-
panels/user-accounts/cc-login-history-dialog.ui | 39 +-
panels/user-accounts/cc-password-dialog.c | 162 ++-
panels/user-accounts/cc-password-dialog.h | 3 +-
panels/user-accounts/cc-password-dialog.ui | 393 +++----
panels/user-accounts/cc-user-image.c | 132 ---
panels/user-accounts/cc-user-image.h | 32 -
panels/user-accounts/cc-user-panel.c | 521 ++++-----
panels/user-accounts/cc-user-panel.ui | 774 ++++++-------
panels/user-accounts/data/carousel.css | 7 -
panels/user-accounts/data/join-dialog.ui | 78 +-
panels/user-accounts/meson.build | 4 -
panels/user-accounts/user-accounts.gresource.xml | 2 -
panels/user-accounts/user-utils.c | 296 +----
panels/user-accounts/user-utils.h | 7 -
shell/cc-panel-loader.c | 4 +-
29 files changed, 1868 insertions(+), 4276 deletions(-)
---
diff --git a/panels/meson.build b/panels/meson.build
index 4498f198a..75941edcb 100644
--- a/panels/meson.build
+++ b/panels/meson.build
@@ -27,7 +27,7 @@ panels = [
'sound',
'universal-access',
'usage',
-# 'user-accounts',
+ 'user-accounts',
'wwan',
]
diff --git a/panels/user-accounts/cc-add-user-dialog.c b/panels/user-accounts/cc-add-user-dialog.c
index 3d1daa481..35601a6ab 100644
--- a/panels/user-accounts/cc-add-user-dialog.c
+++ b/panels/user-accounts/cc-add-user-dialog.c
@@ -20,6 +20,7 @@
#include "config.h"
+#include <adwaita.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -55,32 +56,42 @@ static void on_realm_joined (GObject *source,
static void add_button_clicked_cb (CcAddUserDialog *self);
struct _CcAddUserDialog {
- GtkDialog parent_instance;
+ GtkDialog parent_instance;
GtkButton *add_button;
- GtkToggleButton *enterprise_button;
+ AdwActionRow *enterprise_button;
GtkComboBox *enterprise_domain_combo;
GtkEntry *enterprise_domain_entry;
- GtkLabel *enterprise_domain_hint_label;
- GtkGrid *enterprise_grid;
- GtkLabel *enterprise_hint_label;
+ GtkLabel *enterprise_domain_hint;
+ AdwActionRow *enterprise_domain_row;
+ GtkImage *enterprise_domain_status_icon;
+ AdwPreferencesPage *enterprise_page;
+ AdwPreferencesGroup *enterprise_login_group;
GtkEntry *enterprise_login_entry;
- GtkEntry *enterprise_password_entry;
+ GtkImage *enterprise_login_status_icon;
+ GtkPasswordEntry *enterprise_password_entry;
+ GtkImage *enterprise_password_status_icon;
GtkListStore *enterprise_realm_model;
- GtkRadioButton *local_account_type_standard;
- GtkGrid *local_grid;
- GtkLabel *local_hint_label;
+ GtkSwitch *local_account_type_switch;
GtkEntry *local_name_entry;
+ GtkImage *local_name_status_icon;
+ AdwPreferencesPage *local_page;
+ AdwActionRow *local_password_row;
+ GtkImage *local_password_status_icon;
+ GtkLevelBar *local_strength_indicator;
GtkComboBoxText *local_username_combo;
GtkListStore *local_username_model;
- GtkEntry *local_password_entry;
- GtkRadioButton *local_password_radio;
+ GtkPasswordEntry *local_password_entry;
+ GtkLabel *local_password_hint;
+ GtkCheckButton *local_password_radio;
GtkEntry *local_username_entry;
- GtkLabel *local_username_hint_label;
- GtkLevelBar *local_strength_indicator;
- GtkEntry *local_verify_entry;
- GtkLabel *local_verify_hint_label;
- GtkGrid *offline_grid;
+ AdwActionRow *local_username_row;
+ GtkImage *local_username_status_icon;
+ GtkPasswordEntry *local_verify_entry;
+ AdwActionRow *local_verify_password_row;
+ GtkImage *local_verify_status_icon;
+ AdwPreferencesPage *offline_page;
+ AdwPreferencesGroup *password_group;
GtkSpinner *spinner;
GtkStack *stack;
@@ -132,7 +143,7 @@ show_error_dialog (CcAddUserDialog *self,
"%s", error->message);
}
- g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
gtk_window_present (GTK_WINDOW (dialog));
}
@@ -176,7 +187,7 @@ user_loaded_cb (CcAddUserDialog *self,
finish_action (self);
/* Set a password for the user */
- password = gtk_entry_get_text (self->local_password_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->local_password_entry));
act_user_set_password_mode (user, self->local_password_mode);
if (self->local_password_mode == ACT_USER_PASSWORD_MODE_REGULAR)
act_user_set_password (user, password, "");
@@ -224,9 +235,9 @@ local_create_user (CcAddUserDialog *self)
begin_action (self);
- name = gtk_entry_get_text (self->local_name_entry);
+ name = gtk_editable_get_text (GTK_EDITABLE (self->local_name_entry));
username = gtk_combo_box_text_get_active_text (self->local_username_combo);
- account_type = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->local_account_type_standard))
? ACT_USER_ACCOUNT_TYPE_STANDARD : ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR);
+ account_type = gtk_switch_get_active (self->local_account_type_switch) ?
ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR : ACT_USER_ACCOUNT_TYPE_STANDARD;
g_debug ("Creating local user: %s", username);
@@ -249,23 +260,23 @@ update_password_strength (CcAddUserDialog *self)
const gchar *verify;
gint strength_level;
- password = gtk_entry_get_text (self->local_password_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->local_password_entry));
username = gtk_combo_box_text_get_active_text (self->local_username_combo);
pw_strength (password, NULL, username, &hint, &strength_level);
- gtk_label_set_label (self->local_hint_label, hint);
gtk_level_bar_set_value (self->local_strength_indicator, strength_level);
+ gtk_label_set_label (self->local_password_hint, hint);
if (strength_level > 1) {
- set_entry_validation_checkmark (self->local_password_entry);
+ gtk_image_set_from_icon_name (self->local_password_status_icon, "emblem-ok-symbolic");
} else if (strlen (password) == 0) {
- set_entry_generation_icon (self->local_password_entry);
+ gtk_image_set_from_icon_name (self->local_password_status_icon, "dialog-warning-symbolic");
} else {
- clear_entry_validation_error (self->local_password_entry);
+ gtk_image_set_from_icon_name (self->local_password_status_icon, "dialog-warning-symbolic");
}
- verify = gtk_entry_get_text (self->local_verify_entry);
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->local_verify_entry));
if (strlen (verify) == 0) {
gtk_widget_set_sensitive (GTK_WIDGET (self->local_verify_entry), strength_level > 1);
}
@@ -284,17 +295,17 @@ local_validate (CcAddUserDialog *self)
gint strength;
if (self->local_valid_username) {
- set_entry_validation_checkmark (self->local_username_entry);
+ gtk_image_set_from_icon_name (self->local_username_status_icon, "emblem-ok-symbolic");
}
- name = gtk_entry_get_text (self->local_name_entry);
+ name = gtk_editable_get_text (GTK_EDITABLE (self->local_name_entry));
valid_name = is_valid_name (name);
if (valid_name) {
- set_entry_validation_checkmark (self->local_name_entry);
+ gtk_image_set_from_icon_name (self->local_name_status_icon, "emblem-ok-symbolic");
}
- password = gtk_entry_get_text (self->local_password_entry);
- verify = gtk_entry_get_text (self->local_verify_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->local_password_entry));
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->local_verify_entry));
if (self->local_password_mode == ACT_USER_PASSWORD_MODE_REGULAR) {
strength = update_password_strength (self);
valid_password = strength > 1 && strcmp (password, verify) == 0;
@@ -325,7 +336,7 @@ static void local_username_is_valid_cb (GObject *source_object,
name = gtk_combo_box_text_get_active_text (self->local_username_combo);
if (g_strcmp0 (name, username) == 0) {
self->local_valid_username = valid;
- gtk_label_set_label (self->local_username_hint_label, tip);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (self->local_username_row), tip);
dialog_validate (self);
}
}
@@ -361,7 +372,7 @@ local_username_combo_changed_cb (CcAddUserDialog *self)
{
const gchar *username;
- username = gtk_entry_get_text (self->local_username_entry);
+ username = gtk_editable_get_text (GTK_EDITABLE (self->local_username_entry));
if (*username == '\0')
self->has_custom_username = FALSE;
else if (gtk_widget_has_focus (GTK_WIDGET (self->local_username_entry)) ||
@@ -373,7 +384,7 @@ local_username_combo_changed_cb (CcAddUserDialog *self)
self->local_username_timeout_id = 0;
}
- clear_entry_validation_error (self->local_username_entry);
+ gtk_image_set_from_icon_name (self->local_username_status_icon, "dialog-warning-symbolic");
gtk_widget_set_sensitive (GTK_WIDGET (self->add_button), FALSE);
self->local_valid_username = FALSE;
@@ -627,9 +638,9 @@ local_name_entry_changed_cb (CcAddUserDialog *self)
gtk_list_store_clear (self->local_username_model);
- name = gtk_entry_get_text (self->local_name_entry);
+ name = gtk_editable_get_text (GTK_EDITABLE (self->local_name_entry));
if ((name == NULL || strlen (name) == 0) && !self->has_custom_username) {
- gtk_entry_set_text (self->local_username_entry, "");
+ gtk_editable_set_text (GTK_EDITABLE (self->local_username_entry), "");
} else if (name != NULL && strlen (name) != 0) {
generate_username_choices (name, self->local_username_model);
if (!self->has_custom_username)
@@ -641,7 +652,7 @@ local_name_entry_changed_cb (CcAddUserDialog *self)
self->local_name_timeout_id = 0;
}
- clear_entry_validation_error (self->local_name_entry);
+ gtk_image_set_from_icon_name (self->local_name_status_icon, "dialog-warning-symbolic");
gtk_widget_set_sensitive (GTK_WIDGET (self->add_button), FALSE);
self->local_name_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT, (GSourceFunc)
local_name_timeout, self);
@@ -654,20 +665,20 @@ update_password_match (CcAddUserDialog *self)
const gchar *verify;
const gchar *message = "";
- password = gtk_entry_get_text (self->local_password_entry);
- verify = gtk_entry_get_text (self->local_verify_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->local_password_entry));
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->local_verify_entry));
if (strlen (verify) != 0) {
if (strcmp (password, verify) != 0) {
message = _("The passwords do not match.");
} else {
- set_entry_validation_checkmark (self->local_verify_entry);
+ gtk_image_set_from_icon_name (self->local_verify_status_icon, "emblem-ok-symbolic");
}
}
- gtk_label_set_label (self->local_verify_hint_label, message);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (self->local_verify_password_row), message);
}
static void
-local_password_entry_icon_press_cb (CcAddUserDialog *self)
+generate_password (CcAddUserDialog *self)
{
g_autofree gchar *pwd = NULL;
@@ -675,9 +686,8 @@ local_password_entry_icon_press_cb (CcAddUserDialog *self)
if (pwd == NULL)
return;
- gtk_entry_set_text (self->local_password_entry, pwd);
- gtk_entry_set_text (self->local_verify_entry, pwd);
- gtk_entry_set_visibility (self->local_password_entry, TRUE);
+ gtk_editable_set_text (GTK_EDITABLE (self->local_password_entry), pwd);
+ gtk_editable_set_text (GTK_EDITABLE (self->local_verify_entry), pwd);
gtk_widget_set_sensitive (GTK_WIDGET (self->local_verify_entry), TRUE);
}
@@ -706,12 +716,13 @@ password_focus_out_event_cb (CcAddUserDialog *self)
}
static gboolean
-local_password_entry_key_press_event_cb (CcAddUserDialog *self,
- GdkEvent *event)
+local_password_entry_key_press_event_cb (GtkEventControllerKey *controller,
+ guint keyval,
+ guint keycode,
+ GdkModifierType state,
+ CcAddUserDialog *self)
{
- GdkEventKey *key = (GdkEventKey *)event;
-
- if (key->keyval == GDK_KEY_Tab)
+ if (keyval == GDK_KEY_Tab)
local_password_timeout (self);
return FALSE;
@@ -720,8 +731,6 @@ local_password_entry_key_press_event_cb (CcAddUserDialog *self,
static void
recheck_password_match (CcAddUserDialog *self)
{
- const char *password;
-
if (self->local_password_timeout_id != 0) {
g_source_remove (self->local_password_timeout_id);
self->local_password_timeout_id = 0;
@@ -729,26 +738,21 @@ recheck_password_match (CcAddUserDialog *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->add_button), FALSE);
- password = gtk_entry_get_text (self->local_password_entry);
- if (strlen (password) == 0) {
- gtk_entry_set_visibility (self->local_password_entry, FALSE);
- }
-
self->local_password_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT, (GSourceFunc)
local_password_timeout, self);
}
static void
local_password_entry_changed_cb (CcAddUserDialog *self)
{
- clear_entry_validation_error (self->local_password_entry);
- clear_entry_validation_error (self->local_verify_entry);
+ gtk_image_set_from_icon_name (self->local_password_status_icon, "dialog-warning-symbolic");
+ gtk_image_set_from_icon_name (self->local_verify_status_icon, "dialog-warning-symbolic");
recheck_password_match (self);
}
static void
local_verify_entry_changed_cb (CcAddUserDialog *self)
{
- clear_entry_validation_error (self->local_verify_entry);
+ gtk_image_set_from_icon_name (self->local_verify_status_icon, "dialog-warning-symbolic");
recheck_password_match (self);
}
@@ -757,13 +761,10 @@ local_password_radio_changed_cb (CcAddUserDialog *self)
{
gboolean active;
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->local_password_radio));
+ active = gtk_check_button_get_active (GTK_CHECK_BUTTON (self->local_password_radio));
self->local_password_mode = active ? ACT_USER_PASSWORD_MODE_REGULAR :
ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
- gtk_widget_set_sensitive (GTK_WIDGET (self->local_password_entry), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->local_verify_entry), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->local_strength_indicator), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->local_hint_label), active);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->password_group), active);
dialog_validate (self);
}
@@ -776,14 +777,14 @@ enterprise_validate (CcAddUserDialog *self)
gboolean valid_domain;
GtkTreeIter iter;
- name = gtk_entry_get_text (self->enterprise_login_entry);
+ name = gtk_editable_get_text (GTK_EDITABLE (self->enterprise_login_entry));
valid_name = is_valid_name (name);
if (gtk_combo_box_get_active_iter (self->enterprise_domain_combo, &iter)) {
gtk_tree_model_get (GTK_TREE_MODEL (self->enterprise_realm_model),
&iter, 0, &name, -1);
} else {
- name = gtk_entry_get_text (self->enterprise_domain_entry);
+ name = gtk_editable_get_text (GTK_EDITABLE (self->enterprise_domain_entry));
}
valid_domain = is_valid_name (name) && self->selected_realm != NULL;
@@ -835,7 +836,7 @@ enterprise_add_realm (CcAddUserDialog *self,
/* Prefill domain entry by the existing one */
if (!self->enterprise_domain_chosen && cc_realm_is_configured (realm)) {
- gtk_entry_set_text (self->enterprise_domain_entry, realm_name);
+ gtk_editable_set_text (GTK_EDITABLE (self->enterprise_domain_entry), realm_name);
}
g_debug ("added realm to drop down: %s %s", realm_name,
@@ -902,7 +903,7 @@ on_permit_user_login (GObject *source,
* sure all that is functional.
*/
manager = act_user_manager_get_default ();
- login = cc_realm_calculate_login (common, gtk_entry_get_text (self->enterprise_login_entry));
+ login = cc_realm_calculate_login (common, gtk_editable_get_text (GTK_EDITABLE
(self->enterprise_login_entry)));
g_return_if_fail (login != NULL);
g_debug ("Caching remote user: %s", login);
@@ -934,7 +935,7 @@ enterprise_permit_user_login (CcAddUserDialog *self)
return;
}
- login = cc_realm_calculate_login (common, gtk_entry_get_text (self->enterprise_login_entry));
+ login = cc_realm_calculate_login (common, gtk_editable_get_text (GTK_EDITABLE
(self->enterprise_login_entry)));
g_return_if_fail (login != NULL);
add[0] = login;
@@ -962,12 +963,12 @@ on_join_response (CcAddUserDialog *self,
return;
}
- g_debug ("Logging in as admin user: %s", gtk_entry_get_text (self->join_name));
+ g_debug ("Logging in as admin user: %s", gtk_editable_get_text (GTK_EDITABLE (self->join_name)));
/* Prompted for some admin credentials, try to use them to log in */
cc_realm_login (self->selected_realm,
- gtk_entry_get_text (self->join_name),
- gtk_entry_get_text (self->join_password),
+ gtk_editable_get_text (GTK_EDITABLE (self->join_name)),
+ gtk_editable_get_text (GTK_EDITABLE (self->join_password)),
self->cancellable,
on_join_login,
g_object_ref (self));
@@ -981,7 +982,7 @@ join_show_prompt (CcAddUserDialog *self,
g_autoptr(CcRealmKerberos) kerberos = NULL;
const gchar *name;
- gtk_entry_set_text (self->join_password, "");
+ gtk_editable_set_text (GTK_EDITABLE (self->join_password), "");
gtk_widget_grab_focus (GTK_WIDGET (self->join_password));
kerberos = cc_realm_object_get_kerberos (self->selected_realm);
@@ -990,26 +991,26 @@ join_show_prompt (CcAddUserDialog *self,
gtk_label_set_text (self->join_domain,
cc_realm_kerberos_get_domain_name (kerberos));
- clear_entry_validation_error (self->join_name);
- clear_entry_validation_error (self->join_password);
+ //clear_entry_validation_error (self->join_name);
+ //clear_entry_validation_error (self->join_password);
if (!self->join_prompted) {
name = cc_realm_kerberos_membership_get_suggested_administrator (membership);
if (name && !g_str_equal (name, "")) {
g_debug ("Suggesting admin user: %s", name);
- gtk_entry_set_text (self->join_name, name);
+ gtk_editable_set_text (GTK_EDITABLE (self->join_name), name);
} else {
gtk_widget_grab_focus (GTK_WIDGET (self->join_name));
}
} else if (g_error_matches (error, CC_REALM_ERROR, CC_REALM_ERROR_BAD_PASSWORD)) {
g_debug ("Bad admin password: %s", error->message);
- set_entry_validation_error (self->join_password, error->message);
+ //set_entry_validation_error (self->join_password, error->message);
} else {
g_debug ("Admin login failure: %s", error->message);
g_dbus_error_strip_remote_error (error);
- set_entry_validation_error (self->join_name, error->message);
+ //set_entry_validation_error (self->join_name, error->message);
}
g_debug ("Showing admin password dialog");
@@ -1040,8 +1041,8 @@ on_join_login (GObject *source,
/* Logged in as admin successfully, use creds to join domain */
if (creds != NULL) {
if (!cc_realm_join_as_admin (self->selected_realm,
- gtk_entry_get_text (self->join_name),
- gtk_entry_get_text (self->join_password),
+ gtk_editable_get_text (GTK_EDITABLE (self->join_name)),
+ gtk_editable_get_text (GTK_EDITABLE (self->join_password)),
creds, self->cancellable, on_realm_joined,
g_object_ref (self))) {
show_error_dialog (self, _("No supported way to authenticate with this domain"),
NULL);
@@ -1149,8 +1150,8 @@ on_realm_login (GObject *source,
/* Join the domain, try using the user's creds */
} else if (creds == NULL ||
!cc_realm_join_as_user (self->selected_realm,
- gtk_entry_get_text (self->enterprise_login_entry),
- gtk_entry_get_text (self->enterprise_password_entry),
+ gtk_editable_get_text (GTK_EDITABLE
(self->enterprise_login_entry)),
+ gtk_editable_get_text (GTK_EDITABLE
(self->enterprise_password_entry)),
creds, self->cancellable,
on_realm_joined,
g_object_ref (self))) {
@@ -1164,14 +1165,14 @@ on_realm_login (GObject *source,
} else if (g_error_matches (error, CC_REALM_ERROR, CC_REALM_ERROR_BAD_LOGIN)) {
g_debug ("Problem with the user's login: %s", error->message);
message = _("That login name didn’t work.\nPlease try again.");
- gtk_label_set_text (self->enterprise_hint_label, message);
+ adw_preferences_group_set_description (self->enterprise_login_group, message);
finish_action (self);
gtk_widget_grab_focus (GTK_WIDGET (self->enterprise_login_entry));
} else if (g_error_matches (error, CC_REALM_ERROR, CC_REALM_ERROR_BAD_PASSWORD)) {
g_debug ("Problem with the user's password: %s", error->message);
message = _("That login password didn’t work.\nPlease try again.");
- gtk_label_set_text (self->enterprise_hint_label, message);
+ adw_preferences_group_set_description (self->enterprise_login_group, message);
finish_action (self);
gtk_widget_grab_focus (GTK_WIDGET (self->enterprise_password_entry));
@@ -1190,8 +1191,8 @@ enterprise_check_login (CcAddUserDialog *self)
g_assert (self->selected_realm);
cc_realm_login (self->selected_realm,
- gtk_entry_get_text (self->enterprise_login_entry),
- gtk_entry_get_text (self->enterprise_password_entry),
+ gtk_editable_get_text (GTK_EDITABLE (self->enterprise_login_entry)),
+ gtk_editable_get_text (GTK_EDITABLE (self->enterprise_password_entry)),
self->cancellable,
on_realm_login,
g_object_ref (self));
@@ -1221,8 +1222,8 @@ on_realm_discover_input (GObject *source,
if (self->enterprise_check_credentials) {
enterprise_check_login (self);
}
- set_entry_validation_checkmark (self->enterprise_domain_entry);
- gtk_label_set_text (self->enterprise_domain_hint_label, DOMAIN_DEFAULT_HINT);
+ gtk_image_set_from_icon_name (self->enterprise_domain_status_icon, "emblem-ok-symbolic");
+ gtk_label_set_text (self->enterprise_domain_hint, DOMAIN_DEFAULT_HINT);
g_list_free_full (realms, g_object_unref);
/* The domain is likely invalid*/
@@ -1237,7 +1238,7 @@ on_realm_discover_input (GObject *source,
} else {
message = g_strdup_printf ("%s.", error->message);
}
- gtk_label_set_text (self->enterprise_domain_hint_label, message);
+ gtk_label_set_text (self->enterprise_domain_hint, message);
if (self->enterprise_check_credentials) {
finish_action (self);
@@ -1256,9 +1257,9 @@ enterprise_check_domain (CcAddUserDialog *self)
{
const gchar *domain;
- domain = gtk_entry_get_text (self->enterprise_domain_entry);
+ domain = gtk_editable_get_text (GTK_EDITABLE (self->enterprise_domain_entry));
if (strlen (domain) == 0) {
- gtk_label_set_text (self->enterprise_domain_hint_label, DOMAIN_DEFAULT_HINT);
+ gtk_label_set_text (self->enterprise_domain_hint, DOMAIN_DEFAULT_HINT);
return;
}
@@ -1375,8 +1376,8 @@ enterprise_domain_timeout (CcAddUserDialog *self)
if (gtk_combo_box_get_active_iter (self->enterprise_domain_combo, &iter)) {
gtk_tree_model_get (GTK_TREE_MODEL (self->enterprise_realm_model), &iter, 1,
&self->selected_realm, -1);
- set_entry_validation_checkmark (self->enterprise_domain_entry);
- gtk_label_set_text (self->enterprise_domain_hint_label, DOMAIN_DEFAULT_HINT);
+ gtk_image_set_from_icon_name (self->enterprise_domain_status_icon, "emblem-ok-symbolic");
+ gtk_label_set_text (self->enterprise_domain_hint, DOMAIN_DEFAULT_HINT);
}
else {
enterprise_check_domain (self);
@@ -1394,7 +1395,7 @@ enterprise_domain_combo_changed_cb (CcAddUserDialog *self)
}
g_clear_object (&self->selected_realm);
- clear_entry_validation_error (self->enterprise_domain_entry);
+ gtk_image_set_from_icon_name (self->enterprise_domain_status_icon, "dialog-warning-symbolic");
self->enterprise_domain_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT, (GSourceFunc)
enterprise_domain_timeout, self);
gtk_widget_set_sensitive (GTK_WIDGET (self->add_button), FALSE);
@@ -1421,15 +1422,15 @@ static void
enterprise_login_entry_changed_cb (CcAddUserDialog *self)
{
dialog_validate (self);
- clear_entry_validation_error (self->enterprise_login_entry);
- clear_entry_validation_error (self->enterprise_password_entry);
+ gtk_image_set_from_icon_name (self->enterprise_login_status_icon, "dialog-warning-symbolic");
+ gtk_image_set_from_icon_name (self->enterprise_password_status_icon, "dialog-warning-symbolic");
}
static void
enterprise_password_entry_changed_cb (CcAddUserDialog *self)
{
dialog_validate (self);
- clear_entry_validation_error (self->enterprise_password_entry);
+ gtk_image_set_from_icon_name (self->enterprise_password_status_icon, "dialog-warning-symbolic");
}
static void
@@ -1468,18 +1469,15 @@ mode_change (CcAddUserDialog *self,
switch (mode) {
default:
case MODE_LOCAL:
- gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->local_grid));
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->local_page));
gtk_widget_grab_focus (GTK_WIDGET (self->local_name_entry));
- gtk_toggle_button_set_active (self->enterprise_button, FALSE);
break;
case MODE_ENTERPRISE:
- gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->enterprise_grid));
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->enterprise_page));
gtk_widget_grab_focus (GTK_WIDGET (self->enterprise_domain_entry));
- gtk_toggle_button_set_active (self->enterprise_button, TRUE);
break;
case MODE_OFFLINE:
- gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->offline_grid));
- gtk_toggle_button_set_active (self->enterprise_button, TRUE);
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->offline_page));
break;
}
@@ -1490,10 +1488,7 @@ mode_change (CcAddUserDialog *self,
static void
enterprise_button_toggled_cb (CcAddUserDialog *self)
{
- AccountMode mode;
-
- mode = gtk_toggle_button_get_active (self->enterprise_button) ? MODE_ENTERPRISE : MODE_LOCAL;
- mode_change (self, mode);
+ mode_change (self, MODE_ENTERPRISE);
}
static void
@@ -1608,7 +1603,9 @@ cc_add_user_dialog_dispose (GObject *obj)
self->enterprise_domain_timeout_id = 0;
}
- g_clear_pointer ((GtkWidget **)&self->join_dialog, gtk_widget_destroy);
+ if (self->join_dialog != NULL) {
+ gtk_window_destroy (GTK_WINDOW (self->join_dialog));
+ }
G_OBJECT_CLASS (cc_add_user_dialog_parent_class)->dispose (obj);
}
@@ -1639,26 +1636,36 @@ cc_add_user_dialog_class_init (CcAddUserDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_button);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_combo);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_entry);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_hint_label);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_grid);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_hint_label);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_hint);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_row);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_domain_status_icon);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_page);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_login_group);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_login_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_login_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_password_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog,
enterprise_password_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, enterprise_realm_model);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_account_type_standard);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_grid);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_hint_label);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_account_type_switch);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_page);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_hint);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_row);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_name_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_name_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_combo);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_model);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_entry);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_password_radio);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_entry);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_hint_label);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_row);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_username_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_strength_indicator);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_verify_entry);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_verify_hint_label);
- gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, offline_grid);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_verify_password_row);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, local_verify_status_icon);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, offline_page);
+ gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, password_group);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, spinner);
gtk_widget_class_bind_template_child (widget_class, CcAddUserDialog, stack);
@@ -1669,10 +1676,10 @@ cc_add_user_dialog_class_init (CcAddUserDialogClass *klass)
gtk_widget_class_bind_template_callback (widget_class, enterprise_domain_combo_focus_out_event_cb);
gtk_widget_class_bind_template_callback (widget_class, enterprise_login_entry_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, enterprise_password_entry_changed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, generate_password);
gtk_widget_class_bind_template_callback (widget_class, local_name_entry_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, local_name_entry_focus_out_event_cb);
gtk_widget_class_bind_template_callback (widget_class, local_password_entry_changed_cb);
- gtk_widget_class_bind_template_callback (widget_class, local_password_entry_icon_press_cb);
gtk_widget_class_bind_template_callback (widget_class, local_password_entry_key_press_event_cb);
gtk_widget_class_bind_template_callback (widget_class, local_password_radio_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, local_username_combo_changed_cb);
@@ -1686,7 +1693,7 @@ cc_add_user_dialog_new (GPermission *permission)
{
CcAddUserDialog *self;
- self = g_object_new (CC_TYPE_ADD_USER_DIALOG, "use-header-bar", TRUE, NULL);
+ self = g_object_new (CC_TYPE_ADD_USER_DIALOG, "use-header-bar", 1, NULL);
if (permission != NULL)
self->permission = g_object_ref (permission);
diff --git a/panels/user-accounts/cc-add-user-dialog.ui b/panels/user-accounts/cc-add-user-dialog.ui
index 12a253ac4..1b4b2e56a 100644
--- a/panels/user-accounts/cc-add-user-dialog.ui
+++ b/panels/user-accounts/cc-add-user-dialog.ui
@@ -9,48 +9,35 @@
</columns>
</object>
<template class="CcAddUserDialog" parent="GtkDialog">
- <property name="can_focus">False</property>
- <property name="border_width">5</property>
<property name="resizable">False</property>
<property name="modal">True</property>
- <property name="destroy_with_parent">True</property>
- <property name="type_hint">dialog</property>
+ <property name="hide-on-close">True</property>
<property name="title" translatable="yes">Add User</property>
<property name="icon_name">system-users</property>
+ <property name="default-width">500</property>
<property name="use_header_bar">1</property>
- <child internal-child="headerbar">
- <object class="GtkHeaderBar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="show_close_button">False</property>
- <child>
+ <child type="titlebar">
+ <object class="AdwHeaderBar">
+ <property name="show-end-title-buttons">False</property>
+ <property name="show-start-title-buttons">False</property>
+ <child type="start">
<object class="GtkButton" id="cancel_button">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
+ <signal name="clicked" handler="gtk_window_destroy" object="CcAddUserDialog"/>
<style>
<class name="text-button"/>
</style>
</object>
- <packing>
- <property name="pack_type">start</property>
- </packing>
</child>
- <child>
+ <child type="end">
<object class="GtkButton" id="add_button">
<property name="label" translatable="yes">_Add</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
<signal name="clicked" handler="add_button_clicked_cb" object="CcAddUserDialog" swapped="yes"/>
@@ -59,301 +46,202 @@
<class name="suggested-action"/>
</style>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
- <child>
+ <child type="end">
<object class="GtkSpinner" id="spinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
- <child internal-child="vbox">
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkStack" id="stack">
<child>
- <object class="GtkStack" id="stack">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="transition-type">none</property>
+ <object class="AdwPreferencesPage" id="local_page">
<child>
- <object class="GtkGrid" id="local_grid">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">8</property>
- <property name="border_width">20</property>
- <property name="margin_end">20</property>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkComboBoxText" id="local_username_combo">
- <property name="visible">True</property>
- <property name="has_entry">True</property>
- <property name="entry_text_column">0</property>
- <property name="model">local_username_model</property>
- <property name="hexpand">True</property>
- <signal name="changed" handler="local_username_combo_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="focus-out-event" handler="local_username_combo_focus_out_event_cb"
after="yes" object="CcAddUserDialog" swapped="yes"/>
- <child internal-child="entry">
- <object class="GtkEntry" id="local_username_entry">
+ <object class="AdwActionRow" id="local_name_row">
+ <property name="title" translatable="yes">Name</property>
+ <child>
+ <object class="GtkEntry" id="local_name_entry">
+ <property name="valign">center</property>
+ <property name="max-length">255</property>
<property name="activates_default">True</property>
+ <property name="hexpand">True</property>
+ <signal name="changed" handler="local_name_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
<signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="local_name_entry_focus_out_event_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="local_name_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
</object>
</child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- </packing>
</child>
<child>
- <object class="GtkLabel" id="local_username_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="xalign">0</property>
- <property name="label"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="height-request">50</property>
- <property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="hexpand">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
+ <object class="AdwActionRow" id="local_username_row">
+ <property name="title" translatable="yes">Username</property>
+ <property name="subtitle-lines">2</property>
+ <child>
+ <object class="GtkComboBoxText" id="local_username_combo">
+ <property name="valign">center</property>
+ <property name="has_entry">True</property>
+ <property name="entry_text_column">0</property>
+ <property name="model">local_username_model</property>
+ <signal name="changed" handler="local_username_combo_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="local_username_combo_focus_out_event_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="local_username_entry">
+ <property name="activates_default">True</property>
+ <property name="hexpand">True</property>
+ <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="local_username_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkLabel" id="local_username_label">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Username</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">local_username_combo</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Administrator</property>
+ <property name="subtitle" translatable="yes">Administrators can add and remove other
users, and can change settings for all users. Parental controls cannot be applied to
administrators.</property>
+ <property name="subtitle-lines">3</property>
+ <child type="suffix">
+ <object class="GtkSwitch" id="local_account_type_switch">
+ <property name="valign">center</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Password</property>
<child>
- <object class="GtkEntry" id="local_name_entry">
- <property name="visible">True</property>
- <property name="max-length">255</property>
- <property name="can_focus">True</property>
- <property name="activates_default">True</property>
- <property name="hexpand">True</property>
- <property name="has_focus">True</property>
- <signal name="changed" handler="local_name_entry_changed_cb" object="CcAddUserDialog"
swapped="yes"/>
- <signal name="focus-out-event" handler="local_name_entry_focus_out_event_cb" after="yes"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">User sets password on first login</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="local_password_login_radio">
+ <property name="valign">center</property>
+ <property name="active">True</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
</child>
<child>
- <object class="GtkLabel" id="local_name_label">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Full Name</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">local_name_entry</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Set password now</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="local_password_radio">
+ <property name="valign">center</property>
+ <property name="group">local_password_login_radio</property>
+ <property name="use_underline">True</property>
+ <property name="group">local_password_login_radio</property>
+ <signal name="toggled" handler="local_password_radio_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="password_group">
+ <property name="sensitive">False</property>
<child>
- <object class="GtkBox" id="local_account_type_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <style>
- <class name="linked"/>
- </style>
+ <object class="AdwActionRow" id="local_password_row">
+ <property name="title" translatable="yes">Password</property>
+ <property name="subtitle-lines">2</property>
<child>
- <object class="GtkRadioButton" id="local_account_type_standard">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ <object class="GtkPasswordEntry" id="local_password_entry">
<property name="hexpand">True</property>
- <property name="label" translatable="yes">Standard</property>
- <property name="draw_indicator">False</property>
- <property name="height_request">35</property>
+ <property name="has_tooltip">True</property>
+ <property name="valign">center</property>
+ <property name="show-peek-icon">True</property>
+ <signal name="notify::text" handler="local_password_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerKey">
+ <signal name="key-pressed" handler="local_password_entry_key_press_event_cb"
object="CcAddUserDialog" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="password_focus_out_event_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
</object>
</child>
- <child>
- <object class="GtkRadioButton" id="account_type_admin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="label" translatable="yes">Administrator</property>
- <property name="draw_indicator">False</property>
- <property name="height_request">35</property>
- <property name="group">local_account_type_standard</property>
+ <child type="suffix">
+ <object class="GtkButton">
+ <property name="visible">False</property>
+ <property name="icon-name">system-run-symbolic</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="generate_password" object="CcAddUserDialog"
swapped="yes"/>
+ <style>
+ <class name="flat"/>
+ </style>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="local_password_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
</object>
</child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="local_account_type_label">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Account _Type</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">local_account_type_box</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Password</property>
- <property name="margin_top">12</property>
- <property name="halign">start</property>
- <property name="margin_start">20</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- </packing>
</child>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="margin_start">20</property>
+ <object class="AdwActionRow" id="local_verify_password_row">
+ <property name="title" translatable="yes">Confirm</property>
<child>
- <object class="GtkRadioButton" id="local_password_login_radio">
- <property name="label" translatable="yes">Allow user to set a password when they
next _login</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="use_underline">True</property>
+ <object class="GtkPasswordEntry" id="local_verify_entry">
+ <property name="hexpand">True</property>
+ <property name="valign">center</property>
+ <property name="sensitive">False</property>
+ <property name="show-peek-icon">True</property>
+ <signal name="notify::text" handler="local_verify_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="password_focus_out_event_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
</object>
- <packing>
- <property name="position">0</property>
- </packing>
</child>
- <child>
- <object class="GtkRadioButton" id="local_password_radio">
- <property name="label" translatable="yes">Set a password _now</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">local_password_login_radio</property>
- <property name="use_underline">True</property>
- <signal name="toggled" handler="local_password_radio_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ <child type="suffix">
+ <object class="GtkImage" id="local_verify_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
</object>
- <packing>
- <property name="position">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">5</property>
- <property name="width">2</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="local_password_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Password</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">local_password_entry</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">6</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="local_password_entry">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="has_tooltip">True</property>
- <property name="visibility">False</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="hexpand">True</property>
- <property name="activates_default">True</property>
- <property name="input_purpose">password</property>
- <signal name="notify::text" handler="local_password_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="icon-press" handler="local_password_entry_icon_press_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="focus-out-event" handler="password_focus_out_event_cb" after="yes"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="key-press-event" handler="local_password_entry_key_press_event_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">6</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
<object class="GtkLevelBar" id="local_strength_indicator">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="mode">discrete</property>
+ <property name="mode">continuous</property>
<property name="max-value">5</property>
- <property name="hexpand">True</property>
+ <property name="margin-top">12</property>
<offsets>
<offset name="strength-weak" value="1"/>
<offset name="strength-low" value="2"/>
@@ -362,491 +250,145 @@
<offset name="strength-high" value="5"/>
</offsets>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">7</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="local_hint_label">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="xalign">0</property>
- <property name="label"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="height-request">50</property>
- <property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="hexpand">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">8</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="local_verify_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Confirm</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">local_verify_entry</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">9</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="local_verify_entry">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="hexpand">True</property>
- <property name="input_purpose">password</property>
- <signal name="notify::text" handler="local_verify_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="focus-out-event" handler="password_focus_out_event_cb" after="yes"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="activate" handler="dialog_validate" object="CcAddUserDialog"
swapped="yes"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">9</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
- <object class="GtkLabel" id="local_verify_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="xalign">0</property>
- <property name="label"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
+ <object class="GtkLabel" id="local_password_hint">
+ <property name="halign">start</property>
<property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="hexpand">True</property>
+ <property name="margin-top">12</property>
<style>
<class name="dim-label"/>
</style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">10</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="name">_local</property>
- </packing>
</child>
<child>
- <object class="GtkGrid" id="enterprise_grid">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="row_spacing">8</property>
- <property name="column_spacing">6</property>
- <property name="border_width">20</property>
- <property name="margin_end">20</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Enterprise login allows an existing centrally
managed user account to be used on this device. You can also use this account to access company resources on
the internet.</property>
- <property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="margin_bottom">20</property>
- <property name="max_width_chars">55</property>
- <property name="xalign">0</property>
- <style>
- <class name="dim-label"/>
- </style>
- </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="GtkLabel" id="enterprise_domain_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Domain</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">enterprise_domain_combo</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="enterprise_login_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Username</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">enterprise_login_entry</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="enterprise_password_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Password</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">enterprise_password_entry</property>
- <property name="margin_start">20</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkLabel" id="enterprise_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="xalign">0</property>
- <property name="label"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="height-request">50</property>
- <property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="hexpand">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
+ <object class="AdwActionRow" id="enterprise_button">
+ <property name="visible">False</property>
+ <property name="title" translatable="yes">Enterprise Login</property>
+ <property name="subtitle" translatable="yes">User accounts which are managed by a
company or organisation.</property>
+ <property name="activatable">True</property>
+ <signal name="activated" handler="enterprise_button_toggled_cb" object="CcAddUserDialog"
swapped="yes"/>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">5</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesPage" id="enterprise_page">
+ <property name="visible">True</property>
+ <child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkComboBox" id="enterprise_domain_combo">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="has_entry">True</property>
- <property name="entry_text_column">0</property>
- <property name="model">enterprise_realm_model</property>
- <signal name="changed" handler="enterprise_domain_combo_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
- <signal name="focus-out-event" handler="enterprise_domain_combo_focus_out_event_cb"
after="yes" object="CcAddUserDialog" swapped="yes"/>
- <child internal-child="entry">
- <object class="GtkEntry" id="enterprise_domain_entry">
- <property name="can_focus">True</property>
+ <object class="AdwActionRow" id="enterprise_domain_row">
+ <property name="title" translatable="yes">Domain</property>
+ <child>
+ <object class="GtkComboBox" id="enterprise_domain_combo">
+ <property name="valign">center</property>
+ <property name="has_entry">True</property>
+ <property name="entry_text_column">0</property>
+ <property name="model">enterprise_realm_model</property>
+ <signal name="changed" handler="enterprise_domain_combo_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="enterprise_domain_entry">
+ </object>
+ </child>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="enterprise_domain_combo_focus_out_event_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="enterprise_domain_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
</object>
</child>
</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="GtkLabel" id="enterprise_domain_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="xalign">0</property>
- <property name="label"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="height-request">50</property>
+ <object class="GtkLabel" id="enterprise_domain_hint">
+ <property name="halign">start</property>
+ <property name="margin-top">12</property>
<property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="hexpand">True</property>
<style>
<class name="dim-label"/>
</style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
- </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="GtkEntry" id="enterprise_login_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="hexpand">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
- <property name="invisible_char_set">True</property>
- <property name="input_purpose">password</property>
- <signal name="changed" handler="enterprise_login_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="enterprise_password_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="visibility">False</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
- <property name="invisible_char_set">True</property>
- <property name="input_purpose">password</property>
- <signal name="changed" handler="enterprise_password_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
</object>
</child>
<child>
- <object class="GtkGrid" id="offline_grid">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">8</property>
- <property name="border_width">20</property>
+ <object class="AdwPreferencesGroup" id="enterprise_login_group">
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Enterprise login allows an existing centrally
managed user account to be used on this device. You can also use this account to access company resources on
the internet.</property>
- <property name="wrap">True</property>
- <property name="wrap_mode">word-char</property>
- <property name="margin_bottom">20</property>
- <property name="margin_end">20</property>
- <property name="max_width_chars">55</property>
- <property name="xalign">0</property>
- <style>
- <class name="dim-label"/>
- </style>
- </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="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">network-offline-symbolic</property>
- <property name="pixel_size">160</property>
- <property name="vexpand">True</property>
- <property name="hexpand">True</property>
- <property name="margin_bottom">6</property>
- <property name="valign">end</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">2</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">You are Offline</property>
- <property name="yalign">0</property>
- <property name="justify">center</property>
- <property name="hexpand">True</property>
- <attributes>
- <attribute name="scale" value="1.6"/>
- </attributes>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Username</property>
+ <child>
+ <object class="GtkEntry" id="enterprise_login_entry">
+ <property name="valign">center</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="invisible_char_set">True</property>
+ <property name="input_purpose">password</property>
+ <signal name="changed" handler="enterprise_login_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="enterprise_login_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">2</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">You must be online in order to add enterprise
users.</property>
- <property name="yalign">0</property>
- <property name="justify">center</property>
- <property name="vexpand">True</property>
- <property name="hexpand">True</property>
- <attributes>
- <attribute name="scale" value="1.2"/>
- </attributes>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Password</property>
+ <child>
+ <object class="GtkPasswordEntry" id="enterprise_password_entry">
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <signal name="changed" handler="enterprise_password_entry_changed_cb"
object="CcAddUserDialog" swapped="yes"/>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="enterprise_password_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
</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>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwPreferencesPage" id="offline_page">
<child>
- <object class="GtkToggleButton" id="enterprise_button">
- <property name="label" translatable="yes">_Enterprise Login</property>
- <property name="visible">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="border_width">20</property>
- <signal name="toggled" handler="enterprise_button_toggled_cb" object="CcAddUserDialog"
swapped="yes"/>
+ <object class="AdwStatusPage">
+ <property name="title" translatable="yes">You are Offline</property>
+ <property name="description" translatable="yes">Enterprise login allows an existing
centrally managed user account to be used on this device. You can also use this account to access company
resources on the internet.</property>
+ <property name="icon-name">network-offline-symbolic</property>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
- <action-widgets>
- <action-widget response="-6">cancel_button</action-widget>
- </action-widgets>
</template>
<object class="GtkSizeGroup">
<widgets>
- <widget name="local_username_label"/>
- <widget name="local_name_label"/>
- <widget name="local_account_type_label"/>
- <widget name="enterprise_domain_label"/>
- <widget name="enterprise_login_label"/>
- <widget name="enterprise_password_label"/>
- <widget name="local_password_label"/>
- <widget name="local_verify_label"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup">
- <widgets>
- <widget name="local_username_combo"/>
- <widget name="local_username_hint_label"/>
- <widget name="local_name_entry"/>
- <widget name="local_account_type_box"/>
- <widget name="local_password_entry"/>
- <widget name="local_hint_label"/>
- <widget name="local_verify_entry"/>
- <widget name="local_verify_hint_label"/>
- <widget name="enterprise_domain_combo"/>
- <widget name="enterprise_domain_hint_label"/>
- <widget name="enterprise_login_entry"/>
- <widget name="enterprise_password_entry"/>
- <widget name="enterprise_hint_label"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup">
- <property name="mode">horizontal</property>
- <widgets>
- <widget name="local_account_type_standard"/>
- <widget name="account_type_admin"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup">
- <property name="mode">horizontal</property>
- <widgets>
- <widget name="add_button"/>
<widget name="cancel_button"/>
+ <widget name="add_button"/>
</widgets>
</object>
<object class="GtkListStore" id="enterprise_realm_model">
diff --git a/panels/user-accounts/cc-avatar-chooser.c b/panels/user-accounts/cc-avatar-chooser.c
index aedc5f7d5..a5e4f3c6d 100644
--- a/panels/user-accounts/cc-avatar-chooser.c
+++ b/panels/user-accounts/cc-avatar-chooser.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
+#include <adwaita.h>
#include <gio/gunixoutputstream.h>
#include <glib.h>
#include <glib/gi18n.h>
@@ -31,12 +32,6 @@
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
-#ifdef HAVE_CHEESE
-#include <cheese-avatar-chooser.h>
-#include <cheese-camera-device.h>
-#include <cheese-camera-device-monitor.h>
-#endif /* HAVE_CHEESE */
-
#include "cc-avatar-chooser.h"
#include "cc-crop-area.h"
#include "user-utils.h"
@@ -48,17 +43,9 @@
struct _CcAvatarChooser {
GtkPopover parent;
- GtkWidget *popup_button;
GtkWidget *crop_area;
GtkWidget *user_flowbox;
GtkWidget *flowbox;
- GtkWidget *take_picture_button;
-
-#ifdef HAVE_CHEESE
- CheeseCameraDeviceMonitor *monitor;
- GCancellable *cancellable;
- guint num_cameras;
-#endif /* HAVE_CHEESE */
GnomeDesktopThumbnailFactory *thumb_factory;
GListStore *faces;
@@ -78,17 +65,17 @@ crop_dialog_response (CcAvatarChooser *self,
if (response_id != GTK_RESPONSE_ACCEPT) {
self->crop_area = NULL;
- gtk_widget_destroy (dialog);
+ gtk_window_destroy (GTK_WINDOW (dialog));
return;
}
- pb = cc_crop_area_get_picture (CC_CROP_AREA (self->crop_area));
+ pb = cc_crop_area_create_pixbuf (CC_CROP_AREA (self->crop_area));
pb2 = gdk_pixbuf_scale_simple (pb, PIXEL_SIZE, PIXEL_SIZE, GDK_INTERP_BILINEAR);
set_user_icon_data (self->user, pb2);
self->crop_area = NULL;
- gtk_widget_destroy (dialog);
+ gtk_window_destroy (GTK_WINDOW (dialog));
gtk_popover_popdown (GTK_POPOVER (self));
}
@@ -98,9 +85,11 @@ cc_avatar_chooser_crop (CcAvatarChooser *self,
GdkPixbuf *pixbuf)
{
GtkWidget *dialog;
+ GtkWindow *toplevel;
+ toplevel = (GtkWindow *)gtk_widget_get_native (GTK_WIDGET (self));
dialog = gtk_dialog_new_with_buttons ("",
- GTK_WINDOW (gtk_widget_get_toplevel (self->popup_button)),
+ toplevel,
GTK_DIALOG_USE_HEADER_BAR,
_("_Cancel"),
GTK_RESPONSE_CANCEL,
@@ -118,11 +107,12 @@ cc_avatar_chooser_crop (CcAvatarChooser *self,
self->crop_area = cc_crop_area_new ();
gtk_widget_show (self->crop_area);
cc_crop_area_set_min_size (CC_CROP_AREA (self->crop_area), 48, 48);
- cc_crop_area_set_constrain_aspect (CC_CROP_AREA (self->crop_area), TRUE);
- cc_crop_area_set_picture (CC_CROP_AREA (self->crop_area), pixbuf);
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
- self->crop_area,
- TRUE, TRUE, 8);
+ cc_crop_area_set_paintable (CC_CROP_AREA (self->crop_area),
+ GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf)));
+ gtk_box_prepend (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+ self->crop_area);
+ gtk_widget_set_hexpand (self->crop_area, TRUE);
+ gtk_widget_set_vexpand (self->crop_area, TRUE);
gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
@@ -134,7 +124,6 @@ file_chooser_response (CcAvatarChooser *self,
gint response,
GtkDialog *chooser)
{
- g_autofree gchar *fileuri = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GdkPixbuf) pixbuf = NULL;
g_autoptr(GdkPixbuf) pixbuf2 = NULL;
@@ -142,88 +131,36 @@ file_chooser_response (CcAvatarChooser *self,
g_autoptr(GFileInputStream) stream = NULL;
if (response != GTK_RESPONSE_ACCEPT) {
- gtk_widget_destroy (GTK_WIDGET (chooser));
+ gtk_window_destroy (GTK_WINDOW (chooser));
return;
}
- fileuri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (chooser));
- file = g_file_new_for_uri (fileuri);
-
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
stream = g_file_read (file, NULL, &error);
pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream),
NULL, &error);
if (pixbuf == NULL) {
- g_warning ("Failed to load %s: %s", fileuri, error->message);
+ g_warning ("Failed to load %s: %s", g_file_get_uri (file), error->message);
}
pixbuf2 = gdk_pixbuf_apply_embedded_orientation (pixbuf);
- gtk_widget_destroy (GTK_WIDGET (chooser));
+ gtk_window_destroy (GTK_WINDOW (chooser));
cc_avatar_chooser_crop (self, pixbuf2);
}
-static void
-update_preview (GtkFileChooser *chooser,
- GnomeDesktopThumbnailFactory *thumb_factory)
-{
- g_autofree gchar *uri = NULL;
-
- uri = gtk_file_chooser_get_uri (chooser);
-
- if (uri) {
- g_autoptr(GdkPixbuf) pixbuf = NULL;
- g_autofree char *mime_type = NULL;
- g_autoptr(GFile) file = NULL;
- g_autoptr(GFileInfo) file_info = NULL;
- GtkWidget *preview;
-
- preview = gtk_file_chooser_get_preview_widget (chooser);
-
- file = g_file_new_for_uri (uri);
- file_info = g_file_query_info (file,
- "standard::*",
- G_FILE_QUERY_INFO_NONE,
- NULL, NULL);
-
- if (file_info != NULL &&
- g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY) {
- mime_type = g_strdup (g_file_info_get_content_type (file_info));
- }
-
- if (mime_type) {
- pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
- uri,
- mime_type);
- }
-
- gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
- GTK_RESPONSE_ACCEPT,
- (pixbuf != NULL));
-
- if (pixbuf != NULL) {
- gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
- }
- else {
- gtk_image_set_from_icon_name (GTK_IMAGE (preview),
- "dialog-question",
- GTK_ICON_SIZE_DIALOG);
- }
- }
-
- gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
-}
-
static void
cc_avatar_chooser_select_file (CcAvatarChooser *self)
{
+ g_autoptr(GFile) folder = NULL;
GtkWidget *chooser;
- const gchar *folder;
- GtkWidget *preview;
GtkFileFilter *filter;
+ GtkWindow *toplevel;
+ toplevel = (GtkWindow*) gtk_widget_get_native (GTK_WIDGET (self));
chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
- GTK_WINDOW (gtk_widget_get_toplevel (self->popup_button)),
+ toplevel,
GTK_FILE_CHOOSER_ACTION_OPEN,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Open"), GTK_RESPONSE_ACCEPT,
@@ -231,24 +168,11 @@ cc_avatar_chooser_select_file (CcAvatarChooser *self)
gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
- preview = gtk_image_new ();
- gtk_widget_set_size_request (preview, 128, -1);
- gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (chooser), preview);
- gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (chooser), FALSE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE);
- gtk_widget_show (preview);
-
- /* Preview has to be generated after default handler of "selection-changed"
- * signal, otherwise dialog response sensitivity is rewritten (Bug 547988).
- * Preview also has to be generated on "selection-changed" signal to reflect
- * all changes (Bug 660877). */
- g_signal_connect_after (chooser, "selection-changed",
- G_CALLBACK (update_preview), self->thumb_factory);
-
- folder = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
+ folder = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
if (folder)
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
- folder);
+ folder,
+ NULL);
filter = gtk_file_filter_new ();
gtk_file_filter_add_pixbuf_formats (filter);
@@ -260,74 +184,6 @@ cc_avatar_chooser_select_file (CcAvatarChooser *self)
gtk_window_present (GTK_WINDOW (chooser));
}
-#ifdef HAVE_CHEESE
-static gboolean
-destroy_chooser (GtkWidget *chooser)
-{
- gtk_widget_destroy (chooser);
- return FALSE;
-}
-
-static void
-webcam_response_cb (CcAvatarChooser *self,
- int response,
- GtkDialog *dialog)
-{
- if (response == GTK_RESPONSE_ACCEPT) {
- g_autoptr(GdkPixbuf) pb = NULL;
- g_autoptr(GdkPixbuf) pb2 = NULL;
-
- g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
- pb2 = gdk_pixbuf_scale_simple (pb, PIXEL_SIZE, PIXEL_SIZE, GDK_INTERP_BILINEAR);
-
- set_user_icon_data (self->user, pb2);
- }
- if (response != GTK_RESPONSE_DELETE_EVENT &&
- response != GTK_RESPONSE_NONE)
- g_idle_add ((GSourceFunc) destroy_chooser, dialog);
-
- gtk_popover_popdown (GTK_POPOVER (self));
-}
-
-static void
-webcam_icon_selected (CcAvatarChooser *self)
-{
- GtkWidget *window;
-
- window = cheese_avatar_chooser_new ();
- gtk_window_set_transient_for (GTK_WINDOW (window),
- GTK_WINDOW (gtk_widget_get_toplevel (self->popup_button)));
- gtk_window_set_modal (GTK_WINDOW (window), TRUE);
- g_signal_connect_object (G_OBJECT (window), "response",
- G_CALLBACK (webcam_response_cb), self, G_CONNECT_SWAPPED);
- gtk_widget_show (window);
-}
-
-static void
-update_photo_menu_status (CcAvatarChooser *self)
-{
- if (self->num_cameras == 0)
- gtk_widget_set_visible (self->take_picture_button, FALSE);
- else
- gtk_widget_set_sensitive (self->take_picture_button, TRUE);
-}
-
-static void
-device_added (CcAvatarChooser *self)
-{
- self->num_cameras++;
- update_photo_menu_status (self);
-}
-
-static void
-device_removed (CcAvatarChooser *self)
-{
- self->num_cameras--;
- update_photo_menu_status (self);
-}
-
-#endif /* HAVE_CHEESE */
-
static void
face_widget_activated (CcAvatarChooser *self,
GtkFlowBoxChild *child)
@@ -335,7 +191,7 @@ face_widget_activated (CcAvatarChooser *self,
const gchar *filename;
GtkWidget *image;
- image = gtk_bin_get_child (GTK_BIN (child));
+ image = gtk_flow_box_child_get_child (child);
filename = g_object_get_data (G_OBJECT (image), "filename");
act_user_set_icon_file (self->user, filename);
@@ -372,33 +228,6 @@ create_face_widget (gpointer item,
return image;
}
-#ifdef HAVE_CHEESE
-static void
-setup_cheese_camera_device_monitor (CcAvatarChooser *self)
-{
- g_signal_connect_object (G_OBJECT (self->monitor), "added", G_CALLBACK (device_added), self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (G_OBJECT (self->monitor), "removed", G_CALLBACK (device_removed), self,
G_CONNECT_SWAPPED);
- cheese_camera_device_monitor_coldplug (self->monitor);
- update_photo_menu_status (self);
-}
-
-static void
-cheese_camera_device_monitor_new_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- CcAvatarChooser *self = user_data;
- GObject *ret;
-
- ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, NULL);
- if (ret == NULL)
- return;
-
- self->monitor = CHEESE_CAMERA_DEVICE_MONITOR (ret);
- setup_cheese_camera_device_monitor (self);
-}
-#endif /* HAVE_CHEESE */
-
static GStrv
get_settings_facesdirs (void)
{
@@ -516,63 +345,19 @@ setup_photo_popup (CcAvatarChooser *self)
g_auto(GStrv) system_facesdirs = get_system_facesdirs ();
add_faces_from_dirs (self->faces, system_facesdirs, FALSE);
}
-
-#ifdef HAVE_CHEESE
- gtk_widget_set_visible (self->take_picture_button, TRUE);
-
- self->cancellable = g_cancellable_new ();
- g_async_initable_new_async (CHEESE_TYPE_CAMERA_DEVICE_MONITOR,
- G_PRIORITY_DEFAULT,
- self->cancellable,
- cheese_camera_device_monitor_new_cb,
- self,
- NULL);
-#endif /* HAVE_CHEESE */
-}
-
-static void
-popup_icon_menu (CcAvatarChooser *self)
-{
- gtk_popover_popup (GTK_POPOVER (self));
-}
-
-static gboolean
-on_popup_button_button_pressed (CcAvatarChooser *self,
- GdkEventButton *event)
-{
- if (event->button == 1) {
- if (!gtk_widget_get_visible (GTK_WIDGET (self))) {
- popup_icon_menu (self);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->popup_button), TRUE);
- } else {
- gtk_popover_popdown (GTK_POPOVER (self));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->popup_button), FALSE);
- }
-
- return TRUE;
- }
-
- return FALSE;
}
CcAvatarChooser *
-cc_avatar_chooser_new (GtkWidget *button)
+cc_avatar_chooser_new ()
{
CcAvatarChooser *self;
self = g_object_new (CC_TYPE_AVATAR_CHOOSER,
- "relative-to", button,
NULL);
self->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
- /* Set up the popup */
- self->popup_button = button;
setup_photo_popup (self);
- g_signal_connect_object (button, "toggled",
- G_CALLBACK (popup_icon_menu), self, G_CONNECT_SWAPPED);
- g_signal_connect_object (button, "button-press-event",
- G_CALLBACK (on_popup_button_button_pressed), self, G_CONNECT_SWAPPED);
return self;
}
@@ -583,11 +368,6 @@ cc_avatar_chooser_dispose (GObject *object)
CcAvatarChooser *self = CC_AVATAR_CHOOSER (object);
g_clear_object (&self->thumb_factory);
-#ifdef HAVE_CHEESE
- g_cancellable_cancel (self->cancellable);
- g_clear_object (&self->cancellable);
- g_clear_object (&self->monitor);
-#endif
g_clear_object (&self->user);
G_OBJECT_CLASS (cc_avatar_chooser_parent_class)->dispose (object);
@@ -609,12 +389,8 @@ cc_avatar_chooser_class_init (CcAvatarChooserClass *klass)
gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, user_flowbox);
gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, flowbox);
- gtk_widget_class_bind_template_child (wclass, CcAvatarChooser, take_picture_button);
gtk_widget_class_bind_template_callback (wclass, cc_avatar_chooser_select_file);
-#ifdef HAVE_CHEESE
- gtk_widget_class_bind_template_callback (wclass, webcam_icon_selected);
-#endif
oclass->dispose = cc_avatar_chooser_dispose;
}
@@ -631,24 +407,35 @@ void
cc_avatar_chooser_set_user (CcAvatarChooser *self,
ActUser *user)
{
- g_autoptr(GdkPixbuf) source_pixbuf = NULL;
g_autoptr(GdkPixbuf) pixbuf = NULL;
- GtkWidget *image;
+ const gchar *name;
+ GtkWidget *avatar;
g_return_if_fail (self != NULL);
if (self->user) {
- gtk_container_foreach (GTK_CONTAINER (self->user_flowbox), (GtkCallback) gtk_widget_destroy,
NULL);
+ GtkWidget *child;
+
+ child = gtk_widget_get_first_child (GTK_WIDGET (self->user_flowbox));
+ while (child) {
+ GtkWidget *next = gtk_widget_get_next_sibling (child);
+
+ if (GTK_FLOW_BOX_CHILD (child))
+ gtk_flow_box_remove (GTK_FLOW_BOX (self->user_flowbox), child);
+
+ child = next;
+ }
+
g_clear_object (&self->user);
}
self->user = g_object_ref (user);
- source_pixbuf = generate_default_avatar (user, AVATAR_CHOOSER_PIXEL_SIZE);
- pixbuf = round_image (source_pixbuf);
- image = gtk_image_new_from_pixbuf (pixbuf);
- gtk_image_set_pixel_size (GTK_IMAGE (image), AVATAR_CHOOSER_PIXEL_SIZE);
- gtk_widget_show (image);
- gtk_container_add (GTK_CONTAINER (self->user_flowbox), image);
+ name = act_user_get_real_name (user);
+ if (name == NULL)
+ name = act_user_get_user_name (user);
+ avatar = adw_avatar_new (AVATAR_CHOOSER_PIXEL_SIZE, name, TRUE);
+ gtk_flow_box_append (GTK_FLOW_BOX (self->user_flowbox), avatar);
+
g_signal_connect_object (self->user_flowbox, "child-activated", G_CALLBACK (user_flowbox_activated),
self, G_CONNECT_SWAPPED);
}
diff --git a/panels/user-accounts/cc-avatar-chooser.h b/panels/user-accounts/cc-avatar-chooser.h
index 56a1699fe..2e9e2c764 100644
--- a/panels/user-accounts/cc-avatar-chooser.h
+++ b/panels/user-accounts/cc-avatar-chooser.h
@@ -31,7 +31,7 @@ G_DECLARE_FINAL_TYPE (CcAvatarChooser, cc_avatar_chooser, CC, AVATAR_CHOOSER, Gt
typedef struct _CcAvatarChooser CcAvatarChooser;
-CcAvatarChooser *cc_avatar_chooser_new (GtkWidget *button);
+CcAvatarChooser *cc_avatar_chooser_new (void);
void cc_avatar_chooser_free (CcAvatarChooser *dialog);
void cc_avatar_chooser_set_user (CcAvatarChooser *dialog,
ActUser *user);
diff --git a/panels/user-accounts/cc-avatar-chooser.ui b/panels/user-accounts/cc-avatar-chooser.ui
index 45bcbabfc..fe1696fbb 100644
--- a/panels/user-accounts/cc-avatar-chooser.ui
+++ b/panels/user-accounts/cc-avatar-chooser.ui
@@ -2,15 +2,13 @@
<interface>
<!-- interface-requires gtk+ 3.8 -->
<template class="CcAvatarChooser" parent="GtkPopover">
+ <property name="visible">False</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_VERTICAL</property>
- <property name="border-width">10</property>
+ <property name="spacing">10</property>
<child>
<object class="GtkFlowBox" id="user_flowbox">
- <property name="visible">True</property>
- <property name="border-width">10</property>
<property name="selection-mode">none</property>
<property name="homogeneous">True</property>
<property name="max-children-per-line">5</property>
@@ -19,8 +17,6 @@
</child>
<child>
<object class="GtkFlowBox" id="flowbox">
- <property name="visible">True</property>
- <property name="border-width">10</property>
<property name="selection-mode">none</property>
<property name="homogeneous">True</property>
<property name="max-children-per-line">5</property>
@@ -29,28 +25,15 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="halign">GTK_ALIGN_CENTER</property>
- <property name="border-width">10</property>
- <property name="spacing">10</property>
- <child>
- <object class="GtkButton" id="take_picture_button">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Take a Picture…</property>
- <signal name="clicked" handler="webcam_icon_selected" swapped="yes"/>
- </object>
- </child>
+ <property name="spacing">20</property>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
<property name="label" translatable="yes">Select a File…</property>
<signal name="clicked" handler="cc_avatar_chooser_select_file" swapped="yes"/>
</object>
</child>
</object>
- <packing>
- <property name="pack-type">GTK_PACK_END</property>
- </packing>
</child>
</object>
</child>
diff --git a/panels/user-accounts/cc-crop-area.c b/panels/user-accounts/cc-crop-area.c
index d80f90a80..e003dffdb 100644
--- a/panels/user-accounts/cc-crop-area.c
+++ b/panels/user-accounts/cc-crop-area.c
@@ -1,6 +1,9 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+/*
+ * Copyright 2021 Red Hat, Inc,
*
- * Copyright 2009 Red Hat, Inc,
+ * Authors:
+ * - Matthias Clasen <mclasen redhat com>
+ * - Niels De Graef <nielsdg redhat com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,803 +17,687 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Written by: Matthias Clasen <mclasen redhat com>
*/
#include "config.h"
-#include <stdlib.h>
-
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <gsk/gl/gskglrenderer.h>
#include "cc-crop-area.h"
+/**
+ * CcCropArea:
+ *
+ * A widget that shows a [iface@Gdk.Paintable] and allows the user specify a
+ * cropping rectangle to effectively crop to that given area.
+ */
+
+/* Location of the cursor relative to the cropping rectangle/circle */
+typedef enum {
+ OUTSIDE,
+ INSIDE,
+ TOP,
+ TOP_LEFT,
+ TOP_RIGHT,
+ BOTTOM,
+ BOTTOM_LEFT,
+ BOTTOM_RIGHT,
+ LEFT,
+ RIGHT
+} Location;
+
struct _CcCropArea {
- GtkDrawingArea parent_instance;
-
- GdkPixbuf *browse_pixbuf;
- GdkPixbuf *pixbuf;
- GdkPixbuf *color_shifted;
- gdouble scale;
- GdkRectangle image;
- GdkCursorType current_cursor;
- GdkRectangle crop;
- gint active_region;
- gint last_press_x;
- gint last_press_y;
- gint base_width;
- gint base_height;
- gdouble aspect;
-};
+ GtkWidget parent_instance;
-G_DEFINE_TYPE (CcCropArea, cc_crop_area, GTK_TYPE_DRAWING_AREA);
+ GdkPaintable *paintable;
-static inline guchar
-shift_color_byte (guchar b,
- int shift)
-{
- return CLAMP(b + shift, 0, 255);
-}
+ double scale; /* scale factor to go from paintable size to widget size */
-static void
-shift_colors (GdkPixbuf *pixbuf,
- gint red,
- gint green,
- gint blue,
- gint alpha)
-{
- gint x, y, offset, y_offset, rowstride, width, height;
- guchar *pixels;
- gint channels;
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- channels = gdk_pixbuf_get_n_channels (pixbuf);
-
- for (y = 0; y < height; y++) {
- y_offset = y * rowstride;
- for (x = 0; x < width; x++) {
- offset = y_offset + x * channels;
- if (red != 0)
- pixels[offset] = shift_color_byte (pixels[offset], red);
- if (green != 0)
- pixels[offset + 1] = shift_color_byte (pixels[offset + 1], green);
- if (blue != 0)
- pixels[offset + 2] = shift_color_byte (pixels[offset + 2], blue);
- if (alpha != 0 && channels >= 4)
- pixels[offset + 3] = shift_color_byte (pixels[offset + 3], blue);
- }
- }
-}
+ const char *current_cursor;
+ Location active_region;
+ double drag_offx;
+ double drag_offy;
-static void
-update_pixbufs (CcCropArea *area)
-{
- gint width;
- gint height;
- GtkAllocation allocation;
- gdouble scale;
- gint dest_width, dest_height;
- GtkWidget *widget;
-
- widget = GTK_WIDGET (area);
- gtk_widget_get_allocation (widget, &allocation);
-
- width = gdk_pixbuf_get_width (area->browse_pixbuf);
- height = gdk_pixbuf_get_height (area->browse_pixbuf);
-
- scale = allocation.height / (gdouble)height;
- if (scale * width > allocation.width)
- scale = allocation.width / (gdouble)width;
-
- dest_width = width * scale;
- dest_height = height * scale;
-
- if (area->pixbuf == NULL ||
- gdk_pixbuf_get_width (area->pixbuf) != allocation.width ||
- gdk_pixbuf_get_height (area->pixbuf) != allocation.height) {
- g_clear_object (&area->pixbuf);
- area->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- gdk_pixbuf_get_has_alpha (area->browse_pixbuf),
- 8,
- dest_width, dest_height);
- gdk_pixbuf_fill (area->pixbuf, 0x0);
-
- gdk_pixbuf_scale (area->browse_pixbuf,
- area->pixbuf,
- 0, 0,
- dest_width, dest_height,
- 0, 0,
- scale, scale,
- GDK_INTERP_BILINEAR);
-
- g_clear_object (&area->color_shifted);
- area->color_shifted = gdk_pixbuf_copy (area->pixbuf);
- shift_colors (area->color_shifted, -32, -32, -32, 0);
-
- if (area->scale == 0.0) {
- gdouble scale_to_80, scale_to_image, crop_scale;
-
- /* Scale the crop rectangle to 80% of the area, or less to fit the image */
- scale_to_80 = MIN ((gdouble)gdk_pixbuf_get_width (area->pixbuf) * 0.8 /
area->base_width,
- (gdouble)gdk_pixbuf_get_height (area->pixbuf) * 0.8 /
area->base_height);
- scale_to_image = MIN ((gdouble)dest_width / area->base_width,
- (gdouble)dest_height / area->base_height);
- crop_scale = MIN (scale_to_80, scale_to_image);
-
- area->crop.width = crop_scale * area->base_width / scale;
- area->crop.height = crop_scale * area->base_height / scale;
- area->crop.x = (gdk_pixbuf_get_width (area->browse_pixbuf) - area->crop.width) / 2;
- area->crop.y = (gdk_pixbuf_get_height (area->browse_pixbuf) - area->crop.height) / 2;
- }
-
- area->scale = scale;
- area->image.x = (allocation.width - dest_width) / 2;
- area->image.y = (allocation.height - dest_height) / 2;
- area->image.width = dest_width;
- area->image.height = dest_height;
- }
-}
+ /* In source coordinates. See get_scaled_crop() for widget coordinates */
+ GdkRectangle crop;
+
+ /* In widget coordinates */
+ GdkRectangle image;
+ int min_crop_width;
+ int min_crop_height;
+};
+
+G_DEFINE_TYPE (CcCropArea, cc_crop_area, GTK_TYPE_WIDGET);
static void
-crop_to_widget (CcCropArea *area,
- GdkRectangle *crop)
+update_image_and_crop (CcCropArea *area)
{
- crop->x = area->image.x + area->crop.x * area->scale;
- crop->y = area->image.y + area->crop.y * area->scale;
- crop->width = area->crop.width * area->scale;
- crop->height = area->crop.height * area->scale;
-}
+ GtkAllocation allocation;
+ int width, height;
+ int dest_width, dest_height;
+ double scale;
-typedef enum {
- OUTSIDE,
- INSIDE,
- TOP,
- TOP_LEFT,
- TOP_RIGHT,
- BOTTOM,
- BOTTOM_LEFT,
- BOTTOM_RIGHT,
- LEFT,
- RIGHT
-} Location;
+ if (area->paintable == NULL)
+ return;
-static gboolean
-cc_crop_area_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GdkRectangle crop;
- gint width, height, ix, iy;
- CcCropArea *uarea = CC_CROP_AREA (widget);
-
- if (uarea->browse_pixbuf == NULL)
- return FALSE;
-
- update_pixbufs (uarea);
-
- width = gdk_pixbuf_get_width (uarea->pixbuf);
- height = gdk_pixbuf_get_height (uarea->pixbuf);
- crop_to_widget (uarea, &crop);
-
- ix = uarea->image.x;
- iy = uarea->image.y;
-
- gdk_cairo_set_source_pixbuf (cr, uarea->color_shifted, ix, iy);
- cairo_rectangle (cr, ix, iy, width, crop.y - iy);
- cairo_rectangle (cr, ix, crop.y, crop.x - ix, crop.height);
- cairo_rectangle (cr, crop.x + crop.width, crop.y, width - crop.width - (crop.x - ix), crop.height);
- cairo_rectangle (cr, ix, crop.y + crop.height, width, height - crop.height - (crop.y - iy));
- cairo_fill (cr);
-
- gdk_cairo_set_source_pixbuf (cr, uarea->pixbuf, ix, iy);
- cairo_rectangle (cr, crop.x, crop.y, crop.width, crop.height);
- cairo_fill (cr);
-
- if (uarea->active_region != OUTSIDE) {
- gint x1, x2, y1, y2;
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_set_line_width (cr, 1.0);
- x1 = crop.x + crop.width / 3.0;
- x2 = crop.x + 2 * crop.width / 3.0;
- y1 = crop.y + crop.height / 3.0;
- y2 = crop.y + 2 * crop.height / 3.0;
-
- cairo_move_to (cr, x1 + 0.5, crop.y);
- cairo_line_to (cr, x1 + 0.5, crop.y + crop.height);
-
- cairo_move_to (cr, x2 + 0.5, crop.y);
- cairo_line_to (cr, x2 + 0.5, crop.y + crop.height);
-
- cairo_move_to (cr, crop.x, y1 + 0.5);
- cairo_line_to (cr, crop.x + crop.width, y1 + 0.5);
-
- cairo_move_to (cr, crop.x, y2 + 0.5);
- cairo_line_to (cr, crop.x + crop.width, y2 + 0.5);
- cairo_stroke (cr);
- }
+ gtk_widget_get_allocation (GTK_WIDGET (area), &allocation);
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_set_line_width (cr, 1.0);
- cairo_rectangle (cr,
- crop.x + 0.5,
- crop.y + 0.5,
- crop.width - 1.0,
- crop.height - 1.0);
- cairo_stroke (cr);
-
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_set_line_width (cr, 2.0);
- cairo_rectangle (cr,
- crop.x + 2.0,
- crop.y + 2.0,
- crop.width - 4.0,
- crop.height - 4.0);
- cairo_stroke (cr);
+ /* Get the size of the paintable */
+ width = gdk_paintable_get_intrinsic_width (area->paintable);
+ height = gdk_paintable_get_intrinsic_height (area->paintable);
- return FALSE;
+ /* Find out the scale to convert to widget width/height */
+ scale = allocation.height / (double) height;
+ if (scale * width > allocation.width)
+ scale = allocation.width / (double) width;
+
+ dest_width = width * scale;
+ dest_height = height * scale;
+
+ if (area->scale == 0.0) {
+ double scale_to_80, scale_to_image, crop_scale;
+
+ /* Start with a crop area of 80% of the area, unless it's larger than min_size */
+ scale_to_80 = MIN ((double) dest_width * 0.8, (double) dest_height * 0.8);
+ scale_to_image = MIN ((double) area->min_crop_width, (double) area->min_crop_height);
+ crop_scale = MAX (scale_to_80, scale_to_image);
+
+ /* Divide by `scale` to get back to paintable coordinates */
+ area->crop.width = crop_scale / scale;
+ area->crop.height = crop_scale / scale;
+ area->crop.x = (width - area->crop.width) / 2;
+ area->crop.y = (height - area->crop.height) / 2;
+ }
+
+ area->scale = scale;
+ area->image.x = (allocation.width - dest_width) / 2;
+ area->image.y = (allocation.height - dest_height) / 2;
+ area->image.width = dest_width;
+ area->image.height = dest_height;
+}
+
+/* Returns area->crop in widget coordinates (vs paintable coordsinates) */
+static void
+get_scaled_crop (CcCropArea *area,
+ GdkRectangle *crop)
+{
+ crop->x = area->image.x + area->crop.x * area->scale;
+ crop->y = area->image.y + area->crop.y * area->scale;
+ crop->width = area->crop.width * area->scale;
+ crop->height = area->crop.height * area->scale;
}
typedef enum {
- BELOW,
- LOWER,
- BETWEEN,
- UPPER,
- ABOVE
+ BELOW,
+ LOWER,
+ BETWEEN,
+ UPPER,
+ ABOVE
} Range;
static Range
-find_range (gint x,
- gint min,
- gint max)
+find_range (int x,
+ int min,
+ int max)
{
- gint tolerance = 12;
-
- if (x < min - tolerance)
- return BELOW;
- if (x <= min + tolerance)
- return LOWER;
- if (x < max - tolerance)
- return BETWEEN;
- if (x <= max + tolerance)
- return UPPER;
- return ABOVE;
+ int tolerance = 12;
+
+ if (x < min - tolerance)
+ return BELOW;
+ if (x <= min + tolerance)
+ return LOWER;
+ if (x < max - tolerance)
+ return BETWEEN;
+ if (x <= max + tolerance)
+ return UPPER;
+ return ABOVE;
}
+/* Finds the location of (@x, @y) relative to the crop @rect */
static Location
find_location (GdkRectangle *rect,
- gint x,
- gint y)
+ int x,
+ int y)
{
- Range x_range, y_range;
- Location location[5][5] = {
- { OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE },
- { OUTSIDE, TOP_LEFT, TOP, TOP_RIGHT, OUTSIDE },
- { OUTSIDE, LEFT, INSIDE, RIGHT, OUTSIDE },
- { OUTSIDE, BOTTOM_LEFT, BOTTOM, BOTTOM_RIGHT, OUTSIDE },
- { OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE }
- };
-
- x_range = find_range (x, rect->x, rect->x + rect->width);
- y_range = find_range (y, rect->y, rect->y + rect->height);
-
- return location[y_range][x_range];
+ Range x_range, y_range;
+ Location location[5][5] = {
+ { OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE },
+ { OUTSIDE, TOP_LEFT, TOP, TOP_RIGHT, OUTSIDE },
+ { OUTSIDE, LEFT, INSIDE, RIGHT, OUTSIDE },
+ { OUTSIDE, BOTTOM_LEFT, BOTTOM, BOTTOM_RIGHT, OUTSIDE },
+ { OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE, OUTSIDE }
+ };
+
+ x_range = find_range (x, rect->x, rect->x + rect->width);
+ y_range = find_range (y, rect->y, rect->y + rect->height);
+
+ return location[y_range][x_range];
}
static void
update_cursor (CcCropArea *area,
- gint x,
- gint y)
+ int x,
+ int y)
{
- gint cursor_type;
- GdkRectangle crop;
- gint region;
-
- region = area->active_region;
- if (region == OUTSIDE) {
- crop_to_widget (area, &crop);
- region = find_location (&crop, x, y);
- }
-
- switch (region) {
- case OUTSIDE:
- cursor_type = GDK_LEFT_PTR;
- break;
- case TOP_LEFT:
- cursor_type = GDK_TOP_LEFT_CORNER;
- break;
- case TOP:
- cursor_type = GDK_TOP_SIDE;
- break;
- case TOP_RIGHT:
- cursor_type = GDK_TOP_RIGHT_CORNER;
- break;
- case LEFT:
- cursor_type = GDK_LEFT_SIDE;
- break;
- case INSIDE:
- cursor_type = GDK_FLEUR;
- break;
- case RIGHT:
- cursor_type = GDK_RIGHT_SIDE;
- break;
- case BOTTOM_LEFT:
- cursor_type = GDK_BOTTOM_LEFT_CORNER;
- break;
- case BOTTOM:
- cursor_type = GDK_BOTTOM_SIDE;
- break;
- case BOTTOM_RIGHT:
- cursor_type = GDK_BOTTOM_RIGHT_CORNER;
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (cursor_type != area->current_cursor) {
- g_autoptr(GdkCursor) cursor = NULL;
- cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (area)),
- cursor_type);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (area)), cursor);
- area->current_cursor = cursor_type;
+ const char *cursor_type;
+ GdkRectangle crop;
+ int region;
+
+ region = area->active_region;
+ if (region == OUTSIDE) {
+ get_scaled_crop (area, &crop);
+ region = find_location (&crop, x, y);
+ }
+
+ switch (region) {
+ case OUTSIDE:
+ cursor_type = "default";
+ break;
+ case TOP_LEFT:
+ cursor_type = "nw-resize";
+ break;
+ case TOP:
+ cursor_type = "n-resize";
+ break;
+ case TOP_RIGHT:
+ cursor_type = "ne-resize";
+ break;
+ case LEFT:
+ cursor_type = "w-resize";
+ break;
+ case INSIDE:
+ cursor_type = "move";
+ break;
+ case RIGHT:
+ cursor_type = "e-resize";
+ break;
+ case BOTTOM_LEFT:
+ cursor_type = "sw-resize";
+ break;
+ case BOTTOM:
+ cursor_type = "s-resize";
+ break;
+ case BOTTOM_RIGHT:
+ cursor_type = "se-resize";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (cursor_type != area->current_cursor) {
+ GtkNative *native;
+ g_autoptr (GdkCursor) cursor = NULL;
+
+ native = gtk_widget_get_native (GTK_WIDGET (area));
+ if (!native) {
+ g_warning ("Can't adjust cursor: no GtkNative found");
+ return;
}
+ cursor = gdk_cursor_new_from_name (cursor_type, NULL);
+ gdk_surface_set_cursor (gtk_native_get_surface (native), cursor);
+ area->current_cursor = cursor_type;
+ }
}
static int
-eval_radial_line (gdouble center_x, gdouble center_y,
- gdouble bounds_x, gdouble bounds_y,
- gdouble user_x)
+eval_radial_line (double center_x, double center_y,
+ double bounds_x, double bounds_y,
+ double user_x)
{
- gdouble decision_slope;
- gdouble decision_intercept;
+ double decision_slope;
+ double decision_intercept;
- decision_slope = (bounds_y - center_y) / (bounds_x - center_x);
- decision_intercept = -(decision_slope * bounds_x);
+ decision_slope = (bounds_y - center_y) / (bounds_x - center_x);
+ decision_intercept = -(decision_slope * bounds_x);
- return (int) (decision_slope * user_x + decision_intercept);
+ return (int) (decision_slope * user_x + decision_intercept);
}
static gboolean
-cc_crop_area_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
+on_motion (GtkEventControllerMotion *controller,
+ double event_x,
+ double event_y,
+ void *user_data)
{
- CcCropArea *area = CC_CROP_AREA (widget);
- gint x, y;
- gint delta_x, delta_y;
- gint width, height;
- gint adj_width, adj_height;
- gint pb_width, pb_height;
- GdkRectangle damage;
- gint left, right, top, bottom;
- gdouble new_width, new_height;
- gdouble center_x, center_y;
- gint min_width, min_height;
-
- if (area->browse_pixbuf == NULL)
- return FALSE;
-
- update_cursor (area, event->x, event->y);
-
- crop_to_widget (area, &damage);
- gtk_widget_queue_draw_area (widget,
- damage.x - 1, damage.y - 1,
- damage.width + 2, damage.height + 2);
-
- pb_width = gdk_pixbuf_get_width (area->browse_pixbuf);
- pb_height = gdk_pixbuf_get_height (area->browse_pixbuf);
-
- x = (event->x - area->image.x) / area->scale;
- y = (event->y - area->image.y) / area->scale;
-
- delta_x = x - area->last_press_x;
- delta_y = y - area->last_press_y;
- area->last_press_x = x;
- area->last_press_y = y;
+ CcCropArea *area = CC_CROP_AREA (user_data);
- left = area->crop.x;
- right = area->crop.x + area->crop.width - 1;
- top = area->crop.y;
- bottom = area->crop.y + area->crop.height - 1;
+ if (area->paintable == NULL)
+ return FALSE;
- center_x = (left + right) / 2.0;
- center_y = (top + bottom) / 2.0;
-
- switch (area->active_region) {
- case INSIDE:
- width = right - left + 1;
- height = bottom - top + 1;
-
- left += delta_x;
- right += delta_x;
- top += delta_y;
- bottom += delta_y;
-
- if (left < 0)
- left = 0;
- if (top < 0)
- top = 0;
- if (right > pb_width)
- right = pb_width;
- if (bottom > pb_height)
- bottom = pb_height;
-
- adj_width = right - left + 1;
- adj_height = bottom - top + 1;
- if (adj_width != width) {
- if (delta_x < 0)
- right = left + width - 1;
- else
- left = right - width + 1;
- }
- if (adj_height != height) {
- if (delta_y < 0)
- bottom = top + height - 1;
- else
- top = bottom - height + 1;
- }
-
- break;
-
- case TOP_LEFT:
- if (area->aspect < 0) {
- top = y;
- left = x;
- }
- else if (y < eval_radial_line (center_x, center_y, left, top, x)) {
- top = y;
- new_width = (bottom - top) * area->aspect;
- left = right - new_width;
- }
- else {
- left = x;
- new_height = (right - left) / area->aspect;
- top = bottom - new_height;
- }
- break;
-
- case TOP:
- top = y;
- if (area->aspect > 0) {
- new_width = (bottom - top) * area->aspect;
- right = left + new_width;
- }
- break;
-
- case TOP_RIGHT:
- if (area->aspect < 0) {
- top = y;
- right = x;
- }
- else if (y < eval_radial_line (center_x, center_y, right, top, x)) {
- top = y;
- new_width = (bottom - top) * area->aspect;
- right = left + new_width;
- }
- else {
- right = x;
- new_height = (right - left) / area->aspect;
- top = bottom - new_height;
- }
- break;
-
- case LEFT:
- left = x;
- if (area->aspect > 0) {
- new_height = (right - left) / area->aspect;
- bottom = top + new_height;
- }
- break;
-
- case BOTTOM_LEFT:
- if (area->aspect < 0) {
- bottom = y;
- left = x;
- }
- else if (y < eval_radial_line (center_x, center_y, left, bottom, x)) {
- left = x;
- new_height = (right - left) / area->aspect;
- bottom = top + new_height;
- }
- else {
- bottom = y;
- new_width = (bottom - top) * area->aspect;
- left = right - new_width;
- }
- break;
-
- case RIGHT:
- right = x;
- if (area->aspect > 0) {
- new_height = (right - left) / area->aspect;
- bottom = top + new_height;
- }
- break;
-
- case BOTTOM_RIGHT:
- if (area->aspect < 0) {
- bottom = y;
- right = x;
- }
- else if (y < eval_radial_line (center_x, center_y, right, bottom, x)) {
- right = x;
- new_height = (right - left) / area->aspect;
- bottom = top + new_height;
- }
- else {
- bottom = y;
- new_width = (bottom - top) * area->aspect;
- right = left + new_width;
- }
- break;
-
- case BOTTOM:
- bottom = y;
- if (area->aspect > 0) {
- new_width = (bottom - top) * area->aspect;
- right= left + new_width;
- }
- break;
-
- default:
- return FALSE;
- }
+ update_cursor (area, event_x, event_y);
- min_width = area->base_width / area->scale;
- min_height = area->base_height / area->scale;
+ return FALSE;
+}
- width = right - left + 1;
- height = bottom - top + 1;
- if (area->aspect < 0) {
- if (left < 0)
- left = 0;
- if (top < 0)
- top = 0;
- if (right > pb_width)
- right = pb_width;
- if (bottom > pb_height)
- bottom = pb_height;
-
- width = right - left + 1;
- height = bottom - top + 1;
-
- switch (area->active_region) {
- case LEFT:
- case TOP_LEFT:
- case BOTTOM_LEFT:
- if (width < min_width)
- left = right - min_width;
- break;
- case RIGHT:
- case TOP_RIGHT:
- case BOTTOM_RIGHT:
- if (width < min_width)
- right = left + min_width;
- break;
-
- default: ;
- }
-
- switch (area->active_region) {
- case TOP:
- case TOP_LEFT:
- case TOP_RIGHT:
- if (height < min_height)
- top = bottom - min_height;
- break;
- case BOTTOM:
- case BOTTOM_LEFT:
- case BOTTOM_RIGHT:
- if (height < min_height)
- bottom = top + min_height;
- break;
-
- default: ;
- }
- }
- else {
- if (left < 0 || top < 0 ||
- right > pb_width || bottom > pb_height ||
- width < min_width || height < min_height) {
- left = area->crop.x;
- right = area->crop.x + area->crop.width - 1;
- top = area->crop.y;
- bottom = area->crop.y + area->crop.height - 1;
- }
- }
+static void
+on_drag_begin (GtkGestureDrag *gesture,
+ double start_x,
+ double start_y,
+ void *user_data)
+{
+ CcCropArea *area = CC_CROP_AREA (user_data);
+ GdkRectangle crop;
- area->crop.x = left;
- area->crop.y = top;
- area->crop.width = right - left + 1;
- area->crop.height = bottom - top + 1;
+ if (area->paintable == NULL)
+ return;
- crop_to_widget (area, &damage);
- gtk_widget_queue_draw_area (widget,
- damage.x - 1, damage.y - 1,
- damage.width + 2, damage.height + 2);
+ update_cursor (area, start_x, start_y);
- return FALSE;
+ get_scaled_crop (area, &crop);
+
+ area->active_region = find_location (&crop, start_x, start_y);
+
+ area->drag_offx = 0.0;
+ area->drag_offy = 0.0;
}
-static gboolean
-cc_crop_area_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+on_drag_update (GtkGestureDrag *gesture,
+ double offset_x,
+ double offset_y,
+ void *user_data)
{
- CcCropArea *area = CC_CROP_AREA (widget);
- GdkRectangle crop;
+ CcCropArea *area = CC_CROP_AREA (user_data);
+ double start_x, start_y;
+ int x, y, delta_x, delta_y;
+ int width, height;
+ int adj_width, adj_height;
+ int pb_width, pb_height;
+ int left, right, top, bottom;
+ double new_width, new_height;
+ double center_x, center_y;
+ int min_width, min_height;
+
+ pb_width = gdk_paintable_get_intrinsic_width (area->paintable);
+ pb_height = gdk_paintable_get_intrinsic_height (area->paintable);
+
+ gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
+
+ /* Get the x, y, dx, dy in paintable coords */
+ x = (start_x + offset_x - area->image.x) / area->scale;
+ y = (start_y + offset_y - area->image.y) / area->scale;
+ delta_x = (offset_x - area->drag_offx) / area->scale;
+ delta_y = (offset_y - area->drag_offy) / area->scale;
+
+ /* Helper variables */
+ left = area->crop.x;
+ right = area->crop.x + area->crop.width - 1;
+ top = area->crop.y;
+ bottom = area->crop.y + area->crop.height - 1;
+
+ center_x = (left + right) / 2.0;
+ center_y = (top + bottom) / 2.0;
+
+ /* What we have to do depends on where the user started dragging */
+ switch (area->active_region) {
+ case INSIDE:
+ width = right - left + 1;
+ height = bottom - top + 1;
- if (area->browse_pixbuf == NULL)
- return FALSE;
+ left = MAX (left + delta_x, 0);
+ right = MIN (right + delta_x, pb_width);
+ top = MAX (top + delta_y, 0);
+ bottom = MIN (bottom + delta_y, pb_height);
+
+ adj_width = right - left + 1;
+ adj_height = bottom - top + 1;
+ if (adj_width != width) {
+ if (delta_x < 0)
+ right = left + width - 1;
+ else
+ left = right - width + 1;
+ }
+ if (adj_height != height) {
+ if (delta_y < 0)
+ bottom = top + height - 1;
+ else
+ top = bottom - height + 1;
+ }
- crop_to_widget (area, &crop);
+ break;
+
+ case TOP_LEFT:
+ if (y < eval_radial_line (center_x, center_y, left, top, x)) {
+ top = y;
+ new_width = bottom - top;
+ left = right - new_width;
+ } else {
+ left = x;
+ new_height = right - left;
+ top = bottom - new_height;
+ }
+ break;
+
+ case TOP:
+ top = y;
+ new_width = bottom - top;
+ right = left + new_width;
+ break;
+
+ case TOP_RIGHT:
+ if (y < eval_radial_line (center_x, center_y, right, top, x)) {
+ top = y;
+ new_width = bottom - top;
+ right = left + new_width;
+ } else {
+ right = x;
+ new_height = right - left;
+ top = bottom - new_height;
+ }
+ break;
+
+ case LEFT:
+ left = x;
+ new_height = right - left;
+ bottom = top + new_height;
+ break;
+
+ case BOTTOM_LEFT:
+ if (y < eval_radial_line (center_x, center_y, left, bottom, x)) {
+ left = x;
+ new_height = right - left;
+ bottom = top + new_height;
+ } else {
+ bottom = y;
+ new_width = bottom - top;
+ left = right - new_width;
+ }
+ break;
+
+ case RIGHT:
+ right = x;
+ new_height = right - left;
+ bottom = top + new_height;
+ break;
+
+ case BOTTOM_RIGHT:
+ if (y < eval_radial_line (center_x, center_y, right, bottom, x)) {
+ right = x;
+ new_height = right - left;
+ bottom = top + new_height;
+ } else {
+ bottom = y;
+ new_width = bottom - top;
+ right = left + new_width;
+ }
+ break;
+
+ case BOTTOM:
+ bottom = y;
+ new_width = bottom - top;
+ right= left + new_width;
+ break;
+
+ default:
+ return;
+ }
+
+ min_width = area->min_crop_width / area->scale;
+ min_height = area->min_crop_height / area->scale;
+
+ width = right - left + 1;
+ height = bottom - top + 1;
+ if (left < 0 || top < 0 ||
+ right > pb_width || bottom > pb_height ||
+ width < min_width || height < min_height) {
+ left = area->crop.x;
+ right = area->crop.x + area->crop.width - 1;
+ top = area->crop.y;
+ bottom = area->crop.y + area->crop.height - 1;
+ }
- area->last_press_x = (event->x - area->image.x) / area->scale;
- area->last_press_y = (event->y - area->image.y) / area->scale;
- area->active_region = find_location (&crop, event->x, event->y);
+ area->crop.x = left;
+ area->crop.y = top;
+ area->crop.width = right - left + 1;
+ area->crop.height = bottom - top + 1;
- gtk_widget_queue_draw_area (widget,
- crop.x - 1, crop.y - 1,
- crop.width + 2, crop.height + 2);
+ area->drag_offx = offset_x;
+ area->drag_offy = offset_y;
- return FALSE;
+ gtk_widget_queue_draw (GTK_WIDGET (area));
}
-static gboolean
-cc_crop_area_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+on_drag_end (GtkGestureDrag *gesture,
+ double offset_x,
+ double offset_y,
+ void *user_data)
{
- CcCropArea *area = CC_CROP_AREA (widget);
- GdkRectangle crop;
+ CcCropArea *area = CC_CROP_AREA (user_data);
- if (area->browse_pixbuf == NULL)
- return FALSE;
-
- crop_to_widget (area, &crop);
-
- area->last_press_x = -1;
- area->last_press_y = -1;
- area->active_region = OUTSIDE;
+ area->active_region = OUTSIDE;
+ area->drag_offx = 0.0;
+ area->drag_offy = 0.0;
+}
- gtk_widget_queue_draw_area (widget,
- crop.x - 1, crop.y - 1,
- crop.width + 2, crop.height + 2);
+static void
+on_drag_cancel (GtkGesture *gesture,
+ GdkEventSequence *sequence,
+ void *user_data)
+{
+ CcCropArea *area = CC_CROP_AREA (user_data);
- return FALSE;
+ area->active_region = OUTSIDE;
+ area->drag_offx = 0;
+ area->drag_offy = 0;
}
static void
-cc_crop_area_set_size_request (CcCropArea *area)
+cc_crop_area_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
- gtk_widget_set_size_request (GTK_WIDGET (area),
- area->base_width,
- area->base_height);
+ CcCropArea *area = CC_CROP_AREA (widget);
+ cairo_t *cr;
+ GdkRectangle crop;
+
+ if (area->paintable == NULL)
+ return;
+
+ update_image_and_crop (area);
+
+
+ gtk_snapshot_save (snapshot);
+
+ /* First draw the picture */
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (area->image.x, area->image.y));
+
+ gdk_paintable_snapshot (area->paintable, snapshot, area->image.width, area->image.height);
+
+ /* Draw the cropping UI on top with cairo */
+ cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, area->image.width,
area->image.height));
+
+ get_scaled_crop (area, &crop);
+ crop.x -= area->image.x;
+ crop.y -= area->image.y;
+
+ /* Draw the circle */
+ cairo_save (cr);
+ cairo_arc (cr, crop.x + crop.width / 2, crop.y + crop.width / 2, crop.width / 2, 0, 2 * G_PI);
+ cairo_rectangle (cr, 0, 0, area->image.width, area->image.height);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.4);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ /* draw the four corners */
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_set_line_width (cr, 4.0);
+
+ /* top left corner */
+ cairo_move_to (cr, crop.x + 15, crop.y);
+ cairo_line_to (cr, crop.x, crop.y);
+ cairo_line_to (cr, crop.x, crop.y + 15);
+ /* top right corner */
+ cairo_move_to (cr, crop.x + crop.width - 15, crop.y);
+ cairo_line_to (cr, crop.x + crop.width, crop.y);
+ cairo_line_to (cr, crop.x + crop.width, crop.y + 15);
+ /* bottom right corner */
+ cairo_move_to (cr, crop.x + crop.width - 15, crop.y + crop.height);
+ cairo_line_to (cr, crop.x + crop.width, crop.y + crop.height);
+ cairo_line_to (cr, crop.x + crop.width, crop.y + crop.height - 15);
+ /* bottom left corner */
+ cairo_move_to (cr, crop.x + 15, crop.y + crop.height);
+ cairo_line_to (cr, crop.x, crop.y + crop.height);
+ cairo_line_to (cr, crop.x, crop.y + crop.height - 15);
+
+ cairo_stroke (cr);
+
+ gtk_snapshot_restore (snapshot);
}
static void
cc_crop_area_finalize (GObject *object)
{
- CcCropArea *area = CC_CROP_AREA (object);
-
- g_clear_object (&area->browse_pixbuf);
- g_clear_object (&area->pixbuf);
- g_clear_object (&area->color_shifted);
+ CcCropArea *area = CC_CROP_AREA (object);
- G_OBJECT_CLASS (cc_crop_area_parent_class)->finalize (object);
+ g_clear_object (&area->paintable);
}
static void
cc_crop_area_class_init (CcCropAreaClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->finalize = cc_crop_area_finalize;
- widget_class->draw = cc_crop_area_draw;
- widget_class->button_press_event = cc_crop_area_button_press_event;
- widget_class->button_release_event = cc_crop_area_button_release_event;
- widget_class->motion_notify_event = cc_crop_area_motion_notify_event;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = cc_crop_area_finalize;
+
+ widget_class->snapshot = cc_crop_area_snapshot;
}
static void
cc_crop_area_init (CcCropArea *area)
{
- gtk_widget_add_events (GTK_WIDGET (area), GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK);
-
- area->scale = 0.0;
- area->image.x = 0;
- area->image.y = 0;
- area->image.width = 0;
- area->image.height = 0;
- area->active_region = OUTSIDE;
- area->base_width = 48;
- area->base_height = 48;
- area->aspect = 1;
-
- cc_crop_area_set_size_request (area);
+ GtkGesture *gesture;
+ GtkEventController *controller;
+
+ /* Add handlers for dragging */
+ gesture = gtk_gesture_drag_new ();
+ g_signal_connect (gesture, "drag-begin", G_CALLBACK (on_drag_begin), area);
+ g_signal_connect (gesture, "drag-update", G_CALLBACK (on_drag_update),
+ area);
+ g_signal_connect (gesture, "drag-end", G_CALLBACK (on_drag_end), area);
+ g_signal_connect (gesture, "cancel", G_CALLBACK (on_drag_cancel), area);
+ gtk_widget_add_controller (GTK_WIDGET (area), GTK_EVENT_CONTROLLER (gesture));
+
+ /* Add handlers for motion events */
+ controller = gtk_event_controller_motion_new ();
+ g_signal_connect (controller, "motion", G_CALLBACK (on_motion), area);
+ gtk_widget_add_controller (GTK_WIDGET (area), GTK_EVENT_CONTROLLER (controller));
+
+ area->scale = 0.0;
+ area->image.x = 0;
+ area->image.y = 0;
+ area->image.width = 0;
+ area->image.height = 0;
+ area->active_region = OUTSIDE;
+ area->min_crop_width = 48;
+ area->min_crop_height = 48;
+
+ gtk_widget_set_size_request (GTK_WIDGET (area), 48, 48);
}
GtkWidget *
cc_crop_area_new (void)
{
- return g_object_new (CC_TYPE_CROP_AREA, NULL);
+ return g_object_new (CC_TYPE_CROP_AREA, NULL);
}
+/**
+ * cc_crop_area_create_pixbuf:
+ * @area: A crop area
+ *
+ * Renders the area's paintable, with the cropping applied by the user, into a
+ * GdkPixbuf.
+ *
+ * Returns: (transfer full): The cropped picture
+ */
GdkPixbuf *
-cc_crop_area_get_picture (CcCropArea *area)
+cc_crop_area_create_pixbuf (CcCropArea *area)
{
- gint width, height;
+ g_autoptr (GtkSnapshot) snapshot = NULL;
+ g_autoptr (GskRenderNode) node = NULL;
+ g_autoptr (GskRenderer) renderer = NULL;
+ g_autoptr (GdkTexture) texture = NULL;
+ g_autoptr (GError) error = NULL;
+ graphene_rect_t viewport;
+
+ g_return_val_if_fail (CC_IS_CROP_AREA (area), NULL);
+
+ snapshot = gtk_snapshot_new ();
+ gdk_paintable_snapshot (area->paintable, snapshot,
+ gdk_paintable_get_intrinsic_width (area->paintable),
+ gdk_paintable_get_intrinsic_height (area->paintable));
+ node = gtk_snapshot_free_to_node (g_steal_pointer (&snapshot));
+
+ renderer = gsk_gl_renderer_new ();
+ if (!gsk_renderer_realize (renderer, NULL, &error)) {
+ g_warning ("Couldn't realize GL renderer: %s", error->message);
+ return NULL;
+ }
+ viewport = GRAPHENE_RECT_INIT (area->crop.x, area->crop.y,
+ area->crop.width, area->crop.height);
+ texture = gsk_renderer_render_texture (renderer, node, &viewport);
+ gsk_renderer_unrealize (renderer);
+
+ return gdk_pixbuf_get_from_texture (texture);
+}
- width = gdk_pixbuf_get_width (area->browse_pixbuf);
- height = gdk_pixbuf_get_height (area->browse_pixbuf);
- width = MIN (area->crop.width, width - area->crop.x);
- height = MIN (area->crop.height, height - area->crop.y);
+/**
+ * cc_crop_area_get_paintable:
+ * @area: A crop area
+ *
+ * Returns the area's paintable, unmodified.
+ *
+ * Returns: (transfer none) (nullable): The paintable which the user can crop
+ */
+GdkPaintable *
+cc_crop_area_get_paintable (CcCropArea *area)
+{
+ g_return_val_if_fail (CC_IS_CROP_AREA (area), NULL);
- return gdk_pixbuf_new_subpixbuf (area->browse_pixbuf,
- area->crop.x,
- area->crop.y,
- width, height);
+ return area->paintable;
}
void
-cc_crop_area_set_picture (CcCropArea *area,
- GdkPixbuf *pixbuf)
+cc_crop_area_set_paintable (CcCropArea *area,
+ GdkPaintable *paintable)
{
- int width;
- int height;
-
- g_clear_object (&area->browse_pixbuf);
- if (pixbuf) {
- area->browse_pixbuf = g_object_ref (pixbuf);
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- } else {
- width = 0;
- height = 0;
- }
+ g_return_if_fail (CC_IS_CROP_AREA (area));
+ g_return_if_fail (GDK_IS_PAINTABLE (paintable));
- area->crop.width = 2 * area->base_width;
- area->crop.height = 2 * area->base_height;
- area->crop.x = (width - area->crop.width) / 2;
- area->crop.y = (height - area->crop.height) / 2;
+ g_set_object (&area->paintable, paintable);
- area->scale = 0.0;
- area->image.x = 0;
- area->image.y = 0;
- area->image.width = 0;
- area->image.height = 0;
+ area->scale = 0.0;
+ area->image.x = 0;
+ area->image.y = 0;
+ area->image.width = 0;
+ area->image.height = 0;
- gtk_widget_queue_draw (GTK_WIDGET (area));
+ gtk_widget_queue_draw (GTK_WIDGET (area));
}
+/**
+ * cc_crop_area_set_min_size:
+ * @area: A crop widget
+ * @width: The minimal width
+ * @height: The minimal height
+ *
+ * Sets the minimal size of the crop rectangle (in paintable coordinates)
+ */
void
cc_crop_area_set_min_size (CcCropArea *area,
- gint width,
- gint height)
+ int width,
+ int height)
{
- area->base_width = width;
- area->base_height = height;
-
- cc_crop_area_set_size_request (area);
+ g_return_if_fail (CC_IS_CROP_AREA (area));
- if (area->aspect > 0) {
- area->aspect = area->base_width / (gdouble)area->base_height;
- }
-}
+ area->min_crop_width = width;
+ area->min_crop_height = height;
-void
-cc_crop_area_set_constrain_aspect (CcCropArea *area,
- gboolean constrain)
-{
- if (constrain) {
- area->aspect = area->base_width / (gdouble)area->base_height;
- }
- else {
- area->aspect = -1;
- }
+ gtk_widget_set_size_request (GTK_WIDGET (area),
+ area->min_crop_width,
+ area->min_crop_height);
}
-
diff --git a/panels/user-accounts/cc-crop-area.h b/panels/user-accounts/cc-crop-area.h
index d2bfab54f..da80024ac 100644
--- a/panels/user-accounts/cc-crop-area.h
+++ b/panels/user-accounts/cc-crop-area.h
@@ -17,7 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
+#ifndef _CC_CROP_AREA_H_
+#define _CC_CROP_AREA_H_
#include <glib-object.h>
#include <gtk/gtk.h>
@@ -25,16 +26,17 @@
G_BEGIN_DECLS
#define CC_TYPE_CROP_AREA (cc_crop_area_get_type ())
-G_DECLARE_FINAL_TYPE (CcCropArea, cc_crop_area, CC, CROP_AREA, GtkDrawingArea)
+G_DECLARE_FINAL_TYPE (CcCropArea, cc_crop_area, CC, CROP_AREA, GtkWidget)
-GtkWidget *cc_crop_area_new (void);
-GdkPixbuf *cc_crop_area_get_picture (CcCropArea *area);
-void cc_crop_area_set_picture (CcCropArea *area,
- GdkPixbuf *pixbuf);
-void cc_crop_area_set_min_size (CcCropArea *area,
- gint width,
- gint height);
-void cc_crop_area_set_constrain_aspect (CcCropArea *area,
- gboolean constrain);
+GtkWidget * cc_crop_area_new (void);
+GdkPaintable * cc_crop_area_get_paintable (CcCropArea *area);
+void cc_crop_area_set_paintable (CcCropArea *area,
+ GdkPaintable *paintable);
+void cc_crop_area_set_min_size (CcCropArea *area,
+ int width,
+ int height);
+GdkPixbuf * cc_crop_area_create_pixbuf (CcCropArea *area);
G_END_DECLS
+
+#endif /* _CC_CROP_AREA_H_ */
diff --git a/panels/user-accounts/cc-fingerprint-dialog.c b/panels/user-accounts/cc-fingerprint-dialog.c
index 44fd07460..e757a5670 100644
--- a/panels/user-accounts/cc-fingerprint-dialog.c
+++ b/panels/user-accounts/cc-fingerprint-dialog.c
@@ -60,7 +60,7 @@ struct _CcFingerprintDialog
GtkButton *cancel_button;
GtkButton *delete_prints_button;
GtkButton *done_button;
- GtkContainer *add_print_popover_box;
+ GtkBox *add_print_popover_box;
GtkEntry *enroll_print_entry;
GtkFlowBox *prints_gallery;
GtkHeaderBar *titlebar;
@@ -352,9 +352,11 @@ notify_error (CcFingerprintDialog *self,
static gboolean
fingerprint_icon_draw (GtkWidget *widget,
- cairo_t *cr,
gdouble *progress_data)
{
+ GtkAllocation allocation;
+ g_autoptr (GtkSnapshot) snapshot = NULL;
+ cairo_t *cr;
gdouble progress = 0.0f;
if (progress_data)
@@ -363,15 +365,18 @@ fingerprint_icon_draw (GtkWidget *widget,
if (G_APPROX_VALUE (progress, 0.f, FLT_EPSILON) || progress > 1)
return FALSE;
- GTK_WIDGET_GET_CLASS (widget)->draw (widget, cr);
+ snapshot = gtk_snapshot_new ();
+ gtk_widget_snapshot_child (gtk_widget_get_parent (widget), widget, snapshot);
+ GTK_WIDGET_GET_CLASS (widget)->snapshot (widget, snapshot);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, allocation.width, allocation.height));
if (progress > 0)
{
- g_autoptr(GdkRGBA) outline_color = NULL;
+ GdkRGBA outline_color;
GtkStyleContext *context;
- GtkStateFlags state;
- int outline_width;
- int outline_offset;
+ GtkBorder outline_width, outline_offset;
int width;
int height;
int radius;
@@ -380,25 +385,22 @@ fingerprint_icon_draw (GtkWidget *widget,
context = gtk_widget_get_style_context (widget);
gtk_style_context_save (context);
- state = gtk_style_context_get_state (context);
-
gtk_style_context_add_class (context, "progress");
- gtk_style_context_get (context, state,
- "outline-width", &outline_width,
- "outline-offset", &outline_offset,
- "outline-color", &outline_color,
- NULL);
+
+ gtk_style_context_get_margin (context, &outline_width);
+ gtk_style_context_get_border (context, &outline_offset);
+ gtk_style_context_get_color (context, &outline_color);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
- radius = MIN (width / 2, height / 2) + outline_offset;
- delta = radius - outline_width / 2;
+ radius = MIN (width / 2, height / 2) + outline_offset.left;
+ delta = radius - outline_width.left / 2;
cairo_arc (cr, width / 2., height / 2., delta,
1.5 * G_PI, (1.5 + progress * 2) * G_PI);
- gdk_cairo_set_source_rgba (cr, outline_color);
+ gdk_cairo_set_source_rgba (cr, &outline_color);
- cairo_set_line_width (cr, MIN (outline_width, radius));
+ cairo_set_line_width (cr, MIN (outline_width.left, radius));
cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
cairo_stroke (cr);
@@ -428,7 +430,7 @@ fingerprint_icon_new (const char *icon_name,
gtk_widget_set_name (box, "fingerprint-box");
gtk_widget_set_hexpand (box, TRUE);
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DND);
+ image = gtk_image_new_from_icon_name (icon_name);
if (icon_widget_type == GTK_TYPE_IMAGE)
icon_widget = image;
@@ -436,13 +438,14 @@ fingerprint_icon_new (const char *icon_name,
icon_widget = g_object_new (icon_widget_type, NULL);
if (progress_data)
- g_signal_connect (image, "draw", G_CALLBACK (fingerprint_icon_draw),
- progress_data);
+ {
+ g_signal_connect (image, "realize", G_CALLBACK (fingerprint_icon_draw),
+ progress_data);
+ }
if (g_type_is_a (icon_widget_type, GTK_TYPE_BUTTON))
{
- gtk_button_set_image (GTK_BUTTON (icon_widget), image);
- gtk_button_set_relief (GTK_BUTTON (icon_widget), GTK_RELIEF_NONE);
+ gtk_menu_button_set_child (GTK_MENU_BUTTON (icon_widget), image);
gtk_widget_set_can_focus (icon_widget, FALSE);
}
@@ -450,13 +453,13 @@ fingerprint_icon_new (const char *icon_name,
gtk_widget_set_valign (icon_widget, GTK_ALIGN_CENTER);
gtk_widget_set_name (icon_widget, "fingerprint-image");
- gtk_container_add (GTK_CONTAINER (box), icon_widget);
+ gtk_box_append (GTK_BOX (box), icon_widget);
context = gtk_widget_get_style_context (icon_widget);
gtk_style_context_add_class (context, "fingerprint-image");
label = gtk_label_new_with_mnemonic (label_text);
- gtk_container_add (GTK_CONTAINER (box), label);
+ gtk_box_append (GTK_BOX (box), label);
context = gtk_widget_get_style_context (box);
gtk_style_context_add_class (context, "fingerprint-icon");
@@ -486,11 +489,11 @@ fingerprint_menu_button (const char *icon_name,
gtk_widget_set_focus_on_click (flowbox_child, FALSE);
gtk_widget_set_name (flowbox_child, "fingerprint-flowbox");
- gtk_container_add (GTK_CONTAINER (flowbox_child), box);
+ gtk_widget_insert_after (flowbox_child, box, NULL);
g_object_set_data (G_OBJECT (flowbox_child), "button", button);
g_object_set_data (G_OBJECT (flowbox_child), "icon",
- gtk_button_get_image (GTK_BUTTON (button)));
+ GTK_IMAGE (gtk_menu_button_get_child (GTK_MENU_BUTTON (button))));
g_object_set_data (G_OBJECT (flowbox_child), "label", label);
g_object_set_data (G_OBJECT (button), "flowbox-child", flowbox_child);
@@ -518,6 +521,24 @@ prints_visibility_filter (GtkFlowBoxChild *child,
return g_strv_contains ((const gchar **) self->enrolled_fingers, finger_id);
}
+static GList *
+get_container_children (GtkWidget *container)
+{
+ GtkWidget *child;
+ GList *list = NULL;
+
+ child = gtk_widget_get_first_child (container);
+ while (child) {
+ GtkWidget *next = gtk_widget_get_next_sibling (child);
+
+ list = g_list_append (list, child);
+
+ child = next;
+ }
+
+ return list;
+}
+
static void
update_prints_to_add_visibility (CcFingerprintDialog *self)
{
@@ -525,7 +546,7 @@ update_prints_to_add_visibility (CcFingerprintDialog *self)
GList *l;
guint i;
- print_buttons = gtk_container_get_children (self->add_print_popover_box);
+ print_buttons = get_container_children (GTK_WIDGET (self->add_print_popover_box));
for (i = 0, l = print_buttons; i < N_VALID_FINGERS && l; ++i, l = l->next)
{
@@ -708,7 +729,7 @@ have_multiple_devices (CcFingerprintDialog *self)
{
g_autoptr(GList) devices_rows = NULL;
- devices_rows = gtk_container_get_children (GTK_CONTAINER (self->devices_list));
+ devices_rows = get_container_children (GTK_WIDGET (self->devices_list));
return devices_rows && devices_rows->next;
}
@@ -744,7 +765,7 @@ set_enroll_result_message (CcFingerprintDialog *self,
gtk_style_context_add_class (style_context, ENROLL_STATE_CLASSES[enroll_state]);
- gtk_image_set_from_icon_name (self->enroll_result_image, icon_name, GTK_ICON_SIZE_DND);
+ gtk_image_set_from_icon_name (self->enroll_result_image, icon_name);
gtk_label_set_label (self->enroll_result_message, message);
}
@@ -1000,7 +1021,7 @@ enroll_finger (CcFingerprintDialog *self,
set_enroll_result_message (self, ENROLL_STATE_NORMAL, NULL);
gtk_stack_set_visible_child (self->stack, self->enrollment_view);
gtk_label_set_label (self->enroll_message, enroll_message);
- gtk_entry_set_text (self->enroll_print_entry, finger_name);
+ gtk_editable_set_text (GTK_EDITABLE (self->enroll_print_entry), finger_name);
cc_fprintd_device_call_enroll_start (self->device, finger_id, self->cancellable,
enroll_start_cb, self);
@@ -1019,12 +1040,10 @@ populate_enrollment_view (CcFingerprintDialog *self)
(GtkWidget **) &self->enroll_result_image,
(GtkWidget **) &self->enroll_result_message);
- gtk_container_add (GTK_CONTAINER (self->enroll_print_bin), self->enroll_result_icon);
+ gtk_box_prepend (GTK_BOX (self->enroll_print_bin), self->enroll_result_icon);
style_context = gtk_widget_get_style_context (self->enroll_result_icon);
gtk_style_context_add_class (style_context, "enroll-status");
-
- gtk_widget_show_all (self->enroll_print_bin);
}
static void
@@ -1033,8 +1052,15 @@ reenroll_finger_cb (CcFingerprintDialog *self)
GtkWidget *button;
GtkWidget *flowbox_child;
const char *finger_id;
+ GdkRectangle rect;
- button = gtk_popover_get_relative_to (GTK_POPOVER (self->print_popover));
+ if (!gtk_popover_get_pointing_to (GTK_POPOVER (self->print_popover), &rect))
+ return;
+
+ button = GTK_WIDGET (gtk_flow_box_get_child_at_pos (self->prints_gallery, rect.x, rect. y));
+ if (button == NULL)
+ return;
+
flowbox_child = g_object_get_data (G_OBJECT (button), "flowbox-child");
finger_id = g_object_get_data (G_OBJECT (flowbox_child), "finger-id");
@@ -1049,12 +1075,12 @@ on_print_activated_cb (GtkFlowBox *flowbox,
GtkWidget *selected_button;
selected_button = g_object_get_data (G_OBJECT (child), "button");
- gtk_button_clicked (GTK_BUTTON (selected_button));
+ g_signal_emit_by_name (GTK_MENU_BUTTON (selected_button), "activate");
}
static void
on_enroll_cb (CcFingerprintDialog *self,
- GtkModelButton *button)
+ GtkMenuButton *button)
{
const char *finger_id;
@@ -1070,15 +1096,18 @@ populate_add_print_popover (CcFingerprintDialog *self)
for (i = 0; i < N_VALID_FINGERS; ++i)
{
GtkWidget *finger_item;
+ GtkGesture *gesture;
- finger_item = gtk_model_button_new ();
- gtk_button_set_label (GTK_BUTTON (finger_item), get_finger_name (FINGER_IDS[i]));
- gtk_button_set_use_underline (GTK_BUTTON (finger_item), TRUE);
+ finger_item = gtk_menu_button_new ();
+ gtk_menu_button_set_label (GTK_MENU_BUTTON (finger_item), get_finger_name (FINGER_IDS[i]));
+ gtk_menu_button_set_use_underline (GTK_MENU_BUTTON (finger_item), TRUE);
g_object_set_data (G_OBJECT (finger_item), "finger-id", (gpointer) FINGER_IDS[i]);
- gtk_container_add (self->add_print_popover_box, finger_item);
+ gtk_box_prepend (GTK_BOX (self->add_print_popover_box), finger_item);
- g_signal_connect_object (finger_item, "clicked", G_CALLBACK (on_enroll_cb),
+ gesture = gtk_gesture_click_new ();
+ g_signal_connect_object (gesture, "pressed", G_CALLBACK (on_enroll_cb),
self, G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (finger_item, GTK_EVENT_CONTROLLER (gesture));
}
}
@@ -1104,8 +1133,8 @@ populate_prints_gallery (CcFingerprintDialog *self)
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button),
GTK_WIDGET (self->print_popover));
/* Move the popover on click, so we can just reuse the same instance */
- g_signal_connect_object (button, "clicked",
- G_CALLBACK (gtk_popover_set_relative_to),
+ g_signal_connect_object (button, "activate",
+ G_CALLBACK (gtk_popover_set_pointing_to),
self->print_popover, G_CONNECT_SWAPPED);
g_object_set_data (G_OBJECT (flowbox_child), "finger-id",
@@ -1129,7 +1158,6 @@ populate_prints_gallery (CcFingerprintDialog *self)
gtk_flow_box_insert (self->prints_gallery, self->add_print_icon, -1);
gtk_flow_box_set_max_children_per_line (self->prints_gallery, 1);
- gtk_widget_show_all (GTK_WIDGET (self->prints_gallery));
gtk_flow_box_set_filter_func (self->prints_gallery, prints_visibility_filter,
self, NULL);
@@ -1314,7 +1342,7 @@ on_stack_child_changed (CcFingerprintDialog *self)
gtk_widget_hide (GTK_WIDGET (self->cancel_button));
gtk_widget_hide (GTK_WIDGET (self->done_button));
- gtk_header_bar_set_show_close_button (self->titlebar, TRUE);
+ //FIXME gtk_header_bar_set_show_close_button (self->titlebar, TRUE);
gtk_flow_box_invalidate_filter (self->prints_gallery);
if (visible_child == self->prints_manager)
@@ -1329,7 +1357,7 @@ on_stack_child_changed (CcFingerprintDialog *self)
}
else if (visible_child == self->enrollment_view)
{
- gtk_header_bar_set_show_close_button (self->titlebar, FALSE);
+ //FIXME gtk_header_bar_set_show_close_button (self->titlebar, FALSE);
gtk_widget_show (GTK_WIDGET (self->cancel_button));
gtk_widget_set_sensitive (GTK_WIDGET (self->cancel_button), TRUE);
@@ -1356,9 +1384,9 @@ cc_fingerprint_dialog_init (CcFingerprintDialog *self)
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider,
"/org/gnome/control-center/user-accounts/cc-fingerprint-dialog.css");
- gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
on_stack_child_changed (self);
g_signal_connect_object (self->stack, "notify::visible-child",
@@ -1525,7 +1553,7 @@ static void
fingerprint_dialog_delete_cb (CcFingerprintDialog *self)
{
cc_fingerprint_manager_update_state (self->manager, NULL, NULL);
- gtk_widget_destroy (GTK_WIDGET (self));
+ gtk_window_destroy (GTK_WINDOW (self));
}
static void
diff --git a/panels/user-accounts/cc-fingerprint-dialog.ui b/panels/user-accounts/cc-fingerprint-dialog.ui
index 2613d5edc..17b21d4ad 100644
--- a/panels/user-accounts/cc-fingerprint-dialog.ui
+++ b/panels/user-accounts/cc-fingerprint-dialog.ui
@@ -6,17 +6,12 @@
</style>
<property name="name">fingerprint-dialog</property>
<property name="title" translatable="yes">Fingerprint Manager</property>
- <property name="type-hint">dialog</property>
- <property name="window-position">center-on-parent</property>
<property name="destroy-with-parent">True</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<property name="modal">True</property>
- <signal name="delete-event" handler="fingerprint_dialog_delete_cb"/>
<child type="titlebar">
<object class="GtkHeaderBar" id="titlebar">
- <property name="visible">True</property>
- <property name="show-close-button">True</property>
<child type="title">
<object class="GtkLabel" id="title">
<property name="visible">True</property>
@@ -28,7 +23,6 @@
</child>
<child>
<object class="GtkButton" id="cancel_button">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
@@ -39,7 +33,6 @@
</child>
<child>
<object class="GtkButton" id="back_button">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
@@ -48,14 +41,8 @@
<style>
<class name="image-button"/>
</style>
- <child internal-child="accessible">
- <object class="AtkObject" id="a11y-back">
- <property name="accessible-name" translatable="yes">Back</property>
- </object>
- </child>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
<property name="icon_size">1</property>
@@ -67,8 +54,6 @@
<child>
<object class="GtkButton" id="done_button">
<property name="use-underline">True</property>
- <property name="can-default">True</property>
- <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="label" translatable="yes">_Done</property>
<signal name="clicked" handler="done_button_clicked_cb" object="CcFingerprintDialog"
swapped="yes" />
@@ -76,45 +61,28 @@
<class name="suggested-action"/>
</style>
</object>
- <packing>
- <property name="pack-type">end</property>
- </packing>
</child>
<child>
<object class="GtkSpinner" id="spinner">
- <property name="visible">True</property>
- <property name="active">False</property>
<property name="can_focus">False</property>
</object>
- <packing>
- <property name="pack-type">end</property>
- </packing>
</child>
</object>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="delete_confirmation_infobar">
<property name="visible">False</property>
- <property name="can_focus">False</property>
- <property name="border_width">0</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
+ <child>
+ <object class="GtkBox">
<child>
<object class="GtkButton">
<signal name="clicked" handler="cancel_deletion_button_clicked_cb"
object="CcFingerprintDialog" swapped="yes"/>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="label" translatable="yes">_No</property>
<property name="use-underline">True</property>
</object>
@@ -122,8 +90,6 @@
<child>
<object class="GtkButton">
<signal name="clicked" handler="confirm_deletion_button_clicked_cb"
object="CcFingerprintDialog" swapped="yes"/>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">_Yes</property>
<property name="use-underline">True</property>
@@ -133,21 +99,14 @@
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
</child>
- <child internal-child="content_area">
+ <child>
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="spacing">16</property>
<property name="margin-start">12</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
@@ -157,45 +116,26 @@
<attribute name="weight" value="bold"/>
</attributes>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
- <object class="GtkInfoBar" id="error_infobar">
+ <object class="gtkInfoBar" id="error_infobar">
<property name="name">error_infobar</property>
<property name="visible">False</property>
<property name="can_focus">False</property>
- <property name="border_width">0</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
<style>
<class name="error"/>
</style>
- <child internal-child="content_area">
+ <child>
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="spacing">16</property>
<child>
<object class="GtkLabel" id="infobar_error">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">False</property>
@@ -209,7 +149,6 @@
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="propagate-natural-width">True</property>
@@ -218,7 +157,6 @@
<child>
<object class="GtkStack" id="stack">
- <property name="visible">True</property>
<property name="transition_duration">300</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
@@ -229,7 +167,7 @@
<child>
<object class="GtkBox" id="no_devices_found">
- <property name="visible">True</property>
+ <property name="name" translatable="yes">No fingerprint device</property>
<property name="orientation">vertical</property>
<property name="valign">center</property>
<property name="spacing">12</property>
@@ -238,14 +176,12 @@
</style>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon_name">fingerprint-detection-symbolic</property>
<property name="pixel_size">192</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="label" translatable="yes" comments="Translators: This is the empty
state page label which states that there are no devices ready.">No Fingerprint device</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -255,19 +191,15 @@
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="label" translatable="yes">Ensure the device is properly
connected.</property>
</object>
</child>
</object>
- <packing>
- <property name="name" translatable="yes">No fingerprint device</property>
- </packing>
</child>
<child>
<object class="GtkBox" id="device_selector">
- <property name="visible">True</property>
+ <property name="name" translatable="yes">Fingerprint Device</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
@@ -276,7 +208,6 @@
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="label" translatable="yes">Choose the fingerprint device you want to
configure</property>
<property name="halign">start</property>
<attributes>
@@ -287,7 +218,6 @@
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">True</property>
@@ -305,14 +235,11 @@
</object>
</child>
</object>
- <packing>
- <property name="name" translatable="yes">Fingerprint Device</property>
- </packing>
</child>
<child>
<object class="GtkBox" id="prints_manager">
- <property name="visible">True</property>
+ <property name="name" translatable="yes">Fingerprint Login</property>
<property name="orientation">vertical</property>
<property name="valign">fill</property>
<property name="spacing">12</property>
@@ -327,8 +254,6 @@
<style>
<class name="prints-gallery" />
</style>
- <property name="visible">True</property>
- <property name="margin">12</property>
<property name="column-spacing">12</property>
<property name="row-spacing">12</property>
<property name="homogeneous">True</property>
@@ -346,7 +271,6 @@
<child>
<object class="GtkButton" id="delete_prints_button">
<property name="visible">False</property>
- <property name="can_focus">True</property>
<property name="halign">end</property>
<property name="use-underline">True</property>
<property name="label" translatable="yes">_Delete Fingerprints</property>
@@ -359,14 +283,11 @@
</object>
</child>
</object>
- <packing>
- <property name="name" translatable="yes">Fingerprint Login</property>
- </packing>
</child>
<child>
<object class="GtkBox" id="enrollment_view">
- <property name="visible">True</property>
+ <property name="name" translatable="yes">Fingerprint Enroll</property>
<property name="orientation">vertical</property>
<property name="valign">fill</property>
<property name="spacing">12</property>
@@ -375,14 +296,11 @@
</style>
<child>
<object class="GtkLabel" id="enroll_message">
- <property name="visible">True</property>
<property name="wrap">True</property>
</object>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="margin">12</property>
<property name="spacing">12</property>
<property name="halign">fill</property>
<property name="valign">center</property>
@@ -408,9 +326,6 @@
</object>
</child>
</object>
- <packing>
- <property name="name" translatable="yes">Fingerprint Enroll</property>
- </packing>
</child>
</object>
@@ -426,20 +341,15 @@
<property name="position">bottom</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin">12</property>
<property name="spacing">6</property>
<property name="orientation">vertical</property>
<child>
- <object class="GtkModelButton">
+ <object class="GtkMenuButton">
<property name="label" translatable="yes">_Re-enroll this finger…</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
- <property name="xalign">0.0</property>
- <signal name="clicked" handler="reenroll_finger_cb" object="CcFingerprintDialog" swapped="yes"/>
+ <signal name="activate" handler="reenroll_finger_cb" object="CcFingerprintDialog" swapped="yes"/>
</object>
</child>
</object>
@@ -450,9 +360,7 @@
<property name="position">bottom</property>
<child>
<object class="GtkBox" id="add_print_popover_box">
- <property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin">12</property>
<property name="spacing">6</property>
<property name="orientation">vertical</property>
</object>
diff --git a/panels/user-accounts/cc-login-history-dialog.c b/panels/user-accounts/cc-login-history-dialog.c
index 6670f757a..fcb745711 100644
--- a/panels/user-accounts/cc-login-history-dialog.c
+++ b/panels/user-accounts/cc-login-history-dialog.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <adwaita.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -40,6 +41,7 @@ struct _CcLoginHistoryDialog
GtkDialog parent_instance;
GtkHeaderBar *header_bar;
+ GtkLabel *title_label;
GtkListBox *history_box;
GtkButton *next_button;
GtkButton *previous_button;
@@ -96,18 +98,22 @@ show_week_label (CcLoginHistoryDialog *self)
label = g_strdup_printf(C_("login history week label", "%s — %s"), from, to);
}
- gtk_header_bar_set_subtitle (self->header_bar, label);
+ gtk_label_set_label (self->title_label, label);
}
static void
clear_history (CcLoginHistoryDialog *self)
{
- g_autoptr(GList) list = NULL;
- GList *it;
+ GtkWidget *child;
- list = gtk_container_get_children (GTK_CONTAINER (self->history_box));
- for (it = list; it != NULL; it = it->next) {
- gtk_container_remove (GTK_CONTAINER (self->history_box), GTK_WIDGET (it->data));
+ child = gtk_widget_get_first_child (GTK_WIDGET (self->history_box));
+ while (child) {
+ GtkWidget *next = gtk_widget_get_next_sibling (child);
+
+ if (ADW_ACTION_ROW (child))
+ gtk_list_box_remove (self->history_box, GTK_WIDGET (child));
+
+ child = next;
}
}
@@ -165,7 +171,7 @@ add_record (CcLoginHistoryDialog *self, GDateTime *datetime, gchar *record_strin
g_autofree gchar *date = NULL;
g_autofree gchar *time = NULL;
g_autofree gchar *str = NULL;
- GtkWidget *label, *row;
+ GtkWidget *row;
date = cc_util_get_smart_date (datetime);
/* Translators: This is a time format string in the style of "22:58".
@@ -175,20 +181,9 @@ add_record (CcLoginHistoryDialog *self, GDateTime *datetime, gchar *record_strin
The first %s is a date, and the second %s a time. */
str = g_strdup_printf(C_("login date-time", "%s, %s"), date, time);
- row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_widget_show (row);
- gtk_box_set_homogeneous (GTK_BOX (row), TRUE);
- gtk_container_set_border_width (GTK_CONTAINER (row), 6);
-
- label = gtk_label_new (record_string);
- gtk_widget_show (label);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_box_pack_start (GTK_BOX (row), label, TRUE, TRUE, 0);
-
- label = gtk_label_new (str);
- gtk_widget_show (label);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_box_pack_start (GTK_BOX (row), label, TRUE, TRUE, 0);
+ row = adw_action_row_new ();
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), record_string);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (row), str);
gtk_list_box_insert (self->history_box, row, line);
}
@@ -297,6 +292,7 @@ cc_login_history_dialog_class_init (CcLoginHistoryDialogClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/user-accounts/cc-login-history-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, header_bar);
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, title_label);
gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, history_box);
gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, next_button);
gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, previous_button);
@@ -342,7 +338,7 @@ cc_login_history_dialog_new (ActUser *user)
The %s is the user real name. */
title = g_strdup_printf (_("%s — Account Activity"),
act_user_get_real_name (self->user));
- gtk_header_bar_set_title (self->header_bar, title);
+ gtk_label_set_label (self->title_label, title);
show_week (self);
diff --git a/panels/user-accounts/cc-login-history-dialog.ui b/panels/user-accounts/cc-login-history-dialog.ui
index 95b24e735..e05e4f445 100644
--- a/panels/user-accounts/cc-login-history-dialog.ui
+++ b/panels/user-accounts/cc-login-history-dialog.ui
@@ -8,19 +8,19 @@
<property name="icon_name">system-users</property>
<child internal-child="headerbar">
<object class="GtkHeaderBar" id="header_bar">
- <property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="show_close_button">True</property>
+ <child type="title">
+ <object class="GtkLabel" id="title_label">
+ </object>
+ </child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="can_focus">True</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="previous_button">
- <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
@@ -30,20 +30,15 @@
</style>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
<property name="pixel_size">16</property>
</object>
</child>
</object>
- <packing>
- <property name="pack_type">start</property>
- </packing>
</child>
<child>
<object class="GtkButton" id="next_button">
- <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
@@ -53,63 +48,45 @@
</style>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-next-symbolic</property>
<property name="pixel_size">16</property>
</object>
</child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
</object>
</child>
- <child internal-child="vbox">
+ <child>
<object class="GtkBox">
- <property name="border_width">0</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="width_request">350</property>
<property name="height_request">300</property>
- <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
- <property name="shadow_type">none</property>
<child>
<object class="GtkListBox" id="history_box">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
- <property name="border_width">12</property>
- <property name="selection_mode">none</property>
+ <style>
+ <class name="content"/>
+ </style>
</object>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
diff --git a/panels/user-accounts/cc-password-dialog.c b/panels/user-accounts/cc-password-dialog.c
index b199999c0..5380936f0 100644
--- a/panels/user-accounts/cc-password-dialog.c
+++ b/panels/user-accounts/cc-password-dialog.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <adwaita.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -40,19 +41,25 @@
struct _CcPasswordDialog
{
- GtkDialog parent_instance;
+ AdwPreferencesWindow parent_instance;
- GtkBox *action_radio_box;
- GtkRadioButton *action_now_radio;
- GtkRadioButton *action_login_radio;
+ GtkCheckButton *action_login_radio;
+ GtkCheckButton *action_now_radio;
+ GtkButton *generate_password_button;
GtkButton *ok_button;
- GtkLabel *old_password_label;
- GtkEntry *old_password_entry;
- GtkEntry *password_entry;
+ AdwActionRow *old_password_row;
+ GtkPasswordEntry *old_password_entry;
+ GtkImage *old_password_status_icon;
+ AdwPreferencesGroup *password_group;
+ AdwPreferencesGroup *password_on_next_login_group;
+ GtkPasswordEntry *password_entry;
+ GtkImage *password_entry_status_icon;
GtkLabel *password_hint_label;
+ AdwActionRow *password_row;
GtkLevelBar *strength_indicator;
- GtkEntry *verify_entry;
- GtkLabel *verify_hint_label;
+ GtkPasswordEntry *verify_entry;
+ AdwActionRow *verify_password_row;
+ GtkImage *verify_password_status_icon;
gint password_entry_timeout_id;
@@ -65,7 +72,7 @@ struct _CcPasswordDialog
PasswdHandler *passwd_handler;
};
-G_DEFINE_TYPE (CcPasswordDialog, cc_password_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE (CcPasswordDialog, cc_password_dialog, ADW_TYPE_PREFERENCES_WINDOW)
static gint
update_password_strength (CcPasswordDialog *self)
@@ -77,8 +84,8 @@ update_password_strength (CcPasswordDialog *self)
const gchar *hint;
const gchar *verify;
- password = gtk_entry_get_text (self->password_entry);
- old_password = gtk_entry_get_text (self->old_password_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->password_entry));
+ old_password = gtk_editable_get_text (GTK_EDITABLE (self->old_password_entry));
username = act_user_get_user_name (self->user);
pw_strength (password, old_password, username,
@@ -87,17 +94,19 @@ update_password_strength (CcPasswordDialog *self)
gtk_level_bar_set_value (self->strength_indicator, strength_level);
gtk_label_set_label (self->password_hint_label, hint);
+ gtk_widget_show (GTK_WIDGET (self->password_entry_status_icon));
if (strength_level > 1) {
- set_entry_validation_checkmark (self->password_entry);
+ gtk_image_set_from_icon_name (self->password_entry_status_icon, "emblem-ok-symbolic");
} else if (strlen (password) == 0) {
- set_entry_generation_icon (self->password_entry);
+ //gtk_widget_hide (GTK_WIDGET (self->password_entry_status_icon));
+ //gtk_widget_show (GTK_WIDGET (self->generate_password_button));
} else {
- clear_entry_validation_error (self->password_entry);
+ gtk_image_set_from_icon_name (self->password_entry_status_icon, "dialog-warning-symbolic");
}
- verify = gtk_entry_get_text (self->verify_entry);
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->verify_entry));
if (strlen (verify) == 0) {
- gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), strength_level > 1);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->verify_password_row), strength_level > 1);
}
return strength_level;
@@ -113,7 +122,6 @@ password_changed_cb (PasswdHandler *handler,
const gchar *secondary_text;
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (self)), NULL);
if (!error) {
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
@@ -124,16 +132,16 @@ password_changed_cb (PasswdHandler *handler,
primary_text = error->message;
secondary_text = _("Please choose another password.");
- gtk_entry_set_text (self->password_entry, "");
+ gtk_editable_set_text (GTK_EDITABLE (self->password_entry), "");
gtk_widget_grab_focus (GTK_WIDGET (self->password_entry));
- gtk_entry_set_text (self->verify_entry, "");
+ gtk_editable_set_text (GTK_EDITABLE (self->verify_entry), "");
}
else if (error->code == PASSWD_ERROR_AUTH_FAILED) {
primary_text = error->message;
secondary_text = _("Please type your current password again.");
- gtk_entry_set_text (self->old_password_entry, "");
+ gtk_editable_set_text (GTK_EDITABLE (self->old_password_entry), "");
gtk_widget_grab_focus (GTK_WIDGET (self->old_password_entry));
}
else {
@@ -148,8 +156,7 @@ password_changed_cb (PasswdHandler *handler,
"%s", primary_text);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary_text);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
@@ -157,14 +164,11 @@ ok_button_clicked_cb (CcPasswordDialog *self)
{
const gchar *password;
- password = gtk_entry_get_text (self->password_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->password_entry));
switch (self->password_mode) {
case ACT_USER_PASSWORD_MODE_REGULAR:
if (act_user_get_uid (self->user) == getuid ()) {
- GdkDisplay *display;
- g_autoptr(GdkCursor) cursor = NULL;
-
/* When setting a password for the current user,
* use passwd directly, to preserve the audit trail
* and to e.g. update the keyring password.
@@ -172,10 +176,6 @@ ok_button_clicked_cb (CcPasswordDialog *self)
passwd_change_password (self->passwd_handler, password,
(PasswdCallback) password_changed_cb, self);
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- display = gtk_widget_get_display (GTK_WIDGET (self));
- cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (self)), cursor);
- gdk_display_flush (display);
return;
}
@@ -191,8 +191,6 @@ ok_button_clicked_cb (CcPasswordDialog *self)
default:
g_assert_not_reached ();
}
-
- gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
}
static void
@@ -202,8 +200,8 @@ update_sensitivity (CcPasswordDialog *self)
gboolean can_change;
int strength;
- password = gtk_entry_get_text (self->password_entry);
- verify = gtk_entry_get_text (self->verify_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->password_entry));
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->verify_entry));
if (self->password_mode == ACT_USER_PASSWORD_MODE_REGULAR) {
strength = update_password_strength (self);
@@ -224,12 +222,11 @@ mode_change (CcPasswordDialog *self,
gboolean active;
active = (mode == ACT_USER_PASSWORD_MODE_REGULAR);
- gtk_widget_set_sensitive (GTK_WIDGET (self->password_entry), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->old_password_entry), active);
- gtk_widget_set_sensitive (GTK_WIDGET (self->password_hint_label), active);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_now_radio), active);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->action_login_radio), !active);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->password_row), active);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->verify_password_row), active);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->old_password_row), active);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (self->action_now_radio), active);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (self->action_login_radio), !active);
self->password_mode = mode;
update_sensitivity (self);
@@ -241,7 +238,7 @@ action_now_radio_toggled_cb (CcPasswordDialog *self)
gint active;
ActUserPasswordMode mode;
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->action_now_radio));
+ active = gtk_check_button_get_active (GTK_CHECK_BUTTON (self->action_now_radio));
mode = active ? ACT_USER_PASSWORD_MODE_REGULAR : ACT_USER_PASSWORD_MODE_SET_AT_LOGIN;
mode_change (self, mode);
}
@@ -253,18 +250,18 @@ update_password_match (CcPasswordDialog *self)
const gchar *verify;
const gchar *message = "";
- password = gtk_entry_get_text (self->password_entry);
- verify = gtk_entry_get_text (self->verify_entry);
+ password = gtk_editable_get_text (GTK_EDITABLE (self->password_entry));
+ verify = gtk_editable_get_text (GTK_EDITABLE (self->verify_entry));
if (strlen (verify) > 0) {
if (strcmp (password, verify) != 0) {
message = _("The passwords do not match.");
}
else {
- set_entry_validation_checkmark (self->verify_entry);
+ gtk_image_set_from_icon_name (self->verify_password_status_icon,
"emblem-ok-symbolic");
}
}
- gtk_label_set_label (self->verify_hint_label, message);
+ adw_action_row_set_subtitle (self->verify_password_row, message);
}
static gboolean
@@ -282,8 +279,6 @@ password_entry_timeout (CcPasswordDialog *self)
static void
recheck_password_match (CcPasswordDialog *self)
{
- const gchar *password;
-
if (self->password_entry_timeout_id != 0) {
g_source_remove (self->password_entry_timeout_id);
self->password_entry_timeout_id = 0;
@@ -291,11 +286,6 @@ recheck_password_match (CcPasswordDialog *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), FALSE);
- password = gtk_entry_get_text (self->password_entry);
- if (strlen (password) == 0) {
- gtk_entry_set_visibility (self->password_entry, FALSE);
- }
-
self->password_entry_timeout_id = g_timeout_add (PASSWORD_CHECK_TIMEOUT,
(GSourceFunc) password_entry_timeout,
self);
@@ -304,15 +294,15 @@ recheck_password_match (CcPasswordDialog *self)
static void
password_entry_changed (CcPasswordDialog *self)
{
- clear_entry_validation_error (self->password_entry);
- clear_entry_validation_error (self->verify_entry);
+ gtk_image_set_from_icon_name (self->password_entry_status_icon, "dialog-warning-symbolic");
+ gtk_image_set_from_icon_name (self->verify_password_status_icon, "dialog-warning-symbolic");
recheck_password_match (self);
}
static void
verify_entry_changed (CcPasswordDialog *self)
{
- clear_entry_validation_error (self->verify_entry);
+ gtk_image_set_from_icon_name (self->verify_password_status_icon, "dialog-warning-symbolic");
recheck_password_match (self);
}
@@ -330,18 +320,20 @@ password_entry_focus_out_cb (CcPasswordDialog *self)
return FALSE;
}
+
static gboolean
-password_entry_key_press_cb (CcPasswordDialog *self,
- GdkEvent *event)
+password_entry_key_press_cb (GtkEventControllerKey *controller,
+ guint keyval,
+ guint keycode,
+ GdkModifierType state,
+ CcPasswordDialog *self)
{
- GdkEventKey *key = (GdkEventKey *)event;
-
if (self->password_entry_timeout_id != 0) {
g_source_remove (self->password_entry_timeout_id);
self->password_entry_timeout_id = 0;
}
- if (key->keyval == GDK_KEY_Tab)
+ if (keyval == GDK_KEY_Tab)
password_entry_timeout (self);
return FALSE;
@@ -357,7 +349,7 @@ auth_cb (PasswdHandler *handler,
}
else {
self->old_password_ok = TRUE;
- set_entry_validation_checkmark (self->old_password_entry);
+ gtk_image_set_from_icon_name (self->old_password_status_icon, "emblem-ok-symbolic");
}
update_sensitivity (self);
@@ -370,7 +362,7 @@ old_password_entry_timeout (CcPasswordDialog *self)
update_sensitivity (self);
- text = gtk_entry_get_text (self->old_password_entry);
+ text = gtk_editable_get_text (GTK_EDITABLE (self->old_password_entry));
if (!self->old_password_ok) {
passwd_authenticate (self->passwd_handler, text, (PasswdCallback)auth_cb, self);
}
@@ -402,7 +394,7 @@ old_password_entry_changed (CcPasswordDialog *self)
self->old_password_entry_timeout_id = 0;
}
- clear_entry_validation_error (self->old_password_entry);
+ gtk_image_set_from_icon_name (self->old_password_status_icon, "dialog-warning-symbolic");
gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button), FALSE);
self->old_password_ok = FALSE;
@@ -412,7 +404,7 @@ old_password_entry_changed (CcPasswordDialog *self)
}
static void
-password_entry_icon_press_cb (CcPasswordDialog *self)
+generate_password (CcPasswordDialog *self)
{
g_autofree gchar *pwd = NULL;
@@ -420,10 +412,11 @@ password_entry_icon_press_cb (CcPasswordDialog *self)
if (pwd == NULL)
return;
- gtk_entry_set_text (self->password_entry, pwd);
- gtk_entry_set_text (self->verify_entry, pwd);
- gtk_entry_set_visibility (self->password_entry, TRUE);
- gtk_widget_set_sensitive (GTK_WIDGET (self->verify_entry), TRUE);
+ gtk_editable_set_text (GTK_EDITABLE (self->password_entry), pwd);
+ gtk_editable_set_text (GTK_EDITABLE (self->verify_entry), pwd);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->verify_password_row), TRUE);
+
+ gtk_widget_hide (GTK_WIDGET (self->generate_password_button));
}
static void
@@ -461,25 +454,31 @@ cc_password_dialog_class_init (CcPasswordDialogClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/user-accounts/cc-password-dialog.ui");
- gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_radio_box);
- gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_now_radio);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_login_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, action_now_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, generate_password_button);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_row);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, ok_button);
- gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_label);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, old_password_status_icon);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_group);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_on_next_login_group);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_entry_status_icon);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_hint_label);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, password_row);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, strength_indicator);
gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_entry);
- gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_hint_label);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_password_row);
+ gtk_widget_class_bind_template_child (widget_class, CcPasswordDialog, verify_password_status_icon);
gtk_widget_class_bind_template_callback (widget_class, action_now_radio_toggled_cb);
+ gtk_widget_class_bind_template_callback (widget_class, generate_password);
gtk_widget_class_bind_template_callback (widget_class, old_password_entry_changed);
gtk_widget_class_bind_template_callback (widget_class, old_password_entry_focus_out_cb);
gtk_widget_class_bind_template_callback (widget_class, ok_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, password_entry_changed);
gtk_widget_class_bind_template_callback (widget_class, password_entry_focus_out_cb);
- gtk_widget_class_bind_template_callback (widget_class, password_entry_icon_press_cb);
gtk_widget_class_bind_template_callback (widget_class, password_entry_key_press_cb);
gtk_widget_class_bind_template_callback (widget_class, verify_entry_changed);
}
@@ -496,11 +495,11 @@ CcPasswordDialog *
cc_password_dialog_new (ActUser *user)
{
CcPasswordDialog *self;
+ GtkWindow *window;
g_return_val_if_fail (ACT_IS_USER (user), NULL);
self = g_object_new (CC_TYPE_PASSWORD_DIALOG,
- "use-header-bar", 1,
NULL);
self->user = g_object_ref (user);
@@ -509,21 +508,19 @@ cc_password_dialog_new (ActUser *user)
gboolean visible;
mode_change (self, ACT_USER_PASSWORD_MODE_REGULAR);
- gtk_widget_hide (GTK_WIDGET (self->action_radio_box));
+ gtk_widget_hide (GTK_WIDGET (self->password_on_next_login_group));
visible = (act_user_get_password_mode (user) != ACT_USER_PASSWORD_MODE_NONE);
- gtk_widget_set_visible (GTK_WIDGET (self->old_password_label), visible);
- gtk_widget_set_visible (GTK_WIDGET (self->old_password_entry), visible);
+ gtk_widget_set_visible (GTK_WIDGET (self->old_password_row), visible);
self->old_password_ok = !visible;
self->passwd_handler = passwd_init ();
}
else {
mode_change (self, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
- gtk_widget_show (GTK_WIDGET (self->action_radio_box));
+ gtk_widget_show (GTK_WIDGET (self->password_on_next_login_group));
- gtk_widget_hide (GTK_WIDGET (self->old_password_label));
- gtk_widget_hide (GTK_WIDGET (self->old_password_entry));
+ gtk_widget_hide (GTK_WIDGET (self->old_password_row));
self->old_password_ok = TRUE;
}
@@ -532,7 +529,8 @@ cc_password_dialog_new (ActUser *user)
else
gtk_widget_grab_focus (GTK_WIDGET (self->password_entry));
- gtk_widget_grab_default (GTK_WIDGET (self->ok_button));
+ window = (GtkWindow *) gtk_widget_get_native (GTK_WIDGET (self));
+ gtk_window_set_default_widget (window, GTK_WIDGET (self->ok_button));
return self;
}
diff --git a/panels/user-accounts/cc-password-dialog.h b/panels/user-accounts/cc-password-dialog.h
index 958366b59..39c40ecc5 100644
--- a/panels/user-accounts/cc-password-dialog.h
+++ b/panels/user-accounts/cc-password-dialog.h
@@ -20,13 +20,14 @@
#pragma once
+#include <adwaita.h>
#include <gtk/gtk.h>
#include <act/act.h>
G_BEGIN_DECLS
#define CC_TYPE_PASSWORD_DIALOG (cc_password_dialog_get_type ())
-G_DECLARE_FINAL_TYPE (CcPasswordDialog, cc_password_dialog, CC, PASSWORD_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (CcPasswordDialog, cc_password_dialog, CC, PASSWORD_DIALOG, AdwPreferencesWindow)
CcPasswordDialog *cc_password_dialog_new (ActUser *user);
diff --git a/panels/user-accounts/cc-password-dialog.ui b/panels/user-accounts/cc-password-dialog.ui
index bfcc7585b..d4e68a361 100644
--- a/panels/user-accounts/cc-password-dialog.ui
+++ b/panels/user-accounts/cc-password-dialog.ui
@@ -1,201 +1,151 @@
<?xml version="1.0"?>
<interface>
- <!-- interface-requires gtk+ 2.12 -->
- <!-- interface-naming-policy toplevel-contextual -->
- <template class="CcPasswordDialog" parent="GtkDialog">
- <property name="border_width">6</property>
+ <template class="CcPasswordDialog" parent="AdwPreferencesWindow">
<property name="title" translatable="yes">Change Password</property>
- <property name="resizable">False</property>
<property name="modal">True</property>
- <property name="window_position">center-on-parent</property>
+ <property name="hide-on-close">True</property>
<property name="icon_name">system-users</property>
- <property name="type_hint">dialog</property>
- <child internal-child="headerbar">
- <object class="GtkHeaderBar" id="dialog-header-bar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="show_close_button">False</property>
- <child>
- <object class="GtkButton" id="cancel_button">
- <property name="label" translatable="yes">_Cancel</property>
- <property name="visible">True</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="valign">center</property>
- <style>
- <class name="text-button"/>
- </style>
- </object>
- <packing>
- <property name="pack_type">start</property>
- </packing>
- </child>
+ <property name="default-height">420</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkButton" id="ok_button">
- <property name="label" translatable="yes">Ch_ange</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <property name="valign">center</property>
- <signal name="clicked" handler="ok_button_clicked_cb" object="CcPasswordDialog" swapped="yes"/>
- <style>
- <class name="text-button"/>
- <class name="suggested-action"/>
- </style>
+ <object class="AdwHeaderBar">
+ <property name="show-start-title-buttons">False</property>
+ <property name="show-end-title-buttons">False</property>
+ <child type="start">
+ <object class="GtkButton">
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="visible">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="gtk_window_destroy" object="CcPasswordDialog" swapped="yes"/>
+ <style>
+ <class name="text-button"/>
+ </style>
+ </object>
+ </child>
+ <child type="end">
+ <object class="GtkButton" id="ok_button">
+ <property name="label" translatable="yes">Ch_ange</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="ok_button_clicked_cb" object="CcPasswordDialog"
swapped="yes"/>
+ <style>
+ <class name="text-button"/>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ </child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
- </object>
- </child>
- <child internal-child="vbox">
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
+ <object class="AdwPreferencesPage">
<child>
- <object class="GtkGrid">
- <property name="visible">True</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <property name="hexpand">True</property>
- <child>
- <object class="GtkEntry" id="verify_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="hexpand">True</property>
- <property name="activates_default">True</property>
- <property name="input_purpose">password</property>
- <signal name="notify::text" handler="verify_entry_changed" object="CcPasswordDialog"
swapped="yes"/>
- <signal name="activate" handler="password_entry_focus_out_cb" object="CcPasswordDialog"
swapped="yes"/>
- <signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes"
object="CcPasswordDialog" swapped="yes"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">7</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="password_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="height-request">50</property>
- <property name="wrap">True</property>
- <property name="hexpand">True</property>
- <property name="wrap_mode">word-char</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="verify_hint_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes"></property>
- <property name="width-chars">35</property>
- <property name="max-width-chars">35</property>
- <property name="wrap">True</property>
- <property name="hexpand">True</property>
- <property name="wrap_mode">word-char</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value="0.83"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">8</property>
- </packing>
- </child>
+ <object class="AdwPreferencesGroup" id="password_group">
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Confirm New Password</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">verify_entry</property>
- <property name="margin_start">25</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <object class="AdwActionRow" id="old_password_row">
+ <property name="title" translatable="yes">Current Password</property>
+ <property name="activatable-widget">old_password_entry</property>
+ <child>
+ <object class="GtkPasswordEntry" id="old_password_entry">
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="show-peek-icon">True</property>
+ <signal name="notify::text" handler="old_password_entry_changed"
object="CcPasswordDialog" swapped="yes"/>
+ <signal name="activate" handler="old_password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="old_password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="old_password_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">7</property>
- </packing>
</child>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_New Password</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">password_entry</property>
- <property name="margin_start">25</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <object class="AdwActionRow" id="password_row">
+ <property name="title" translatable="yes">New Password</property>
+ <property name="activatable-widget">password_entry</property>
+ <child>
+ <object class="GtkPasswordEntry" id="password_entry">
+ <property name="hexpand">True</property>
+ <property name="show-peek-icon">True</property>
+ <property name="valign">center</property>
+ <signal name="notify::text" handler="password_entry_changed"
object="CcPasswordDialog" swapped="yes"/>
+ <signal name="activate" handler="password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerKey">
+ <signal name="key-pressed" handler="password_entry_key_press_cb"
object="CcPasswordDialog" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkBox">
+ <child>
+ <object class="GtkButton" id="generate_password_button">
+ <property name="visible">False</property>
+ <property name="icon-name">emblem-system-symbolic</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="generate_password" object="CcPasswordDialog"
swapped="yes"/>
+ <style>
+ <class name="flat"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="password_entry_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- </packing>
</child>
<child>
- <object class="GtkEntry" id="password_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="hexpand">True</property>
- <property name="activates_default">True</property>
- <property name="input_purpose">password</property>
- <signal name="notify::text" handler="password_entry_changed" object="CcPasswordDialog"
swapped="yes"/>
- <signal name="activate" handler="password_entry_focus_out_cb" object="CcPasswordDialog"
swapped="yes"/>
- <signal name="focus-out-event" handler="password_entry_focus_out_cb" after="yes"
object="CcPasswordDialog" swapped="yes"/>
- <signal name="key-press-event" handler="password_entry_key_press_cb"
object="CcPasswordDialog" swapped="yes"/>
- <signal name="icon-press" handler="password_entry_icon_press_cb"
object="CcPasswordDialog" swapped="yes"/>
+ <object class="AdwActionRow" id="verify_password_row">
+ <property name="title" translatable="yes">Confirm Password</property>
+ <property name="activatable-widget">verify_entry</property>
+ <child>
+ <object class="GtkPasswordEntry" id="verify_entry">
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="show-peek-icon">True</property>
+ <signal name="notify::text" handler="verify_entry_changed" object="CcPasswordDialog"
swapped="yes"/>
+ <signal name="activate" handler="password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ <child>
+ <object class="GtkEventControllerFocus">
+ <signal name="leave" handler="password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="suffix">
+ <object class="GtkImage" id="verify_password_status_icon">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- </packing>
</child>
<child>
<object class="GtkLevelBar" id="strength_indicator">
- <property name="visible">True</property>
- <property name="mode">discrete</property>
+ <property name="mode">continuous</property>
<property name="max-value">5</property>
+ <property name="margin-top">12</property>
<offsets>
<offset name="strength-weak" value="1"/>
<offset name="strength-low" value="2"/>
@@ -204,102 +154,51 @@
<offset name="strength-high" value="5"/>
</offsets>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">5</property>
- </packing>
</child>
<child>
- <object class="GtkLabel" id="old_password_label">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Current _Password</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">old_password_entry</property>
- <property name="margin_start">25</property>
- <property name="margin_bottom">12</property>
+ <object class="GtkLabel" id="password_hint_label">
+ <property name="halign">start</property>
+ <property name="margin-top">12</property>
+ <property name="wrap">True</property>
<style>
<class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="old_password_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="hexpand">True</property>
- <property name="activates_default">True</property>
- <property name="margin_bottom">12</property>
- <property name="input_purpose">password</property>
- <signal name="notify::text" handler="old_password_entry_changed"
object="CcPasswordDialog" swapped="yes"/>
- <signal name="activate" handler="old_password_entry_focus_out_cb"
object="CcPasswordDialog" swapped="yes"/>
- <signal name="focus-out-event" handler="old_password_entry_focus_out_cb" after="yes"
object="CcPasswordDialog" swapped="yes"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="password_on_next_login_group">
+ <property name="visible">False</property>
<child>
- <object class="GtkBox" id="action_radio_box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkRadioButton" id="action_login_radio">
- <property name="label" translatable="yes">Allow user to change their password on
next login</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ <object class="AdwActionRow" id="action_login_row">
+ <property name="title" translatable="yes">Allow user to change their password on next
login</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="action_login_radio">
<property name="receives_default">False</property>
<property name="active">True</property>
- <property name="draw_indicator">True</property>
</object>
- <packing>
- <property name="position">0</property>
- </packing>
</child>
- <child>
- <object class="GtkRadioButton" id="action_now_radio">
- <property name="label" translatable="yes">Set a password now</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="action_now_row">
+ <property name="title" translatable="yes">Set a password now</property>
+ <child type="prefix">
+ <object class="GtkCheckButton" id="action_now_radio">
<property name="receives_default">False</property>
<property name="active">True</property>
- <property name="draw_indicator">True</property>
<property name="group">action_login_radio</property>
<signal name="toggled" handler="action_now_radio_toggled_cb"
object="CcPasswordDialog" swapped="yes"/>
</object>
- <packing>
- <property name="position">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">3</property>
- </packing>
</child>
</object>
- <packing>
- <property name="position">0</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
- <action-widgets>
- <action-widget response="0">cancel_button</action-widget>
- </action-widgets>
</template>
</interface>
diff --git a/panels/user-accounts/cc-user-panel.c b/panels/user-accounts/cc-user-panel.c
index 7e9659054..1d52cf9ce 100644
--- a/panels/user-accounts/cc-user-panel.c
+++ b/panels/user-accounts/cc-user-panel.c
@@ -45,13 +45,11 @@
#include "cc-add-user-dialog.h"
#include "cc-avatar-chooser.h"
-#include "cc-carousel.h"
#include "cc-language-chooser.h"
#include "cc-login-history-dialog.h"
#include "cc-password-dialog.h"
#include "cc-realm-manager.h"
#include "cc-user-accounts-resources.h"
-#include "cc-user-image.h"
#include "cc-fingerprint-manager.h"
#include "cc-fingerprint-dialog.h"
#include "user-utils.h"
@@ -59,7 +57,6 @@
#include "cc-common-language.h"
#include "cc-permission-infobar.h"
#include "cc-util.h"
-#include "list-box-helper.h"
#define USER_ACCOUNTS_PERMISSION "org.gnome.controlcenter.user-accounts.administration"
@@ -69,16 +66,13 @@ struct _CcUserPanel {
ActUserManager *um;
GSettings *login_screen_settings;
- GtkBox *accounts_box;
GtkBox *account_settings_box;
- GtkListBox *account_settings_listbox;
- GtkListBox *authentication_and_login_listbox;
GtkListBoxRow *account_type_row;
GtkSwitch *account_type_switch;
- GtkButton *add_user_button;
+ GtkWidget *add_user_button;
GtkListBoxRow *autologin_row;
GtkSwitch *autologin_switch;
- CcCarousel *carousel;
+ GtkButton *back_button;
GtkLabel *fingerprint_state_label;
GtkListBoxRow *fingerprint_row;
GtkStack *full_name_stack;
@@ -89,39 +83,37 @@ struct _CcUserPanel {
GtkListBoxRow *language_row;
GtkLabel *last_login_button_label;
GtkListBoxRow *last_login_row;
- GtkBox *no_users_box;
+ GtkWidget *no_users_box;
GtkRevealer *notification_revealer;
+ AdwPreferencesGroup *other_users;
+ GtkListBox *other_users_listbox;
+ AdwPreferencesRow *other_users_row;
GtkLabel *password_button_label;
#ifdef HAVE_MALCONTENT
GtkLabel *parental_controls_button_label;
- GtkImage *parental_control_go_next;
GtkListBoxRow *parental_controls_row;
#endif
GtkListBoxRow *password_row;
CcPermissionInfobar *permission_infobar;
GtkButton *remove_user_button;
GtkStack *stack;
- GtkToggleButton *user_icon_button;
- CcUserImage *user_icon_image;
- CcUserImage *user_icon_image2;
- GtkStack *user_icon_stack;
+ AdwAvatar *user_avatar;
+ GtkMenuButton *user_avatar_edit_button;
GtkOverlay *users_overlay;
ActUser *selected_user;
GPermission *permission;
CcLanguageChooser *language_chooser;
+ GListStore *other_users_model;
CcAvatarChooser *avatar_chooser;
CcFingerprintManager *fingerprint_manager;
-
- gint other_accounts;
};
CC_PANEL_REGISTER (CcUserPanel, cc_user_panel)
static void show_restart_notification (CcUserPanel *self, const gchar *locale);
-static gint user_compare (gconstpointer i, gconstpointer u);
typedef struct {
CcUserPanel *self;
@@ -147,7 +139,7 @@ show_error_dialog (CcUserPanel *self,
{
GtkWidget *dialog;
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_USE_HEADER_BAR,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -159,112 +151,72 @@ show_error_dialog (CcUserPanel *self,
"%s", error->message);
}
- g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
gtk_window_present (GTK_WINDOW (dialog));
}
+static void show_user (ActUser *user, CcUserPanel *self);
+
static ActUser *
get_selected_user (CcUserPanel *self)
{
return self->selected_user;
}
-static const gchar *
-get_real_or_user_name (ActUser *user)
-{
- const gchar *name;
-
- name = act_user_get_real_name (user);
- if (name == NULL)
- name = act_user_get_user_name (user);
-
- return name;
-}
-
-static void show_user (ActUser *user, CcUserPanel *self);
-
static void
-set_selected_user (CcUserPanel *self, CcCarouselItem *item)
+set_selected_user (CcUserPanel *self,
+ AdwActionRow *row)
{
uid_t uid;
-
- uid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "uid"));
+
+ uid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "uid"));
g_set_object (&self->selected_user,
act_user_manager_get_user_by_id (self->um, uid));
-
- if (self->selected_user != NULL) {
- show_user (self->selected_user, self);
- }
+ show_user (self->selected_user, self);
}
-static GtkWidget *
-create_carousel_entry (CcUserPanel *self, ActUser *user)
+static void
+show_current_user (CcUserPanel *self)
{
- GtkWidget *box, *widget;
- g_autofree gchar *label = NULL;
- g_autofree gchar *subtitle_label = NULL;
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
- widget = cc_user_image_new ();
- cc_user_image_set_user (CC_USER_IMAGE (widget), user);
- gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
-
- label = g_markup_printf_escaped ("<b>%s</b>",
- get_real_or_user_name (user));
- widget = gtk_label_new (label);
- gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
- gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
- gtk_widget_set_margin_top (widget, 5);
- gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
-
- if (act_user_get_uid (user) == getuid ())
- subtitle_label = g_strdup_printf ("<small>%s</small>", _("Your account"));
- else
- subtitle_label = g_strdup (" ");
-
- widget = gtk_label_new (subtitle_label);
- gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
-
- gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
- gtk_style_context_add_class (gtk_widget_get_style_context (widget),
- "dim-label");
+ ActUser *user;
- return box;
+ user = act_user_manager_get_user_by_id (self->um, getuid ());
+ if (user != NULL)
+ show_user (user, self);
}
-static void
-user_added (CcUserPanel *self, ActUser *user)
+static const gchar *
+get_real_or_user_name (ActUser *user)
{
- GtkWidget *item, *widget;
- gboolean show_carousel;
-
- if (act_user_is_system_account (user)) {
- return;
- }
-
- g_debug ("user added: %d %s\n", act_user_get_uid (user), get_real_or_user_name (user));
-
- widget = create_carousel_entry (self, user);
- item = cc_carousel_item_new ();
- gtk_container_add (GTK_CONTAINER (item), widget);
-
- g_object_set_data (G_OBJECT (item), "uid", GINT_TO_POINTER (act_user_get_uid (user)));
- gtk_container_add (GTK_CONTAINER (self->carousel), item);
+ const gchar *name;
- if (act_user_get_uid (user) != getuid ()) {
- self->other_accounts++;
- }
+ name = act_user_get_real_name (user);
+ if (name == NULL)
+ name = act_user_get_user_name (user);
- /* Show heading for other accounts if new one have been added. */
- show_carousel = (self->other_accounts > 0);
- gtk_revealer_set_reveal_child (GTK_REVEALER (self->carousel), show_carousel);
+ return name;
+}
- gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->users_overlay));
+static GtkWidget *
+create_user_row (gpointer item,
+ gpointer user_data)
+{
+ ActUser *user = ACT_USER (item);
+ GtkWidget *row, *user_image;
+
+ row = adw_action_row_new ();
+ g_object_set_data (G_OBJECT (row), "uid", GINT_TO_POINTER (act_user_get_uid (user)));
+ gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row),
+ get_real_or_user_name (user));
+ user_image = adw_avatar_new (48, get_real_or_user_name (user), TRUE);
+ adw_action_row_add_prefix (ADW_ACTION_ROW (row), user_image);
+
+ return row;
}
static gint
-sort_users (gconstpointer a, gconstpointer b)
+sort_users (gconstpointer a, gconstpointer b, gpointer user_data)
{
ActUser *ua, *ub;
@@ -290,112 +242,62 @@ sort_users (gconstpointer a, gconstpointer b)
}
static void
-reload_users (CcUserPanel *self, ActUser *selected_user)
+user_changed (CcUserPanel *self, ActUser *user)
{
- ActUser *user;
- GSList *list, *l;
- CcCarouselItem *item = NULL;
- GtkSettings *settings;
- gboolean animations;
- guint users_count;
-#ifdef HAVE_MALCONTENT
- g_autofree gchar *malcontent_control_path = NULL;
-#endif
-
- settings = gtk_widget_get_settings (GTK_WIDGET (self->carousel));
+ GSList *user_list, *l;
- g_object_get (settings, "gtk-enable-animations", &animations, NULL);
- g_object_set (settings, "gtk-enable-animations", FALSE, NULL);
+ g_list_store_remove_all (self->other_users_model);
+ user_list = act_user_manager_list_users (self->um);
+ for (l = user_list; l; l = l->next) {
+ ActUser *other_user = ACT_USER (l->data);
- cc_carousel_purge_items (self->carousel);
- self->other_accounts = 0;
+ if (act_user_is_system_account (other_user)) {
+ continue;
+ }
- list = act_user_manager_list_users (self->um);
- users_count = g_slist_length (list);
- g_debug ("Got %d users\n", users_count);
+ if (act_user_get_uid (other_user) == getuid ()) {
+ continue;
+ }
- list = g_slist_sort (list, (GCompareFunc) sort_users);
- for (l = list; l; l = l->next) {
- user = l->data;
- g_debug ("adding user %s\n", get_real_or_user_name (user));
- user_added (self, user);
+ g_list_store_insert_sorted (self->other_users_model,
+ other_user,
+ sort_users,
+ self);
}
- g_slist_free (list);
-
- if (cc_carousel_get_item_count (self->carousel) == 0)
- gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->no_users_box));
- if (self->other_accounts == 0)
- gtk_revealer_set_reveal_child (GTK_REVEALER (self->carousel), FALSE);
- if (selected_user)
- item = cc_carousel_find_item (self->carousel, selected_user, user_compare);
- cc_carousel_select_item (self->carousel, item);
-
- g_object_set (settings, "gtk-enable-animations", animations, NULL);
-#ifdef HAVE_MALCONTENT
- /* Parental Controls row not to be shown for single user setups, or if
- * malcontent-control is not available (which can happen if
- * libmalcontent is installed but malcontent-control is not). */
- malcontent_control_path = g_find_program_in_path ("malcontent-control");
-
- if (malcontent_control_path == NULL) {
- gtk_widget_set_visible (GTK_WIDGET (self->parental_controls_row), FALSE);
- } else if (selected_user != NULL) {
- gtk_widget_set_visible (GTK_WIDGET (self->parental_controls_row),
- act_user_get_account_type (selected_user) !=
ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR);
- } else {
- gtk_widget_set_visible (GTK_WIDGET (self->parental_controls_row), users_count > 1);
- }
-#endif
+ if (self->selected_user == user)
+ show_user (user, self);
}
-static gint
-user_compare (gconstpointer i,
- gconstpointer u)
+static void
+on_add_user_dialog_response (CcUserPanel *self,
+ gint response,
+ CcAddUserDialog *dialog)
{
- CcCarouselItem *item;
ActUser *user;
- gint uid_a, uid_b;
- gint result;
-
- item = (CcCarouselItem *) i;
- user = ACT_USER (u);
- uid_a = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "uid"));
- uid_b = act_user_get_uid (user);
-
- result = uid_a - uid_b;
-
- return result;
-}
+ user = cc_add_user_dialog_get_user (dialog);
+ if (user != NULL) {
+ set_default_avatar (user);
+ show_user (user, self);
+ }
-static void
-user_changed (CcUserPanel *self, ActUser *user)
-{
- reload_users (self, self->selected_user);
+ gtk_window_destroy (GTK_WINDOW (dialog));
}
static void
add_user (CcUserPanel *self)
{
CcAddUserDialog *dialog;
- g_autoptr(GdkPixbuf) pixbuf = NULL;
GtkWindow *toplevel;
- ActUser *user;
dialog = cc_add_user_dialog_new (self->permission);
- toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
+ toplevel = GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self)));
gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
- gtk_dialog_run (GTK_DIALOG (dialog));
-
- user = cc_add_user_dialog_get_user (dialog);
- if (user != NULL) {
- set_default_avatar (user);
- reload_users (self, user);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ gtk_window_present (GTK_WINDOW (dialog));
+ g_signal_connect_object (dialog, "response", G_CALLBACK (on_add_user_dialog_response),
+ self, G_CONNECT_SWAPPED);
}
static void
@@ -410,6 +312,8 @@ delete_user_done (ActUserManager *manager,
ACT_USER_MANAGER_ERROR_PERMISSION_DENIED))
show_error_dialog (self, _("Failed to delete user"), error);
}
+
+ show_current_user (self);
}
static void
@@ -420,7 +324,7 @@ delete_user_response (CcUserPanel *self,
ActUser *user;
gboolean remove_files;
- gtk_widget_destroy (dialog);
+ gtk_window_destroy (GTK_WINDOW (dialog));
if (response_id == GTK_RESPONSE_CANCEL) {
return;
@@ -576,7 +480,7 @@ delete_enterprise_user_response (CcUserPanel *self,
AsyncDeleteData *data;
ActUser *user;
- gtk_widget_destroy (dialog);
+ gtk_window_destroy (GTK_WINDOW (dialog));
if (response_id != GTK_RESPONSE_ACCEPT) {
return;
@@ -609,16 +513,16 @@ delete_user (CcUserPanel *self)
return;
}
else if (act_user_get_uid (user) == getuid ()) {
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))),
0,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
_("You cannot delete your own account."));
g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
+ G_CALLBACK (gtk_window_destroy), NULL);
}
else if (act_user_is_logged_in_anywhere (user)) {
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))),
0,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
@@ -628,10 +532,10 @@ delete_user (CcUserPanel *self)
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("Deleting a user while they are logged in can
leave the system in an inconsistent state."));
g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
+ G_CALLBACK (gtk_window_destroy), NULL);
}
else if (act_user_is_local_account (user)) {
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))),
0,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
@@ -653,7 +557,7 @@ delete_user (CcUserPanel *self)
G_CALLBACK (delete_user_response), self, G_CONNECT_SWAPPED);
}
else {
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))),
0,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
@@ -672,7 +576,7 @@ delete_user (CcUserPanel *self)
}
g_signal_connect (dialog, "close",
- G_CALLBACK (gtk_widget_destroy), NULL);
+ G_CALLBACK (gtk_window_destroy), NULL);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
@@ -815,8 +719,8 @@ is_parental_controls_enabled_for_user (ActUser *user)
/* FIXME: should become asynchronous */
system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (system_bus == NULL) {
- g_warning ("Error getting system bus while trying to show user details: %s", error->message);
- return FALSE;
+ g_warning ("Error getting system bus while trying to show user details: %s", error->message);
+ return FALSE;
}
manager = mct_manager_new (system_bus);
@@ -862,6 +766,7 @@ show_user (ActUser *user, CcUserPanel *self)
{
g_autofree gchar *lang = NULL;
g_autofree gchar *name = NULL;
+ const gchar *avatar_file;
gboolean show, enable;
ActUser *current;
#ifdef HAVE_MALCONTENT
@@ -870,14 +775,25 @@ show_user (ActUser *user, CcUserPanel *self)
self->selected_user = user;
- cc_user_image_set_user (self->user_icon_image, user);
- cc_user_image_set_user (self->user_icon_image2, user);
-
+ adw_avatar_set_text (self->user_avatar, get_real_or_user_name (user));
cc_avatar_chooser_set_user (self->avatar_chooser, user);
+ avatar_file = act_user_get_icon_file (user);
+ if (avatar_file) {
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+
+ pixbuf = gdk_pixbuf_new_from_file_at_size (avatar_file,
+ adw_avatar_get_size (self->user_avatar),
+ adw_avatar_get_size (self->user_avatar),
+ NULL);
+ if (pixbuf) {
+ adw_avatar_set_custom_image (self->user_avatar,
+ GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf)));
+ }
+ }
- gtk_label_set_label (self->full_name_label, act_user_get_real_name (user));
- gtk_entry_set_text (self->full_name_entry, act_user_get_real_name (user));
- gtk_widget_set_tooltip_text (GTK_WIDGET (self->full_name_label), act_user_get_user_name (user));
+ gtk_label_set_label (self->full_name_label, get_real_or_user_name (user));
+ gtk_editable_set_text (GTK_EDITABLE (self->full_name_entry), gtk_label_get_label
(self->full_name_label));
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->full_name_label), get_real_or_user_name (user));
g_signal_handlers_block_by_func (self->full_name_edit_button, full_name_edit_button_toggled, self);
gtk_stack_set_visible_child (self->full_name_stack, GTK_WIDGET (self->full_name_label));
@@ -887,10 +803,6 @@ show_user (ActUser *user, CcUserPanel *self)
enable = (act_user_get_account_type (user) == ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR);
gtk_switch_set_active (self->account_type_switch, enable);
- /* Do not show the "Account Type" option when there's a single user account. */
- show = (self->other_accounts != 0);
- gtk_widget_set_visible (GTK_WIDGET (self->account_settings_box), show);
-
gtk_label_set_label (self->password_button_label, get_password_mode_text (user));
enable = act_user_is_local_account (user);
gtk_widget_set_sensitive (GTK_WIDGET (self->password_button_label), enable);
@@ -901,13 +813,11 @@ show_user (ActUser *user, CcUserPanel *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->autologin_switch), get_autologin_possible (user));
lang = g_strdup (act_user_get_language (user));
-
if (lang && *lang != '\0') {
name = gnome_get_language_from_locale (lang, NULL);
} else {
name = g_strdup ("—");
}
-
gtk_label_set_label (self->language_button_label, name);
/* Fingerprint: show when self, local, enabled, and possible */
@@ -955,14 +865,18 @@ show_user (ActUser *user, CcUserPanel *self)
gtk_label_set_text (self->parental_controls_button_label, _("Disabled"));
gtk_style_context_remove_class (context, "dim-label");
- gtk_widget_show (GTK_WIDGET (self->parental_control_go_next));
gtk_widget_show (GTK_WIDGET (self->parental_controls_row));
}
#endif
- /* Language: do not show for current user */
- show = act_user_get_uid (user) != getuid();
- gtk_widget_set_visible (GTK_WIDGET (self->language_row), show);
+ /* Current user */
+ show = act_user_get_uid (user) == getuid();
+ gtk_widget_set_visible (GTK_WIDGET (self->account_settings_box), !show);
+ gtk_widget_set_visible (GTK_WIDGET (self->remove_user_button), !show);
+ gtk_widget_set_visible (GTK_WIDGET (self->back_button), !show);
+ gtk_widget_set_visible (GTK_WIDGET (self->other_users), show);
+ show = g_list_model_get_n_items (G_LIST_MODEL (self->other_users_model)) > 0;
+ gtk_widget_set_visible (GTK_WIDGET (self->other_users_row), show);
/* Last login: show when administrator or current user */
current = act_user_manager_get_user_by_id (self->um, getuid ());
@@ -990,7 +904,7 @@ full_name_entry_activate (CcUserPanel *self)
ActUser *user;
user = get_selected_user (self);
- text = gtk_entry_get_text (self->full_name_entry);
+ text = gtk_editable_get_text (GTK_EDITABLE (self->full_name_entry));
if (g_strcmp0 (text, act_user_get_real_name (user)) != 0 &&
is_valid_name (text)) {
act_user_set_real_name (user, text);
@@ -1014,13 +928,14 @@ full_name_edit_button_toggled (CcUserPanel *self)
}
static gboolean
-full_name_entry_key_press_cb (CcUserPanel *self,
- GdkEvent *event)
+full_name_entry_key_press_cb (GtkEventController *controller,
+ guint keyval,
+ guint keycode,
+ GdkModifierType state,
+ CcUserPanel *self)
{
- GdkEventKey *key = (GdkEventKey *)event;
-
- if (key->keyval == GDK_KEY_Escape) {
- gtk_entry_set_text (self->full_name_entry, act_user_get_real_name (self->selected_user));
+ if (keyval == GDK_KEY_Escape) {
+ gtk_editable_set_text (GTK_EDITABLE (self->full_name_entry), act_user_get_real_name
(self->selected_user));
full_name_entry_activate (self);
@@ -1137,20 +1052,16 @@ change_language (CcUserPanel *self)
current_language = act_user_get_language (user);
if (self->language_chooser) {
- cc_language_chooser_clear_filter (self->language_chooser);
+ cc_language_chooser_clear_filter (self->language_chooser);
cc_language_chooser_set_language (self->language_chooser, NULL);
}
else {
self->language_chooser = cc_language_chooser_new ();
gtk_window_set_transient_for (GTK_WINDOW (self->language_chooser),
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))));
+ GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))));
g_signal_connect_object (self->language_chooser, "response",
G_CALLBACK (language_response), self, G_CONNECT_SWAPPED);
- g_signal_connect (self->language_chooser, "delete-event",
- G_CALLBACK (gtk_widget_hide_on_delete), NULL);
-
- gdk_window_set_cursor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (self))),
NULL);
}
if (current_language && *current_language != '\0')
@@ -1168,28 +1079,27 @@ change_password (CcUserPanel *self)
user = get_selected_user (self);
dialog = cc_password_dialog_new (user);
- parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
+ parent = (GtkWindow *) gtk_widget_get_native (GTK_WIDGET (self));
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
change_fingerprint (CcUserPanel *self)
{
ActUser *user;
- GtkWindow *top_level;
+ GtkWindow *parent;
CcFingerprintDialog *dialog;
user = get_selected_user (self);
- top_level = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
+ parent = (GtkWindow *) gtk_widget_get_native (GTK_WIDGET (self));
g_assert (g_strcmp0 (g_get_user_name (), act_user_get_user_name (user)) == 0);
dialog = cc_fingerprint_dialog_new (self->fingerprint_manager);
- gtk_window_set_transient_for (GTK_WINDOW (dialog), top_level);
- gtk_widget_show (GTK_WIDGET (dialog));
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
@@ -1198,19 +1108,14 @@ show_history (CcUserPanel *self)
CcLoginHistoryDialog *dialog;
ActUser *user;
GtkWindow *parent;
- gint parent_width;
user = get_selected_user (self);
dialog = cc_login_history_dialog_new (user);
- parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
- gtk_window_get_size (parent, &parent_width, NULL);
- gtk_window_set_default_size (GTK_WINDOW (dialog), parent_width * 0.6, -1);
+ parent = (GtkWindow *) gtk_widget_get_native (GTK_WIDGET (self));
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
- gtk_dialog_run (GTK_DIALOG (dialog));
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ gtk_window_present (GTK_WINDOW (dialog));
}
#ifdef HAVE_MALCONTENT
@@ -1240,7 +1145,7 @@ spawn_malcontent_control (CcUserPanel *self)
}
#endif
-static void
+/*static void
activate_row (GtkListBox *box, GtkListBoxRow *row, CcUserPanel *self)
{
if (!gtk_widget_get_sensitive (GTK_WIDGET (row)))
@@ -1258,10 +1163,10 @@ activate_row (GtkListBox *box, GtkListBoxRow *row, CcUserPanel *self)
#ifdef HAVE_MALCONTENT
if (row == self->parental_controls_row) {
- spawn_malcontent_control (self);
+ spawn_malcontent_control (self);
}
#endif
-}
+}*/
static void
users_loaded (CcUserPanel *self)
@@ -1269,7 +1174,10 @@ users_loaded (CcUserPanel *self)
GtkWidget *dialog;
if (act_user_manager_no_service (self->um)) {
- dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
+ GtkWidget *toplevel;
+
+ toplevel = (GtkWidget *)gtk_widget_get_native (GTK_WIDGET (self));
+ dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel ),
GTK_DIALOG_MODAL,
GTK_MESSAGE_OTHER,
GTK_BUTTONS_CLOSE,
@@ -1277,49 +1185,32 @@ users_loaded (CcUserPanel *self)
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("Please make sure that the AccountService is
installed and enabled."));
g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy),
+ G_CALLBACK (gtk_window_destroy),
NULL);
gtk_widget_show (dialog);
- gtk_widget_set_sensitive (GTK_WIDGET (self->accounts_box), FALSE);
+ gtk_stack_set_visible_child (self->stack, self->no_users_box);
+ } else {
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->users_overlay));
+ show_current_user (self);
}
g_signal_connect_object (self->um, "user-changed", G_CALLBACK (user_changed), self,
G_CONNECT_SWAPPED);
g_signal_connect_object (self->um, "user-is-logged-in-changed", G_CALLBACK (user_changed), self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->um, "user-added", G_CALLBACK (user_added), self, G_CONNECT_SWAPPED);
g_signal_connect_object (self->um, "user-removed", G_CALLBACK (user_changed), self,
G_CONNECT_SWAPPED);
-
- reload_users (self, NULL);
}
static void
add_unlock_tooltip (GtkWidget *widget)
{
- gchar *names[3];
- g_autoptr(GIcon) icon;
-
- names[0] = "changes-allow-symbolic";
- names[1] = "changes-allow";
- names[2] = NULL;
- icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
- setup_tooltip_with_embedded_icon (widget,
- /* Translator comments:
- * We split the line in 2 here to "make it look good", as there's
- * no good way to do this in GTK+ for tooltips. See:
- * https://bugzilla.gnome.org/show_bug.cgi?id=657168 */
- _("To make changes,\nclick the * icon first"),
- "*",
- icon);
- g_signal_connect (widget, "button-release-event",
- G_CALLBACK (show_tooltip_now), NULL);
+ gtk_widget_set_tooltip_text (widget,
+ _("This panel must be unlocked to change this setting"));
}
static void
remove_unlock_tooltip (GtkWidget *widget)
{
- setup_tooltip_with_embedded_icon (widget, NULL, NULL, NULL);
- g_signal_handlers_disconnect_by_func (widget,
- G_CALLBACK (show_tooltip_now), NULL);
+ gtk_widget_set_tooltip_text (widget, NULL);
}
static guint
@@ -1369,7 +1260,7 @@ on_permission_changed (CcUserPanel *self)
is_authorized = g_permission_get_allowed (G_PERMISSION (self->permission));
- gtk_widget_set_sensitive (GTK_WIDGET (self->add_user_button), is_authorized);
+ gtk_widget_set_sensitive (self->add_user_button, is_authorized);
user = get_selected_user (self);
if (!user) {
@@ -1380,48 +1271,33 @@ on_permission_changed (CcUserPanel *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->remove_user_button), is_authorized && !self_selected
&& !would_demote_only_admin (user));
if (is_authorized) {
- setup_tooltip_with_embedded_icon (GTK_WIDGET (self->remove_user_button), _("Delete the
selected user account"), NULL, NULL);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->remove_user_button), _("Delete the selected
user account"));
}
else {
- gchar *names[3];
- g_autoptr(GIcon) icon = NULL;
-
- names[0] = "changes-allow-symbolic";
- names[1] = "changes-allow";
- names[2] = NULL;
- icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
-
- setup_tooltip_with_embedded_icon (GTK_WIDGET (self->remove_user_button),
- _("To delete the selected user account,\nclick the * icon
first"),
- "*",
- icon);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->remove_user_button),
+ _("To delete the selected user account,\nclick the * icon
first"));
}
if (!act_user_is_local_account (user)) {
- gtk_widget_set_sensitive (GTK_WIDGET (self->account_type_row), FALSE);
- remove_unlock_tooltip (GTK_WIDGET (self->account_type_row));
- gtk_widget_set_sensitive (GTK_WIDGET (self->autologin_row), FALSE);
- remove_unlock_tooltip (GTK_WIDGET (self->autologin_row));
-
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), FALSE);
+ gtk_widget_set_visible (GTK_WIDGET (self->autologin_row), FALSE);
} else if (is_authorized && act_user_is_local_account (user)) {
if (would_demote_only_admin (user)) {
- gtk_widget_set_sensitive (GTK_WIDGET (self->account_type_row), FALSE);
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), FALSE);
} else {
- gtk_widget_set_sensitive (GTK_WIDGET (self->account_type_row), TRUE);
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), TRUE);
}
- remove_unlock_tooltip (GTK_WIDGET (self->account_type_row));
- gtk_widget_set_sensitive (GTK_WIDGET (self->autologin_row), get_autologin_possible (user));
- remove_unlock_tooltip (GTK_WIDGET (self->autologin_row));
+ gtk_widget_set_visible (GTK_WIDGET (self->autologin_row), get_autologin_possible (user));
}
else {
- gtk_widget_set_sensitive (GTK_WIDGET (self->account_type_row), FALSE);
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), FALSE);
if (would_demote_only_admin (user)) {
- remove_unlock_tooltip (GTK_WIDGET (self->account_type_row));
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), FALSE);
} else {
- add_unlock_tooltip (GTK_WIDGET (self->account_type_row));
+ gtk_widget_set_visible (GTK_WIDGET (self->account_type_row), TRUE);
}
- gtk_widget_set_sensitive (GTK_WIDGET (self->autologin_row), FALSE);
+ gtk_widget_set_visible (GTK_WIDGET (self->autologin_row), FALSE);
add_unlock_tooltip (GTK_WIDGET (self->autologin_row));
}
@@ -1445,7 +1321,8 @@ on_permission_changed (CcUserPanel *self)
if (self->fingerprint_manager)
fingerprint_state = cc_fingerprint_manager_get_state (self->fingerprint_manager);
- gtk_stack_set_visible_child (self->user_icon_stack, GTK_WIDGET (self->user_icon_button));
+ gtk_widget_set_sensitive (GTK_WIDGET (self->user_avatar_edit_button), TRUE);
+ remove_unlock_tooltip (GTK_WIDGET (self->user_avatar_edit_button));
gtk_widget_set_sensitive (GTK_WIDGET (self->language_row), TRUE);
remove_unlock_tooltip (GTK_WIDGET (self->language_row));
@@ -1461,7 +1338,8 @@ on_permission_changed (CcUserPanel *self)
remove_unlock_tooltip (GTK_WIDGET (self->last_login_row));
}
else {
- gtk_stack_set_visible_child (self->user_icon_stack, GTK_WIDGET (self->user_icon_image));
+ gtk_widget_set_sensitive (GTK_WIDGET (self->user_avatar_edit_button), FALSE);
+ add_unlock_tooltip (GTK_WIDGET (self->user_avatar_edit_button));
gtk_widget_set_sensitive (GTK_WIDGET (self->language_row), FALSE);
add_unlock_tooltip (GTK_WIDGET (self->language_row));
@@ -1480,14 +1358,17 @@ on_permission_changed (CcUserPanel *self)
static void
setup_main_window (CcUserPanel *self)
{
- g_autoptr(GIcon) icon = NULL;
g_autoptr(GError) error = NULL;
- gchar *names[3];
gboolean loaded;
- self->other_accounts = 0;
+ self->other_users_model = g_list_store_new (ACT_TYPE_USER);
+ gtk_list_box_bind_model (self->other_users_listbox,
+ G_LIST_MODEL (self->other_users_model),
+ (GtkListBoxCreateWidgetFunc)create_user_row,
+ self,
+ NULL);
- add_unlock_tooltip (GTK_WIDGET (self->user_icon_image));
+ add_unlock_tooltip (GTK_WIDGET (self->user_avatar));
self->permission = (GPermission *)polkit_permission_new_sync (USER_ACCOUNTS_PERMISSION, NULL, NULL,
&error);
if (self->permission != NULL) {
@@ -1498,14 +1379,12 @@ setup_main_window (CcUserPanel *self)
g_warning ("Cannot create '%s' permission: %s", USER_ACCOUNTS_PERMISSION, error->message);
}
- names[0] = "changes-allow-symbolic";
- names[1] = "changes-allow";
- names[2] = NULL;
- icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
- setup_tooltip_with_embedded_icon (GTK_WIDGET (self->remove_user_button),
- _("To delete the selected user account,\nclick the * icon first"),
- "*",
- icon);
+#ifdef HAVE_MALCONTENT
+ g_signal_connect_object (self->parental_controls_row, "activated", G_CALLBACK
(spawn_malcontent_control), self, G_CONNECT_SWAPPED);
+#endif
+
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->remove_user_button),
+ _("To delete the selected user account,\nclick the * icon first"));
g_object_get (self->um, "is-loaded", &loaded, NULL);
if (loaded)
@@ -1541,13 +1420,9 @@ static void
cc_user_panel_constructed (GObject *object)
{
CcUserPanel *self = CC_USER_PANEL (object);
- CcShell *shell;
G_OBJECT_CLASS (cc_user_panel_parent_class)->constructed (object);
- shell = cc_panel_get_shell (CC_PANEL (self));
- cc_shell_embed_widget_in_header (shell, GTK_WIDGET (self->add_user_button), GTK_POS_RIGHT);
-
cc_permission_infobar_set_permission (self->permission_infobar, self->permission);
cc_permission_infobar_set_title (self->permission_infobar, _("Unlock to Add Users and Change
Settings"));
}
@@ -1561,8 +1436,6 @@ cc_user_panel_init (CcUserPanel *self)
g_resources_register (cc_user_accounts_get_resource ());
/* register types that the builder might need */
- type = cc_user_image_get_type ();
- type = cc_carousel_get_type ();
type = cc_permission_infobar_get_type ();
gtk_widget_init_template (GTK_WIDGET (self));
@@ -1571,13 +1444,12 @@ cc_user_panel_init (CcUserPanel *self)
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider,
"/org/gnome/control-center/user-accounts/user-accounts-dialog.css");
- gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
self->login_screen_settings = settings_or_null ("org.gnome.login-screen");
- self->avatar_chooser = cc_avatar_chooser_new (GTK_WIDGET (self->user_icon_button));
setup_main_window (self);
}
@@ -1588,7 +1460,7 @@ cc_user_panel_dispose (GObject *object)
g_clear_object (&self->selected_user);
g_clear_object (&self->login_screen_settings);
- g_clear_pointer ((GtkWidget **)&self->language_chooser, gtk_widget_destroy);
+ g_clear_pointer ((GtkWindow **)&self->language_chooser, gtk_window_destroy);
g_clear_object (&self->permission);
G_OBJECT_CLASS (cc_user_panel_parent_class)->dispose (object);
@@ -1614,16 +1486,14 @@ cc_user_panel_class_init (CcUserPanelClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/user-accounts/cc-user-panel.ui");
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, accounts_box);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, account_settings_box);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, account_settings_listbox);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, authentication_and_login_listbox);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, account_type_row);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, account_type_switch);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, add_user_button);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, autologin_row);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, autologin_switch);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, carousel);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, avatar_chooser);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, back_button);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, fingerprint_state_label);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, fingerprint_row);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, full_name_stack);
@@ -1636,9 +1506,11 @@ cc_user_panel_class_init (CcUserPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, last_login_row);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, no_users_box);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, notification_revealer);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, other_users);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, other_users_row);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, other_users_listbox);
#ifdef HAVE_MALCONTENT
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, parental_controls_button_label);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, parental_control_go_next);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, parental_controls_row);
#endif
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, password_button_label);
@@ -1646,14 +1518,11 @@ cc_user_panel_class_init (CcUserPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, permission_infobar);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, remove_user_button);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, stack);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_icon_button);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_icon_image);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_icon_image2);
- gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_icon_stack);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_avatar);
+ gtk_widget_class_bind_template_child (widget_class, CcUserPanel, user_avatar_edit_button);
gtk_widget_class_bind_template_child (widget_class, CcUserPanel, users_overlay);
gtk_widget_class_bind_template_callback (widget_class, account_type_changed);
- gtk_widget_class_bind_template_callback (widget_class, activate_row);
gtk_widget_class_bind_template_callback (widget_class, add_user);
gtk_widget_class_bind_template_callback (widget_class, autologin_changed);
gtk_widget_class_bind_template_callback (widget_class, change_fingerprint);
@@ -1666,4 +1535,6 @@ cc_user_panel_class_init (CcUserPanelClass *klass)
gtk_widget_class_bind_template_callback (widget_class, dismiss_notification);
gtk_widget_class_bind_template_callback (widget_class, restart_now);
gtk_widget_class_bind_template_callback (widget_class, set_selected_user);
+ gtk_widget_class_bind_template_callback (widget_class, show_current_user);
+ gtk_widget_class_bind_template_callback (widget_class, show_history);
}
diff --git a/panels/user-accounts/cc-user-panel.ui b/panels/user-accounts/cc-user-panel.ui
index b3e14264f..37145408a 100644
--- a/panels/user-accounts/cc-user-panel.ui
+++ b/panels/user-accounts/cc-user-panel.ui
@@ -1,17 +1,4 @@
<interface>
- <object class="GtkButton" id="add_user_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Add User…</property>
- <property name="use_underline">True</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip_text" translatable="yes">Create a user account</property>
- <signal name="clicked" handler="add_user" object="CcUserPanel" swapped="yes"/>
- <style>
- <class name="suggested-action"/>
- </style>
- </object>
<object class="GtkListStore" id="shortname-model">
<columns>
<!-- column-name gchararray -->
@@ -27,513 +14,380 @@
</columns>
</object>
<template class="CcUserPanel" parent="CcPanel">
- <property name="visible">True</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="CcPermissionInfobar" id="permission_infobar">
- <property name="visible">True</property>
+ <child type="titlebar">
+ <object class="AdwHeaderBar">
+ <property name="show-end-title-buttons">True</property>
+ <property name="show-start-title-buttons">False</property>
+ <property name="title-widget">
+ <object class="AdwWindowTitle">
+ <property name="title" translatable="yes">Users</property>
+ </object>
+ </property>
+ <child type="start">
+ <object class="GtkButton" id="back_button">
+ <property name="visible">False</property>
+ <property name="icon-name">go-previous-symbolic</property>
+ <signal name="clicked" handler="show_current_user" object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
</object>
</child>
- <child>
- <object class="GtkStack" id="stack">
- <property name="visible">True</property>
- <property name="visible-child">no_users_box</property>
+ <child type="content">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkOverlay" id="users_overlay">
- <property name="visible">True</property>
- <child type="overlay">
- <object class="GtkRevealer" id="notification_revealer">
- <property name="visible">True</property>
- <property name="halign">GTK_ALIGN_CENTER</property>
- <property name="valign">GTK_ALIGN_START</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <style>
- <class name="app-notification"/>
- </style>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="wrap">True</property>
- <property name="max_width_chars">30</property>
- <property name="label" translatable="yes">Your session needs to be restarted for
changes to take effect</property>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="valign">GTK_ALIGN_CENTER</property>
- <property name="label" translatable="yes">Restart Now</property>
- <signal name="clicked" handler="restart_now" object="CcUserPanel" swapped="yes"/>
- </object>
- </child>
+ <object class="CcPermissionInfobar" id="permission_infobar"/>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible-child">no_users_box</property>
+ <child>
+ <object class="GtkOverlay" id="users_overlay">
+ <child type="overlay">
+ <object class="GtkRevealer" id="notification_revealer">
+ <property name="halign">GTK_ALIGN_CENTER</property>
+ <property name="valign">GTK_ALIGN_START</property>
<child>
- <object class="GtkButton" id="dismiss_button">
- <property name="visible">True</property>
- <property name="valign">GTK_ALIGN_CENTER</property>
- <signal name="clicked" handler="dismiss_notification" object="CcUserPanel"
swapped="yes"/>
+ <object class="GtkBox">
+ <property name="spacing">6</property>
<style>
- <class name="flat"/>
+ <class name="app-notification"/>
</style>
<child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">window-close-symbolic</property>
+ <object class="GtkLabel">
+ <property name="wrap">True</property>
+ <property name="max_width_chars">30</property>
+ <property name="label" translatable="yes">Your session needs to be restarted for
changes to take effect</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="can_focus">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="label" translatable="yes">Restart Now</property>
+ <signal name="clicked" handler="restart_now" object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="dismiss_button">
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <signal name="clicked" handler="dismiss_notification" object="CcUserPanel"
swapped="yes"/>
+ <style>
+ <class name="flat"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
</object>
</child>
</object>
</child>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="accounts_box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="border_width">0</property>
-
<child>
- <object class="CcCarousel" id="carousel">
- <property name="visible">True</property>
- <signal name="item-activated" handler="set_selected_user" object="CcUserPanel"
swapped="yes"/>
- </object>
- <packing>
- <property name="fill">False</property>
- <property name="expand">False</property>
- </packing>
- </child>
-
- <child>
- <object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="expand">True</property>
- <property name="hscrollbar-policy">GTK_POLICY_NEVER</property>
-
+ <object class="AdwPreferencesPage">
<child>
- <object class="HdyClamp">
- <property name="visible">True</property>
- <property name="margin-top">30</property>
- <property name="margin-bottom">30</property>
-
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="halign">GTK_ALIGN_CENTER</property>
- <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
- <property name="spacing">20</property>
-
+ <object class="GtkOverlay">
+ <property name="halign">center</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="valign">GTK_ALIGN_CENTER</property>
- <property name="spacing">10</property>
- <property name="margin-top">10</property>
- <property name="margin-bottom">10</property>
- <child>
- <object class="GtkStack" id="user_icon_stack">
- <property name="visible">True</property>
- <property name="halign">GTK_ALIGN_END</property>
- <style>
- <class name="user-icon-button"/>
- </style>
- <child>
- <object class="CcUserImage" id="user_icon_image">
- <property name="visible">True</property>
- <property name="icon_name">avatar-default</property>
- <property name="pixel_size">96</property>
- <property name="halign">GTK_ALIGN_END</property>
- <style>
- <class name="user-icon-button"/>
- </style>
- <child internal-child="accessible">
- <object class="AtkObject">
- <property name="accessible-name" translatable="yes">User
Icon</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkToggleButton" id="user_icon_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <style>
- <class name="user-icon-button"/>
- </style>
- <child internal-child="accessible">
- <object class="AtkObject">
- <property name="accessible-name" translatable="yes">User
Icon</property>
- </object>
- </child>
- <child>
- <object class="CcUserImage" id="user_icon_image2">
- <property name="visible">True</property>
- <property name="icon_name">avatar-default</property>
- <property name="pixel_size">96</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
-
+ <object class="AdwAvatar" id="user_avatar">
+ <property name="show-initials">True</property>
+ <property name="size">120</property>
+ <property name="halign">center</property>
+ </object>
+ </child>
+ <child type="overlay">
+ <object class="GtkMenuButton" id="user_avatar_edit_button">
+ <property name="sensitive">False</property>
+ <property name="halign">end</property>
+ <property name="valign">end</property>
+ <property name="icon-name">document-edit-symbolic</property>
+ <property name="popover">
+ <object class="CcAvatarChooser" id="avatar_chooser"/>
+ </property>
+ <style>
+ <class name="circular"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="authentication_and_login_box">
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Name</property>
+ <child>
+ <object class="GtkStack" id="full_name_stack">
+ <property name="hhomogeneous">False</property>
<child>
- <object class="GtkStack" id="full_name_stack">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="full_name_label">
- <property name="visible">True</property>
- <property name="halign">GTK_ALIGN_START</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_END</property>
- <property name="width-chars">18</property>
- <property name="max-width-chars">30</property>
- <property name="xalign">0</property>
- <attributes>
- <attribute name="scale" value="1.2"/>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="full_name_entry">
- <property name="visible">True</property>
- <property name="max-length">255</property>
- <property name="width-chars">18</property>
- <property name="max-width-chars">30</property>
- <property name="valign">GTK_ALIGN_CENTER</property>
- <signal name="activate" handler="full_name_entry_activate"
object="CcUserPanel" swapped="yes"/>
- <signal name="key-press-event"
handler="full_name_entry_key_press_cb" object="CcUserPanel" swapped="yes"/>
- </object>
- </child>
+ <object class="GtkLabel" id="full_name_label">
</object>
</child>
<child>
- <object class="GtkToggleButton" id="full_name_edit_button">
- <property name="visible">True</property>
- <signal name="toggled" handler="full_name_edit_button_toggled"
object="CcUserPanel" swapped="yes"/>
+ <object class="GtkEntry" id="full_name_entry">
+ <property name="max-length">255</property>
+ <property name="width-chars">18</property>
+ <property name="max-width-chars">30</property>
<property name="valign">GTK_ALIGN_CENTER</property>
- <style>
- <class name="circular"/>
- </style>
+ <signal name="activate" handler="full_name_entry_activate"
object="CcUserPanel" swapped="yes"/>
<child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="margin">5</property>
- <property name="icon-name">document-edit-symbolic</property>
+ <object class="GtkEventControllerKey">
+ <property name="propagation-phase">capture</property>
+ <signal name="key-pressed" handler="full_name_entry_key_press_cb"
object="CcUserPanel" swapped="yes"/>
</object>
</child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
-
<child>
- <object class="GtkBox" id="account_settings_box">
- <property name="visible">True</property>
- <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
- <property name="spacing">10</property>
+ <object class="GtkToggleButton" id="full_name_edit_button">
+ <signal name="toggled" handler="full_name_edit_button_toggled"
object="CcUserPanel" swapped="yes"/>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <style>
+ <class name="flat"/>
+ </style>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Account Settings</property>
- <property name="halign">GTK_ALIGN_START</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <object class="GtkImage">
+ <property name="icon-name">document-edit-symbolic</property>
</object>
</child>
- <child>
- <object class="GtkListBox" id="account_settings_listbox">
- <property name="visible">True</property>
- <property name="selection-mode">GTK_SELECTION_NONE</property>
- <signal name="row-activated" handler="activate_row"/>
- <style>
- <class name="boxed-list"/>
- </style>
- <child>
- <object class="HdyActionRow" id="account_type_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">_Administrator</property>
- <property name="subtitle" translatable="yes">Administrators can add
and remove other users, and can change settings for all users.</property>
- <property name="subtitle-lines">0</property>
- <property name="use_underline">True</property>
- <child>
- <object class="GtkSwitch" id="account_type_switch">
- <property name="visible">True</property>
- <property name="valign">center</property>
- <signal name="notify::active" handler="account_type_changed"
object="CcUserPanel" swapped="yes"/>
- </object>
- </child>
- </object>
- </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="password_row">
+ <property name="title" translatable="yes">_Password</property>
+ <property name="use_underline">True</property>
+ <property name="activatable">True</property>
+ <signal name="activated" handler="change_password" object="CcUserPanel"
swapped="yes"/>
+ <child>
+ <object class="GtkLabel" id="password_button_label"/>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="fingerprint_row">
+ <property name="visible">True</property> <!-- FIXME -->
+ <property name="title" translatable="yes">_Fingerprint Login</property>
+ <property name="use_underline">True</property>
+ <property name="activatable">True</property>
+ <signal name="activated" handler="change_fingerprint" object="CcUserPanel"
swapped="yes"/>
+ <child>
+ <object class="GtkLabel" id="fingerprint_state_label">
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="autologin_row">
+ <property name="title" translatable="yes">A_utomatic Login</property>
+ <property name="use_underline">True</property>
+ <property name="activatable_widget">autologin_switch</property>
+ <child>
+ <object class="GtkSwitch" id="autologin_switch">
+ <property name="valign">center</property>
+ <signal name="notify::active" handler="autologin_changed"
object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="last_login_row">
+ <property name="title" translatable="yes">Account Activity</property>
+ <property name="activatable">True</property>
+ <property name="use_underline">True</property>
+ <signal name="activated" handler="show_history" object="CcUserPanel"
swapped="yes"/>
+ <child>
+ <object class="GtkLabel" id="last_login_button_label">
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
- <child>
- <object class="HdyActionRow" id="parental_controls_row">
- <property name="visible">False</property>
- <property name="title" translatable="yes">_Parental
Controls</property>
- <property name="subtitle" translatable="yes">Open the Parental
Controls application.</property>
- <property name="subtitle-lines">0</property>
- <property name="use_underline">True</property>
- <property name="activatable">True</property>
- <property name="visible">False</property>
- <child>
- <object class="GtkLabel" id="parental_controls_button_label">
- <property name="visible">True</property>
- <property name="valign">0.5</property>
- </object>
- </child>
- <child>
- <object class="GtkImage" id="parental_control_go_next">
- <property name="visible">True</property>
- <property name="icon-name">go-next-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- </object>
- </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="account_settings_box">
+ <child>
+ <object class="AdwActionRow" id="account_type_row">
+ <property name="title" translatable="yes">_Administrator</property>
+ <property name="subtitle" translatable="yes">Administrators can add and remove
other users, and can change settings for all users.</property>
+ <property name="subtitle-lines">0</property>
+ <property name="use_underline">True</property>
+ <property name="activatable-widget">account_type_switch</property>
+ <child>
+ <object class="GtkSwitch" id="account_type_switch">
+ <property name="valign">center</property>
+ <signal name="notify::active" handler="account_type_changed"
object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
- <child>
- <object class="HdyActionRow" id="language_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">_Language</property>
- <property name="use_underline">True</property>
- <property name="activatable">True</property>
- <child>
- <object class="GtkLabel" id="language_button_label">
- <property name="visible">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon-name">go-next-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
+ <child>
+ <object class="AdwActionRow" id="parental_controls_row">
+ <property name="visible">False</property>
+ <property name="title" translatable="yes">_Parental Controls</property>
+ <property name="subtitle" translatable="yes">Open the Parental Controls
application.</property>
+ <property name="subtitle-lines">0</property>
+ <property name="use_underline">True</property>
+ <property name="activatable">True</property>
+ <child>
+ <object class="GtkLabel" id="parental_controls_button_label">
+ <property name="valign">0.5</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="parental_control_go_next">
+ <property name="icon-name">go-next-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
</object>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="language_row">
+ <property name="title" translatable="yes">_Language</property>
+ <property name="use_underline">True</property>
+ <property name="activatable">True</property>
+ <signal name="activated" handler="change_language" object="CcUserPanel"
swapped="yes"/>
<child>
- <object class="GtkBox" id="authentication_and_login_box">
- <property name="visible">True</property>
- <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
- <property name="spacing">10</property>
- <property name="margin-top">10</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Authentication &
Login</property>
- <property name="halign">GTK_ALIGN_START</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkListBox" id="authentication_and_login_listbox">
- <property name="visible">True</property>
- <property name="selection-mode">GTK_SELECTION_NONE</property>
- <signal name="row-activated" handler="activate_row"/>
- <style>
- <class name="boxed-list"/>
- </style>
- <child>
- <object class="HdyActionRow" id="password_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">_Password</property>
- <property name="use_underline">True</property>
- <property name="activatable">True</property>
- <child>
- <object class="GtkLabel" id="password_button_label">
- <property name="visible">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon-name">go-next-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="HdyActionRow" id="fingerprint_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">_Fingerprint
Login</property>
- <property name="use_underline">True</property>
- <property name="activatable">True</property>
- <child>
- <object class="GtkLabel" id="fingerprint_state_label">
- <property name="visible">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon-name">go-next-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="HdyActionRow" id="autologin_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">A_utomatic Login</property>
- <property name="use_underline">True</property>
- <property name="activatable_widget">autologin_switch</property>
- <child>
- <object class="GtkSwitch" id="autologin_switch">
- <property name="visible">True</property>
- <property name="valign">center</property>
- <signal name="notify::active" handler="autologin_changed"
object="CcUserPanel" swapped="yes"/>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="HdyActionRow" id="last_login_row">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Account Activity</property>
- <property name="activatable">True</property>
- <property name="use_underline">True</property>
- <child>
- <object class="GtkLabel" id="last_login_button_label">
- <property name="visible">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon-name">go-next-symbolic</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
+ <object class="GtkLabel" id="language_button_label">
+ <style>
+ <class name="dim-label"/>
+ </style>
</object>
</child>
<child>
- <object class="GtkButton" id="remove_user_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="halign">GTK_ALIGN_END</property>
- <property name="label" translatable="yes">Remove User…</property>
- <property name="margin-top">10</property>
- <property name="margin-bottom">10</property>
- <signal name="clicked" handler="delete_user" object="CcUserPanel"
swapped="yes"/>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
<style>
- <class name="destructive-action"/>
+ <class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
</object>
</child>
+
+ <child>
+ <object class="AdwPreferencesGroup">
+ <child>
+ <object class="GtkButton" id="remove_user_button">
+ <property name="visible">False</property>
+ <property name="label" translatable="yes">Remove User…</property>
+ <signal name="clicked" handler="delete_user" object="CcUserPanel" swapped="yes"/>
+ <style>
+ <class name="destructive-action"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup" id="other_users">
+ <property name="visible">False</property>
+ <property name="title" translatable="yes">Other Users</property>
+ <child>
+ <object class="AdwPreferencesRow" id="other_users_row">
+ <child>
+ <object class="GtkListBox" id="other_users_listbox">
+ <property name="selection-mode">none</property>
+ <signal name="row-activated" handler="set_selected_user"
object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="add_user_button">
+ <property name="title" translatable="yes">Add User…</property>
+ <property name="icon-name">list-add-symbolic</property>
+ <property name="activatable">True</property>
+ <signal name="activated" handler="add_user" object="CcUserPanel" swapped="yes"/>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="no_users_box">
- <property name="visible">True</property>
- <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
- <property name="valign">GTK_ALIGN_CENTER</property>
- <property name="spacing">12</property>
- <style>
- <class name="dim-label"/>
- </style>
<child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">avatar-default-symbolic</property>
- <property name="pixel_size">192</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes" comments="Translators: This is the empty state
page label which states that there are no users to show in the panel.">No Users Found</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- <attribute name="scale" value="1.6"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Unlock to add a user account.</property>
+ <object class="GtkBox" id="no_users_box">
+ <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="spacing">12</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">avatar-default-symbolic</property>
+ <property name="pixel_size">192</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes" comments="Translators: This is the empty state
page label which states that there are no users to show in the panel.">No Users Found</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.6"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Unlock to add a user account.</property>
+ </object>
+ </child>
</object>
</child>
</object>
</child>
</object>
</child>
- </object>
- </child>
</template>
- <object class="GtkSizeGroup">
- <property name="mode">both</property>
- <widgets>
- <widget name="user_icon_button"/>
- <widget name="user_icon_image"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup">
- <property name="mode">both</property>
- <widgets>
- <widget name="language_row"/>
- <widget name="password_row"/>
- <widget name="fingerprint_row"/>
- <widget name="autologin_row"/>
- <widget name="last_login_row"/>
- </widgets>
- </object>
</interface>
diff --git a/panels/user-accounts/data/carousel.css b/panels/user-accounts/data/carousel.css
index 738562cee..adab2e50b 100644
--- a/panels/user-accounts/data/carousel.css
+++ b/panels/user-accounts/data/carousel.css
@@ -21,10 +21,3 @@
border-bottom-color: @theme_bg_color;
margin-bottom: -2px;
}
-
-.carousel-item {
- background: transparent;
- box-shadow: none;
- border: none;
- color: @theme_fg_color;
-}
diff --git a/panels/user-accounts/data/join-dialog.ui b/panels/user-accounts/data/join-dialog.ui
index 0fda6f77e..4da78e256 100644
--- a/panels/user-accounts/data/join-dialog.ui
+++ b/panels/user-accounts/data/join-dialog.ui
@@ -3,46 +3,34 @@
<!-- interface-requires gtk+ 3.8 -->
<object class="GtkDialog" id="join-dialog">
<property name="can_focus">False</property>
- <property name="border_width">10</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
- <property name="type_hint">dialog</property>
<property name="title" translatable="yes">Add User</property>
<property name="use_header_bar">1</property>
<child internal-child="headerbar">
<object class="GtkHeaderBar" id="join-dialog-header-bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="show_close_button">False</property>
- <child>
+ <child type="start">
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
<style>
<class name="text-button"/>
</style>
</object>
- <packing>
- <property name="pack_type">start</property>
- </packing>
</child>
- <child>
+ <child type="end">
<object class="GtkButton" id="button2">
<property name="label" translatable="yes" comments="Translators: This button enrolls the
computer in the domain in order to use enterprise logins.">_Enroll</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
<style>
@@ -50,13 +38,10 @@
<class name="suggested-action"/>
</style>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
- <child internal-child="vbox">
+ <child>
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
@@ -65,7 +50,6 @@
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="border_width">5</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
@@ -78,11 +62,6 @@
<attribute name="scale" value="1.2"/>
</attributes>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="label12">
@@ -94,11 +73,6 @@
enrolled in the domain. Please have your network administrator
type their domain password here.</property>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
@@ -120,12 +94,6 @@ type their domain password here.</property>
<class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="join-domain">
@@ -135,12 +103,6 @@ type their domain password here.</property>
<property name="margin_bottom">5</property>
<property name="xalign">0</property>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="label14">
@@ -154,12 +116,6 @@ type their domain password here.</property>
<class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
<object class="GtkEntry" id="join-name">
@@ -170,12 +126,6 @@ type their domain password here.</property>
<property name="invisible_char_set">True</property>
<property name="activates_default">True</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="GtkLabel" id="label15">
@@ -189,12 +139,6 @@ type their domain password here.</property>
<class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
<object class="GtkEntry" id="join-password">
@@ -207,26 +151,10 @@ type their domain password here.</property>
<property name="invisible_char_set">True</property>
<property name="input_purpose">password</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>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
diff --git a/panels/user-accounts/meson.build b/panels/user-accounts/meson.build
index 8ba697ac0..f6c865e0e 100644
--- a/panels/user-accounts/meson.build
+++ b/panels/user-accounts/meson.build
@@ -101,7 +101,6 @@ common_sources = files(
resource_data = files(
'cc-add-user-dialog.ui',
'cc-avatar-chooser.ui',
- 'cc-carousel.ui',
'cc-login-history-dialog.ui',
'cc-password-dialog.ui',
'cc-user-panel.ui',
@@ -109,7 +108,6 @@ resource_data = files(
'data/icons/fingerprint-detection-complete-symbolic.svg',
'data/icons/fingerprint-detection-symbolic.svg',
'data/icons/fingerprint-detection-warning-symbolic.svg',
- 'data/carousel.css',
'data/join-dialog.ui',
'data/user-accounts-dialog.css',
'data/cc-fingerprint-dialog.css',
@@ -152,13 +150,11 @@ enum_headers = [
sources = common_sources + files(
'cc-avatar-chooser.c',
- 'cc-carousel.c',
'cc-crop-area.c',
'cc-fingerprint-manager.c',
'cc-fingerprint-dialog.c',
'cc-login-history-dialog.c',
'cc-password-dialog.c',
- 'cc-user-image.c',
'cc-user-panel.c',
'run-passwd.c',
)
diff --git a/panels/user-accounts/user-accounts.gresource.xml
b/panels/user-accounts/user-accounts.gresource.xml
index 47c987e94..ac8756ac2 100644
--- a/panels/user-accounts/user-accounts.gresource.xml
+++ b/panels/user-accounts/user-accounts.gresource.xml
@@ -3,14 +3,12 @@
<gresource prefix="/org/gnome/control-center/user-accounts">
<file preprocess="xml-stripblanks">cc-add-user-dialog.ui</file>
<file preprocess="xml-stripblanks">cc-avatar-chooser.ui</file>
- <file preprocess="xml-stripblanks">cc-carousel.ui</file>
<file preprocess="xml-stripblanks">cc-login-history-dialog.ui</file>
<file preprocess="xml-stripblanks">cc-password-dialog.ui</file>
<file preprocess="xml-stripblanks">cc-user-panel.ui</file>
<file preprocess="xml-stripblanks">cc-fingerprint-dialog.ui</file>
<file alias="join-dialog.ui" preprocess="xml-stripblanks">data/join-dialog.ui</file>
<file alias="user-accounts-dialog.css">data/user-accounts-dialog.css</file>
- <file alias="carousel.css">data/carousel.css</file>
<file alias="cc-fingerprint-dialog.css">data/cc-fingerprint-dialog.css</file>
</gresource>
diff --git a/panels/user-accounts/user-utils.c b/panels/user-accounts/user-utils.c
index eb818b666..dfcf88017 100644
--- a/panels/user-accounts/user-utils.c
+++ b/panels/user-accounts/user-utils.c
@@ -42,297 +42,6 @@
#define IMAGE_SIZE 512
-typedef struct {
- gchar *text;
- gchar *placeholder_str;
- GIcon *icon;
- gunichar placeholder;
- gulong query_id;
-} IconShapeData;
-
-static IconShapeData *
-icon_shape_data_new (const gchar *text,
- const gchar *placeholder,
- GIcon *icon)
-{
- IconShapeData *data;
-
- data = g_new0 (IconShapeData, 1);
-
- data->text = g_strdup (text);
- data->placeholder_str = g_strdup (placeholder);
- data->placeholder = g_utf8_get_char_validated (placeholder, -1);
- data->icon = g_object_ref (icon);
-
- return data;
-}
-
-static void
-icon_shape_data_free (gpointer user_data)
-{
- IconShapeData *data = user_data;
-
- g_clear_pointer (&data->text, g_free);
- g_clear_pointer (&data->placeholder_str, g_free);
- g_clear_object (&data->icon);
- g_free (data);
-}
-
-static void
-icon_shape_renderer (cairo_t *cr,
- PangoAttrShape *attr,
- gboolean do_path,
- gpointer user_data)
-{
- IconShapeData *data = user_data;
- gdouble x, y;
-
- cairo_get_current_point (cr, &x, &y);
- if (GPOINTER_TO_UINT (attr->data) == data->placeholder) {
- gdouble ascent;
- gdouble height;
- g_autoptr(GdkPixbuf) pixbuf = NULL;
- g_autoptr(GtkIconInfo) info = NULL;
-
- ascent = pango_units_to_double (attr->ink_rect.y);
- height = pango_units_to_double (attr->ink_rect.height);
- info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (),
- data->icon,
- (gint)height,
- GTK_ICON_LOOKUP_FORCE_SIZE |
GTK_ICON_LOOKUP_USE_BUILTIN);
- pixbuf = gtk_icon_info_load_icon (info, NULL);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- cairo_reset_clip (cr);
- gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y + ascent);
- cairo_paint (cr);
- }
-}
-
-static PangoAttrList *
-create_shape_attr_list_for_layout (PangoLayout *layout,
- IconShapeData *data)
-{
- PangoAttrList *attrs;
- PangoFontMetrics *metrics;
- gint ascent, descent;
- PangoRectangle ink_rect, logical_rect;
- const gchar *p;
- const gchar *text;
- gint placeholder_len;
-
- /* Get font metrics and prepare fancy shape size */
- metrics = pango_context_get_metrics (pango_layout_get_context (layout),
- pango_layout_get_font_description (layout),
- NULL);
- ascent = pango_font_metrics_get_ascent (metrics);
- descent = pango_font_metrics_get_descent (metrics);
- pango_font_metrics_unref (metrics);
-
- logical_rect.x = 0;
- logical_rect.y = - ascent;
- logical_rect.width = ascent + descent;
- logical_rect.height = ascent + descent;
-
- ink_rect = logical_rect;
-
- attrs = pango_attr_list_new ();
- text = pango_layout_get_text (layout);
- placeholder_len = strlen (data->placeholder_str);
- for (p = text; (p = strstr (p, data->placeholder_str)); p += placeholder_len) {
- PangoAttribute *attr;
-
- attr = pango_attr_shape_new_with_data (&ink_rect,
- &logical_rect,
- GUINT_TO_POINTER (g_utf8_get_char (p)),
- NULL, NULL);
-
- attr->start_index = p - text;
- attr->end_index = attr->start_index + placeholder_len;
-
- pango_attr_list_insert (attrs, attr);
- }
-
- return attrs;
-}
-
-static gboolean
-query_unlock_tooltip (GtkWidget *widget,
- gint x,
- gint y,
- gboolean keyboard_tooltip,
- GtkTooltip *tooltip)
-{
- GtkWidget *label;
- PangoLayout *layout;
- PangoAttrList *attrs;
- IconShapeData *data;
-
- data = g_object_get_data (G_OBJECT (widget), "icon-shape-data");
- label = g_object_get_data (G_OBJECT (widget), "tooltip-label");
- if (label == NULL) {
- label = gtk_label_new (data->text);
- g_object_ref_sink (label);
- g_object_set_data_full (G_OBJECT (widget),
- "tooltip-label", label, g_object_unref);
- }
-
- layout = gtk_label_get_layout (GTK_LABEL (label));
- pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
- icon_shape_renderer,
- data, NULL);
-
- attrs = create_shape_attr_list_for_layout (layout, data);
- gtk_label_set_attributes (GTK_LABEL (label), attrs);
- pango_attr_list_unref (attrs);
-
- gtk_tooltip_set_custom (tooltip, label);
-
- return TRUE;
-}
-
-void
-setup_tooltip_with_embedded_icon (GtkWidget *widget,
- const gchar *text,
- const gchar *placeholder,
- GIcon *icon)
-{
- IconShapeData *data;
-
- data = g_object_get_data (G_OBJECT (widget), "icon-shape-data");
- if (data) {
- gtk_widget_set_has_tooltip (widget, FALSE);
- g_signal_handler_disconnect (widget, data->query_id);
- g_object_set_data (G_OBJECT (widget), "icon-shape-data", NULL);
- g_object_set_data (G_OBJECT (widget), "tooltip-label", NULL);
- }
-
- if (!placeholder) {
- gtk_widget_set_tooltip_text (widget, text);
- return;
- }
-
- data = icon_shape_data_new (text, placeholder, icon);
- g_object_set_data_full (G_OBJECT (widget),
- "icon-shape-data",
- data,
- icon_shape_data_free);
-
- gtk_widget_set_has_tooltip (widget, TRUE);
- data->query_id = g_signal_connect (widget, "query-tooltip",
- G_CALLBACK (query_unlock_tooltip), NULL);
-
-}
-
-gboolean
-show_tooltip_now (GtkWidget *widget,
- GdkEvent *event)
-{
- GtkSettings *settings;
- gint timeout;
-
- settings = gtk_widget_get_settings (widget);
-
- g_object_get (settings, "gtk-tooltip-timeout", &timeout, NULL);
- g_object_set (settings, "gtk-tooltip-timeout", 1, NULL);
- gtk_tooltip_trigger_tooltip_query (gtk_widget_get_display (widget));
- g_object_set (settings, "gtk-tooltip-timeout", timeout, NULL);
-
- return FALSE;
-}
-
-static gboolean
-query_tooltip (GtkWidget *widget,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- gpointer user_data)
-{
- if (GTK_ENTRY_ICON_SECONDARY == gtk_entry_get_icon_at_pos (GTK_ENTRY (widget), x, y)) {
- g_autofree gchar *tip = NULL;
-
- tip = gtk_entry_get_icon_tooltip_text (GTK_ENTRY (widget),
- GTK_ENTRY_ICON_SECONDARY);
- gtk_tooltip_set_text (tooltip, tip);
-
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-static void
-icon_released (GtkEntry *entry)
-{
- GtkSettings *settings;
- gint timeout;
-
- settings = gtk_widget_get_settings (GTK_WIDGET (entry));
-
- g_object_get (settings, "gtk-tooltip-timeout", &timeout, NULL);
- g_object_set (settings, "gtk-tooltip-timeout", 1, NULL);
- gtk_tooltip_trigger_tooltip_query (gtk_widget_get_display (GTK_WIDGET (entry)));
- g_object_set (settings, "gtk-tooltip-timeout", timeout, NULL);
-}
-
-
-
-void
-set_entry_validation_error (GtkEntry *entry,
- const gchar *text)
-{
- g_object_set (entry, "caps-lock-warning", FALSE, NULL);
- gtk_entry_set_icon_from_icon_name (entry,
- GTK_ENTRY_ICON_SECONDARY,
- "dialog-warning-symbolic");
- gtk_entry_set_icon_activatable (entry,
- GTK_ENTRY_ICON_SECONDARY,
- TRUE);
- g_signal_connect (entry, "icon-release",
- G_CALLBACK (icon_released), NULL);
- g_signal_connect (entry, "query-tooltip",
- G_CALLBACK (query_tooltip), NULL);
- g_object_set (entry, "has-tooltip", TRUE, NULL);
- gtk_entry_set_icon_tooltip_text (entry,
- GTK_ENTRY_ICON_SECONDARY,
- text);
-}
-
-void
-set_entry_generation_icon (GtkEntry *entry)
-{
- g_object_set (entry, "caps-lock-warning", FALSE, NULL);
- gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, "system-run-symbolic");
- gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, TRUE);
-}
-
-void
-set_entry_validation_checkmark (GtkEntry *entry)
-{
- g_object_set (entry, "caps-lock-warning", FALSE, NULL);
- gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, "object-select-symbolic");
- gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE);
-}
-
-void
-clear_entry_validation_error (GtkEntry *entry)
-{
- gboolean warning;
-
- g_object_get (entry, "caps-lock-warning", &warning, NULL);
-
- if (warning)
- return;
-
- g_object_set (entry, "has-tooltip", FALSE, NULL);
- gtk_entry_set_icon_from_pixbuf (entry,
- GTK_ENTRY_ICON_SECONDARY,
- NULL);
- g_object_set (entry, "caps-lock-warning", TRUE, NULL);
-}
-
/* Taken from defines.h in shadow-utils. On Linux, this value is much smaller
* than the sysconf limit LOGIN_NAME_MAX, and values larger than this will
* result in failure when running useradd. We could check UT_NAMESIZE instead,
@@ -364,6 +73,9 @@ is_valid_name (const gchar *name)
gboolean is_empty = TRUE;
const gchar *c;
+ if (name == NULL)
+ return is_empty;
+
/* Valid names must contain:
* 1) at least one character.
* 2) at least one non-"space" character.
@@ -533,8 +245,6 @@ is_valid_username_finish (GAsyncResult *result,
if (tip != NULL) {
*tip = g_steal_pointer (&data->tip);
- if (*tip == NULL)
- *tip = g_strdup (_("This will be used to name your home folder and can’t be
changed."));
}
if (username != NULL)
diff --git a/panels/user-accounts/user-utils.h b/panels/user-accounts/user-utils.h
index 09c6cdd71..0ce08b7a1 100644
--- a/panels/user-accounts/user-utils.h
+++ b/panels/user-accounts/user-utils.h
@@ -25,13 +25,6 @@
G_BEGIN_DECLS
-void setup_tooltip_with_embedded_icon (GtkWidget *widget,
- const gchar *text,
- const gchar *placeholder,
- GIcon *icon);
-gboolean show_tooltip_now (GtkWidget *widget,
- GdkEvent *event);
-
void set_entry_generation_icon (GtkEntry *entry);
void set_entry_validation_checkmark (GtkEntry *entry);
void set_entry_validation_error (GtkEntry *entry,
diff --git a/shell/cc-panel-loader.c b/shell/cc-panel-loader.c
index f9b834c45..66c513e18 100644
--- a/shell/cc-panel-loader.c
+++ b/shell/cc-panel-loader.c
@@ -61,7 +61,7 @@ extern GType cc_sound_panel_get_type (void);
extern GType cc_bolt_panel_get_type (void);
#endif /* BUILD_THUNDERBOLT */
extern GType cc_ua_panel_get_type (void);
-//extern GType cc_user_panel_get_type (void);
+extern GType cc_user_panel_get_type (void);
#ifdef BUILD_WACOM
extern GType cc_wacom_panel_get_type (void);
#endif /* BUILD_WACOM */
@@ -133,7 +133,7 @@ static CcPanelLoaderVtable default_panels[] =
#endif
PANEL_TYPE("universal-access", cc_ua_panel_get_type, NULL),
PANEL_TYPE("usage", cc_usage_panel_get_type, NULL),
- //PANEL_TYPE("user-accounts", cc_user_panel_get_type, NULL),
+ PANEL_TYPE("user-accounts", cc_user_panel_get_type, NULL),
#ifdef BUILD_WACOM
PANEL_TYPE("wacom", cc_wacom_panel_get_type, cc_wacom_panel_static_init_func),
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]