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