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.

Reply via email to