[PATCH] ui/ncurses: Properly reposition cursor after menu update

Samuel Mendoza-Jonas sam.mj at au1.ibm.com
Fri May 15 15:58:24 AEST 2015


The currently selected item in the main menu can be set to an item off
the visible portion of the menu after the additional or removal of a
boot option. Update the currently selected item and/or the current view
such that the item remains in the visible area.

Signed-off-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
---
 ui/ncurses/nc-cui.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 2fc779e..56e7653 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -184,6 +184,7 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 {
 	struct pmenu *menu = cui->main;
 	struct cui_opt_data *cod;
+	int idx, top, rows, cols;
 	static int user_idx = 0;
 
 	/* Was the edit cancelled? */
@@ -222,6 +223,22 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 
 		/* Re-attach the items array. */
 		set_menu_items(menu->ncm, menu->items);
+
+		/* If our index is above the current top row, align
+		 * us to the new top. Otherwise, align us to the new
+		 * bottom */
+		menu_format(cui->main->ncm, &rows, &cols);
+		top = top_row(cui->main->ncm);
+		idx = item_index(item->nci);
+
+		if (top >= idx)
+			top = idx;
+		else
+			top = idx < rows ? 0 : idx - rows + 1;
+
+		set_top_row(cui->main->ncm, top);
+		set_current_item(item->pmenu->ncm, item->nci);
+
 		nc_scr_post(&menu->scr);
 	} else {
 		cod = item->data;
@@ -229,7 +246,6 @@ static void cui_boot_editor_on_exit(struct cui *cui,
 
 	cod->bd = talloc_steal(cod, bd);
 
-	set_current_item(item->pmenu->ncm, item->nci);
 out:
 	cui_set_current(cui, &cui->main->scr);
 	talloc_free(cui->boot_editor);
@@ -562,7 +578,7 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
 		/* If our index is above the current top row, align
 		 * us to the new top. Otherwise, align us to the new
 		 * bottom */
-		top = top < idx ? idx - rows : idx;
+		top = top < idx ? idx - rows + 1 : idx;
 
 		set_top_row(cui->main->ncm, top);
 		set_current_item(cui->main->ncm, selected);
@@ -586,6 +602,7 @@ static void cui_device_remove(struct device *dev, void *arg)
 	struct cui *cui = cui_from_arg(arg);
 	struct boot_option *opt;
 	unsigned int i;
+	int rows, cols, top, last;
 	int result;
 
 	pb_log("%s: %p %s\n", __func__, dev, dev->id);
@@ -622,6 +639,15 @@ static void cui_device_remove(struct device *dev, void *arg)
 
 	result = set_menu_items(cui->main->ncm, cui->main->items);
 
+	/* Move cursor to 'Exit' menu entry */
+	menu_format(cui->main->ncm, &rows, &cols);
+	last = cui->main->item_count - 1;
+	set_current_item(cui->main->ncm, cui->main->items[last]);
+	if (!item_visible(cui->main->items[last])) {
+		top = last < rows ? 0 : last - rows + 1;
+		set_top_row(cui->main->ncm, top);
+	}
+
 	if (result)
 		pb_log("%s: set_menu_items failed: %d\n", __func__, result);
 
-- 
2.1.0



More information about the Petitboot mailing list