Lagrange [work/v1.10]

Fixed issues with tall popup menus

=> 3bbbd1399373755cec95e9685d18ecebec3b9c24

diff --git a/src/ui/lookupwidget.c b/src/ui/lookupwidget.c
index e57a5fdc..da0113ce 100644
--- a/src/ui/lookupwidget.c
+++ b/src/ui/lookupwidget.c
@@ -665,8 +665,9 @@ static iBool processEvent_LookupWidget_(iLookupWidget *d, const SDL_Event *ev) {
                                            (bottom_Rect(rect_Root(root)) - bottom_Rect(navBarBounds)) / 2));
             setPos_Widget(w, windowToLocal_Widget(w, bottomLeft_Rect(bounds_Widget(url))));
 #if defined (iPlatformAppleMobile)
+            /* TODO: Check this again. */
             /* Adjust height based on keyboard size. */ {
-                w->rect.size.y = visibleSize_Root(root).y - top_Rect(bounds_Widget(w));
+                w->rect.size.y = bottom_Rect(visibleRect_Root(root)) - top_Rect(bounds_Widget(w));
                 if (deviceType_App() == phone_AppDeviceType) {
                     float l, r;
                     safeAreaInsets_iOS(&l, NULL, &r, NULL);
diff --git a/src/ui/root.c b/src/ui/root.c
index d847480f..95126654 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -1529,6 +1529,35 @@ iRect safeRect_Root(const iRoot *d) {
     return rect;
 }
 
-iInt2 visibleSize_Root(const iRoot *d) {
-    return addY_I2(size_Root(d), -get_MainWindow()->keyboardHeight);
+iRect visibleRect_Root(const iRoot *d) {
+    iRect visRect = rect_Root(d);
+#if defined (iPlatformAppleMobile)
+    /* TODO: Check this on device... Maybe DisplayUsableBounds would be good here, too? */
+    float left, top, right, bottom;
+    safeAreaInsets_iOS(&left, &top, &right, &bottom);
+    visRect.pos.x = (int) left;
+    visRect.size.x -= (int) (left + right);
+    visRect.pos.y = (int) top;
+    visRect.size.y -= (int) (top + bottom);
+#endif
+#if defined (iPlatformDesktop)
+    /* Apply the usable bounds of the display. */
+    SDL_Rect usable; {
+        const float ratio = d->window->pixelRatio;
+        SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(d->window->win), &usable);
+        iInt2 winPos;
+        SDL_GetWindowPosition(d->window->win, &winPos.x, &winPos.y);
+        mulfv_I2(&winPos, ratio);
+        usable.x *= ratio;
+        usable.y *= ratio;
+        usable.w *= ratio;
+        usable.h *= ratio;
+        /* Make it relative to the window. */
+        usable.x -= winPos.x;
+        usable.y -= winPos.y;
+        visRect = intersect_Rect(visRect, init_Rect(usable.x, usable.y, usable.w, usable.h));        
+    }
+#endif
+    adjustEdges_Rect(&visRect, 0, 0, -get_MainWindow()->keyboardHeight, 0);
+    return visRect;
 }
diff --git a/src/ui/root.h b/src/ui/root.h
index 04dd5e16..851d927d 100644
--- a/src/ui/root.h
+++ b/src/ui/root.h
@@ -40,6 +40,6 @@ void        updateToolbarColors_Root            (iRoot *);
 iInt2       size_Root                           (const iRoot *);
 iRect       rect_Root                           (const iRoot *);
 iRect       safeRect_Root                       (const iRoot *);
-iInt2       visibleSize_Root                    (const iRoot *); /* may be obstructed by software keyboard */
+iRect       visibleRect_Root                    (const iRoot *); /* may be obstructed by software keyboard */
 iBool       isNarrow_Root                       (const iRoot *);
 int         appIconSize_Root                    (void);
diff --git a/src/ui/util.c b/src/ui/util.c
index 760bf48f..88348ff8 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1038,7 +1038,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, int menuOpenFlags) {
     iRect displayRect = zero_Rect(); 
     for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) {
         SDL_Rect dispBounds;
-        SDL_GetDisplayBounds(i, &dispBounds);
+        SDL_GetDisplayUsableBounds(i, &dispBounds);
         displayRect = union_Rect(
             displayRect, init_Rect(dispBounds.x, dispBounds.y, dispBounds.w, dispBounds.h));
     }
@@ -1070,7 +1070,7 @@ void openMenuFlags_Widget(iWidget *d, iInt2 windowCoord, int menuOpenFlags) {
         iInt2 menuPos = add_I2(winPos,
                                divf_I2(sub_I2(windowCoord, divi_I2(gap2_UI, 2)), pixelRatio));
         /* Check display bounds. */ {
-            const iInt2 menuSize = divf_I2(d->rect.size, pixelRatio);
+            iInt2 menuSize = divf_I2(d->rect.size, pixelRatio);
             if (menuOpenFlags & center_MenuOpenFlags) {
                 iInt2 winSize;
                 SDL_GetWindowSize(sdlWin, &winSize.x, &winSize.y);
diff --git a/src/ui/widget.c b/src/ui/widget.c
index b509cbe2..6ce5e02a 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -1142,11 +1142,9 @@ static iBool isOverflowScrollPossible_Widget_(const iWidget *d, int delta) {
         return iFalse;
     }
     iRect       bounds  = boundsWithoutVisualOffset_Widget(d);
-    const iRect winRect = adjusted_Rect(safeRect_Root(d->root),
-                                        zero_I2(),
-                                        init_I2(0, -get_MainWindow()->keyboardHeight));
-    const int yTop    = top_Rect(winRect);
-    const int yBottom = bottom_Rect(winRect);
+    const iRect winRect = visibleRect_Root(d->root);
+    const int   yTop    = top_Rect(winRect);
+    const int   yBottom = bottom_Rect(winRect);
     if (delta == 0) {
         if (top_Rect(bounds) >= yTop && bottom_Rect(bounds) <= yBottom) {
             return iFalse; /* fits inside just fine */
@@ -1162,11 +1160,9 @@ iBool scrollOverflow_Widget(iWidget *d, int delta) {
     if (!isOverflowScrollPossible_Widget_(d, delta)) {
         return iFalse;
     }
-    iRect       bounds  = boundsWithoutVisualOffset_Widget(d);
-    const iRect winRect = adjusted_Rect(safeRect_Root(d->root),
-                                        zero_I2(),
-                                        init_I2(0, -get_MainWindow()->keyboardHeight));
-    iRangei validPosRange = { bottom_Rect(winRect) - height_Rect(bounds), top_Rect(winRect) };
+    iRect       bounds        = boundsWithoutVisualOffset_Widget(d);
+    const iRect winRect       = visibleRect_Root(d->root);
+    iRangei     validPosRange = { bottom_Rect(winRect) - height_Rect(bounds), top_Rect(winRect) };
     if (validPosRange.start > validPosRange.end) {
         validPosRange.start = validPosRange.end; /* no room to scroll */
     }
@@ -1244,18 +1240,28 @@ iBool processEvent_Widget(iWidget *d, const SDL_Event *ev) {
             /* TODO: Motion events occur frequently. Maybe it would help if these were handled
                via audiences that specifically register to listen for motion, to minimize the
                number of widgets that need to process them. */
-            const int hoverScrollLimit = 2 * lineHeight_Text(default_FontId);
+            const int hoverScrollLimit = 1.5f * lineHeight_Text(default_FontId);
             float speed = 0.0f;
             if (ev->motion.y < hoverScrollLimit) {
                 speed = (hoverScrollLimit - ev->motion.y) / (float) hoverScrollLimit;
             }
             else {
-                const int bottomLimit = bottom_Rect(rect_Root(d->root)) - hoverScrollLimit;
-                if (ev->motion.y > bottomLimit ) {
+                const iWindow *win = window_Widget(d);
+                SDL_Rect usable;
+                SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(win->win),
+                                           &usable);
+                const int bottomLimit =
+                    iMin(bottom_Rect(rect_Root(d->root)), usable.h * win->pixelRatio) -
+                    hoverScrollLimit;
+                if (ev->motion.y > bottomLimit) {
                     speed = -(ev->motion.y - bottomLimit) / (float) hoverScrollLimit;
                 }
+                printf("my:%d bottomLimit:%d => %f (%d)\n", ev->motion.y, bottomLimit, speed
+                       ,isOverflowScrollPossible_Widget_(d, speed)); fflush(stdout);
             }
-            if (speed != 0.0f && isOverflowScrollPossible_Widget_(d, speed > 0 ? 1 : -1)) {
+            const int dir = speed > 0 ? 1 : -1;
+            if (speed != 0.0f && isOverflowScrollPossible_Widget_(d, dir)) {
+//                speed = dir * powf(speed, 1.5f);
                 const uint32_t nowTime = SDL_GetTicks();
                 uint32_t elapsed = nowTime - lastHoverOverflowMotionTime_;
                 if (elapsed > 100) {
diff --git a/src/ui/window.c b/src/ui/window.c
index c63ad76a..fa364cff 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1676,9 +1676,13 @@ iWindow *newPopup_Window(iInt2 screenPos, iWidget *rootWidget) {
 #if !defined (iPlatformApple)
     setForceSoftwareRender_App(iTrue);
 #endif
+    SDL_Rect usableRect;
+    SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(get_MainWindow()->base.win),
+                               &usableRect);
     iWindow *win =
         new_Window(popup_WindowType,
-                   (iRect){ screenPos, divf_I2(rootWidget->rect.size, get_Window()->pixelRatio) },
+                   (iRect){ screenPos, min_I2(divf_I2(rootWidget->rect.size, get_Window()->pixelRatio),
+                                              init_I2(usableRect.w, usableRect.h)) },
                    SDL_WINDOW_ALWAYS_ON_TOP |
 #if !defined (iPlatformAppleDesktop)
                    SDL_WINDOW_BORDERLESS |
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.10/cdiff/3bbbd1399373755cec95e9685d18ecebec3b9c24
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
67.431617 milliseconds
Gemini-to-HTML Time
0.330451 milliseconds

This content has been proxied by September (ba2dc).