Lagrange [dev]

Improved focus switching for dialogs

=> d3cb0d94c52ab75032fc17ab477b251b5b1356ef

diff --git a/res/about/version.gmi b/res/about/version.gmi
index a76769db..021db644 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -7,6 +7,7 @@
 # Release notes
 
 ## 1.1.1
+* Fixed focus cycling inside dialogs. Widgets outside a dialog are not allowed to be focused.
 * Fixed missing cursor in the New Identity "Valid until" field.
 * Fixed word wrapping issue in unread feed entry titles.
 * Fixed "Import Links as Bookmarks" so it can be used to import local copies of remote bookmarks when viewing the remote source page.
diff --git a/src/app.c b/src/app.c
index 29d88c2b..f44fdf4f 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1008,7 +1008,7 @@ static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) {
                     sscanf(cstr_String(text_InputWidget(findChild_Widget(dlg, "ident.until"))),
                            "%04u-%u-%u %u:%u:%u",
                            &val[0], &val[1], &val[2], &val[3], &val[4], &val[5]);
-                if (n <= 0 || val[0] < (unsigned) today.year) {
+                if (n <= 0) {
                     makeMessage_Widget(orange_ColorEscape "INVALID DATE",
                                        "Please check the \"Valid until\" date. Examples:\n"
                                        "\u2022 2030\n"
@@ -1022,6 +1022,7 @@ static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) {
                 until.hour   = n >= 4 ? val[3] : 0;
                 until.minute = n >= 5 ? val[4] : 0;
                 until.second = n == 6 ? val[5] : 0;
+                until.gmtOffsetSeconds = today.gmtOffsetSeconds;
                 /* In the past? */ {
                     iTime now, t;
                     initCurrent_Time(&now);
@@ -1471,6 +1472,7 @@ iBool handleCommand_App(const char *cmd) {
     }
     else if (equal_Command(cmd, "ident.new")) {
         iWidget *dlg = makeIdentityCreation_Widget();
+        setFocus_Widget(findChild_Widget(dlg, "ident.until"));
         setCommandHandler_Widget(dlg, handleIdentityCreationCommands_);
         return iTrue;
     }
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index ae73c9c9..3f799e3c 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -331,6 +331,7 @@ void end_InputWidget(iInputWidget *d, iBool accept) {
 }
 
 static void insertChar_InputWidget_(iInputWidget *d, iChar chr) {
+    iWidget *w = as_Widget(d);
     if (d->mode == insert_InputMode) {
         insert_Array(&d->text, d->cursor, &chr);
         d->cursor++;
@@ -341,7 +342,8 @@ static void insertChar_InputWidget_(iInputWidget *d, iChar chr) {
         }
         set_Array(&d->text, d->cursor++, &chr);
         if (d->maxLen && d->cursor == d->maxLen) {
-            setFocus_Widget(NULL);
+            iWidget *nextFocus = findFocusable_Widget(w, forward_WidgetFocusDir);
+            setFocus_Widget(nextFocus == w ? NULL : nextFocus);
         }
     }
     showCursor_InputWidget_(d);
diff --git a/src/ui/util.c b/src/ui/util.c
index 91945db8..4d5ed916 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -764,9 +764,9 @@ iWidget *makeSheet_Widget(const char *id) {
     setFrameColor_Widget(sheet, uiSeparator_ColorId);
     setBackgroundColor_Widget(sheet, uiBackground_ColorId);
     setFlags_Widget(sheet,
-                    mouseModal_WidgetFlag | keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag |
-                        arrangeSize_WidgetFlag | centerHorizontal_WidgetFlag |
-                        overflowScrollable_WidgetFlag,
+                    focusRoot_WidgetFlag | mouseModal_WidgetFlag | keepOnTop_WidgetFlag |
+                        arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag |
+                        centerHorizontal_WidgetFlag | overflowScrollable_WidgetFlag,
                     iTrue);
     return sheet;
 }
diff --git a/src/ui/widget.c b/src/ui/widget.c
index e2d0f922..ddb3f092 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -877,8 +877,22 @@ static const iWidget *findFocusable_Widget_(const iWidget *d, const iWidget *sta
     return NULL;
 }
 
+static const iWidget *findFocusRoot_Widget_(const iWidget *d) {
+    iForEach(ObjectList, i, d->children) {
+        const iWidget *root = findFocusRoot_Widget_(constAs_Widget(i.object));
+        if (root) {
+            return root;
+        }
+    }
+    if (d->flags & focusRoot_WidgetFlag) {
+        return d;
+    }
+    return NULL;
+}
+
 iAny *findFocusable_Widget(const iWidget *startFrom, enum iWidgetFocusDir focusDir) {
-    iWidget *root = get_Window()->root;
+    const iWidget *root = findFocusRoot_Widget_(get_Window()->root);
+    iAssert(root != NULL);
     iBool getNext = (startFrom ? iFalse : iTrue);
     const iWidget *found = findFocusable_Widget_(root, startFrom, &getNext, focusDir);
     if (!found && startFrom) {
diff --git a/src/ui/widget.h b/src/ui/widget.h
index e40b333b..79f68b3c 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -90,6 +90,7 @@ enum iWidgetFlag {
 #define wrapText_WidgetFlag                 iBit64(36)
 #define borderTop_WidgetFlag                iBit64(37)
 #define overflowScrollable_WidgetFlag       iBit64(38)
+#define focusRoot_WidgetFlag                iBit64(39)
 
 enum iWidgetAddPos {
     back_WidgetAddPos,
diff --git a/src/ui/window.c b/src/ui/window.c
index 66994e79..8df92706 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -781,6 +781,7 @@ void init_Window(iWindow *d, iRect rect) {
     }
 #endif
     d->root = new_Widget();
+    setFlags_Widget(d->root, focusRoot_WidgetFlag, iTrue);
     d->presentTime = 0.0;
     d->frameTime = SDL_GetTicks();
     d->loadAnimTimer = 0;
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/dev/cdiff/d3cb0d94c52ab75032fc17ab477b251b5b1356ef
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
29.943175 milliseconds
Gemini-to-HTML Time
0.423578 milliseconds

This content has been proxied by September (3851b).