This is an automated email from the git hooks/post-receive script.
git pushed a commit to reference refs/pull/125/head
in repository enlightenment.
View the commit online.
commit 7e1c607443090a7e5b75fe7eebcaf6d39f3a0167
Author: [email protected] <[email protected]>
AuthorDate: Mon Mar 9 21:18:45 2026 -0600
feat(networkmanager): add saved connections query and delete via D-Bus
Implements enm_saved_connections_get() which queries NM Settings for all
saved connections, decodes the 802-11-wireless SSID byte array, and
populates NM_Manager.saved_connections (SSID -> D-Bus path hash).
Implements enm_connection_delete() to call Delete on a Settings.Connection
proxy. Both use a _Saved_Conn_Ctx context struct to safely carry the D-Bus
path through async callbacks, since eldbus_message_path_get() returns NULL
for method reply messages.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
src/modules/connman/e_mod_main.c | 6 +-
src/modules/networkmanager/e_networkmanager.c | 193 ++++++++++++++++++++++++++
src/modules/networkmanager/e_networkmanager.h | 7 +
3 files changed, 205 insertions(+), 1 deletion(-)
diff --git a/src/modules/connman/e_mod_main.c b/src/modules/connman/e_mod_main.c
index 8151ffbd3..5dc159204 100644
--- a/src/modules/connman/e_mod_main.c
+++ b/src/modules/connman/e_mod_main.c
@@ -123,7 +123,11 @@ _econnman_service_new_end(struct Connman_Manager *cm,
}
fd = malloc(sizeof(*fd));
- EINA_SAFETY_ON_NULL_RETURN_VAL(fd, end);
+ if (!fd)
+ {
+ evas_object_del(end);
+ return NULL;
+ }
fd->cm = cm;
fd->path = eina_stringshare_add(cs->path);
diff --git a/src/modules/networkmanager/e_networkmanager.c b/src/modules/networkmanager/e_networkmanager.c
index 1279314fd..84fa76ba5 100644
--- a/src/modules/networkmanager/e_networkmanager.c
+++ b/src/modules/networkmanager/e_networkmanager.c
@@ -15,6 +15,9 @@
#define NM_IFACE_IP4 "org.freedesktop.NetworkManager.IP4Config"
#define NM_IFACE_PROPS "org.freedesktop.DBus.Properties"
#define NM_IFACE_AGENT_MGR "org.freedesktop.NetworkManager.AgentManager"
+#define NM_IFACE_SETTINGS "org.freedesktop.NetworkManager.Settings"
+#define NM_IFACE_SCONN "org.freedesktop.NetworkManager.Settings.Connection"
+#define NM_SETTINGS_PATH "/org/freedesktop/NetworkManager/Settings"
#define NM_CONNECTION_TIMEOUT (60 * 1000)
@@ -1068,6 +1071,190 @@ _manager_device_removed(void *data, const Eldbus_Message *msg)
eina_stringshare_del(shared);
}
+/* -------------------------------------------------------------------------- */
+/* Saved connections (for forget button) */
+/* -------------------------------------------------------------------------- */
+
+struct _Saved_Conn_Ctx
+{
+ struct NM_Manager *nm;
+ const char *path; /* stringshare: connection D-Bus object path */
+ Eldbus_Proxy *proxy; /* Settings.Connection proxy — unref in callback */
+ Eldbus_Object *obj; /* connection object — unref in callback */
+};
+
+static void
+_saved_conn_settings_cb(void *data, const Eldbus_Message *msg,
+ Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct _Saved_Conn_Ctx *ctx = data;
+ Eldbus_Message_Iter *settings, *dict_entry, *setting_dict, *variant;
+ const char *setting_name, *key;
+ char ssid_str[256];
+
+ if (eldbus_message_error_get(msg, NULL, NULL))
+ goto done;
+ if (!eldbus_message_arguments_get(msg, "a{sa{sv}}", &settings))
+ goto done;
+
+ while (eldbus_message_iter_get_and_next(settings, 'e', &dict_entry))
+ {
+ Eldbus_Message_Iter *inner_entry;
+
+ if (!eldbus_message_iter_arguments_get(dict_entry, "sa{sv}",
+ &setting_name, &setting_dict))
+ continue;
+
+ if (strcmp(setting_name, "802-11-wireless") != 0)
+ continue;
+
+ while (eldbus_message_iter_get_and_next(setting_dict, 'e', &inner_entry))
+ {
+ if (!eldbus_message_iter_arguments_get(inner_entry, "sv",
+ &key, &variant))
+ continue;
+
+ if (!strcmp(key, "ssid"))
+ {
+ Eldbus_Message_Iter *ssid_iter;
+ unsigned char byte;
+ int i = 0;
+
+ if (!eldbus_message_iter_arguments_get(variant, "ay", &ssid_iter))
+ continue;
+
+ while (eldbus_message_iter_get_and_next(ssid_iter, 'y', &byte)
+ && i < (int)(sizeof(ssid_str) - 1))
+ ssid_str[i++] = (char)byte;
+ ssid_str[i] = '\0';
+
+ if (i > 0 && ctx->nm->saved_connections)
+ {
+ /* Remove old entry first to avoid leaking stringshare */
+ eina_hash_del_by_key(ctx->nm->saved_connections, ssid_str);
+ eina_hash_add(ctx->nm->saved_connections, ssid_str,
+ eina_stringshare_add(ctx->path));
+
+ /* Trigger popup refresh so forget buttons appear */
+ enm_mod_aps_changed(ctx->nm);
+ }
+ goto done;
+ }
+ }
+ }
+
+done:
+ eldbus_proxy_unref(ctx->proxy);
+ eldbus_object_unref(ctx->obj);
+ eina_stringshare_del(ctx->path);
+ free(ctx);
+}
+
+static void
+_saved_conn_list_cb(void *data, const Eldbus_Message *msg,
+ Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct NM_Manager *nm = data;
+ Eldbus_Message_Iter *conn_array;
+ const char *conn_path;
+
+ if (eldbus_message_error_get(msg, NULL, NULL))
+ return;
+ if (!eldbus_message_arguments_get(msg, "ao", &conn_array))
+ return;
+
+ while (eldbus_message_iter_get_and_next(conn_array, 'o', &conn_path))
+ {
+ struct _Saved_Conn_Ctx *ctx;
+
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx) continue;
+
+ ctx->nm = nm;
+ ctx->path = eina_stringshare_add(conn_path);
+ ctx->obj = eldbus_object_get(conn, NM_BUS_NAME, conn_path);
+ ctx->proxy = eldbus_proxy_get(ctx->obj, NM_IFACE_SCONN);
+
+ eldbus_proxy_call(ctx->proxy, "GetSettings",
+ _saved_conn_settings_cb, ctx, -1, "");
+ /* ctx, proxy, and obj are freed/unref'd inside _saved_conn_settings_cb */
+ }
+}
+
+static void
+_saved_connections_free_cb(void *data)
+{
+ eina_stringshare_del(data);
+}
+
+void
+enm_saved_connections_get(struct NM_Manager *nm)
+{
+ Eldbus_Object *settings_obj;
+ Eldbus_Proxy *settings_proxy;
+
+ EINA_SAFETY_ON_NULL_RETURN(nm);
+
+ if (nm->saved_connections)
+ eina_hash_free(nm->saved_connections);
+ nm->saved_connections = eina_hash_string_superfast_new(
+ _saved_connections_free_cb);
+
+ settings_obj = eldbus_object_get(conn, NM_BUS_NAME, NM_SETTINGS_PATH);
+ settings_proxy = eldbus_proxy_get(settings_obj, NM_IFACE_SETTINGS);
+ eldbus_proxy_call(settings_proxy, "ListConnections",
+ _saved_conn_list_cb, nm, -1, "");
+ /* Unref immediately — Eldbus holds internal refs during the pending call */
+ eldbus_proxy_unref(settings_proxy);
+ eldbus_object_unref(settings_obj);
+}
+
+static void
+_connection_delete_cb(void *data, const Eldbus_Message *msg,
+ Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct _Saved_Conn_Ctx *ctx = data;
+ const char *err_name, *err_msg;
+
+ if (eldbus_message_error_get(msg, &err_name, &err_msg))
+ {
+ ERR("Failed to delete connection %s: %s %s",
+ ctx->path, err_name, err_msg);
+ goto done;
+ }
+
+ INF("Connection %s deleted successfully", ctx->path);
+ /* Refresh saved connections to update forget button visibility */
+ enm_saved_connections_get(ctx->nm);
+
+done:
+ eldbus_proxy_unref(ctx->proxy);
+ eldbus_object_unref(ctx->obj);
+ eina_stringshare_del(ctx->path);
+ free(ctx);
+}
+
+void
+enm_connection_delete(struct NM_Manager *nm, const char *connection_path)
+{
+ struct _Saved_Conn_Ctx *ctx;
+
+ EINA_SAFETY_ON_NULL_RETURN(nm);
+ EINA_SAFETY_ON_NULL_RETURN(connection_path);
+
+ ctx = malloc(sizeof(*ctx));
+ EINA_SAFETY_ON_NULL_RETURN(ctx);
+
+ ctx->nm = nm;
+ ctx->path = eina_stringshare_add(connection_path);
+ ctx->obj = eldbus_object_get(conn, NM_BUS_NAME, connection_path);
+ ctx->proxy = eldbus_proxy_get(ctx->obj, NM_IFACE_SCONN);
+
+ eldbus_proxy_call(ctx->proxy, "Delete",
+ _connection_delete_cb, ctx, -1, "");
+ /* ctx, proxy, and obj are freed/unref'd inside _connection_delete_cb */
+}
+
static struct NM_Manager *
_manager_new(void)
{
@@ -1126,6 +1313,12 @@ _manager_free(struct NM_Manager *nm)
_device_free(dev);
}
+ if (nm->saved_connections)
+ {
+ eina_hash_free(nm->saved_connections);
+ nm->saved_connections = NULL;
+ }
+
free(nm->ip_address);
eina_stringshare_del(nm->active_ap_path);
eina_stringshare_del(nm->active_connection_path);
diff --git a/src/modules/networkmanager/e_networkmanager.h b/src/modules/networkmanager/e_networkmanager.h
index 22336f060..553ca6db9 100644
--- a/src/modules/networkmanager/e_networkmanager.h
+++ b/src/modules/networkmanager/e_networkmanager.h
@@ -118,6 +118,9 @@ struct NM_Manager
Eldbus_Proxy *ip4_proxy;
Eldbus_Object *ip4_obj;
const char *ip4_path;
+
+ /* Saved WiFi connections: SSID (string) -> connection D-Bus path (stringshare) */
+ Eina_Hash *saved_connections;
};
/* Ecore Events */
@@ -151,6 +154,10 @@ const char *enm_state_to_str(enum NM_State state);
const char *enm_device_type_to_str(enum NM_Device_Type type);
const char *enm_ap_security_to_str(uint32_t wpa_flags, uint32_t rsn_flags);
+/* Saved connections */
+void enm_saved_connections_get(struct NM_Manager *nm);
+void enm_connection_delete(struct NM_Manager *nm, const char *connection_path);
+
/* Log */
extern int _e_nm_log_dom;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.