Lagrange [work/v1.10]

Focus cycling with dialogs; Ctrl+G is an alternative for Escape

=> 0b80601b2ebd2765878f0829bff656a4f65bbf1f

diff --git a/src/app.c b/src/app.c
index 2aa08247..d3cced8e 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1767,12 +1767,15 @@ void processEvents_App(enum iAppEventMode eventMode) {
                     /* Focus cycling. */
                     if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_TAB) {
                         iWidget *startFrom = focus_Widget();
+                        const iBool isLimitedFocus = focusRoot_Widget(startFrom) != root_Widget(startFrom);
                         /* Go to a sidebar if one is visible. */
-                        if (!startFrom && isVisible_Widget(findWidget_App("sidebar"))) {
+                        if (!startFrom && !isLimitedFocus && 
+                            isVisible_Widget(findWidget_App("sidebar"))) {
                             setFocus_Widget(as_Widget(
                                 list_SidebarWidget((iSidebarWidget *) findWidget_App("sidebar"))));
                         }
-                        else if (!startFrom && isVisible_Widget(findWidget_App("sidebar2"))) {
+                        else if (!startFrom && !isLimitedFocus && 
+                            isVisible_Widget(findWidget_App("sidebar2"))) {
                             setFocus_Widget(as_Widget(
                                 list_SidebarWidget((iSidebarWidget *) findWidget_App("sidebar2"))));
                         }
@@ -1785,6 +1788,21 @@ void processEvents_App(enum iAppEventMode eventMode) {
                         wasUsed = iTrue;
                     }
                 }
+                if (!wasUsed) {
+                    /* ^G is an alternative for Escape. */
+                    if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == 'g' &&
+                        keyMods_Sym(ev.key.keysym.mod) == KMOD_CTRL) {
+                        SDL_KeyboardEvent esc = ev.key;
+                        esc.keysym.sym = SDLK_ESCAPE;
+                        esc.keysym.mod = 0;
+                        SDL_PushEvent((SDL_Event *) &esc);
+                        esc.state = SDL_RELEASED;
+                        esc.type  = SDL_KEYUP;
+                        esc.timestamp++;
+                        SDL_PushEvent((SDL_Event *) &esc);
+                        wasUsed = iTrue;
+                    }
+                }
                 if (ev.type == SDL_USEREVENT && ev.user.code == command_UserEventCode) {
 #if defined (iPlatformAppleDesktop)
                     handleCommand_MacOS(command_UserEvent(&ev));
@@ -3890,7 +3908,7 @@ iBool handleCommand_App(const char *cmd) {
             iWidget *idPanel = panel_Mobile(dlg, 3);
             iWidget *button  = findUserData_Widget(findChild_Widget(dlg, "panel.top"), idPanel);
             postCommand_Widget(button, "panel.open");
-    }
+        }
     }
     else if (equal_Command(cmd, "navigate.home")) {
         /* Look for bookmarks tagged "homepage". */
diff --git a/src/ui/widget.c b/src/ui/widget.c
index ed37fc5d..b0efeabf 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -2166,21 +2166,27 @@ static const iWidget *findFocusRoot_Widget_(const iWidget *d) {
     return NULL;
 }
 
+const iWidget *focusRoot_Widget(const iWidget *d) {
+    iRoot *uiRoot = (d ? d->root : get_Window()->keyRoot);
+    return findFocusRoot_Widget_(uiRoot->widget);
+}
+
 iAny *findFocusable_Widget(const iWidget *startFrom, enum iWidgetFocusDir focusDir) {
     if (!get_Window()) {
         return NULL;
     }
-    iRoot *uiRoot = (startFrom ? startFrom->root : get_Window()->keyRoot);
-    const iWidget *focusRoot = findFocusRoot_Widget_(uiRoot->widget);
+    const iWidget *focusRoot = focusRoot_Widget(startFrom);
     iAssert(focusRoot != NULL);
     iBool getNext = (startFrom ? iFalse : iTrue);
     const iWidget *found = findFocusable_Widget_(focusRoot, startFrom, &getNext, focusDir);
     if (!found && startFrom) {
         getNext = iTrue;
         /* Switch to the next root, if available. */
-        found = findFocusable_Widget_(findFocusRoot_Widget_(otherRoot_Window(get_Window(),
-                                                                             uiRoot)->widget),
-                                      NULL, &getNext, focusDir);
+        found = findFocusable_Widget_(
+            findFocusRoot_Widget_(otherRoot_Window(get_Window(), focusRoot->root)->widget),
+            NULL,
+            &getNext,
+            focusDir);
     }
     return iConstCast(iWidget *, found);
 }
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 44020eff..5ce884c9 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -336,6 +336,7 @@ void        scrollInfo_Widget           (const iWidget *, iWidgetScrollInfo *inf
 
 int         backgroundFadeColor_Widget  (void);
 
+const iWidget *focusRoot_Widget     (const iWidget *);
 void        setFocus_Widget         (iWidget *); /* widget must be flagged `focusable` */
 void        setKeyboardGrab_Widget  (iWidget *); /* sets focus on any widget */
 iWidget *   focus_Widget            (void);
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.10/cdiff/0b80601b2ebd2765878f0829bff656a4f65bbf1f
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
67.024548 milliseconds
Gemini-to-HTML Time
0.296126 milliseconds

This content has been proxied by September (ba2dc).