Fix a number of small errors in area coordinate handling
authorSeverin <eiseljulian@gmail.com>
Fri, 29 Jun 2018 22:42:19 +0000 (00:42 +0200)
committerSeverin <eiseljulian@gmail.com>
Fri, 29 Jun 2018 22:42:19 +0000 (00:42 +0200)
For example collapsing the lower part of the topbar with 2x interface scale
would hide the top-bar header region. There were also more asserts when changing
window size and moving area edges afterwards (same assert as in T55298).
Fixes are similar to e626998a262ebe4f.

With all the recent fixes I've done, area geometry handling should be stable
again. Let's hope I'm right :)

source/blender/editors/include/ED_screen.h
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/windowmanager/intern/wm_window.c

index 1b5425b54c8e5b58ff79c7d5a4e6be39f42a4f98..a2a619209db0b557270784ed964c9e5136f41155 100644 (file)
@@ -150,6 +150,8 @@ void    ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
 int     ED_area_headersize(void);
 int     ED_area_header_alignment(const ScrArea *area);
 int     ED_area_global_size_y(const ScrArea *area);
+int     ED_area_global_min_size_y(const ScrArea *area);
+int     ED_area_global_max_size_y(const ScrArea *area);
 bool    ED_area_is_global(const ScrArea *area);
 int     ED_region_global_size_y(void);
 void    ED_area_update_region_sizes(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
index 16eeff01e58fe08e2ea493f6aa1d29c7727bd7fd..e96580855d325188ff2a8b33c46939b8dd09efc8 100644 (file)
@@ -2362,6 +2362,16 @@ int ED_area_global_size_y(const ScrArea *area)
        BLI_assert(ED_area_is_global(area));
        return round_fl_to_int(area->global->cur_fixed_height * UI_DPI_FAC);
 }
+int ED_area_global_min_size_y(const ScrArea *area)
+{
+       BLI_assert(ED_area_is_global(area));
+       return round_fl_to_int(area->global->size_min * UI_DPI_FAC);
+}
+int ED_area_global_max_size_y(const ScrArea *area)
+{
+       BLI_assert(ED_area_is_global(area));
+       return round_fl_to_int(area->global->size_max * UI_DPI_FAC);
+}
 
 bool ED_area_is_global(const ScrArea *area)
 {
index c3d18abc2cf9df63cc056c5714746a1549f507bd..b3424ae3fb4ba03733ac630ad2bb9ced7a7b410b 100644 (file)
@@ -718,7 +718,7 @@ static void screen_vertices_scale(
                /* adjust headery if verts are along the edge of window */
                if (sa->v1->vec.y > window_rect->ymin)
                        headery += U.pixelsize;
-               if (sa->v2->vec.y < window_rect->ymax)
+               if (sa->v2->vec.y < (window_rect->ymax - 1))
                        headery += U.pixelsize;
 
                if (area_geometry_height(sa) < headery) {
@@ -744,21 +744,32 @@ static void screen_vertices_scale(
 
        /* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set. */
        for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
+               int height = ED_area_global_size_y(area) - 1;
+
                if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
                        continue;
                }
+
+               if (area->v1->vec.y > window_rect->ymin) {
+                       height += U.pixelsize;
+               }
+               if (area->v2->vec.y < (window_rect->ymax - 1)) {
+                       height += U.pixelsize;
+               }
+
                /* width */
                area->v1->vec.x = area->v2->vec.x = window_rect->xmin;
                area->v3->vec.x = area->v4->vec.x = window_rect->xmax - 1;
                /* height */
                area->v1->vec.y = area->v4->vec.y = window_rect->ymin;
                area->v2->vec.y = area->v3->vec.y = window_rect->ymax - 1;
+
                switch (area->global->align) {
                        case GLOBAL_AREA_ALIGN_TOP:
-                               area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - ED_area_global_size_y(area);
+                               area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - height;
                                break;
                        case GLOBAL_AREA_ALIGN_BOTTOM:
-                               area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + ED_area_global_size_y(area);
+                               area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + height;
                                break;
                }
        }
index e4de87e0b463b6870a36a048ceffced35433cc13..9c27bda5ec87052744d6968fc8554e3fc20154d7 100644 (file)
@@ -1235,8 +1235,8 @@ static void area_move_set_limits(
        if (use_bigger_smaller_snap != NULL) {
                *use_bigger_smaller_snap = false;
                for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) {
-                       const int size_min = round_fl_to_int(area->global->size_min * UI_DPI_FAC);
-                       const int size_max = round_fl_to_int(area->global->size_max * UI_DPI_FAC);
+                       const int size_min = ED_area_global_min_size_y(area) - 1;
+                       const int size_max = ED_area_global_max_size_y(area) - 1;
 
                        /* logic here is only tested for lower edge :) */
                        /* left edge */
index 7ca51724268f7a92ed965ad3dee412cb3e226a36..43231855162bd99361b2695349b23182bc7f00ee 100644 (file)
@@ -2013,22 +2013,37 @@ void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)
  */
 void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
 {
-       rcti rect;
+       rcti window_rect, screen_rect;
 
-       BLI_rcti_init(&rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
+       WM_window_rect_calc(win, &window_rect);
+       screen_rect = window_rect;
 
        /* Substract global areas from screen rectangle. */
        for (ScrArea *global_area = win->global_areas.areabase.first; global_area; global_area = global_area->next) {
+               int height = ED_area_global_size_y(global_area) - 1;
+
                if (global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
                        continue;
                }
 
                switch (global_area->global->align) {
                        case GLOBAL_AREA_ALIGN_TOP:
-                               rect.ymax -= ED_area_global_size_y(global_area);
+                               if ((screen_rect.ymax - height) > window_rect.ymin) {
+                                       height += U.pixelsize;
+                               }
+                               if (screen_rect.ymax < (window_rect.ymax - 1)) {
+                                       height += U.pixelsize;
+                               }
+                               screen_rect.ymax -= height;
                                break;
                        case GLOBAL_AREA_ALIGN_BOTTOM:
-                               rect.ymin += ED_area_global_size_y(global_area);
+                               if (screen_rect.ymin > window_rect.ymin) {
+                                       height += U.pixelsize;
+                               }
+                               if ((screen_rect.ymin + height) < (window_rect.ymax - 1)) {
+                                       height += U.pixelsize;
+                               }
+                               screen_rect.ymin += height;
                                break;
                        default:
                                BLI_assert(0);
@@ -2036,9 +2051,9 @@ void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
                }
        }
 
-       BLI_assert(rect.xmin < rect.xmax);
-       BLI_assert(rect.ymin < rect.ymax);
-       *r_rect = rect;
+       BLI_assert(screen_rect.xmin < screen_rect.xmax);
+       BLI_assert(screen_rect.ymin < screen_rect.ymax);
+       *r_rect = screen_rect;
 }
 
 bool WM_window_is_fullscreen(wmWindow *win)