Lagrange [dev]

Window: Priority widget for handling keys

=> 2385c33c3fcb51d08de07fadbe481be309123b28

diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 3e2764bf..a9716c08 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -514,6 +514,7 @@ static void setLinkNumberMode_DocumentWidget_(iDocumentWidget *d, iBool set) {
 #if defined (iPlatformAppleDesktop)
         enableMenuItemsOnHomeRow_MacOS(!set);
 #endif
+        window_Widget(d)->keyPriority = set ? as_Widget(d) : NULL;
         if (d->menu) {
             setFlags_Widget(d->menu, disabled_WidgetFlag, set);
         }
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 843a46bd..3d839bea 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -242,6 +242,9 @@ void deinit_Widget(iWidget *d) {
         if (win->hover == d) {
             win->hover = NULL;
         }
+        if (win->keyPriority == d) {
+            win->keyPriority = NULL;
+        }
     }
     if (d->flags & nativeMenu_WidgetFlag) {
         releaseNativeMenu_Widget(d);
@@ -261,6 +264,9 @@ static void aboutToBeDestroyed_Widget_(iWidget *d) {
     if (win->focus == d) {
         win->focus = NULL;
     }
+    if (win->keyPriority == d) {
+        win->keyPriority = NULL;
+    }
     if (win->lastHover == d) {
         win->lastHover = NULL;
     }
@@ -2428,6 +2434,7 @@ void setFocus_Widget(iWidget *d) {
     iWindow *win = d ? window_Widget(d) : get_Window();
     iAssert(win);
     if (win->focus != d) {
+        win->keyPriority = NULL;
         if (win->focus) {
             iAssert(!contains_PtrSet(win->focus->root->pendingDestruction, win->focus));
             postCommand_Widget(win->focus, "focus.lost");
diff --git a/src/ui/window.c b/src/ui/window.c
index a5424a92..2c7b2ada 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -601,6 +601,7 @@ void init_Window(iWindow *d, enum iWindowType type, iRect rect, uint32_t flags)
     d->hover         = NULL;
     d->lastHover     = NULL;
     d->mouseGrab     = NULL;
+    d->keyPriority   = NULL;
     d->focus         = NULL;
     d->pendingCursor = NULL;
     d->isExposed     = (deviceType_App() != desktop_AppDeviceType);
@@ -1372,18 +1373,21 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
                     }
                 }
             }
-//            const iWidget *oldHover = d->hover;
             iBool wasUsed = iFalse;
             /* Dispatch first to the mouse-grabbed widget. */
-//            iWidget *widget = d->root.widget;
             if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEWHEEL ||
                 event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEBUTTONDOWN) {
                 if (mouseGrab_Widget()) {
                     iWidget *grabbed = mouseGrab_Widget();
-                    setCurrent_Root(grabbed->root /* findRoot_Window(d, grabbed)*/);
+                    setCurrent_Root(grabbed->root);
                     wasUsed = dispatchEvent_Widget(grabbed, &event);
                 }
             }
+            /* If there is a priority handler for key events, offer the event to it first.
+               This is similar to mouse grabbing, but the handler can refuse the event. */
+            if (d->keyPriority && (event.type == SDL_KEYDOWN || event.type == SDL_KEYDOWN)) {
+                wasUsed = dispatchEvent_Widget(d->keyPriority, &event);
+            }
             /* Dispatch the event to the tree of widgets. */
             if (!wasUsed) {
                 wasUsed = dispatchEvent_Window(d, &event);
@@ -1449,6 +1453,7 @@ iBool setKeyRoot_Window(iWindow *d, iRoot *root) {
         d->keyRoot = root;
         postCommand_App("keyroot.changed");
         postRefresh_Window(d);
+        d->keyPriority = NULL;
         return iTrue;
     }
     return iFalse;
diff --git a/src/ui/window.h b/src/ui/window.h
index 21271e67..cc674fcf 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -99,6 +99,7 @@ struct Impl_Window {
     iWidget *     hover;
     iWidget *     lastHover;    /* cleared if deleted */
     iWidget *     mouseGrab;
+    iWidget *     keyPriority;  /* window dispatches keyboard events to this widget first */
     iWidget *     focus;
     float         pixelRatio;   /* conversion between points and pixels, e.g., coords, window size */
     float         displayScale; /* DPI-based scaling factor of current display, affects uiScale only */
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/dev/cdiff/2385c33c3fcb51d08de07fadbe481be309123b28
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
28.632884 milliseconds
Gemini-to-HTML Time
0.264113 milliseconds

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