Make unsaved Nearby networks clickable, add password-entry dialog
Rows for scanned networks not yet in breadcrumbs' saved config were both dimmed and disabled (set_sensitive(false)), so there was no way to add them from the popover. They now stay visually dimmed via the existing wifi-popover-row-unsaved style but remain clickable, opening a small password dialog that saves + joins the network via `breadcrumbs add` + `breadcrumbs join`.
This commit is contained in:
parent
e057f97e82
commit
8471cc02fe
5 changed files with 98 additions and 9 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -119,7 +119,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "breadbar"
|
name = "breadbar"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bread-theme",
|
"bread-theme",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "breadbar"
|
name = "breadbar"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Minimal status bar and notification daemon for Hyprland on Wayland"
|
description = "Minimal status bar and notification daemon for Hyprland on Wayland"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
|
|
@ -142,3 +142,19 @@ pub fn spawn_join(ssid: String) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fire-and-forget: save a new network with its password, then join it.
|
||||||
|
pub fn spawn_add_and_join(ssid: String, password: String) {
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let added = tokio::process::Command::new("breadcrumbs")
|
||||||
|
.args(["add", &ssid, &password])
|
||||||
|
.output()
|
||||||
|
.await;
|
||||||
|
if matches!(added, Ok(o) if o.status.success()) {
|
||||||
|
let _ = tokio::process::Command::new("breadcrumbs")
|
||||||
|
.args(["join", &ssid])
|
||||||
|
.output()
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
78
src/main.rs
78
src/main.rs
|
|
@ -814,7 +814,6 @@ impl App {
|
||||||
row.add_css_class("wifi-popover-row");
|
row.add_css_class("wifi-popover-row");
|
||||||
if !entry.saved {
|
if !entry.saved {
|
||||||
row.add_css_class("wifi-popover-row-unsaved");
|
row.add_css_class("wifi-popover-row-unsaved");
|
||||||
row.set_sensitive(false);
|
|
||||||
}
|
}
|
||||||
let is_current = entry.ssid == self.current_ssid;
|
let is_current = entry.ssid == self.current_ssid;
|
||||||
if is_current {
|
if is_current {
|
||||||
|
|
@ -837,13 +836,16 @@ impl App {
|
||||||
row_box.append(&lbl);
|
row_box.append(&lbl);
|
||||||
row.set_child(Some(&row_box));
|
row.set_child(Some(&row_box));
|
||||||
|
|
||||||
if entry.saved {
|
|
||||||
let ssid_clone = entry.ssid.clone();
|
let ssid_clone = entry.ssid.clone();
|
||||||
|
let saved = entry.saved;
|
||||||
row.connect_clicked(move |btn| {
|
row.connect_clicked(move |btn| {
|
||||||
|
if saved {
|
||||||
bar::wifi::spawn_join(ssid_clone.clone());
|
bar::wifi::spawn_join(ssid_clone.clone());
|
||||||
|
} else {
|
||||||
|
show_add_network_dialog(btn, ssid_clone.clone());
|
||||||
|
}
|
||||||
close_parent_popover(btn);
|
close_parent_popover(btn);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
self.wifi_popover_box.append(&row);
|
self.wifi_popover_box.append(&row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -901,6 +903,76 @@ fn close_parent_popover(widget: >k4::Button) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Small modal prompting for a password, then saves + joins the network via
|
||||||
|
/// `breadcrumbs add` + `breadcrumbs join`.
|
||||||
|
fn show_add_network_dialog(anchor: >k4::Button, ssid: String) {
|
||||||
|
let dialog = gtk4::Window::new();
|
||||||
|
dialog.set_title(Some(&format!("Add “{ssid}”")));
|
||||||
|
dialog.set_resizable(false);
|
||||||
|
dialog.add_css_class("wifi-add-dialog");
|
||||||
|
if let Some(root) = anchor.root() {
|
||||||
|
if let Ok(win) = root.downcast::<gtk4::Window>() {
|
||||||
|
dialog.set_transient_for(Some(&win));
|
||||||
|
dialog.set_modal(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = gtk4::Box::new(gtk4::Orientation::Vertical, 8);
|
||||||
|
body.set_margin_top(12);
|
||||||
|
body.set_margin_bottom(12);
|
||||||
|
body.set_margin_start(12);
|
||||||
|
body.set_margin_end(12);
|
||||||
|
|
||||||
|
let lbl = gtk4::Label::new(Some(&format!("Password for {ssid}")));
|
||||||
|
lbl.set_xalign(0.0);
|
||||||
|
body.append(&lbl);
|
||||||
|
|
||||||
|
let entry = gtk4::PasswordEntry::new();
|
||||||
|
entry.set_show_peek_icon(true);
|
||||||
|
body.append(&entry);
|
||||||
|
|
||||||
|
let btn_row = gtk4::Box::new(gtk4::Orientation::Horizontal, 8);
|
||||||
|
btn_row.set_halign(gtk4::Align::End);
|
||||||
|
let cancel_btn = gtk4::Button::with_label("Cancel");
|
||||||
|
let connect_btn = gtk4::Button::with_label("Connect");
|
||||||
|
connect_btn.add_css_class("suggested-action");
|
||||||
|
btn_row.append(&cancel_btn);
|
||||||
|
btn_row.append(&connect_btn);
|
||||||
|
body.append(&btn_row);
|
||||||
|
|
||||||
|
dialog.set_child(Some(&body));
|
||||||
|
|
||||||
|
let d = dialog.clone();
|
||||||
|
cancel_btn.connect_clicked(move |_| d.close());
|
||||||
|
|
||||||
|
let dialog_for_connect = dialog.clone();
|
||||||
|
let entry_for_connect = entry.clone();
|
||||||
|
let ssid_for_connect = ssid.clone();
|
||||||
|
connect_btn.connect_clicked(move |_| {
|
||||||
|
let password = entry_for_connect.text().to_string();
|
||||||
|
if password.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bar::wifi::spawn_add_and_join(ssid_for_connect.clone(), password);
|
||||||
|
dialog_for_connect.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
let dialog_for_activate = dialog.clone();
|
||||||
|
let entry_for_activate = entry.clone();
|
||||||
|
let ssid_for_activate = ssid.clone();
|
||||||
|
entry.connect_activate(move |_| {
|
||||||
|
let password = entry_for_activate.text().to_string();
|
||||||
|
if password.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bar::wifi::spawn_add_and_join(ssid_for_activate.clone(), password);
|
||||||
|
dialog_for_activate.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.present();
|
||||||
|
entry.grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
fn stat_pair(icon_svg: &str, label: >k4::Label) -> gtk4::Box {
|
fn stat_pair(icon_svg: &str, label: >k4::Label) -> gtk4::Box {
|
||||||
let pair = gtk4::Box::new(gtk4::Orientation::Horizontal, 0);
|
let pair = gtk4::Box::new(gtk4::Orientation::Horizontal, 0);
|
||||||
pair.add_css_class("stat-pair");
|
pair.add_css_class("stat-pair");
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ fn load_css() -> String {
|
||||||
.wifi-popover-row-active {{ color: {accent}; }}\
|
.wifi-popover-row-active {{ color: {accent}; }}\
|
||||||
.wifi-popover-row-unsaved {{ opacity: 0.4; }}\
|
.wifi-popover-row-unsaved {{ opacity: 0.4; }}\
|
||||||
.wifi-popover-loading {{ opacity: 0.5; padding: 8px; }}\
|
.wifi-popover-loading {{ opacity: 0.5; padding: 8px; }}\
|
||||||
|
window.wifi-add-dialog {{ background-color: {bg_rgba}; color: {on_bg}; min-width: 240px; }}\
|
||||||
.media-widget {{ border-radius: 4px; padding: 0 6px; cursor: pointer; }}\
|
.media-widget {{ border-radius: 4px; padding: 0 6px; cursor: pointer; }}\
|
||||||
.media-widget:hover {{ background: alpha({on_bg}, 0.10); }}\
|
.media-widget:hover {{ background: alpha({on_bg}, 0.10); }}\
|
||||||
.media-indicator {{ font-size: 11px; opacity: 0.7; margin-right: 2px; }}\
|
.media-indicator {{ font-size: 11px; opacity: 0.7; margin-right: 2px; }}\
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue