From dcf0fd00a0074b21fcaedc64f237e79c992db1df Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 9 Apr 2026 12:02:41 +0700 Subject: [PATCH] ui: add wifi_hidden_prompt dialog Modal SSID + optional passphrase prompt with the same callback shape as wifi_auth_prompt. Used by the upcoming popup "Hidden..." button. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/meson.build | 1 + src/ui/wifi_auth.c | 27 ++++++++-- src/ui/wifi_auth.h | 4 +- src/ui/wifi_hidden.c | 115 +++++++++++++++++++++++++++++++++++++++++++ src/ui/wifi_hidden.h | 13 +++++ 5 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 src/ui/wifi_hidden.c create mode 100644 src/ui/wifi_hidden.h diff --git a/src/meson.build b/src/meson.build index 7b069c1..a7a4324 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,6 +12,7 @@ e_iwd_sources = [ 'iwd/iwd_network.c', 'ui/wifi_list.c', 'ui/wifi_auth.c', + 'ui/wifi_hidden.c', 'ui/wifi_status.c', ] diff --git a/src/ui/wifi_auth.c b/src/ui/wifi_auth.c index 1b5614a..f5e8842 100644 --- a/src/ui/wifi_auth.c +++ b/src/ui/wifi_auth.c @@ -3,6 +3,7 @@ typedef struct _Auth_Ctx { + Evas_Object *win; /* top-level window hosting the popup */ Evas_Object *popup; Evas_Object *entry; Wifi_Auth_Cb cb; @@ -16,7 +17,7 @@ _finish(Auth_Ctx *c, Eina_Bool ok, const char *pass) if (c->fired) return; c->fired = EINA_TRUE; if (c->cb) c->cb(c->data, pass, ok); - evas_object_del(c->popup); + if (c->win) evas_object_del(c->win); free(c); } @@ -40,14 +41,28 @@ _on_del(void *data, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *ev EI _finish(data, EINA_FALSE, NULL); } -void -wifi_auth_prompt(Evas_Object *parent, const char *ssid, +Evas_Object * +wifi_auth_prompt(Evas_Object *parent EINA_UNUSED, const char *ssid, Wifi_Auth_Cb cb, void *data) { Auth_Ctx *c = calloc(1, sizeof(*c)); c->cb = cb; c->data = data; - Evas_Object *p = elm_popup_add(parent); + /* A floating top-level window so the popup is actually visible — + * elm_popup parented to a gadcon popup's sub-canvas never shows. */ + Evas_Object *win = elm_win_add(NULL, "eiwd-auth", ELM_WIN_DIALOG_BASIC); + elm_win_title_set(win, "iwd Wi-Fi"); + elm_win_autodel_set(win, EINA_TRUE); + elm_win_center(win, EINA_TRUE, EINA_TRUE); + evas_object_resize(win, 360, 200); + c->win = win; + + Evas_Object *bg = elm_bg_add(win); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bg); + evas_object_show(bg); + + Evas_Object *p = elm_popup_add(win); c->popup = p; char title[256]; snprintf(title, sizeof(title), "Connect to %s", ssid ? ssid : "network"); @@ -79,8 +94,10 @@ wifi_auth_prompt(Evas_Object *parent, const char *ssid, elm_object_part_content_set(p, "button2", bok); evas_object_smart_callback_add(bok, "clicked", _on_ok, c); - evas_object_event_callback_add(p, EVAS_CALLBACK_DEL, _on_del, c); + evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _on_del, c); evas_object_show(p); + evas_object_show(win); elm_object_focus_set(entry, EINA_TRUE); + return win; } diff --git a/src/ui/wifi_auth.h b/src/ui/wifi_auth.h index 561d2ce..19a738b 100644 --- a/src/ui/wifi_auth.h +++ b/src/ui/wifi_auth.h @@ -7,7 +7,7 @@ typedef void (*Wifi_Auth_Cb)(void *data, const char *passphrase, Eina_Bool ok); /* Show a modal passphrase dialog. cb is called exactly once with ok=EINA_TRUE * + passphrase, or ok=EINA_FALSE on cancel. The dialog destroys itself. */ -void wifi_auth_prompt(Evas_Object *parent, const char *ssid, - Wifi_Auth_Cb cb, void *data); +Evas_Object *wifi_auth_prompt(Evas_Object *parent, const char *ssid, + Wifi_Auth_Cb cb, void *data); #endif diff --git a/src/ui/wifi_hidden.c b/src/ui/wifi_hidden.c new file mode 100644 index 0000000..1e936f8 --- /dev/null +++ b/src/ui/wifi_hidden.c @@ -0,0 +1,115 @@ +#include "wifi_hidden.h" +#include + +typedef struct _Hidden_Ctx +{ + Evas_Object *win; + Evas_Object *popup; + Evas_Object *e_ssid; + Evas_Object *e_pass; + Wifi_Hidden_Cb cb; + void *data; + Eina_Bool fired; +} Hidden_Ctx; + +static void +_finish(Hidden_Ctx *c, Eina_Bool ok) +{ + if (c->fired) return; + c->fired = EINA_TRUE; + const char *ssid = ok ? elm_entry_entry_get(c->e_ssid) : NULL; + const char *pass = ok ? elm_entry_entry_get(c->e_pass) : NULL; + if (c->cb) c->cb(c->data, ssid, pass, ok); + if (c->win) evas_object_del(c->win); + free(c); +} + +static void +_on_ok(void *data, Evas_Object *o EINA_UNUSED, void *ev EINA_UNUSED) +{ + Hidden_Ctx *c = data; + const char *ssid = elm_entry_entry_get(c->e_ssid); + if (!ssid || !*ssid) return; /* require non-empty SSID */ + _finish(c, EINA_TRUE); +} + +static void +_on_cancel(void *data, Evas_Object *o EINA_UNUSED, void *ev EINA_UNUSED) +{ + _finish(data, EINA_FALSE); +} + +static void +_on_del(void *data, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *ev EINA_UNUSED) +{ + _finish(data, EINA_FALSE); +} + +static Evas_Object * +_labelled_entry(Evas_Object *box, const char *label_text, Eina_Bool password) +{ + Evas_Object *lbl = elm_label_add(box); + elm_object_text_set(lbl, label_text); + evas_object_size_hint_align_set(lbl, 0.0, 0.5); + elm_box_pack_end(box, lbl); + evas_object_show(lbl); + + Evas_Object *e = elm_entry_add(box); + elm_entry_single_line_set(e, EINA_TRUE); + elm_entry_scrollable_set(e, EINA_TRUE); + if (password) elm_entry_password_set(e, EINA_TRUE); + evas_object_size_hint_weight_set(e, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(e, EVAS_HINT_FILL, 0); + elm_box_pack_end(box, e); + evas_object_show(e); + return e; +} + +void +wifi_hidden_prompt(Evas_Object *parent EINA_UNUSED, Wifi_Hidden_Cb cb, void *data) +{ + Hidden_Ctx *c = calloc(1, sizeof(*c)); + c->cb = cb; c->data = data; + + /* Floating top-level so the popup actually shows. */ + Evas_Object *win = elm_win_add(NULL, "eiwd-hidden", ELM_WIN_DIALOG_BASIC); + elm_win_title_set(win, "iwd Wi-Fi"); + elm_win_autodel_set(win, EINA_TRUE); + elm_win_center(win, EINA_TRUE, EINA_TRUE); + evas_object_resize(win, 360, 220); + c->win = win; + + Evas_Object *bg = elm_bg_add(win); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bg); + evas_object_show(bg); + + Evas_Object *p = elm_popup_add(win); + c->popup = p; + elm_object_part_text_set(p, "title,text", "Connect to hidden network"); + + Evas_Object *box = elm_box_add(p); + elm_box_padding_set(box, 0, 4); + + c->e_ssid = _labelled_entry(box, "SSID:", EINA_FALSE); + c->e_pass = _labelled_entry(box, "Passphrase (optional):", EINA_TRUE); + + evas_object_show(box); + elm_object_content_set(p, box); + + Evas_Object *bcancel = elm_button_add(p); + elm_object_text_set(bcancel, "Cancel"); + elm_object_part_content_set(p, "button1", bcancel); + evas_object_smart_callback_add(bcancel, "clicked", _on_cancel, c); + + Evas_Object *bok = elm_button_add(p); + elm_object_text_set(bok, "Connect"); + elm_object_part_content_set(p, "button2", bok); + evas_object_smart_callback_add(bok, "clicked", _on_ok, c); + + evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _on_del, c); + + evas_object_show(p); + evas_object_show(win); + elm_object_focus_set(c->e_ssid, EINA_TRUE); +} diff --git a/src/ui/wifi_hidden.h b/src/ui/wifi_hidden.h new file mode 100644 index 0000000..09b4dde --- /dev/null +++ b/src/ui/wifi_hidden.h @@ -0,0 +1,13 @@ +#ifndef WIFI_HIDDEN_H +#define WIFI_HIDDEN_H + +#include + +/* Called once with ok=EINA_TRUE + ssid (and optional passphrase, may be ""), + * or ok=EINA_FALSE on cancel. The dialog destroys itself. */ +typedef void (*Wifi_Hidden_Cb)(void *data, const char *ssid, + const char *passphrase, Eina_Bool ok); + +void wifi_hidden_prompt(Evas_Object *parent, Wifi_Hidden_Cb cb, void *data); + +#endif