From 38eb38caa05e2b5c7ea5ff4bdcdd50189dd664b0 Mon Sep 17 00:00:00 2001 From: santoshxshrestha Date: Thu, 1 Jan 2026 17:58:39 +0545 Subject: [PATCH 1/4] fix: fix the typo in the widget.rs file regarding the help text --- src/apps/core/widget.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/apps/core/widget.rs b/src/apps/core/widget.rs index 3944bfe..d61e894 100644 --- a/src/apps/core/widget.rs +++ b/src/apps/core/widget.rs @@ -19,7 +19,7 @@ const INFO_TEXT: [&str; 2] = [ "(Enter) connect to network | (↑) move up | (↓) move down", ]; -const HELP_TEST: [&str; 11] = [ +const HELP_TEXT: [&str; 12] = [ "[Esc] quit", "(Ctrl+c) force quit", "(Ctrl+R) scan for networks", @@ -31,6 +31,7 @@ const HELP_TEST: [&str; 11] = [ "(h) help", "(?) help", "(s) view saved networks", + "(x) disconnect from current network", ]; impl Widget for &App { @@ -177,7 +178,7 @@ impl Widget for &App { height: area.height * 2 / 3, }; - let help_paragraph = Paragraph::new(HELP_TEST.join("\n")) + let help_paragraph = Paragraph::new(HELP_TEXT.join("\n")) .block(help_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); From c3050b0dfa2b6d18294ebf1dfea14f8ca1796917 Mon Sep 17 00:00:00 2001 From: santoshxshrestha Date: Sat, 3 Jan 2026 02:42:46 +0545 Subject: [PATCH 2/4] fix: removed the cursor handler from the render function --- CHANGELOG.md | 4 ++++ src/apps/core.rs | 26 ++++++++++++++++++++++++++ src/apps/core/widget.rs | 32 -------------------------------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6503694..4708d1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed + +- Fixed the rerendering issue of the cursor by removing it from the render method and placing it to the draw method. + ## [1.1.0] - 2025-01-01 ### Added diff --git a/src/apps/core.rs b/src/apps/core.rs index 1d9a5cb..19a6480 100644 --- a/src/apps/core.rs +++ b/src/apps/core.rs @@ -10,7 +10,13 @@ use crate::apps::handlers::flags::Flags; use crate::utils::connect::connect_to_saved_network; use crate::utils::disconnect_connection::disconnect_connected_network; use crate::utils::scan::scan_networks; +use crossterm::cursor; +use crossterm::cursor::DisableBlinking; +use crossterm::cursor::EnableBlinking; +use crossterm::execute; use ratatui::Frame; +use ratatui::layout::Position; +use std::io; use std::sync::{Arc, Mutex}; mod delete_handler; mod help_handlers; @@ -55,6 +61,26 @@ impl Default for App { impl App { fn draw(&self, frame: &mut Frame) { frame.render_widget(self, frame.area()); + + // Set cursor position for SSID or Password popups + if self.wifi_credentials.flags.show_ssid_popup + || self.wifi_credentials.flags.show_password_popup + { + frame.set_cursor_position(Position::new( + frame.area().x + frame.area().width / 4 + self.wifi_credentials.cursor_pos + 1, + frame.area().y + frame.area().height / 4 + 1, + )); + // The reason for using io::stdout() here is that the crossterm execute! macro needs a writable output target to send + // terminal commands to. io::stdout() provides a handle to the standard output (the terminal), so the commands (Show, MoveTo, EnableBlinking) + // are sent to the terminal for immediate effect. + // + // If you remove io::stdout(), execute! won’t know where to send the commands, resulting in a compilation error. + // You must provide a valid output stream (like io::stdout()) for terminal control commands to work. + // EnableBlinking + let _ = execute!(io::stdout(), cursor::Show, EnableBlinking); + } else { + let _ = execute!(io::stdout(), cursor::Hide, DisableBlinking); + } } fn exit(&mut self) { diff --git a/src/apps/core/widget.rs b/src/apps/core/widget.rs index d61e894..e75a366 100644 --- a/src/apps/core/widget.rs +++ b/src/apps/core/widget.rs @@ -1,9 +1,5 @@ use super::App; -use crossterm::cursor::DisableBlinking; -use crossterm::cursor::EnableBlinking; -use crossterm::cursor::{self, MoveTo}; -use crossterm::execute; use ratatui::widgets::Clear; use ratatui::{ buffer::Buffer, @@ -12,7 +8,6 @@ use ratatui::{ text::Line, widgets::{Block, Paragraph, Row, Table, TableState, Widget}, }; -use std::io; const INFO_TEXT: [&str; 2] = [ "[Esc] quit | (Ctrl+R) scan for networks | (h) help ", @@ -115,7 +110,6 @@ impl Widget for &App { // handle the render of the saved connections list if self.flags.show_saved { Clear.render(area, buf); - let _ = execute!(io::stdout(), cursor::Hide, DisableBlinking); let saved_block = Block::default() .title("Saved Connections") .borders(ratatui::widgets::Borders::ALL) @@ -182,8 +176,6 @@ impl Widget for &App { .block(help_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); - let _ = execute!(io::stdout(), cursor::Hide, DisableBlinking); - help_paragraph.render(help_area, buf); } @@ -209,8 +201,6 @@ impl Widget for &App { .block(popup_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); - let _ = execute!(io::stdout(), cursor::Hide, DisableBlinking); - confirmation_paragraph.render(popup_area, buf); } @@ -234,16 +224,6 @@ impl Widget for &App { .block(popup_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); - let _ = execute!( - io::stdout(), - cursor::Show, - MoveTo( - popup_area.x + self.wifi_credentials.cursor_pos + 1, - popup_area.y + 1, - ), - EnableBlinking - ); - ssid_paragraph.render(popup_area, buf); } @@ -268,16 +248,6 @@ impl Widget for &App { .block(popup_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); - let _ = execute!( - io::stdout(), - cursor::Show, - MoveTo( - popup_area.x + self.wifi_credentials.cursor_pos + 1, - popup_area.y + 1, - ), - EnableBlinking - ); - password_paragraph.render(popup_area, buf); } @@ -306,8 +276,6 @@ impl Widget for &App { .block(status_block) .style(ratatui::style::Style::default().fg(ratatui::style::Color::White)); - let _ = execute!(io::stdout(), cursor::Hide, DisableBlinking); - status_paragraph.render(status_area, buf); } } From b38baeef59bc77b52ac19e45558f47dab0b351a0 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Fri, 2 Jan 2026 21:00:57 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20`cur?= =?UTF-8?q?sor`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @santoshxshrestha. * https://github.com/santoshxshrestha/nmtui/pull/28#issuecomment-3706216163 The following files were modified: * `src/apps/core.rs` * `src/apps/core/widget.rs` --- src/apps/core.rs | 22 +++++++++++++++++++++- src/apps/core/widget.rs | 11 +++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/apps/core.rs b/src/apps/core.rs index 19a6480..af97902 100644 --- a/src/apps/core.rs +++ b/src/apps/core.rs @@ -59,6 +59,17 @@ impl Default for App { } impl App { + /// Render the application UI and manage terminal cursor visibility and position for SSID/password popups. + /// + /// When an SSID or password popup is visible, this sets the terminal cursor to the popup's input position + /// and enables cursor blinking; otherwise it hides the cursor and disables blinking. + /// + /// # Examples + /// + /// ```no_run + /// // Assuming `app` is an initialized `App` and `frame` is a mutable `ratatui::Frame`: + /// // app.draw(&mut frame); + /// ``` fn draw(&self, frame: &mut Frame) { frame.render_widget(self, frame.area()); @@ -83,6 +94,15 @@ impl App { } } + /// Mark the application to exit by setting its internal exit flag. + /// + /// # Examples + /// + /// ``` + /// let mut app = App::default(); + /// app.exit(); + /// assert!(app.app_state.exit); + /// ``` fn exit(&mut self) { self.app_state.exit = true; } @@ -157,4 +177,4 @@ impl App { fn reset_selection(&mut self) { self.selected = 0; } -} +} \ No newline at end of file diff --git a/src/apps/core/widget.rs b/src/apps/core/widget.rs index e75a366..c9744ce 100644 --- a/src/apps/core/widget.rs +++ b/src/apps/core/widget.rs @@ -30,12 +30,11 @@ const HELP_TEXT: [&str; 12] = [ ]; impl Widget for &App { - /// Render the application's terminal UI into the provided drawing area buffer. + /// Render the application's terminal UI into the provided drawing area. /// - /// This draws the main network table and, depending on internal flags and state, - /// overlays the saved-connections list, help menu, delete-confirmation popup, - /// hidden-SSID input popup, password input popup, and status popup. Cursor - /// visibility and blinking are adjusted as needed for input popups. + /// Draws the main network table and, depending on the app's flags and state, + /// conditionally overlays the saved-connections list, help menu, delete-confirmation + /// popup, hidden-SSID input popup, password input popup, and status popup. /// /// # Examples /// @@ -279,4 +278,4 @@ impl Widget for &App { status_paragraph.render(status_area, buf); } } -} +} \ No newline at end of file From ecc9b9b23c6a1f96ef14fc7ae11e567f065cb82d Mon Sep 17 00:00:00 2001 From: santoshxshrestha Date: Sat, 3 Jan 2026 02:51:41 +0545 Subject: [PATCH 4/4] formatter i guess --- src/apps/core.rs | 2 +- src/apps/core/widget.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/core.rs b/src/apps/core.rs index af97902..215c014 100644 --- a/src/apps/core.rs +++ b/src/apps/core.rs @@ -177,4 +177,4 @@ impl App { fn reset_selection(&mut self) { self.selected = 0; } -} \ No newline at end of file +} diff --git a/src/apps/core/widget.rs b/src/apps/core/widget.rs index c9744ce..02a7465 100644 --- a/src/apps/core/widget.rs +++ b/src/apps/core/widget.rs @@ -278,4 +278,4 @@ impl Widget for &App { status_paragraph.render(status_area, buf); } } -} \ No newline at end of file +}