This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository enlightenment.
View the commit online.
commit d90b0be668b6d08f63c2e9fa74b96c5f0eed47d5
Author: Carsten Haitzler <[email protected]>
AuthorDate: Sun Jul 19 09:26:06 2026 +0100
networkmanager: add autofill + store/remember of fields
---
src/modules/networkmanager/agent.c | 39 ++++++++
src/modules/networkmanager/e_mod_main.c | 132 +++++++++++++++++++++++++-
src/modules/networkmanager/e_mod_main.h | 18 ++++
src/modules/networkmanager/e_networkmanager.c | 12 +++
src/modules/networkmanager/e_networkmanager.h | 2 +
5 files changed, 202 insertions(+), 1 deletion(-)
diff --git a/src/modules/networkmanager/agent.c b/src/modules/networkmanager/agent.c
index a3d2ca111..db526c353 100644
--- a/src/modules/networkmanager/agent.c
+++ b/src/modules/networkmanager/agent.c
@@ -31,6 +31,8 @@ struct _E_NM_Agent_Dialog
E_Dialog *dialog;
E_NM_Agent_Request *req;
Eina_Bool is_vpn;
+ char *conn_path;
+ char *setting_name;
/* Wifi mode: single field. */
Evas_Object *psk_entry;
/* VPN mode: parallel arrays of size n_fields. */
@@ -52,6 +54,9 @@ static E_NM_Agent_Dialog *_current_dialog = NULL;
static void
_dialog_send_ok(E_NM_Agent_Dialog *ad)
{
+ const char *setting_name = ad->setting_name;
+ const char *conn_path = ad->conn_path;
+
if (!ad->req) { e_object_del(E_OBJECT(ad->dialog)); return; }
if (!ad->is_vpn)
@@ -59,6 +64,7 @@ _dialog_send_ok(E_NM_Agent_Dialog *ad)
/* elm_entry stores markup internally; convert to plain UTF-8 so that
* passwords containing '<' or '&' survive the round-trip to NM. */
char *psk = elm_entry_markup_to_utf8(elm_entry_entry_get(ad->psk_entry));
+ enm_config_field_value_set(conn_path, setting_name, "psk", psk);
e_nm_agent_reply_secrets(ad->req, psk);
free(psk);
}
@@ -78,6 +84,8 @@ _dialog_send_ok(E_NM_Agent_Dialog *ad)
utf8[i] = elm_entry_markup_to_utf8(
elm_entry_entry_get(ad->field_entries[i]));
values[i] = utf8[i] ?: "";
+ enm_config_field_value_set(conn_path, setting_name,
+ ad->field_names[i], values[i]);
}
e_nm_agent_reply_vpn_secrets(ad->req,
(const char *const *)ad->field_names,
@@ -157,6 +165,8 @@ _dialog_del_cb(void *data)
for (unsigned int i = 0; i < ad->n_fields; i++) free(ad->field_names[i]);
free(ad->field_names);
}
+ free(ad->conn_path);
+ free(ad->setting_name);
free(ad->field_entries);
free(ad);
}
@@ -270,6 +280,19 @@ _field_column_min_width_set(Evas_Object *table, int col)
evas_object_show(rect);
}
+static void
+_entry_text_set_plain(Evas_Object *entry, const char *text)
+{
+ char *markup;
+
+ if (!entry || !text || !text[0]) return;
+ markup = elm_entry_utf8_to_markup(text);
+ if (!markup) return;
+ elm_entry_entry_set(entry, markup);
+ elm_entry_cursor_end_set(entry);
+ free(markup);
+}
+
/* -------------------------------------------------------------------------- */
/* Dialog construction */
/* -------------------------------------------------------------------------- */
@@ -289,6 +312,10 @@ _dialog_new(E_NM_Agent_Request *req, const char *ssid)
ad->dialog = dialog;
ad->req = req;
ad->is_vpn = EINA_FALSE;
+ if (e_nm_agent_request_connection_path_get(req))
+ ad->conn_path = strdup(e_nm_agent_request_connection_path_get(req));
+ if (e_nm_agent_request_setting_name_get(req))
+ ad->setting_name = strdup(e_nm_agent_request_setting_name_get(req));
e_dialog_resizable_set(dialog, 0);
e_dialog_title_set(dialog, _("WiFi Password Required"));
@@ -330,6 +357,10 @@ _dialog_new(E_NM_Agent_Request *req, const char *ssid)
elm_table_pack(table, entry, 1, 0, 1, 1);
evas_object_show(entry);
ad->psk_entry = entry;
+ _entry_text_set_plain(entry,
+ enm_config_field_value_get(ad->conn_path,
+ ad->setting_name,
+ "psk"));
check = elm_check_add(table);
elm_object_text_set(check, _("Show password"));
@@ -373,6 +404,10 @@ _vpn_dialog_new(E_NM_Agent_Request *req, const char *conn_name,
ad->dialog = dialog;
ad->req = req;
ad->is_vpn = EINA_TRUE;
+ if (e_nm_agent_request_connection_path_get(req))
+ ad->conn_path = strdup(e_nm_agent_request_connection_path_get(req));
+ if (e_nm_agent_request_setting_name_get(req))
+ ad->setting_name = strdup(e_nm_agent_request_setting_name_get(req));
ad->n_fields = n_fields;
ad->field_names = calloc(n_fields ?: 1, sizeof(*ad->field_names));
ad->field_entries = calloc(n_fields ?: 1, sizeof(*ad->field_entries));
@@ -461,6 +496,10 @@ _vpn_dialog_new(E_NM_Agent_Request *req, const char *conn_name,
evas_object_show(entry);
ad->field_entries[i] = entry;
+ _entry_text_set_plain(entry,
+ enm_config_field_value_get(ad->conn_path,
+ ad->setting_name,
+ field));
}
evas_object_show(frame);
diff --git a/src/modules/networkmanager/e_mod_main.c b/src/modules/networkmanager/e_mod_main.c
index b14f6aa03..fbd3b6218 100644
--- a/src/modules/networkmanager/e_mod_main.c
+++ b/src/modules/networkmanager/e_mod_main.c
@@ -9,6 +9,7 @@ E_Module *networkmanager_mod = NULL;
E_NM_Config *networkmanager_config = NULL;
static Eina_Stringshare *_theme_path = NULL;
static E_Config_DD *conf_edd = NULL;
+static E_Config_DD *saved_field_edd = NULL;
const char _e_nm_name[] = "networkmanager";
const char _e_nm_Name[] = N_("NetworkManager");
@@ -19,6 +20,111 @@ static void _enm_traffic_timer_start(E_NM_Module_Context *ctxt);
static void _enm_traffic_timer_stop(E_NM_Module_Context *ctxt);
static void _enm_configure_registry_register(void);
static void _enm_configure_registry_unregister(void);
+static void _enm_saved_field_free(E_NM_Saved_Field *sf);
+
+static E_NM_Saved_Field *
+_enm_saved_field_find(const char *conn_path, const char *setting_name,
+ const char *field_name)
+{
+ Eina_List *l;
+ E_NM_Saved_Field *sf;
+
+ if (!networkmanager_config || !conn_path || !setting_name || !field_name)
+ return NULL;
+
+ EINA_LIST_FOREACH(networkmanager_config->saved_fields, l, sf)
+ {
+ if ((!sf->conn_path) || (!sf->setting_name) || (!sf->field_name))
+ continue;
+ if (strcmp(sf->conn_path, conn_path)) continue;
+ if (strcmp(sf->setting_name, setting_name)) continue;
+ if (strcmp(sf->field_name, field_name)) continue;
+ return sf;
+ }
+ return NULL;
+}
+
+static void
+_enm_saved_field_free(E_NM_Saved_Field *sf)
+{
+ if (!sf) return;
+ eina_stringshare_del(sf->conn_path);
+ eina_stringshare_del(sf->setting_name);
+ eina_stringshare_del(sf->field_name);
+ eina_stringshare_del(sf->value);
+ free(sf);
+}
+
+const char *
+enm_config_field_value_get(const char *conn_path, const char *setting_name,
+ const char *field_name)
+{
+ E_NM_Saved_Field *sf;
+
+ sf = _enm_saved_field_find(conn_path, setting_name, field_name);
+ return sf ? sf->value : NULL;
+}
+
+void
+enm_config_field_value_set(const char *conn_path, const char *setting_name,
+ const char *field_name, const char *value)
+{
+ E_NM_Saved_Field *sf;
+
+ if (!networkmanager_config || !conn_path || !setting_name || !field_name)
+ return;
+
+ sf = _enm_saved_field_find(conn_path, setting_name, field_name);
+ if ((!value) || (!value[0]))
+ {
+ if (!sf) return;
+ networkmanager_config->saved_fields =
+ eina_list_remove(networkmanager_config->saved_fields, sf);
+ _enm_saved_field_free(sf);
+ e_config_save_queue();
+ return;
+ }
+
+ if (!sf)
+ {
+ sf = E_NEW(E_NM_Saved_Field, 1);
+ if (!sf) return;
+ sf->conn_path = eina_stringshare_add(conn_path);
+ sf->setting_name = eina_stringshare_add(setting_name);
+ sf->field_name = eina_stringshare_add(field_name);
+ if ((!sf->conn_path) || (!sf->setting_name) || (!sf->field_name))
+ {
+ _enm_saved_field_free(sf);
+ return;
+ }
+ networkmanager_config->saved_fields =
+ eina_list_append(networkmanager_config->saved_fields, sf);
+ }
+
+ eina_stringshare_replace(&sf->value, value);
+ e_config_save_queue();
+}
+
+void
+enm_config_fields_clear_for_connection(const char *conn_path)
+{
+ Eina_List *l, *ln;
+ E_NM_Saved_Field *sf;
+ Eina_Bool changed = EINA_FALSE;
+
+ if (!networkmanager_config || !conn_path) return;
+
+ EINA_LIST_FOREACH_SAFE(networkmanager_config->saved_fields, l, ln, sf)
+ {
+ if ((!sf->conn_path) || strcmp(sf->conn_path, conn_path)) continue;
+ networkmanager_config->saved_fields =
+ eina_list_remove_list(networkmanager_config->saved_fields, l);
+ _enm_saved_field_free(sf);
+ changed = EINA_TRUE;
+ }
+
+ if (changed) e_config_save_queue();
+}
typedef struct _Enm_Traffic_Worker
{
@@ -649,7 +755,11 @@ _enm_vpn_forget_ok_cb(void *data, E_Dialog *d)
{
struct NM_VPN_Connection *vc =
enm_vpn_find_by_uuid(ctxt->nm, ctx->uuid);
- if (vc) enm_vpn_delete(ctxt->nm, vc);
+ if (vc)
+ {
+ enm_config_fields_clear_for_connection(vc->path);
+ enm_vpn_delete(ctxt->nm, vc);
+ }
}
/* Clear the dialog's data ref before delete so the del-attach cb
* cannot double-free the ctx. */
@@ -1100,6 +1210,7 @@ _enm_forget_click_cb(void *data, Evas_Object *obj EINA_UNUSED,
/* Kick off the actual async delete — ConnectionRemoved signal will
* trigger enm_saved_connections_get once NM has committed the removal. */
+ enm_config_fields_clear_for_connection(conn_path);
enm_connection_delete(nm, conn_path);
eina_stringshare_del(conn_path);
}
@@ -3039,12 +3150,23 @@ e_modapi_init(E_Module *m)
E_NM_Module_Context *ctxt;
conf_edd = E_CONFIG_DD_NEW("NetworkManager_Config", E_NM_Config);
+ saved_field_edd =
+ E_CONFIG_DD_NEW("NetworkManager_Saved_Field", E_NM_Saved_Field);
+#undef T
+#undef D
+#define T E_NM_Saved_Field
+#define D saved_field_edd
+ E_CONFIG_VAL(D, T, conn_path, STRI);
+ E_CONFIG_VAL(D, T, setting_name, STRI);
+ E_CONFIG_VAL(D, T, field_name, STRI);
+ E_CONFIG_VAL(D, T, value, STRI);
#undef T
#undef D
#define T E_NM_Config
#define D conf_edd
E_CONFIG_VAL(D, T, config_version, INT);
E_CONFIG_VAL(D, T, poll_time, DOUBLE);
+ E_CONFIG_LIST(D, T, saved_fields, saved_field_edd);
networkmanager_config = e_config_domain_load("module.networkmanager",
conf_edd);
@@ -3154,8 +3276,16 @@ e_modapi_shutdown(E_Module *m)
if (networkmanager_config && networkmanager_config->config_dialog)
e_object_del(E_OBJECT(networkmanager_config->config_dialog));
+ if (networkmanager_config)
+ {
+ E_NM_Saved_Field *sf;
+
+ EINA_LIST_FREE(networkmanager_config->saved_fields, sf)
+ _enm_saved_field_free(sf);
+ }
E_FREE(networkmanager_config);
E_CONFIG_DD_FREE(conf_edd);
+ E_CONFIG_DD_FREE(saved_field_edd);
eina_log_domain_unregister(_e_nm_log_dom);
_e_nm_log_dom = -1;
diff --git a/src/modules/networkmanager/e_mod_main.h b/src/modules/networkmanager/e_mod_main.h
index 97615695e..1561407e3 100644
--- a/src/modules/networkmanager/e_mod_main.h
+++ b/src/modules/networkmanager/e_mod_main.h
@@ -14,11 +14,21 @@ extern int _e_nm_log_dom;
typedef struct E_NM_Instance E_NM_Instance;
typedef struct E_NM_Module_Context E_NM_Module_Context;
typedef struct E_NM_Config E_NM_Config;
+typedef struct E_NM_Saved_Field E_NM_Saved_Field;
+
+struct E_NM_Saved_Field
+{
+ const char *conn_path;
+ const char *setting_name;
+ const char *field_name;
+ const char *value;
+};
struct E_NM_Config
{
int config_version;
double poll_time;
+ Eina_List *saved_fields;
E_Config_Dialog *config_dialog;
E_Module *module;
};
@@ -94,6 +104,14 @@ void enm_popup_del(E_NM_Instance *inst);
void enm_mod_aps_update_now(void);
void enm_config_dialog_show(E_NM_Instance *inst);
void enm_config_poll_time_set(double tim);
+const char *enm_config_field_value_get(const char *conn_path,
+ const char *setting_name,
+ const char *field_name);
+void enm_config_field_value_set(const char *conn_path,
+ const char *setting_name,
+ const char *field_name,
+ const char *value);
+void enm_config_fields_clear_for_connection(const char *conn_path);
const char *e_nm_theme_path(void);
/* Register the password-dialog UI callbacks with the agent subsystem. */
diff --git a/src/modules/networkmanager/e_networkmanager.c b/src/modules/networkmanager/e_networkmanager.c
index f2c1fc738..2eb077c06 100644
--- a/src/modules/networkmanager/e_networkmanager.c
+++ b/src/modules/networkmanager/e_networkmanager.c
@@ -3085,6 +3085,18 @@ e_nm_agent_callbacks_set(const E_NM_Agent_Callbacks *cbs, void *data)
_agent_cb_data = data;
}
+const char *
+e_nm_agent_request_connection_path_get(const E_NM_Agent_Request *req)
+{
+ return req ? req->conn_path : NULL;
+}
+
+const char *
+e_nm_agent_request_setting_name_get(const E_NM_Agent_Request *req)
+{
+ return req ? req->setting_name : NULL;
+}
+
static void
_agent_request_free(E_NM_Agent_Request *req)
{
diff --git a/src/modules/networkmanager/e_networkmanager.h b/src/modules/networkmanager/e_networkmanager.h
index 9ed81d26f..45b934f14 100644
--- a/src/modules/networkmanager/e_networkmanager.h
+++ b/src/modules/networkmanager/e_networkmanager.h
@@ -55,6 +55,8 @@ struct _E_NM_Agent_Callbacks
};
void e_nm_agent_callbacks_set(const E_NM_Agent_Callbacks *cbs, void *data);
+const char *e_nm_agent_request_connection_path_get(const E_NM_Agent_Request *req);
+const char *e_nm_agent_request_setting_name_get(const E_NM_Agent_Request *req);
void e_nm_agent_reply_secrets(E_NM_Agent_Request *req, const char *psk);
void e_nm_agent_reply_cancel(E_NM_Agent_Request *req);
void e_nm_agent_reply_vpn_secrets(E_NM_Agent_Request *req,
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.