Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 23 May 2018 08:50:35 +0000 (10:50 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 23 May 2018 08:51:11 +0000 (10:51 +0200)
18 files changed:
1  2 
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_align.c
source/blender/editors/interface/interface_anim.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_utils.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d.c
source/blender/editors/interface/view2d_ops.c

@@@ -365,18 -337,18 +365,18 @@@ static void ui_block_bounds_calc_center
        ymax = WM_window_pixels_y(window);
  
        ui_block_bounds_calc(block);
-       
        width  = BLI_rctf_size_x(&block->rect);
        height = BLI_rctf_size_y(&block->rect);
-       
        startx = (xmax * 0.5f) - (width * 0.5f);
        starty = (ymax * 0.5f) - (height * 0.5f);
-       
 -      ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
 +      UI_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
-       
        /* now recompute bounds and safety */
        ui_block_bounds_calc(block);
-       
  }
  
  static void ui_block_bounds_calc_centered_pie(uiBlock *block)
@@@ -1222,10 -1291,10 +1222,10 @@@ void UI_block_end_ex(const bContext *C
                ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
        }
  
 -      if (block->flag & UI_BLOCK_LOOP) {
 +      if (block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)) {
                ui_menu_block_set_keymaps(C, block);
        }
-       
        /* after keymaps! */
        switch (block->bounds_type) {
                case UI_BLOCK_BOUNDS_NONE:
@@@ -1303,7 -1372,8 +1303,7 @@@ void UI_block_draw(const bContext *C, u
        ARegion *ar;
        uiBut *but;
        rcti rect;
-       
 -      int multisample_enabled;
        /* get menu region or area region */
        ar = CTX_wm_menu(C);
        if (!ar)
        if (!block->endblock)
                UI_block_end(C, block);
  
 -      /* disable AA, makes widgets too blurry */
 -      multisample_enabled = glIsEnabled(GL_MULTISAMPLE);
 -      if (multisample_enabled)
 -              glDisable(GL_MULTISAMPLE);
 -
        /* we set this only once */
 -      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-       
        /* scale fonts */
        ui_fontscale(&style.paneltitle.points, block->aspect);
        ui_fontscale(&style.grouplabel.points, block->aspect);
        ui_fontscale(&style.widgetlabel.points, block->aspect);
        ui_fontscale(&style.widget.points, block->aspect);
-       
        /* scale block min/max to rect */
        ui_but_to_pixelrect(&rect, ar, block, NULL);
-       
        /* pixel space for AA widgets */
 -      glMatrixMode(GL_PROJECTION);
 -      glPushMatrix();
 -      glMatrixMode(GL_MODELVIEW);
 -      glPushMatrix();
 -      glLoadIdentity();
 +      gpuPushProjectionMatrix();
 +      gpuPushMatrix();
 +      gpuLoadIdentity();
  
        wmOrtho2_region_pixelspace(ar);
-       
        /* back */
        if (block->flag & UI_BLOCK_RADIAL)
                ui_draw_pie_center(block);
                }
        }
  
 -      /* restore matrix */
 -      glMatrixMode(GL_PROJECTION);
 -      glPopMatrix();
 -      glMatrixMode(GL_MODELVIEW);
 -      glPopMatrix();
 +      UI_widgetbase_draw_cache_end();
 +      UI_icon_draw_cache_end();
 +      BLF_batch_draw_end();
-       
 -      if (multisample_enabled)
 -              glEnable(GL_MULTISAMPLE);
 +      /* restore matrix */
 +      gpuPopProjectionMatrix();
 +      gpuPopMatrix();
 +}
 +
 +static void ui_block_message_subscribe(ARegion *ar, struct wmMsgBus *mbus, uiBlock *block)
 +{
 +      uiBut *but_prev = NULL;
 +      /* possibly we should keep the region this block is contained in? */
 +      for (uiBut *but = block->buttons.first; but; but = but->next) {
 +              if (but->rnapoin.type && but->rnaprop) {
 +                      /* quick check to avoid adding buttons representing a vector, multiple times. */
 +                      if ((but_prev &&
 +                          (but_prev->rnaprop == but->rnaprop) &&
 +                          (but_prev->rnapoin.type == but->rnapoin.type) &&
 +                          (but_prev->rnapoin.data == but->rnapoin.data) &&
 +                          (but_prev->rnapoin.id.data == but->rnapoin.id.data)) == false)
 +                      {
 +                              /* TODO: could make this into utility function. */
 +                              WM_msg_subscribe_rna(
 +                                      mbus, &but->rnapoin, but->rnaprop,
 +                                      &(const wmMsgSubscribeValue){
 +                                          .owner = ar,
 +                                          .user_data = ar,
 +                                          .notify = ED_region_do_msg_notify_tag_redraw,
 +                                      }, __func__);
 +                              but_prev = but;
 +                      }
 +              }
 +      }
 +}
  
 -      ui_draw_links(block);
 +void UI_region_message_subscribe(ARegion *ar, struct wmMsgBus *mbus)
 +{
 +      for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
 +              ui_block_message_subscribe(ar, mbus, block);
 +      }
  }
  
  /* ************* EVENTS ************* */
@@@ -240,11 -238,10 +240,11 @@@ void ui_but_anim_autokey(bContext *C, u
        if (special) {
                /* NLA Strip property */
                if (IS_AUTOKEY_ON(scene)) {
 +                      Depsgraph *depsgraph = CTX_data_depsgraph(C);
                        ReportList *reports = CTX_wm_reports(C);
                        ToolSettings *ts = scene->toolsettings;
-                       
 -                      insert_keyframe_direct(reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, 0);
 +                      insert_keyframe_direct(depsgraph, reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, 0);
                        WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
                }
        }
                 * making it easier to set up corrective drivers
                 */
                if (IS_AUTOKEY_ON(scene)) {
 +                      Depsgraph *depsgraph = CTX_data_depsgraph(C);
                        ReportList *reports = CTX_wm_reports(C);
                        ToolSettings *ts = scene->toolsettings;
-                       
 -                      insert_keyframe_direct(reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, INSERTKEY_DRIVER);
 +                      insert_keyframe_direct(depsgraph, reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, INSERTKEY_DRIVER);
                        WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
                }
        }
        else {
                id = but->rnapoin.id.data;
-               
                /* TODO: this should probably respect the keyingset only option for anim */
                if (autokeyframe_cfra_can_key(scene, id)) {
 +                      Depsgraph *depsgraph = CTX_data_depsgraph(C);
                        ReportList *reports = CTX_wm_reports(C);
                        ToolSettings *ts = scene->toolsettings;
                        short flag = ANIM_get_keyframing_flags(scene, 1);
                         *       because a button may control all items of an array at once.
                         *       E.g., color wheels (see T42567). */
                        BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
 -                      insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
 +                      insert_keyframe(depsgraph, reports, id, action,
 +                                      ((fcu->grp) ? (fcu->grp->name) : (NULL)),
                                        fcu->rna_path, but->rnaindex, cfra, ts->keyframe_type, flag);
-                       
                        WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
                }
        }
@@@ -163,101 -90,68 +163,101 @@@ void UI_draw_roundbox_4fv(bool filled, 
                mul_v2_fl(vec[a], rad);
        }
  
 -      glBegin(mode);
 +      unsigned int vert_ct = 0;
 +      vert_ct += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
 +      vert_ct += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
 +      vert_ct += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
 +      vert_ct += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4fv(col);
  
 +      immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_ct);
        /* start with corner right-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
 -              glVertex2f(maxx - rad, miny);
 +              immVertex2f(pos, maxx - rad, miny);
                for (a = 0; a < 7; a++) {
 -                      glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
 +                      immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
                }
 -              glVertex2f(maxx, miny + rad);
 +              immVertex2f(pos, maxx, miny + rad);
        }
        else {
 -              glVertex2f(maxx, miny);
 +              immVertex2f(pos, maxx, miny);
        }
-       
        /* corner right-top */
        if (roundboxtype & UI_CNR_TOP_RIGHT) {
 -              glVertex2f(maxx, maxy - rad);
 +              immVertex2f(pos, maxx, maxy - rad);
                for (a = 0; a < 7; a++) {
 -                      glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
 +                      immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
                }
 -              glVertex2f(maxx - rad, maxy);
 +              immVertex2f(pos, maxx - rad, maxy);
        }
        else {
 -              glVertex2f(maxx, maxy);
 +              immVertex2f(pos, maxx, maxy);
        }
-       
        /* corner left-top */
        if (roundboxtype & UI_CNR_TOP_LEFT) {
 -              glVertex2f(minx + rad, maxy);
 +              immVertex2f(pos, minx + rad, maxy);
                for (a = 0; a < 7; a++) {
 -                      glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
 +                      immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
                }
 -              glVertex2f(minx, maxy - rad);
 +              immVertex2f(pos, minx, maxy - rad);
        }
        else {
 -              glVertex2f(minx, maxy);
 +              immVertex2f(pos, minx, maxy);
        }
-       
        /* corner left-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
 -              glVertex2f(minx, miny + rad);
 +              immVertex2f(pos, minx, miny + rad);
                for (a = 0; a < 7; a++) {
 -                      glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
 +                      immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
                }
 -              glVertex2f(minx + rad, miny);
 +              immVertex2f(pos, minx + rad, miny);
        }
        else {
 -              glVertex2f(minx, miny);
 +              immVertex2f(pos, minx, miny);
        }
-       
 -      glEnd();
 +      immEnd();
 +      immUnbindProgram();
 +#endif
 +
 +      uiWidgetBaseParameters widget_params = {
 +              .recti.xmin = minx, .recti.ymin = miny,
 +              .recti.xmax = maxx, .recti.ymax = maxy,
 +              .radi = rad,
 +              .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
 +              .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
 +              .color_inner1[0] = col[0], .color_inner2[0] = col[0],
 +              .color_inner1[1] = col[1], .color_inner2[1] = col[1],
 +              .color_inner1[2] = col[2], .color_inner2[2] = col[2],
 +              .color_inner1[3] = col[3], .color_inner2[3] = col[3],
 +              .alpha_discard = 1.0f,
 +      };
 +
 +      Gwn_Batch *batch = ui_batch_roundbox_get(filled, false);
 +      GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
 +      GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
 +      GWN_batch_draw(batch);
  }
  
 -static void round_box_shade_col(const float col1[3], float const col2[3], const float fac)
 +#if 0
 +static void round_box_shade_col(unsigned attrib, const float col1[3], float const col2[3], const float fac)
  {
 -      float col[3] = {
 +      float col[4] = {
                fac * col1[0] + (1.0f - fac) * col2[0],
                fac * col1[1] + (1.0f - fac) * col2[1],
 -              fac * col1[2] + (1.0f - fac) * col2[2]
 +              fac * col1[2] + (1.0f - fac) * col2[2],
 +              1.0f
        };
 -      glColor3fv(col);
 +      immAttrib4fv(attrib, col);
  }
 +#endif
  
  /* linear horizontal shade within button or in outline */
  /* view2d scrollers use it */
@@@ -302,109 -185,82 +302,109 @@@ void UI_draw_roundbox_shade_x
  
        /* start with corner right-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
-               
 -              round_box_shade_col(coltop, coldown, 0.0);
 -              glVertex2f(maxx - rad, miny);
 +              round_box_shade_col(color, coltop, coldown, 0.0);
 +              immVertex2f(pos, maxx - rad, miny);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(coltop, coldown, vec[a][1] * idiv);
 -                      glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
 +                      round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
 +                      immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
                }
-               
 -              round_box_shade_col(coltop, coldown, rad * idiv);
 -              glVertex2f(maxx, miny + rad);
 +              round_box_shade_col(color, coltop, coldown, rad * idiv);
 +              immVertex2f(pos, maxx, miny + rad);
        }
        else {
 -              round_box_shade_col(coltop, coldown, 0.0);
 -              glVertex2f(maxx, miny);
 +              round_box_shade_col(color, coltop, coldown, 0.0);
 +              immVertex2f(pos, maxx, miny);
        }
-       
        /* corner right-top */
        if (roundboxtype & UI_CNR_TOP_RIGHT) {
-               
 -              round_box_shade_col(coltop, coldown, (div - rad) * idiv);
 -              glVertex2f(maxx, maxy - rad);
 +              round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
 +              immVertex2f(pos, maxx, maxy - rad);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(coltop, coldown, (div - rad + vec[a][1]) * idiv);
 -                      glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
 +                      round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
 +                      immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
                }
 -              round_box_shade_col(coltop, coldown, 1.0);
 -              glVertex2f(maxx - rad, maxy);
 +              round_box_shade_col(color, coltop, coldown, 1.0);
 +              immVertex2f(pos, maxx - rad, maxy);
        }
        else {
 -              round_box_shade_col(coltop, coldown, 1.0);
 -              glVertex2f(maxx, maxy);
 +              round_box_shade_col(color, coltop, coldown, 1.0);
 +              immVertex2f(pos, maxx, maxy);
        }
-       
        /* corner left-top */
        if (roundboxtype & UI_CNR_TOP_LEFT) {
-               
 -              round_box_shade_col(coltop, coldown, 1.0);
 -              glVertex2f(minx + rad, maxy);
 +              round_box_shade_col(color, coltop, coldown, 1.0);
 +              immVertex2f(pos, minx + rad, maxy);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(coltop, coldown, (div - vec[a][1]) * idiv);
 -                      glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
 +                      round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
 +                      immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
                }
-               
 -              round_box_shade_col(coltop, coldown, (div - rad) * idiv);
 -              glVertex2f(minx, maxy - rad);
 +              round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
 +              immVertex2f(pos, minx, maxy - rad);
        }
        else {
 -              round_box_shade_col(coltop, coldown, 1.0);
 -              glVertex2f(minx, maxy);
 +              round_box_shade_col(color, coltop, coldown, 1.0);
 +              immVertex2f(pos, minx, maxy);
        }
-       
        /* corner left-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
-               
 -              round_box_shade_col(coltop, coldown, rad * idiv);
 -              glVertex2f(minx, miny + rad);
 +              round_box_shade_col(color, coltop, coldown, rad * idiv);
 +              immVertex2f(pos, minx, miny + rad);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(coltop, coldown, (rad - vec[a][1]) * idiv);
 -                      glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
 +                      round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
 +                      immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
                }
-               
 -              round_box_shade_col(coltop, coldown, 0.0);
 -              glVertex2f(minx + rad, miny);
 +              round_box_shade_col(color, coltop, coldown, 0.0);
 +              immVertex2f(pos, minx + rad, miny);
        }
        else {
 -              round_box_shade_col(coltop, coldown, 0.0);
 -              glVertex2f(minx, miny);
 +              round_box_shade_col(color, coltop, coldown, 0.0);
 +              immVertex2f(pos, minx, miny);
        }
  
 -      glEnd();
 +      immEnd();
 +      immUnbindProgram();
 +#endif
 +
 +      uiWidgetBaseParameters widget_params = {
 +              .recti.xmin = minx, .recti.ymin = miny,
 +              .recti.xmax = maxx, .recti.ymax = maxy,
 +              .radi = rad,
 +              .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
 +              .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
 +              .color_inner1[0] = min_ff(1.0f, col[0] + shadetop),
 +              .color_inner2[0] = max_ff(0.0f, col[0] + shadedown),
 +              .color_inner1[1] = min_ff(1.0f, col[1] + shadetop),
 +              .color_inner2[1] = max_ff(0.0f, col[1] + shadedown),
 +              .color_inner1[2] = min_ff(1.0f, col[2] + shadetop),
 +              .color_inner2[2] = max_ff(0.0f, col[2] + shadedown),
 +              .color_inner1[3] = 1.0f,
 +              .color_inner2[3] = 1.0f,
 +              .alpha_discard = 1.0f,
 +      };
 +
 +      Gwn_Batch *batch = ui_batch_roundbox_get(filled, false);
 +      GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
 +      GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
 +      GWN_batch_draw(batch);
  }
  
 +#if 0 /* unused */
  /* linear vertical shade within button or in outline */
  /* view2d scrollers use it */
  void UI_draw_roundbox_shade_y(
                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
        const float div = maxx - minx;
        const float idiv = 1.0f / div;
 -      float colLeft[3], colRight[3], color[4];
 +      float colLeft[3], colRight[3];
 +      int vert_count = 0;
        int a;
-       
        /* mult */
        for (a = 0; a < 7; a++) {
                mul_v2_fl(vec[a], rad);
  
        /* start with corner right-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
 -              round_box_shade_col(colLeft, colRight, 0.0);
 -              glVertex2f(maxx - rad, miny);
 +              round_box_shade_col(color, colLeft, colRight, 0.0);
 +              immVertex2f(pos, maxx - rad, miny);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(colLeft, colRight, vec[a][0] * idiv);
 -                      glVertex2f(maxx - rad + vec[a][0], miny + vec[a][1]);
 +                      round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
 +                      immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
                }
-               
 -              round_box_shade_col(colLeft, colRight, rad * idiv);
 -              glVertex2f(maxx, miny + rad);
 +              round_box_shade_col(color, colLeft, colRight, rad * idiv);
 +              immVertex2f(pos, maxx, miny + rad);
        }
        else {
 -              round_box_shade_col(colLeft, colRight, 0.0);
 -              glVertex2f(maxx, miny);
 +              round_box_shade_col(color, colLeft, colRight, 0.0);
 +              immVertex2f(pos, maxx, miny);
        }
-       
        /* corner right-top */
        if (roundboxtype & UI_CNR_TOP_RIGHT) {
 -              round_box_shade_col(colLeft, colRight, 0.0);
 -              glVertex2f(maxx, maxy - rad);
 +              round_box_shade_col(color, colLeft, colRight, 0.0);
 +              immVertex2f(pos, maxx, maxy - rad);
-               
                for (a = 0; a < 7; a++) {
-                       
 -                      round_box_shade_col(colLeft, colRight, (div - rad - vec[a][0]) * idiv);
 -                      glVertex2f(maxx - vec[a][1], maxy - rad + vec[a][0]);
 +                      round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
 +                      immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
                }
 -              round_box_shade_col(colLeft, colRight, (div - rad) * idiv);
 -              glVertex2f(maxx - rad, maxy);
 +              round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
 +              immVertex2f(pos, maxx - rad, maxy);
        }
        else {
 -              round_box_shade_col(colLeft, colRight, 0.0);
 -              glVertex2f(maxx, maxy);
 +              round_box_shade_col(color, colLeft, colRight, 0.0);
 +              immVertex2f(pos, maxx, maxy);
        }
-       
        /* corner left-top */
        if (roundboxtype & UI_CNR_TOP_LEFT) {
 -              round_box_shade_col(colLeft, colRight, (div - rad) * idiv);
 -              glVertex2f(minx + rad, maxy);
 +              round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
 +              immVertex2f(pos, minx + rad, maxy);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(colLeft, colRight, (div - rad + vec[a][0]) * idiv);
 -                      glVertex2f(minx + rad - vec[a][0], maxy - vec[a][1]);
 +                      round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
 +                      immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
                }
-               
 -              round_box_shade_col(colLeft, colRight, 1.0);
 -              glVertex2f(minx, maxy - rad);
 +              round_box_shade_col(color, colLeft, colRight, 1.0);
 +              immVertex2f(pos, minx, maxy - rad);
        }
        else {
 -              round_box_shade_col(colLeft, colRight, 1.0);
 -              glVertex2f(minx, maxy);
 +              round_box_shade_col(color, colLeft, colRight, 1.0);
 +              immVertex2f(pos, minx, maxy);
        }
-       
        /* corner left-bottom */
        if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
 -              round_box_shade_col(colLeft, colRight, 1.0);
 -              glVertex2f(minx, miny + rad);
 +              round_box_shade_col(color, colLeft, colRight, 1.0);
 +              immVertex2f(pos, minx, miny + rad);
-               
                for (a = 0; a < 7; a++) {
 -                      round_box_shade_col(colLeft, colRight, (vec[a][0]) * idiv);
 -                      glVertex2f(minx + vec[a][1], miny + rad - vec[a][0]);
 +                      round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
 +                      immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
                }
-               
 -              round_box_shade_col(colLeft, colRight, 1.0);
 -              glVertex2f(minx + rad, miny);
 +              round_box_shade_col(color, colLeft, colRight, 1.0);
 +              immVertex2f(pos, minx + rad, miny);
        }
        else {
 -              round_box_shade_col(colLeft, colRight, 1.0);
 -              glVertex2f(minx, miny);
 +              round_box_shade_col(color, colLeft, colRight, 1.0);
 +              immVertex2f(pos, minx, miny);
        }
  
 -      glEnd();
 +      immEnd();
 +      immUnbindProgram();
  }
 +#endif /* unused */
  
 -/* plain antialiased unfilled rectangle */
 -void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad)
 +void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
  {
 -      float color[4];
 -
 -      if (roundboxtype & UI_RB_ALPHA) {
 -              glGetFloatv(GL_CURRENT_COLOR, color);
 -              color[3] = 0.5;
 -              glColor4fv(color);
 -              glEnable(GL_BLEND);
 -      }
 +      int ofs_y = 4 * U.pixelsize;
  
 -      /* set antialias line */
 -      glEnable(GL_LINE_SMOOTH);
 -      glEnable(GL_BLEND);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
  
 -      UI_draw_roundbox_gl_mode(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4fv(color);
  
 -      glDisable(GL_BLEND);
 -      glDisable(GL_LINE_SMOOTH);
 +      immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
 +      immUnbindProgram();
  }
  
 -/* (old, used in outliner) plain antialiased filled box */
 -void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad)
 -{
 -      ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA);
 -}
 +/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
  
 -void UI_draw_text_underline(int pos_x, int pos_y, int len, int height)
 +/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
 +void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3])
  {
 -      int ofs_y = 4 * U.pixelsize;
 -      glRecti(pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
 -}
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
 +      /* add a 1px offset, looks nicer */
 +      const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
 +      const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
 +      int a;
 +      float vec[4][2] = {
 +          {0.195, 0.02},
 +          {0.55, 0.169},
 +          {0.831, 0.45},
 +          {0.98, 0.805},
 +      };
  
 -/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
 +
 +      /* mult */
 +      for (a = 0; a < 4; a++) {
 +              mul_v2_fl(vec[a], rad);
 +      }
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
 +      immBeginAtMost(GWN_PRIM_LINE_STRIP, 25);
 +
 +      immAttrib3ubv(col, highlight);
 +
 +      /* start with corner left-top */
 +      if (roundboxtype & UI_CNR_TOP_LEFT) {
 +              immVertex2f(pos, minx, maxy - rad);
 +              for (a = 0; a < 4; a++) {
 +                      immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
 +              }
 +              immVertex2f(pos, minx + rad, maxy);
 +      }
 +      else {
 +              immVertex2f(pos, minx, maxy);
 +      }
 +
 +      /* corner right-top */
 +      if (roundboxtype & UI_CNR_TOP_RIGHT) {
 +              immVertex2f(pos, maxx - rad, maxy);
 +              for (a = 0; a < 4; a++) {
 +                      immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
 +              }
 +              immVertex2f(pos, maxx, maxy - rad);
 +      }
 +      else {
 +              immVertex2f(pos, maxx, maxy);
 +      }
 +
 +      immAttrib3ubv(col, highlight_fade);
 +
 +      /* corner right-bottom */
 +      if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
 +              immVertex2f(pos, maxx, miny + rad);
 +              for (a = 0; a < 4; a++) {
 +                      immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
 +              }
 +              immVertex2f(pos, maxx - rad, miny);
 +      }
 +      else {
 +              immVertex2f(pos, maxx, miny);
 +      }
 +
 +      /* corner left-bottom */
 +      if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
 +              immVertex2f(pos, minx + rad, miny);
 +              for (a = 0; a < 4; a++) {
 +                      immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
 +              }
 +              immVertex2f(pos, minx, miny + rad);
 +      }
 +      else {
 +              immVertex2f(pos, minx, miny);
 +      }
 +
 +      immAttrib3ubv(col, highlight);
 +
 +      /* back to corner left-top */
 +      immVertex2f(pos, minx, roundboxtype & UI_CNR_TOP_LEFT ? maxy - rad : maxy);
 +
 +      immEnd();
 +      immUnbindProgram();
 +}
  
  void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
  {
  
        if (!ibuf) return;
  
-       
 +      float facx = 1.0f;
 +      float facy = 1.0f;
++
        int w = BLI_rcti_size_x(rect);
        int h = BLI_rcti_size_y(rect);
-       
        /* scissor doesn't seem to be doing the right thing...? */
  #if 0
 -      //glColor4f(1.0, 0.f, 0.f, 1.f);
 -      //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
 -
        /* prevent drawing outside widget area */
        GLint scissor[4];
        glGetIntegerv(GL_SCISSOR_BOX, scissor);
 -      glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
 +      glScissor(rect->xmin, rect->ymin, w, h);
  #endif
-       
        glEnable(GL_BLEND);
-       
 -      glColor4f(0.0, 0.0, 0.0, 0.0);
        if (w != ibuf->x || h != ibuf->y) {
 -              float facx = (float)w / (float)ibuf->x;
 -              float facy = (float)h / (float)ibuf->y;
 -              glPixelZoom(facx, facy);
 +              facx = (float)w / (float)ibuf->x;
 +              facy = (float)h / (float)ibuf->y;
        }
 -      glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
  
 -      glPixelZoom(1.0f, 1.0f);
 +      IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
 +      immDrawPixelsTex(&state, (float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect,
 +                       facx, facy, NULL);
-       
        glDisable(GL_BLEND);
-       
  #if 0
        // restore scissortest
        glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
@@@ -788,17 -566,16 +788,17 @@@ void ui_draw_but_HISTOGRAM(ARegion *UNU
                .ymin = (float)recti->ymin + 1,
                .ymax = (float)recti->ymax - 1
        };
-       
        float w = BLI_rctf_size_x(&rect);
        float h = BLI_rctf_size_y(&rect) * hist->ymax;
-       
        glEnable(GL_BLEND);
 -      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  
 -      UI_ThemeColor4(TH_PREVIEW_BACK);
 +      float color[4];
 +      UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
        UI_draw_roundbox_corner_set(UI_CNR_ALL);
 -      UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
 +      UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
  
        /* need scissor test, histogram can draw outside of boundary */
        GLint scissor[4];
        }
        else {
                if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R)
 -                      histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line);
 +                      histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
                if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G)
 -                      histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line);
 +                      histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
                if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B)
 -                      histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line);
 +                      histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
        }
  
-       
 +      immUnbindProgram();
++
        /* outline */
        draw_scope_end(&rect, scissor);
  }
@@@ -898,12 -642,12 +898,12 @@@ void ui_draw_but_WAVEFORM(ARegion *UNUS
                scopes->wavefrm_yfac = 0.98f;
        float w = BLI_rctf_size_x(&rect) - 7;
        float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
 -      float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) / 2.0f;
 +      float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
        float w3 = w / 3.0f;
-       
        /* log scale for alpha */
        float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
-       
        unit_m3(colors);
  
        for (int c = 0; c < 3; c++) {
                char str[4];
                BLI_snprintf(str, sizeof(str), "%-3d", i * 20);
                str[3] = '\0';
 -              fdrawline(rect.xmin + 22, yofs + (i / 5.f) * h, rect.xmax + 1, yofs + (i / 5.f) * h);
 -              BLF_draw_default(rect.xmin + 1, yofs - 5 + (i / 5.f) * h, 0, str, sizeof(str) - 1);
 -              /* in the loop because blf_draw reset it */
 -              glEnable(GL_BLEND);
 -              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +              BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
 +              BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
        }
 +
 +      /* Flush text cache before drawing things on top. */
 +      BLF_batch_draw_flush();
 +
 +      glEnable(GL_BLEND);
 +      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 +
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +
 +      immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
 +
 +      /* draw grid lines here */
 +      immBegin(GWN_PRIM_LINES, 12);
 +
 +      for (int i = 0; i < 6; i++) {
 +              immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
 +              immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
 +      }
 +
 +      immEnd();
 +
        /* 3 vertical separation */
        if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
 +              immBegin(GWN_PRIM_LINES, 4);
 +
                for (int i = 1; i < 3; i++) {
 -                      fdrawline(rect.xmin + i * w3, rect.ymin, rect.xmin + i * w3, rect.ymax);
 +                      immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
 +                      immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
                }
 +
 +              immEnd();
        }
-       
        /* separate min max zone on the right */
 -      fdrawline(rect.xmin + w, rect.ymin, rect.xmin + w, rect.ymax);
 +      immBegin(GWN_PRIM_LINES, 2);
 +      immVertex2f(pos, rect.xmin + w, rect.ymin);
 +      immVertex2f(pos, rect.xmin + w, rect.ymax);
 +      immEnd();
 +
        /* 16-235-240 level in case of ITU-R BT601/709 */
 -      glColor4f(1.f, 0.4f, 0.f, 0.2f);
 +      immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
        if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
 -              fdrawline(rect.xmin + 22, yofs + h * 16.0f / 255.0f, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
 -              fdrawline(rect.xmin + 22, yofs + h * 235.0f / 255.0f, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
 -              fdrawline(rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
 -              fdrawline(rect.xmin + w3, yofs + h * 240.0f / 255.0f, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
 +              immBegin(GWN_PRIM_LINES, 8);
 +
 +              immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
 +              immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
 +
 +              immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
 +              immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
 +
 +              immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
 +              immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
 +
 +              immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
 +              immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
 +
 +              immEnd();
        }
        /* 7.5 IRE black point level for NTSC */
 -      if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA)
 -              fdrawline(rect.xmin, yofs + h * 0.075f, rect.xmax + 1, yofs + h * 0.075f);
 +      if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
 +              immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
 +              immEnd();
 +      }
  
        if (scopes->ok && scopes->waveform_1 != NULL) {
 -
 -              /* LUMA (1 channel) */
                glBlendFunc(GL_ONE, GL_ONE);
 -              glColor3f(alpha, alpha, alpha);
                glPointSize(1.0);
  
 +              /* LUMA (1 channel) */
                if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
 +                      float col[3] = {alpha, alpha, alpha};
  
 -                      glBlendFunc(GL_ONE, GL_ONE);
 +                      gpuPushMatrix();
 +                      gpuTranslate2f(rect.xmin, yofs);
 +                      gpuScale2f(w, h);
  
 -                      glPushMatrix();
 -                      glEnableClientState(GL_VERTEX_ARRAY);
 +                      waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
  
 -                      glTranslatef(rect.xmin, yofs, 0.f);
 -                      glScalef(w, h, 0.f);
 -                      glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
 -                      glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
 -
 -                      glDisableClientState(GL_VERTEX_ARRAY);
 -                      glPopMatrix();
 +                      gpuPopMatrix();
  
                        /* min max */
 -                      glColor3f(0.5f, 0.5f, 0.5f);
 +                      immUniformColor3f(0.5f, 0.5f, 0.5f);
                        min = yofs + scopes->minmax[0][0] * h;
                        max = yofs + scopes->minmax[0][1] * h;
                        CLAMP(min, rect.ymin, rect.ymax);
@@@ -1178,13 -892,13 +1178,13 @@@ void ui_draw_but_VECTORSCOPE(ARegion *U
                .ymin = (float)recti->ymin + 1,
                .ymax = (float)recti->ymax - 1
        };
-       
        float w = BLI_rctf_size_x(&rect);
        float h = BLI_rctf_size_y(&rect);
 -      float centerx = rect.xmin + w / 2;
 -      float centery = rect.ymin + h / 2;
 +      float centerx = rect.xmin + w * 0.5f;
 +      float centery = rect.ymin + h * 0.5f;
        float diam = (w < h) ? w : h;
-       
        float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
  
        glEnable(GL_BLEND);
  
        /* need scissor test, hvectorscope can draw outside of boundary */
        GLint scissor[4];
 -      glGetIntegerv(GL_VIEWPORT, scissor);
 -      glScissor(ar->winrct.xmin + (rect.xmin - 1),
 -                ar->winrct.ymin + (rect.ymin - 1),
 +      glGetIntegerv(GL_SCISSOR_BOX, scissor);
 +      glScissor((rect.xmin - 1),
 +                (rect.ymin - 1),
                  (rect.xmax + 1) - (rect.xmin - 1),
                  (rect.ymax + 1) - (rect.ymin - 1));
-       
 -      glColor4f(1.f, 1.f, 1.f, 0.08f);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +
 +      immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
        /* draw grid elements */
        /* cross */
 -      fdrawline(centerx - (diam / 2) - 5, centery, centerx + (diam / 2) + 5, centery);
 -      fdrawline(centerx, centery - (diam / 2) - 5, centerx, centery + (diam / 2) + 5);
 +      immBegin(GWN_PRIM_LINES, 4);
 +
 +      immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
 +      immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
 +
 +      immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
 +      immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
 +
 +      immEnd();
 +
        /* circles */
        for (int j = 0; j < 5; j++) {
 -              glBegin(GL_LINE_LOOP);
                const int increment = 15;
 +              immBegin(GWN_PRIM_LINE_LOOP, (int)(360 / increment));
                for (int i = 0; i <= 360 - increment; i += increment) {
                        const float a = DEG2RADF((float)i);
 -                      const float r = (j + 1) / 10.0f;
 -                      glVertex2f(polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
 +                      const float r = (j + 1) * 0.1f;
 +                      immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
                }
 -              glEnd();
 +              immEnd();
        }
        /* skin tone line */
 -      glColor4f(1.f, 0.4f, 0.f, 0.2f);
 -      fdrawline(polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5, skin_rad),
 -                polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1, skin_rad));
 +      immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
 +
 +      immBegin(GWN_PRIM_LINES, 2);
 +      immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
 +      immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
 +      immEnd();
 +
        /* saturation points */
        for (int i = 0; i < 6; i++)
 -              vectorscope_draw_target(centerx, centery, diam, colors[i]);
 +              vectorscope_draw_target(pos, centerx, centery, diam, colors[i]);
-       
        if (scopes->ok && scopes->vecscope != NULL) {
                /* pixel point cloud */
 -              glBlendFunc(GL_ONE, GL_ONE);
 -              glColor3f(alpha, alpha, alpha);
 +              float col[3] = {alpha, alpha, alpha};
  
 -              glPushMatrix();
 -              glEnableClientState(GL_VERTEX_ARRAY);
 +              glBlendFunc(GL_ONE, GL_ONE);
 +              glPointSize(1.0);
  
 -              glTranslatef(centerx, centery, 0.f);
 -              glScalef(diam, diam, 0.f);
 +              gpuPushMatrix();
 +              gpuTranslate2f(centerx, centery);
 +              gpuScaleUniform(diam);
  
 -              glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
 -              glPointSize(1.0);
 -              glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
 +              waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
  
 -              glDisableClientState(GL_VERTEX_ARRAY);
 -              glPopMatrix();
 +              gpuPopMatrix();
        }
  
 +      immUnbindProgram();
 +
        /* outline */
        draw_scope_end(&rect, scissor);
  
@@@ -1434,21 -1117,21 +1434,21 @@@ void ui_draw_but_COLORBAND(uiBut *but, 
  
        v1[1] = y1 + sizey_solid;
        v2[1] = rect->ymax;
-       
 -      glBegin(GL_TRIANGLE_STRIP);
 +      immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2);
        for (int a = 0; a <= sizex; a++) {
                float pos = ((float)a) / sizex;
                BKE_colorband_evaluate(coba, pos, colf);
                if (display)
                        IMB_colormanagement_scene_linear_to_display_v3(colf, display);
-               
                v1[0] = v2[0] = x1 + a;
-               
 -              glColor4fv(colf);
 -              glVertex2fv(v1);
 -              glVertex2fv(v2);
 +              immAttrib4fv(color, colf);
 +              immVertex2fv(position, v1);
 +              immVertex2fv(position, v2);
        }
 -      glEnd();
 +      immEnd();
  
        /* layer: color ramp without alpha for reference when manipulating ramp properties */
        v1[1] = y1;
  
        /* layer: box outline */
        glEnable(GL_BLEND);
 -      glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
 -      fdrawline(x1, y1, x1 + sizex, y1);
 -      glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
 -      fdrawline(x1, y1 - 1, x1 + sizex, y1 - 1);
 +      immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
 +
 +      immBegin(GWN_PRIM_LINES, 2);
 +      immVertex2f(position, x1, y1);
 +      immVertex2f(position, x1 + sizex, y1);
 +      immEnd();
 +
 +      immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
 +
 +      immBegin(GWN_PRIM_LINES, 2);
 +      immVertex2f(position, x1, y1 - 1);
 +      immVertex2f(position, x1 + sizex, y1 - 1);
 +      immEnd();
 +
        glDisable(GL_BLEND);
-       
        /* layer: draw handles */
        for (int a = 0; a < coba->tot; a++, cbd++) {
                if (a != coba->cur) {
  
  void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
  {
 -      static GLuint displist = 0;
 +      /* sphere color */
        float diffuse[3] = {1.0f, 1.0f, 1.0f};
 +      float light[3];
        float size;
-       
        /* backdrop */
 -      glColor3ubv((unsigned char *)wcol->inner);
        UI_draw_roundbox_corner_set(UI_CNR_ALL);
 -      UI_draw_roundbox_gl_mode(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
 +      UI_draw_roundbox_3ubAlpha(true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, (unsigned char *)wcol->inner, 255);
-       
 -      /* sphere color */
        glCullFace(GL_BACK);
        glEnable(GL_CULL_FACE);
-       
        /* setup lights */
 -      GPULightData light = {0};
 -      light.type = GPU_LIGHT_SUN;
 -      copy_v3_v3(light.diffuse, diffuse);
 -      zero_v3(light.specular);
 -      ui_but_v3_get(but, light.direction);
 -
 -      GPU_basic_shader_light_set(0, &light);
 -      for (int a = 1; a < 8; a++)
 -              GPU_basic_shader_light_set(a, NULL);
 -
 -      /* setup shader */
 -      GPU_basic_shader_colors(diffuse, NULL, 0, 1.0f);
 -      GPU_basic_shader_bind(GPU_SHADER_LIGHTING);
 +      ui_but_v3_get(but, light);
  
        /* transform to button */
 -      glPushMatrix();
 -      glTranslatef(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect), 0.0f);
 +      gpuPushMatrix();
-       
        if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect))
 -              size = BLI_rcti_size_x(rect) / 200.f;
 +              size = 0.5f * BLI_rcti_size_x(rect);
        else
 -              size = BLI_rcti_size_y(rect) / 200.f;
 +              size = 0.5f * BLI_rcti_size_y(rect);
  
 -      glScalef(size, size, MIN2(size, 1.0f));
 +      gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
 +      gpuScaleUniform(size);
  
 -      if (displist == 0) {
 -              GLUquadricObj *qobj;
 -
 -              displist = glGenLists(1);
 -              glNewList(displist, GL_COMPILE);
 -
 -              qobj = gluNewQuadric();
 -              gluQuadricDrawStyle(qobj, GLU_FILL);
 -              GPU_basic_shader_bind(GPU_basic_shader_bound_options());
 -              gluSphere(qobj, 100.0, 32, 24);
 -              gluDeleteQuadric(qobj);
 -
 -              glEndList();
 -      }
 -
 -      glCallList(displist);
 +      Gwn_Batch *sphere = GPU_batch_preset_sphere(2);
 +      GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
 +      GWN_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
 +      GWN_batch_uniform_3fv(sphere, "light", light);
 +      GWN_batch_draw(sphere);
  
        /* restore */
 -      GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
 -      GPU_default_lights();
        glDisable(GL_CULL_FACE);
-       
        /* AA circle */
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor3ubv((unsigned char *)wcol->inner);
 +
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
 -      glColor3ubv((unsigned char *)wcol->inner);
 -      glutil_draw_lined_arc(0.0f, M_PI * 2.0, 100.0f, 32);
 +      imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
        glDisable(GL_BLEND);
        glDisable(GL_LINE_SMOOTH);
  
@@@ -1578,27 -1265,23 +1578,27 @@@ static void ui_draw_but_curve_grid(unsi
        float dx = step * zoomx;
        float fx = rect->xmin + zoomx * (-offsx);
        if (fx > rect->xmin) fx -= dx * (floorf(fx - rect->xmin));
-       
 -      while (fx < rect->xmax) {
 -              glVertex2f(fx, rect->ymin);
 -              glVertex2f(fx, rect->ymax);
 -              fx += dx;
 -      }
        float dy = step * zoomy;
        float fy = rect->ymin + zoomy * (-offsy);
        if (fy > rect->ymin) fy -= dy * (floorf(fy - rect->ymin));
 +
 +      float line_count = floorf((rect->xmax - fx) / dx) + 1.0f +
 +                         floorf((rect->ymax - fy) / dy) + 1.0f;
 +
 +      immBegin(GWN_PRIM_LINES, (int)line_count * 2);
 +      while (fx < rect->xmax) {
 +              immVertex2f(pos, fx, rect->ymin);
 +              immVertex2f(pos, fx, rect->ymax);
 +              fx += dx;
 +      }
        while (fy < rect->ymax) {
 -              glVertex2f(rect->xmin, fy);
 -              glVertex2f(rect->xmax, fy);
 +              immVertex2f(pos, rect->xmin, fy);
 +              immVertex2f(pos, rect->xmax, fy);
                fy += dy;
        }
 -      glEnd();
 +      immEnd();
-       
  }
  
  static void gl_shaded_color(unsigned char *col, int shade)
@@@ -1731,31 -1406,31 +1731,31 @@@ void ui_draw_but_CURVE(ARegion *ar, uiB
                }
                else if (cumap->cur == 3) {
                        float lum = IMB_colormanagement_get_luminance(cumap->sample);
 -                      glColor3ub(240, 240, 240);
 +                      immUniformColor3ub(240, 240, 240);
-                       
 -                      glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin);
 -                      glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax);
 +                      immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
 +                      immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
                }
                else {
                        if (cumap->cur == 0)
 -                              glColor3ub(240, 100, 100);
 +                              immUniformColor3ub(240, 100, 100);
                        else if (cumap->cur == 1)
 -                              glColor3ub(100, 240, 100);
 +                              immUniformColor3ub(100, 240, 100);
                        else
 -                              glColor3ub(100, 100, 240);
 +                              immUniformColor3ub(100, 100, 240);
-                       
 -                      glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
 -                      glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
 +                      immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
 +                      immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
                }
 -              glEnd();
 +              immEnd();
        }
  
        /* the curve */
 -      glColor3ubv((unsigned char *)wcol->item);
 +      immUniformColor3ubv((unsigned char *)wcol->item);
        glEnable(GL_LINE_SMOOTH);
        glEnable(GL_BLEND);
 -      glBegin(GL_LINE_STRIP);
 +      immBegin(GWN_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2);
-       
        if (cuma->table == NULL)
                curvemapping_changed(cumap, false);
  
        else {
                float fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
                float fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
 -              glVertex2f(fx, fy);
 +              immVertex2f(pos, fx, fy);
        }
 -      glEnd();
 +      immEnd();
        glDisable(GL_LINE_SMOOTH);
        glDisable(GL_BLEND);
 +      immUnbindProgram();
  
        /* the points, use aspect to make them visible on edges */
 +      format = immVertexFormat();
 +      pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +
        cmp = cuma->curve;
        glPointSize(3.0f);
 -      glBegin(GL_POINTS);
 +      immBegin(GWN_PRIM_POINTS, cuma->totpoint);
        for (int a = 0; a < cuma->totpoint; a++) {
 +              float color[4];
                if (cmp[a].flag & CUMA_SELECT)
 -                      UI_ThemeColor(TH_TEXT_HI);
 +                      UI_GetThemeColor4fv(TH_TEXT_HI, color);
                else
 -                      UI_ThemeColor(TH_TEXT);
 +                      UI_GetThemeColor4fv(TH_TEXT, color);
                float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
                float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
 -              glVertex2f(fx, fy);
 +              immAttrib4fv(col, color);
 +              immVertex2f(pos, fx, fy);
        }
 -      glEnd();
 +      immEnd();
 +      immUnbindProgram();
-       
        /* restore scissortest */
        glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  
@@@ -1974,53 -1624,46 +1974,53 @@@ void ui_draw_but_NODESOCKET(ARegion *ar
            -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
            0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
        };
-       
        GLint scissor[4];
-       
        /* need scissor test, can draw outside of boundary */
 -      glGetIntegerv(GL_VIEWPORT, scissor);
 +      glGetIntegerv(GL_SCISSOR_BOX, scissor);
-       
        rcti scissor_new = {
 -              .xmin = ar->winrct.xmin + recti->xmin,
 -              .ymin = ar->winrct.ymin + recti->ymin,
 -              .xmax = ar->winrct.xmin + recti->xmax,
 -              .ymax = ar->winrct.ymin + recti->ymax
 +              .xmin = recti->xmin,
 +              .ymin = recti->ymin,
 +              .xmax = recti->xmax,
 +              .ymax = recti->ymax
        };
  
 -      BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new);
 +      rcti scissor_region = {0, ar->winx, 0, ar->winy};
 +
 +      BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
        glScissor(scissor_new.xmin,
                  scissor_new.ymin,
                  BLI_rcti_size_x(&scissor_new),
                  BLI_rcti_size_y(&scissor_new));
-       
 -      glColor4ubv(but->col);
 -
        float x = 0.5f * (recti->xmin + recti->xmax);
        float y = 0.5f * (recti->ymin + recti->ymax);
  
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4ubv(but->col);
 +
        glEnable(GL_BLEND);
 -      glBegin(GL_POLYGON);
 +      immBegin(GWN_PRIM_TRI_FAN, 16);
        for (int a = 0; a < 16; a++)
 -              glVertex2f(x + size * si[a], y + size * co[a]);
 -      glEnd();
 +              immVertex2f(pos, x + size * si[a], y + size * co[a]);
 +      immEnd();
-       
 -      glColor4ub(0, 0, 0, 150);
 +      immUniformColor4ub(0, 0, 0, 150);
        glLineWidth(1);
        glEnable(GL_LINE_SMOOTH);
 -      glBegin(GL_LINE_LOOP);
 +      immBegin(GWN_PRIM_LINE_LOOP, 16);
        for (int a = 0; a < 16; a++)
 -              glVertex2f(x + size * si[a], y + size * co[a]);
 -      glEnd();
 +              immVertex2f(pos, x + size * si[a], y + size * co[a]);
 +      immEnd();
        glDisable(GL_LINE_SMOOTH);
        glDisable(GL_BLEND);
  
-       
 +      immUnbindProgram();
++
        /* restore scissortest */
        glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  }
@@@ -2095,22 -1702,14 +2095,22 @@@ void UI_draw_box_shadow(unsigned char a
  {
        glEnable(GL_BLEND);
  
 -      glBegin(GL_QUADS);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
 +
 +      immBegin(GWN_PRIM_TRIS, 54);
  
        /* accumulated outline boxes to make shade not linear, is more pleasant */
 -      ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
 -      ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
 -      ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
 +      ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
 +      ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
 +      ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
-       
 -      glEnd();
 +      immEnd();
 +
 +      immUnbindProgram();
  
        glDisable(GL_BLEND);
  }
  void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
  {
        float rad;
-       
 -      if (radius > (BLI_rctf_size_y(rct) - 10.0f) / 2.0f)
 -              rad = (BLI_rctf_size_y(rct) - 10.0f) / 2.0f;
 +      if (radius > (BLI_rctf_size_y(rct) - 10.0f) * 0.5f)
 +              rad = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f;
        else
                rad = radius;
  
        {
                a = i * aspect;
        }
-       
        glEnable(GL_BLEND);
 -
        const float dalpha = alpha * 2.0f / 255.0f;
        float calpha = dalpha;
 -      for (; i--; a -= aspect) {
 +      float visibility = 1.0f;
 +      for (; i--;) {
                /* alpha ranges from 2 to 20 or so */
 -              glColor4f(0.0f, 0.0f, 0.0f, calpha);
 +#if 0 /* Old Method (pre 2.8) */
 +              float color[4] = {0.0f, 0.0f, 0.0f, calpha};
 +              UI_draw_roundbox_4fv(true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color);
 +#endif
 +              /* Compute final visibility to match old method result. */
 +              /* TODO we could just find a better fit function inside the shader instead of this. */
 +              visibility = visibility * (1.0f - calpha);
                calpha += dalpha;
 -
 -              UI_draw_roundbox_gl_mode(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a);
        }
-       
 +      uiWidgetBaseParameters widget_params = {
 +              .recti.xmin = rct->xmin, .recti.ymin = rct->ymin,
 +              .recti.xmax = rct->xmax, .recti.ymax = rct->ymax - 10.0f,
 +              .rect.xmin = rct->xmin - a, .rect.ymin = rct->ymin - a,
 +              .rect.xmax = rct->xmax + a, .rect.ymax = rct->ymax - 10.0f + a,
 +              .radi = rad,
 +              .rad = rad + a,
 +              .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
 +              .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
 +              .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
 +              .alpha_discard = 1.0f,
 +      };
 +
 +      Gwn_Batch *batch = ui_batch_roundbox_shadow_get();
 +      GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
 +      GWN_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
 +      GWN_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
 +      GWN_batch_draw(batch);
 +
        /* outline emphasis */
        glEnable(GL_LINE_SMOOTH);
 -      glColor4ub(0, 0, 0, 100);
 -      UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f);
 +      float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
 +      UI_draw_roundbox_4fv(false, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f, color);
        glDisable(GL_LINE_SMOOTH);
-       
        glDisable(GL_BLEND);
  }
 -
 -/**
 - * Reset GL state (keep minimal).
 - *
 - * \note Blender's internal code doesn't assume these are reset,
 - * but external callbacks may depend on their state.
 - */
 -void UI_reinit_gl_state(void)
 -{
 -      glLineWidth(1.0f);
 -      glPointSize(1.0f);
 -}
@@@ -2987,11 -3167,8 +2987,11 @@@ static void ui_textedit_end(bContext *C
  
                        ui_searchbox_free(C, data->searchbox);
                        data->searchbox = NULL;
 +                      if (but->free_search_arg) {
 +                              MEM_SAFE_FREE(but->search_arg);
 +                      }
                }
-               
                but->editstr = NULL;
                but->pos = -1;
        }
@@@ -6774,9 -6882,6 +6774,9 @@@ static bool ui_but_menu(bContext *C, ui
                                uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
                                        ICON_NONE, "ANIM_OT_paste_driver_button");
                        }
-                       
++
 +                      uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
 +                              ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
                }
                else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
                        /* pass */
                                uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
                                        ICON_NONE, "ANIM_OT_paste_driver_button");
                        }
-                       
++
 +                      uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
 +                              ICON_NONE, "SCREEN_OT_drivers_editor_show");
                }
-               
                /* Keying Sets */
                /* TODO: check on modifyability of Keying Set when doing this */
                if (is_anim) {
@@@ -7443,11 -7498,10 +7443,11 @@@ static bool ui_region_contains_point_px
                ui_window_to_region(ar, &mx, &my);
  
                /* check if in the rect */
 -              if (!BLI_rcti_isect_pt(&v2d->mask, mx, my))
 +              if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) || UI_view2d_mouse_in_scrollers(ar, &ar->v2d, x, y)) {
                        return false;
 +              }
        }
-       
        return true;
  }
  
@@@ -8165,9 -8211,8 +8165,9 @@@ void UI_context_update_anim_flag(const 
                for (block = ar->uiblocks.first; block; block = block->next) {
                        for (but = block->buttons.first; but; but = but->next) {
                                ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
 +                              ui_but_override_flag(but);
                                ED_region_tag_redraw(ar);
-                               
                                if (but->active) {
                                        activebut = but;
                                }
@@@ -255,10 -239,11 +255,10 @@@ static void vicon_keytype_draw_wrapper(
         * (since we're doing this offscreen, free from any particular space_id)
         */
        struct bThemeState theme_state;
-       
 -      int xco, yco;
        UI_Theme_Store(&theme_state);
        UI_SetTheme(SPACE_ACTION, RGN_TYPE_WINDOW);
-       
        /* the "x" and "y" given are the bottom-left coordinates of the icon,
         * while the draw_keyframe_shape() function needs the midpoint for
         * the keyframe
@@@ -566,11 -528,16 +566,11 @@@ static void init_internal_icons(void
                                        IMB_freeImBuf(b16buf);
                                        b16buf = nbuf;
                                }
-                               
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-                               
                                glBindTexture(GL_TEXTURE_2D, 0);
 -
 -                              if (glGetError() == GL_OUT_OF_MEMORY) {
 -                                      glDeleteTextures(1, &icongltex.id);
 -                                      icongltex.id = 0;
 -                              }
                        }
                }
        }
@@@ -817,11 -745,15 +817,11 @@@ int UI_icon_get_width(int icon_id
                        printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
                return 0;
        }
-       
 -      di = (DrawInfo *)icon->drawinfo;
 -      if (!di) {
 -              di = icon_create_drawinfo();
 -              icon->drawinfo = di;
 -      }
 -
 -      if (di)
 +      di = icon_ensure_drawinfo(icon);
 +      if (di) {
                return ICON_DEFAULT_WIDTH;
 +      }
  
        return 0;
  }
@@@ -72,10 -72,8 +72,10 @@@ typedef enum 
        UI_WTYPE_NUMBER,
        UI_WTYPE_SLIDER,
        UI_WTYPE_EXEC,
 +      UI_WTYPE_TOOLBAR_ITEM,
 +      UI_WTYPE_TAB,
        UI_WTYPE_TOOLTIP,
-       
        /* strings */
        UI_WTYPE_NAME,
        UI_WTYPE_NAME_LINK,
@@@ -245,10 -255,9 +245,10 @@@ struct uiBut 
  
        uiButCompleteFunc autocomplete_func;
        void *autofunc_arg;
-       
        uiButSearchCreateFunc search_create_func;
        uiButSearchFunc search_func;
 +      bool free_search_arg;
        void *search_arg;
  
        uiButHandleRenameFunc rename_func;
@@@ -1495,21 -1441,16 +1495,21 @@@ void uiItemFullR(uiLayout *layout, Poin
        expand = (flag & UI_ITEM_R_EXPAND) != 0;
        icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
        no_bg = (flag & UI_ITEM_R_NO_BG) != 0;
 +      compact = (flag & UI_ITEM_R_COMPACT) != 0;
  
        /* get size */
 -      ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, &w, &h);
 +      ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h);
  
 -      if (no_bg)
 -              UI_block_emboss_set(block, UI_EMBOSS_NONE);
 +      int prev_emboss = layout->emboss;
 +      if (no_bg) {
 +              layout->emboss = UI_EMBOSS_NONE;
 +      }
-       
        /* array property */
        if (index == RNA_NO_INDEX && is_array)
 -              ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand, slider, toggle, icon_only);
 +              ui_item_array(
 +                          layout, block, name, icon, ptr, prop, len, 0, 0, w, h,
 +                          expand, slider, toggle, icon_only, compact);
        /* enum item */
        else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
                if (icon && name[0] && !icon_only)
@@@ -398,15 -415,15 +398,15 @@@ void UI_draw_icon_tri(float x, float y
        float f3 = 0.15 * U.widget_unit;
        float f5 = 0.25 * U.widget_unit;
        float f7 = 0.35 * U.widget_unit;
-       
        if (dir == 'h') {
 -              ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y);
 +              UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
        }
        else if (dir == 't') {
 -              ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3);
 +              UI_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color);
        }
        else { /* 'v' = vertical, down */
 -              ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7);
 +              UI_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color);
        }
  }
  
@@@ -436,19 -449,12 +436,19 @@@ static void ui_draw_anti_x(unsigned in
  
        glLineWidth(2.0);
  
 -      fdrawline(x1, y1, x2, y2);
 -      fdrawline(x1, y2, x2, y1);
 +      immBegin(GWN_PRIM_LINES, 4);
 +
 +      immVertex2f(pos, x1, y1);
 +      immVertex2f(pos, x2, y2);
 +
 +      immVertex2f(pos, x1, y2);
 +      immVertex2f(pos, x2, y1);
 +
 +      immEnd();
-       
        glDisable(GL_LINE_SMOOTH);
        glDisable(GL_BLEND);
-       
  }
  
  /* x 'icon' for panel header */
@@@ -470,59 -476,23 +470,59 @@@ static void ui_draw_panel_scalewidget(u
        xmax = rect->xmax - 3;
        ymin = rect->ymin + 3;
        ymax = rect->ymin + PNL_HEADER - 2;
-               
        dx = 0.5f * (xmax - xmin);
        dy = 0.5f * (ymax - ymin);
-       
        glEnable(GL_BLEND);
 -      glColor4ub(255, 255, 255, 50);
 -      fdrawline(xmin, ymin, xmax, ymax);
 -      fdrawline(xmin + dx, ymin, xmax, ymax - dy);
 +      immUniformColor4ub(255, 255, 255, 50);
 +
 +      immBegin(GWN_PRIM_LINES, 4);
 +
 +      immVertex2f(pos, xmin, ymin);
 +      immVertex2f(pos, xmax, ymax);
 +
 +      immVertex2f(pos, xmin + dx, ymin);
 +      immVertex2f(pos, xmax, ymax - dy);
 +
 +      immEnd();
-       
++
 +      immUniformColor4ub(0, 0, 0, 50);
 +
 +      immBegin(GWN_PRIM_LINES, 4);
 +
 +      immVertex2f(pos, xmin, ymin + 1);
 +      immVertex2f(pos, xmax, ymax + 1);
 +
 +      immVertex2f(pos, xmin + dx, ymin + 1);
 +      immVertex2f(pos, xmax, ymax - dy + 1);
 +
 +      immEnd();
  
 -      glColor4ub(0, 0, 0, 50);
 -      fdrawline(xmin, ymin + 1, xmax, ymax + 1);
 -      fdrawline(xmin + dx, ymin + 1, xmax, ymax - dy + 1);
        glDisable(GL_BLEND);
  }
 -static void ui_draw_panel_dragwidget(const rctf *rect)
 +
 +static void immRectf_tris_color_ex(unsigned int pos, float x1, float y1, float x2, float y2,
 +                              unsigned int col, const float color[3])
  {
 -      unsigned char col_back[3], col_high[3], col_dark[3];
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x1, y1);
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x2, y1);
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x2, y2);
 +
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x1, y1);
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x2, y2);
 +      immAttrib4fv(col, color);
 +      immVertex2f(pos, x1, y2);
 +}
 +
 +static void ui_draw_panel_dragwidget(unsigned int pos, unsigned int col, const rctf *rect)
 +{
 +      float col_high[4], col_dark[4];
        const int col_tint = 84;
  
        const int px = (int)U.pixelsize;
@@@ -580,10 -549,10 +580,10 @@@ static void ui_draw_aligned_panel_heade
        if (dir == 'h') {
                hrect.xmin = rect->xmin + pnl_icons;
                hrect.ymin += 2.0f / block->aspect;
 -              UI_fontstyle_draw(&style->paneltitle, &hrect, activename);
 +              UI_fontstyle_draw(&style->paneltitle, &hrect, activename, col_title);
        }
        else {
-               /* ignore 'pnl_icons', otherwise the text gets offset horizontally 
+               /* ignore 'pnl_icons', otherwise the text gets offset horizontally
                 * + 0.001f to avoid flirting with float inaccuracy
                 */
                hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
@@@ -727,16 -569,58 +727,16 @@@ static void template_ID
                                UI_but_flag_enable(but, UI_BUT_DISABLED);
                        }
                }
-       
                if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
-               
 -              if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
 +              if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
                        uiDefButR(block, UI_BTYPE_TOGGLE, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
                }
        }
-       
        if (flag & UI_ID_ADD_NEW) {
 -              int w = id ? UI_UNIT_X : (flag & UI_ID_OPEN) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
 -
 -              /* i18n markup, does nothing! */
 -              BLT_I18N_MSGID_MULTI_CTXT("New", BLT_I18NCONTEXT_DEFAULT,
 -                                               BLT_I18NCONTEXT_ID_SCENE,
 -                                               BLT_I18NCONTEXT_ID_OBJECT,
 -                                               BLT_I18NCONTEXT_ID_MESH,
 -                                               BLT_I18NCONTEXT_ID_CURVE,
 -                                               BLT_I18NCONTEXT_ID_METABALL,
 -                                               BLT_I18NCONTEXT_ID_MATERIAL,
 -                                               BLT_I18NCONTEXT_ID_TEXTURE,
 -                                               BLT_I18NCONTEXT_ID_IMAGE,
 -                                               BLT_I18NCONTEXT_ID_LATTICE,
 -                                               BLT_I18NCONTEXT_ID_LAMP,
 -                                               BLT_I18NCONTEXT_ID_CAMERA,
 -                                               BLT_I18NCONTEXT_ID_WORLD,
 -                                               BLT_I18NCONTEXT_ID_SCREEN,
 -                                               BLT_I18NCONTEXT_ID_TEXT,
 -              );
 -              BLT_I18N_MSGID_MULTI_CTXT("New", BLT_I18NCONTEXT_ID_SPEAKER,
 -                                               BLT_I18NCONTEXT_ID_SOUND,
 -                                               BLT_I18NCONTEXT_ID_ARMATURE,
 -                                               BLT_I18NCONTEXT_ID_ACTION,
 -                                               BLT_I18NCONTEXT_ID_NODETREE,
 -                                               BLT_I18NCONTEXT_ID_BRUSH,
 -                                               BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
 -                                               BLT_I18NCONTEXT_ID_GPENCIL,
 -                                               BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
 -              );
 -
 -              if (newop) {
 -                      but = uiDefIconTextButO(block, UI_BTYPE_BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
 -                                              (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL);
 -                      UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
 -              }
 -              else {
 -                      but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
 -                                             0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 -                      UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
 -              }
 -
 -              if ((idfrom && idfrom->lib) || !editable)
 -                      UI_but_flag_enable(but, UI_BUT_DISABLED);
 +              template_id_def_new_but(block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
        }
  
        /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
@@@ -1630,9 -1168,9 +1630,9 @@@ static void do_constraint_panels(bConte
         *
         * object_test_constraints(ob);
         * if (ob->pose) BKE_pose_update_constraint_flags(ob->pose); */
-       
 -      if (ob->type == OB_ARMATURE) DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
 -      else DAG_id_tag_update(&ob->id, OB_RECALC_OB);
 +      if (ob->type == OB_ARMATURE) DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
 +      else DEG_id_tag_update(&ob->id, OB_RECALC_OB);
  
        WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
  }
@@@ -170,146 -172,51 +170,146 @@@ eAutoPropButsReturn uiDefAutoButsRNA
        RNA_STRUCT_BEGIN (ptr, prop)
        {
                flag = RNA_property_flag(prop);
 -              if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop) == 0))
 +
 +              if (flag & PROP_HIDDEN) {
                        continue;
 +              }
 +              if (check_prop && check_prop(ptr, prop) == 0) {
 +                      return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
 +                      continue;
 +              }
  
 -              if (label_align != '\0') {
 -                      PropertyType type = RNA_property_type(prop);
 -                      const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
 +              switch (label_align) {
 +                      case UI_BUT_LABEL_ALIGN_COLUMN:
 +                      case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN:
 +                      {
 +                              PropertyType type = RNA_property_type(prop);
 +                              const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
  
 -                      name = RNA_property_ui_name(prop);
 +                              name = RNA_property_ui_name(prop);
  
 -                      if (label_align == 'V') {
 -                              col = uiLayoutColumn(layout, true);
 +                              if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
 +                                      col = uiLayoutColumn(layout, true);
  
 -                              if (!is_boolean)
 -                                      uiItemL(col, name, ICON_NONE);
 -                      }
 -                      else {  /* (label_align == 'H') */
 -                              BLI_assert(label_align == 'H');
 -                              split = uiLayoutSplit(layout, 0.5f, false);
 +                                      if (!is_boolean)
 +                                              uiItemL(col, name, ICON_NONE);
 +                              }
 +                              else {
 +                                      BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
 +                                      split = uiLayoutSplit(layout, 0.5f, false);
 +
 +                                      col = uiLayoutColumn(split, false);
 +                                      uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
 +                                      col = uiLayoutColumn(split, false);
 +                              }
  
 -                              col = uiLayoutColumn(split, false);
 -                              uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
 -                              col = uiLayoutColumn(split, false);
 +                              /* may meed to add more cases here.
 +                               * don't override enum flag names */
 +
 +                              /* name is shown above, empty name for button below */
 +                              name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
 +
 +                              break;
                        }
 +                      case UI_BUT_LABEL_ALIGN_NONE:
 +                      default:
 +                              col = layout;
 +                              name = NULL; /* no smart label alignment, show default name with button */
 +                              break;
 +              }
 +
 +              uiItemFullR(col, ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : 0, name, ICON_NONE);
 +              return_info &= ~UI_PROP_BUTS_NONE_ADDED;
 +      }
 +      RNA_STRUCT_END;
 +
 +      return return_info;
 +}
 +
 +/* *** RNA collection search menu *** */
 +
 +typedef struct CollItemSearch {
 +      struct CollItemSearch *next, *prev;
 +      void *data;
 +      char *name;
 +      int index;
 +      int iconid;
 +} CollItemSearch;
  
 -                      /* may meed to add more cases here.
 -                       * don't override enum flag names */
 +static int sort_search_items_list(const void *a, const void *b)
 +{
 +      const CollItemSearch *cis1 = a;
 +      const CollItemSearch *cis2 = b;
 +
 +      if (BLI_strcasecmp(cis1->name, cis2->name) > 0)
 +              return 1;
 +      else
 +              return 0;
 +}
 +
 +void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items)
 +{
 +      uiRNACollectionSearch *data = arg;
 +      char *name;
 +      int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
 +      ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
 +      CollItemSearch *cis;
 +      const bool skip_filter = !(data->but_changed && *data->but_changed);
 +
 +      /* build a temporary list of relevant items first */
 +      RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop)
 +      {
 +
 +              if (flag & PROP_ID_SELF_CHECK)
 +                      if (itemptr.data == data->target_ptr.id.data)
 +                              continue;
  
 -                      /* name is shown above, empty name for button below */
 -                      name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
 +              /* use filter */
 +              if (RNA_property_type(data->target_prop) == PROP_POINTER) {
 +                      if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0)
 +                              continue;
                }
 -              else {
 -                      col = layout;
 -                      name = NULL; /* no smart label alignment, show default name with button */
 +
 +              name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
 +              iconid = 0;
 +              if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
 +                      iconid = ui_id_icon_get(C, itemptr.data, false);
 +              }
 +
 +              if (name) {
 +                      if (skip_filter || BLI_strcasestr(name, str)) {
 +                              cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
 +                              cis->data = itemptr.data;
 +                              cis->name = MEM_dupallocN(name);
 +                              cis->index = i;
 +                              cis->iconid = iconid;
 +                              BLI_addtail(items_list, cis);
 +                      }
 +                      MEM_freeN(name);
                }
  
 -              uiItemFullR(col, ptr, prop, -1, 0, 0, name, ICON_NONE);
 -              tot++;
 +              i++;
 +      }
 +      RNA_PROP_END;
 +
 +      BLI_listbase_sort(items_list, sort_search_items_list);
 +
 +      /* add search items from temporary list */
 +      for (cis = items_list->first; cis; cis = cis->next) {
 +              if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
 +                      break;
 +              }
        }
 -      RNA_STRUCT_END;
  
 -      return tot;
 +      for (cis = items_list->first; cis; cis = cis->next) {
 +              MEM_freeN(cis->name);
 +      }
 +      BLI_freelistN(items_list);
 +      MEM_freeN(items_list);
  }
  
 -/***************************** ID Utilities *******************************/
  
- /***************************** ID Utilities *******************************/ 
++/***************************** ID Utilities *******************************/
  int UI_icon_from_id(ID *id)
  {
        Object *ob;
@@@ -104,12 -98,10 +104,12 @@@ enum 
  
  typedef struct uiWidgetTrias {
        unsigned int tot;
-       
 +      int type;
 +      float size, center[2];
        float vec[16][2];
        const unsigned int (*index)[3];
-       
  } uiWidgetTrias;
  
  /* max as used by round_box__edges */
@@@ -123,9 -114,9 +123,9 @@@ typedef struct uiWidgetBase 
        float outer_v[WIDGET_SIZE_MAX][2];
        float inner_v[WIDGET_SIZE_MAX][2];
        float inner_uv[WIDGET_SIZE_MAX][2];
-       
 -      bool draw_inner, draw_outline, draw_emboss, draw_shadedir;
 +      bool draw_inner, draw_outline, draw_emboss;
-       
        uiWidgetTrias tria1;
        uiWidgetTrias tria2;
  
@@@ -952,13 -601,12 +952,13 @@@ static void shape_preset_trias_from_rec
  {
        float centx, centy, size;
        int a;
-       
 +      tria->type = ROUNDBOX_TRIA_CHECK;
        /* center position and size */
 -      centx = rect->xmin + 0.5f * BLI_rcti_size_y(rect);
 -      centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
 -      size = 0.5f * BLI_rcti_size_y(rect);
 +      tria->center[0] = centx = rect->xmin + 0.5f * BLI_rcti_size_y(rect);
 +      tria->center[1] = centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
 +      tria->size = size = 0.5f * BLI_rcti_size_y(rect);
-       
        for (a = 0; a < 6; a++) {
                tria->vec[a][0] = size * g_shape_preset_checkmark_vert[a][0] + centx;
                tria->vec[a][1] = size * g_shape_preset_checkmark_vert[a][1] + centy;
@@@ -1287,15 -905,15 +1287,15 @@@ static void widget_draw_icon_ex
                        alpha *= 0.5f;
                }
        }
-       
        glEnable(GL_BLEND);
-       
        if (icon && icon != ICON_BLANK1) {
                float ofs = 1.0f / aspect;
-               
                if (but->drawflag & UI_BUT_ICON_LEFT) {
                        /* special case - icon_only pie buttons */
 -                      if (ui_block_is_pie_menu(but->block) && but->type != UI_BTYPE_MENU && but->str && but->str[0] == '\0')
 +                      if (ui_block_is_pie_menu(but->block) && !ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_POPOVER) && but->str && but->str[0] == '\0')
                                xs = rect->xmin + 2.0f * ofs;
                        else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL)
                                xs = rect->xmin + 2.0f * ofs;
@@@ -1780,12 -1392,8 +1780,12 @@@ static void widget_draw_text(uiFontStyl
                /* text button selection */
                if ((but->selend - but->selsta) > 0) {
                        int selsta_draw, selwidth_draw;
-                       
                        if (drawstr[0] != 0) {
 +                              /* We are drawing on top of widget bases. Flush cache. */
 +                              glEnable(GL_BLEND);
 +                              UI_widgetbase_draw_cache_flush();
 +                              glDisable(GL_BLEND);
  
                                if (but->selsta >= but->ofs) {
                                        selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
@@@ -2116,14 -1688,12 +2116,14 @@@ static struct uiWidgetColors wcol_num 
        {180, 180, 180, 255},
        {153, 153, 153, 255},
        {90, 90, 90, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      -20, 0
 +      -20, 0,
 +      0,
 +      0.5f,
  };
  
  static struct uiWidgetColors wcol_numslider = {
        {180, 180, 180, 255},
        {153, 153, 153, 255},
        {128, 128, 128, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      -20, 0
 +      -20, 0,
 +      0,
 +      0.5f,
  };
  
  static struct uiWidgetColors wcol_text = {
        {153, 153, 153, 255},
        {153, 153, 153, 255},
        {90, 90, 90, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      0, 25
 +      0, 25,
 +      0,
 +      0.2f,
  };
  
  static struct uiWidgetColors wcol_option = {
        {70, 70, 70, 255},
        {70, 70, 70, 255},
        {255, 255, 255, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      15, -15
 +      15, -15,
 +      0,
 +      0.3333333f,
  };
  
  /* button that shows popup */
@@@ -2177,14 -1741,12 +2177,14 @@@ static struct uiWidgetColors wcol_menu 
        {70, 70, 70, 255},
        {70, 70, 70, 255},
        {255, 255, 255, 255},
-       
        {255, 255, 255, 255},
        {204, 204, 204, 255},
-       
        1,
 -      15, -15
 +      15, -15,
 +      0,
 +      0.2f,
  };
  
  /* button that starts pulldown */
@@@ -2193,14 -1755,12 +2193,14 @@@ static struct uiWidgetColors wcol_pulld
        {63, 63, 63, 255},
        {86, 128, 194, 255},
        {255, 255, 255, 255},
-       
        {0, 0, 0, 255},
        {0, 0, 0, 255},
-       
        0,
 -      25, -20
 +      25, -20,
 +      0,
 +      0.2f,
  };
  
  /* button inside menu */
@@@ -2209,14 -1769,12 +2209,14 @@@ static struct uiWidgetColors wcol_menu_
        {0, 0, 0, 0},
        {86, 128, 194, 255},
        {172, 172, 172, 128},
-       
        {255, 255, 255, 255},
        {0, 0, 0, 255},
-       
        1,
 -      38, 0
 +      38, 0,
 +      0,
 +      0.2f,
  };
  
  /* backdrop menu + title text color */
@@@ -2225,14 -1783,12 +2225,14 @@@ static struct uiWidgetColors wcol_menu_
        {25, 25, 25, 230},
        {45, 45, 45, 230},
        {100, 100, 100, 255},
-       
        {160, 160, 160, 255},
        {255, 255, 255, 255},
-       
        0,
 -      25, -20
 +      25, -20,
 +      0,
 +      0.25f,
  };
  
  /* pie menus */
@@@ -2273,14 -1825,12 +2273,14 @@@ static struct uiWidgetColors wcol_radi
        {70, 70, 70, 255},
        {86, 128, 194, 255},
        {255, 255, 255, 255},
-       
        {255, 255, 255, 255},
        {0, 0, 0, 255},
-       
        1,
 -      15, -15
 +      15, -15,
 +      0,
 +      0.2f,
  };
  
  static struct uiWidgetColors wcol_regular = {
        {153, 153, 153, 255},
        {100, 100, 100, 255},
        {25, 25, 25, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.25f,
  };
  
  static struct uiWidgetColors wcol_tool = {
        {153, 153, 153, 255},
        {100, 100, 100, 255},
        {25, 25, 25, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      15, -15
 +      15, -15,
 +      0,
 +      0.2f,
 +};
 +
 +static struct uiWidgetColors wcol_toolbar_item = {
 +      .outline = {0x19, 0x19, 0x19, 0xff},
 +      .inner = {0x46, 0x46, 0x46, 0xff},
 +      .inner_sel = {0xcc, 0xcc, 0xcc, 0xff},
 +      .item = {0x0, 0x0, 0x0, 0xff},
 +
 +      .text = {0xff, 0xff, 0xff, 0xff},
 +      .text_sel = {0x33, 0x33, 0x33, 0xff},
 +
 +      .shaded = 0,
 +      .shadetop = 0,
 +      .shadedown = 0,
 +      .alpha_check = 0,
 +      .roundness = 0.3f,
  };
  
  static struct uiWidgetColors wcol_box = {
        {128, 128, 128, 255},
        {100, 100, 100, 255},
        {25, 25, 25, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.2f,
  };
  
  static struct uiWidgetColors wcol_toggle = {
        {153, 153, 153, 255},
        {100, 100, 100, 255},
        {25, 25, 25, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.25f,
  };
  
  static struct uiWidgetColors wcol_scroll = {
        {80, 80, 80, 180},
        {100, 100, 100, 180},
        {128, 128, 128, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        1,
 -      5, -5
 +      5, -5,
 +      0,
 +      0.5f,
  };
  
  static struct uiWidgetColors wcol_progress = {
        {190, 190, 190, 255},
        {100, 100, 100, 180},
        {128, 128, 128, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.25f,
  };
  
  static struct uiWidgetColors wcol_list_item = {
        {0, 0, 0, 0},
        {86, 128, 194, 255},
        {90, 90, 90, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.2f,
 +};
 +
 +struct uiWidgetColors wcol_tab = {
 +      {60, 60, 60, 255},
 +      {83, 83, 83, 255},
 +      {114, 114, 114, 255},
 +      {90, 90, 90, 255},
 +
 +      {0, 0, 0, 255},
 +      {0, 0, 0, 255},
 +
 +      0,
 +      0, 0,
 +      0,
 +      0.25f,
  };
  
  /* free wcol struct to play with */
@@@ -2425,14 -1930,12 +2425,14 @@@ static struct uiWidgetColors wcol_tmp 
        {128, 128, 128, 255},
        {100, 100, 100, 255},
        {25, 25, 25, 255},
-       
        {0, 0, 0, 255},
        {255, 255, 255, 255},
-       
        0,
 -      0, 0
 +      0, 0,
 +      0,
 +      0.25f,
  };
  
  
@@@ -2524,11 -2018,9 +2524,11 @@@ static void widget_state(uiWidgetType *
                        widget_state_blend(wt->wcol.inner, wcol_state->inner_anim_sel, wcol_state->blend);
                else if (state & UI_BUT_DRIVEN)
                        widget_state_blend(wt->wcol.inner, wcol_state->inner_driven_sel, wcol_state->blend);
 +              else if (state & UI_BUT_OVERRIDEN)
 +                      widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden_sel, wcol_state->blend);
  
                copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
-               
                if (state & UI_SELECT)
                        SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
        }
@@@ -2723,10 -2209,10 +2723,10 @@@ static void widget_softshadow(const rct
  
        for (step = 1; step <= (int)radout; step++) {
                float expfac = sqrtf(step / radout);
-               
                round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
-               
 -              glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
 +              immUniformColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
  
                widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
  
@@@ -2756,30 -2243,30 +2756,30 @@@ static void widget_menu_back(uiWidgetCo
                roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
                rect->ymax += 0.1f * U.widget_unit;
        }
-       
        glEnable(GL_BLEND);
 -      widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit);
 +      widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
-       
 -      round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit);
 +      round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
        wtb.draw_emboss = false;
        widgetbase_draw(&wtb, wcol);
-       
        glDisable(GL_BLEND);
  }
  
 -
  static void ui_hsv_cursor(float x, float y)
  {
 -      glPushMatrix();
 -      glTranslatef(x, y, 0.0f);
 +      unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
  
 -      glColor3f(1.0f, 1.0f, 1.0f);
 -      glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 8);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +
 +      immUniformColor3f(1.0f, 1.0f, 1.0f);
 +      imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8);
-       
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
 -      glColor3f(0.0f, 0.0f, 0.0f);
 -      glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 12);
 +      immUniformColor3f(0.0f, 0.0f, 0.0f);
 +      imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12);
        glDisable(GL_BLEND);
        glDisable(GL_LINE_SMOOTH);
  
@@@ -2831,11 -2316,14 +2831,11 @@@ static void ui_draw_but_HSVCIRCLE(uiBu
        const float centy = BLI_rcti_cent_y_fl(rect);
        float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
  
 -      /* gouraud triangle fan */
        ColorPicker *cpicker = but->custom_data;
        const float *hsv_ptr = cpicker->color_data;
 -      float xpos, ypos, ang = 0.0f;
        float rgb[3], hsvo[3], hsv[3], col[3], colcent[3];
 -      int a;
        bool color_profile = ui_but_is_colorpicker_display_space(but);
-               
        /* color */
        ui_but_v3_get(but, rgb);
  
                else
                        hsv[2] = 0.5f;
        }
-       
        ui_color_picker_to_rgb(0.0f, 0.0f, hsv[2], colcent, colcent + 1, colcent + 2);
  
 -      glBegin(GL_TRIANGLE_FAN);
 -      glColor3fv(colcent);
 -      glVertex2f(centx, centy);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
 +
 +      immBegin(GWN_PRIM_TRI_FAN, tot + 2);
 +      immAttrib3fv(color, colcent);
 +      immVertex2f(pos, centx, centy);
-       
 -      for (a = 0; a <= tot; a++, ang += radstep) {
 +      float ang = 0.0f;
 +      for (int a = 0; a <= tot; a++, ang += radstep) {
                float si = sinf(ang);
                float co = cosf(ang);
-               
                ui_hsvcircle_vals_from_pos(hsv, hsv + 1, rect, centx + co * radius, centy + si * radius);
  
                ui_color_picker_to_rgb_v(hsv, col);
@@@ -2975,12 -2448,7 +2975,12 @@@ void ui_draw_gradient(const rcti *rect
        }
  
        /* old below */
-       
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
 +      immBegin(GWN_PRIM_TRIS, steps * 3 * 6);
        for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */
                const float dx_next = dx + color_step;
  
                sx2 = rect->xmin + dx_next * BLI_rcti_size_x(rect);
                sy = rect->ymin;
                dy = (float)BLI_rcti_size_y(rect) / 3.0f;
-               
 -              glBegin(GL_QUADS);
                for (a = 0; a < 3; a++, sy += dy) {
 -                      glColor4f(col0[a][0], col0[a][1], col0[a][2], alpha);
 -                      glVertex2f(sx1, sy);
 +                      immAttrib4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
 +                      immVertex2f(pos, sx1, sy);
-                       
++
 +                      immAttrib4f(col, col1[a][0], col1[a][1], col1[a][2], alpha);
 +                      immVertex2f(pos, sx2, sy);
 +
 +                      immAttrib4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
 +                      immVertex2f(pos, sx2, sy + dy);
  
 -                      glColor4f(col1[a][0], col1[a][1], col1[a][2], alpha);
 -                      glVertex2f(sx2, sy);
 +                      immAttrib4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
 +                      immVertex2f(pos, sx1, sy);
  
 -                      glColor4f(col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
 -                      glVertex2f(sx2, sy + dy);
 +                      immAttrib4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
 +                      immVertex2f(pos, sx2, sy + dy);
-                       
 -                      glColor4f(col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
 -                      glVertex2f(sx1, sy + dy);
 +                      immAttrib4f(col, col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
 +                      immVertex2f(pos, sx1, sy + dy);
                }
 -              glEnd();
        }
 +      immEnd();
 +
 +      immUnbindProgram();
  }
  
  bool ui_but_is_colorpicker_display_space(uiBut *but)
@@@ -3132,15 -2593,12 +3132,15 @@@ static void ui_draw_but_HSVCUBE(uiBut *
        ui_hsvcube_pos_from_vals(but, rect, hsv_n, &x, &y);
        CLAMP(x, rect->xmin + 3.0f, rect->xmax - 3.0f);
        CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
-       
        ui_hsv_cursor(x, y);
-       
        /* outline */
 -      glColor3ub(0,  0,  0);
 -      fdrawbox((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
 +      unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor3ub(0, 0, 0);
 +      imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
 +      immUnbindProgram();
  }
  
  /* vertical 'value' slider, using new widget code */
@@@ -3188,14 -2644,9 +3188,14 @@@ static void ui_draw_but_HSV_v(uiBut *bu
        wcol_tmp.shadetop = 127;
        wcol_tmp.shadedown = -128;
        wcol_tmp.shaded = 1;
-       
        widgetbase_draw(&wtb, &wcol_tmp);
  
 +      /* We are drawing on top of widget bases. Flush cache. */
 +      glEnable(GL_BLEND);
 +      UI_widgetbase_draw_cache_flush();
 +      glDisable(GL_BLEND);
 +
        /* cursor */
        x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
        y = rect->ymin + v    * BLI_rcti_size_y(rect);
@@@ -3268,80 -2695,14 +3268,80 @@@ static void widget_numbut_draw(uiWidget
        }
  
        /* decoration */
 -      if (!(state & UI_STATE_TEXT_INPUT)) {
 -              shape_preset_init_number_arrows(&wtb.tria1, rect, 0.6f, 'l');
 -              shape_preset_init_number_arrows(&wtb.tria2, rect, 0.6f, 'r');
 -      }
 +      if ((state & UI_ACTIVE) && !(state & UI_STATE_TEXT_INPUT)) {
 +              uiWidgetColors wcol_zone;
 +              uiWidgetBase wtb_zone;
 +              rcti rect_zone;
 +              int roundboxalign_zone;
 +
 +              /* left arrow zone */
 +              widget_init(&wtb_zone);
 +              wtb_zone.draw_outline = false;
 +              wtb_zone.draw_emboss = false;
 +
 +              wcol_zone = *wcol;
 +              copy_v3_v3_char(wcol_zone.item, wcol->text);
 +              if (state & UI_STATE_ACTIVE_LEFT) {
 +                      widget_active_color(wcol_zone.inner);
 +              }
  
 -      widgetbase_draw(&wtb, wcol);
 +              rect_zone = *rect;
 +              rect_zone.xmax = rect->xmin + handle_width + U.pixelsize;
 +              roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
 +              round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
 +
 +              shape_preset_init_number_arrows(&wtb_zone.tria1, &rect_zone, 0.6f, 'l');
 +              widgetbase_draw(&wtb_zone, &wcol_zone);
 +
 +              /* right arrow zone */
 +              widget_init(&wtb_zone);
 +              wtb_zone.draw_outline = false;
 +              wtb_zone.draw_emboss = false;
 +              wtb_zone.tria1.type = ROUNDBOX_TRIA_ARROWS;
 +
 +              wcol_zone = *wcol;
 +              copy_v3_v3_char(wcol_zone.item, wcol->text);
 +              if (state & UI_STATE_ACTIVE_RIGHT) {
 +                      widget_active_color(wcol_zone.inner);
 +              }
 +
 +              rect_zone = *rect;
 +              rect_zone.xmin = rect->xmax - handle_width - U.pixelsize;
 +              roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
 +              round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
 +
 +              shape_preset_init_number_arrows(&wtb_zone.tria2, &rect_zone, 0.6f, 'r');
 +              widgetbase_draw(&wtb_zone, &wcol_zone);
 +
 +              /* middle highlight zone */
 +              widget_init(&wtb_zone);
 +              wtb_zone.draw_outline = false;
 +              wtb_zone.draw_emboss = false;
 +
 +              wcol_zone = *wcol;
 +              copy_v3_v3_char(wcol_zone.item, wcol->text);
 +              if (!(state & (UI_STATE_ACTIVE_LEFT | UI_STATE_ACTIVE_RIGHT))) {
 +                      widget_active_color(wcol_zone.inner);
 +              }
 +
 +              rect_zone = *rect;
 +              rect_zone.xmin = rect->xmin + handle_width - U.pixelsize;
 +              rect_zone.xmax = rect->xmax - handle_width + U.pixelsize;
 +              round_box_edges(&wtb_zone, 0, &rect_zone, 0);
 +              widgetbase_draw(&wtb_zone, &wcol_zone);
 +
 +              /* outline */
 +              wtb.draw_inner = false;
 +              widgetbase_draw(&wtb, wcol);
 +      }
 +      else {
 +              /* inner and outline */
 +              widgetbase_draw(&wtb, wcol);
 +      }
-       
        if (!(state & UI_STATE_TEXT_INPUT)) {
 +              const float textofs = 0.425f * BLI_rcti_size_y(rect);
 +
                /* text space */
                rect->xmin += textofs;
                rect->xmax -= textofs;
@@@ -3375,12 -2783,12 +3375,12 @@@ void UI_draw_widget_scroll(uiWidgetColo
        horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
  
        if (horizontal)
 -              rad = 0.5f * BLI_rcti_size_y(rect);
 +              rad = wcol->roundness * BLI_rcti_size_y(rect);
        else
 -              rad = 0.5f * BLI_rcti_size_x(rect);
 +              rad = wcol->roundness * BLI_rcti_size_x(rect);
-       
 -      wtb.draw_shadedir = (horizontal) ? true : false;
 +      wtb.uniform_params.shade_dir = (horizontal) ? 1.0f : 0.0;
-       
        /* draw back part, colors swapped and shading inverted */
        if (horizontal)
                SWAP(short, wcol->shadetop, wcol->shadedown);
@@@ -3640,15 -3059,16 +3640,15 @@@ static void widget_swatch(uiBut *but, u
                        col[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
                }
        }
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.25f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-               
        ui_but_v3_get(but, col);
  
 -      if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
 +      if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_OVERRIDEN | UI_BUT_REDALERT)) {
                /* draw based on state - color for keyed etc */
                widgetbase_draw(&wtb, wcol);
  
@@@ -3716,11 -3127,12 +3716,11 @@@ static void widget_icon_has_anim(uiBut 
        if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
                uiWidgetBase wtb;
                float rad;
-               
                widget_init(&wtb);
                wtb.draw_outline = false;
-               
 -              /* rounded */
 -              rad = 0.5f * BLI_rcti_size_y(rect);
 +              rad = wcol->roundness * BLI_rcti_size_y(rect);
                round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
                widgetbase_draw(&wtb, wcol);
        }
@@@ -3736,15 -3148,16 +3736,15 @@@ static void widget_textbut(uiWidgetColo
  {
        uiWidgetBase wtb;
        float rad;
-       
        if (state & UI_SELECT)
                SWAP(short, wcol->shadetop, wcol->shadedown);
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        widgetbase_draw(&wtb, wcol);
  }
  
@@@ -3753,19 -3166,18 +3753,19 @@@ static void widget_menubut(uiWidgetColo
  {
        uiWidgetBase wtb;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        /* decoration */
        shape_preset_trias_from_rect_menu(&wtb.tria1, rect);
-       
 +      /* copy size and center to 2nd tria */
 +      wtb.tria2 = wtb.tria1;
        widgetbase_draw(&wtb, wcol);
-       
        /* text space, arrows are about 0.6 height of button */
        rect->xmax -= (6 * BLI_rcti_size_y(rect)) / 10;
  }
@@@ -3774,12 -3186,13 +3774,12 @@@ static void widget_menuiconbut(uiWidget
  {
        uiWidgetBase wtb;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        /* decoration */
        widgetbase_draw(&wtb, wcol);
  }
@@@ -3790,10 -3203,11 +3790,10 @@@ static void widget_menunodebut(uiWidget
        uiWidgetBase wtb;
        uiWidgetColors wcol_backup = *wcol;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
  
        wcol->inner[0] = min_ii(wcol->inner[0] + 15, 255);
@@@ -3863,14 -3277,14 +3863,14 @@@ static void widget_list_itembut(uiWidge
  {
        uiWidgetBase wtb;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* rounded, but no outline */
 +      /* no outline */
        wtb.draw_outline = false;
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
-       
        widgetbase_draw(&wtb, wcol);
  }
  
@@@ -3892,10 -3306,11 +3892,10 @@@ static void widget_optionbut(uiWidgetCo
        recttemp.ymin += delta;
        recttemp.xmax -= delta;
        recttemp.ymax -= delta;
-       
 -      /* half rounded */
 -      rad = BLI_rcti_size_y(&recttemp) / 3;
 +      rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
        round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
-       
        /* decoration */
        if (state & UI_SELECT) {
                shape_preset_trias_from_rect_checkmark(&wtb.tria1, &recttemp);
@@@ -3931,12 -3346,13 +3931,12 @@@ static void widget_radiobut(uiWidgetCol
  {
        uiWidgetBase wtb;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        widgetbase_draw(&wtb, wcol);
  }
  
@@@ -3956,12 -3372,13 +3956,12 @@@ static void widget_box(uiBut *but, uiWi
                wcol->inner[1] = but->col[1];
                wcol->inner[2] = but->col[2];
        }
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        widgetbase_draw(&wtb, wcol);
-               
        copy_v3_v3_char(wcol->inner, old_col);
  }
  
@@@ -3969,12 -3386,13 +3969,12 @@@ static void widget_but(uiWidgetColors *
  {
        uiWidgetBase wtb;
        float rad;
-       
        widget_init(&wtb);
-       
 -      /* half rounded */
 -      rad = 0.2f * U.widget_unit;
 +      rad = wcol->roundness * U.widget_unit;
        round_box_edges(&wtb, roundboxalign, rect, rad);
-       
        widgetbase_draw(&wtb, wcol);
  }
  
  static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
  {
        uiWidgetBase wtb;
 -      const float rad = 0.25f * U.widget_unit;
 +      const float rad = wcol->roundness * U.widget_unit;
-       
        widget_init(&wtb);
-       
        /* half rounded */
        round_box_edges(&wtb, roundboxalign, rect, rad);
  
@@@ -4083,20 -3443,15 +4083,20 @@@ static void widget_draw_extra_mask(cons
        if (but->block->drawextra) {
                /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
                but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
-               
 +              unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +
                /* make mask to draw over image */
                UI_GetThemeColor3ubv(TH_BACK, col);
 -              glColor3ubv(col);
 +              immUniformColor3ubv(col);
  
                round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
 -              widgetbase_outline(&wtb);
 +              widgetbase_outline(&wtb, pos);
 +
 +              immUnbindProgram();
        }
-       
        /* outline */
        round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
        wtb.draw_outline = true;
@@@ -4156,16 -3511,6 +4156,16 @@@ static uiWidgetType *widget_type(uiWidg
                        wt.draw = widget_roundbut_exec;
                        break;
  
-                       
 +              case UI_WTYPE_TOOLBAR_ITEM:
 +                      wt.wcol_theme = &btheme->tui.wcol_toolbar_item;
 +                      wt.draw = widget_roundbut_exec;
 +                      break;
++
 +              case UI_WTYPE_TAB:
 +                      wt.wcol_theme = &btheme->tui.wcol_tab;
 +                      wt.draw = widget_tab;
 +                      break;
 +
                case UI_WTYPE_TOOLTIP:
                        wt.wcol_theme = &btheme->tui.wcol_tooltip;
                        wt.draw = widget_menu_back;
@@@ -4287,8 -3632,8 +4287,8 @@@ static int widget_roundbox_set(uiBut *b
  
        /* alignment */
        if ((but->drawflag & UI_BUT_ALIGN) && but->type != UI_BTYPE_PULLDOWN) {
-               
 -              /* ui_block_position has this correction too, keep in sync */
 +              /* ui_popup_block_position has this correction too, keep in sync */
                if (but->drawflag & (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_STITCH_TOP))
                        rect->ymax += U.pixelsize;
                if (but->drawflag & (UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_STITCH_LEFT))
@@@ -4402,18 -3743,9 +4402,18 @@@ void ui_draw_but(const bContext *C, ARe
                        case UI_BTYPE_SEPR:
                        case UI_BTYPE_SEPR_LINE:
                                break;
-                               
                        case UI_BTYPE_BUT:
 +#ifdef USE_TOOLBAR_HACK
 +                              if (UI_but_is_tool(but)) {
 +                                      wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);
 +                              }
 +                              else {
 +                                      wt = widget_type(UI_WTYPE_EXEC);
 +                              }
 +#else
                                wt = widget_type(UI_WTYPE_EXEC);
 +#endif
                                break;
  
                        case UI_BTYPE_NUM:
                                /* option buttons have strings outside, on menus use different colors */
                                if (but->block->flag & UI_BLOCK_LOOP)
                                        wt->state = widget_state_option_menu;
-                               
                                break;
-                               
                        case UI_BTYPE_MENU:
                        case UI_BTYPE_BLOCK:
 +                      case UI_BTYPE_POPOVER:
                                if (but->flag & UI_BUT_NODE_LINK) {
                                        /* new node-link button, not active yet XXX */
                                        wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
@@@ -893,16 -869,13 +893,16 @@@ void ui_theme_init_default(void
  
        btheme->tui.menu_shadow_fac = 0.5f;
        btheme->tui.menu_shadow_width = 12;
-       
        /* Bone Color Sets */
        ui_theme_init_boneColorSets(btheme);
-       
        /* common (new) variables */
        ui_theme_init_new(btheme);
-       
 +      /* Manipulator. */
 +      ui_theme_space_init_manipulator_colors(btheme);
 +
        /* space view3d */
        rgba_char_args_set_fl(btheme->tv3d.back,       0.225, 0.225, 0.225, 1.0);
        rgba_char_args_set(btheme->tv3d.text,       0, 0, 0, 255);
@@@ -1301,38 -1270,28 +1301,38 @@@ void UI_ThemeColor(int colorid
  void UI_ThemeColor4(int colorid)
  {
        const unsigned char *cp;
-       
        cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
        glColor4ubv(cp);
 -
  }
  
  /* set the color with offset for shades */
  void UI_ThemeColorShade(int colorid, int offset)
  {
 -      int r, g, b;
 +      unsigned char col[4];
 +      UI_GetThemeColorShade4ubv(colorid, offset, col);
 +      glColor4ubv(col);
 +}
 +
 +void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
 +{
 +      int r, g, b, a;
        const unsigned char *cp;
-       
        cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
 -      r = offset + (int) cp[0];
 +      r = coloffset + (int) cp[0];
        CLAMP(r, 0, 255);
 -      g = offset + (int) cp[1];
 +      g = coloffset + (int) cp[1];
        CLAMP(g, 0, 255);
 -      b = offset + (int) cp[2];
 +      b = coloffset + (int) cp[2];
        CLAMP(b, 0, 255);
 -      glColor4ub(r, g, b, cp[3]);
 +      a = alphaoffset + (int) cp[3];
 +      CLAMP(a, 0, 255);
 +
 +      glColor4ub(r, g, b, a);
  }
 -void UI_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
 +
 +void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, unsigned char col[4])
  {
        int r, g, b, a;
        const unsigned char *cp;
@@@ -2172,9 -2014,13 +2172,9 @@@ void init_userdef_do_versions(void
                                strcpy(km->idname, "Property Editor");
                }
        }
-       
 -      if (!USER_VERSION_ATLEAST(250, 16)) {
 -              if (U.wmdrawmethod == USER_DRAW_TRIPLE)
 -                      U.wmdrawmethod = USER_DRAW_AUTOMATIC;
 -      }
        if (!USER_VERSION_ATLEAST(252, 3)) {
-               if (U.flag & USER_LMOUSESELECT) 
+               if (U.flag & USER_LMOUSESELECT)
                        U.flag &= ~USER_TWOBUTTONMOUSE;
        }
        if (!USER_VERSION_ATLEAST(252, 4)) {
                        rgba_char_args_test_set(btheme->tinfo.info_debug_text, 0, 0, 0, 255);
                }
        }
-       
        if (!USER_VERSION_ATLEAST(269, 9)) {
                bTheme *btheme;
 -
 -              U.tw_size = U.tw_size * 5.0f;
 -
                /* Action Editor (and NLA Editor) - Keyframe Colors */
                /* Graph Editor - larger vertex size defaults */
                for (btheme = U.themes.first; btheme; btheme = btheme->next) {
                U.uiflag |= USER_LOCK_CURSOR_ADJUST;
        }
  
-       
 +      if (!USER_VERSION_ATLEAST(280, 9)) {
 +              /* interface_widgets.c */
 +              struct uiWidgetColors wcol_tab = {
 +                      {60, 60, 60, 255},
 +                      {83, 83, 83, 255},
 +                      {114, 114, 114, 255},
 +                      {90, 90, 90, 255},
 +
 +                      {0, 0, 0, 255},
 +                      {0, 0, 0, 255},
 +
 +                      0,
 +                      0, 0
 +              };
 +
 +              for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
 +                      char tmp[4];
 +
 +                      btheme->tui.wcol_tab = wcol_tab;
 +                      btheme->ttopbar = btheme->tv3d;
 +                      /* swap colors */
 +                      copy_v4_v4_char(tmp, btheme->ttopbar.header);
 +                      copy_v4_v4_char(btheme->ttopbar.header, btheme->ttopbar.tab_inactive);
 +                      copy_v4_v4_char(btheme->ttopbar.back, tmp);
 +              }
 +      }
-                               rgba_char_args_set(btheme->tseq.anim_active,    204, 112, 26, 102);     
++
 +      if (!USER_VERSION_ATLEAST(280, 9)) {
 +              /* Timeline removal */
 +              for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
 +                      if (btheme->tipo.anim_active[3] == 0) {
 +                              rgba_char_args_set(btheme->tipo.anim_active,    204, 112, 26, 102);
 +                      }
 +                      if (btheme->tseq.anim_active[3] == 0) {
++                              rgba_char_args_set(btheme->tseq.anim_active,    204, 112, 26, 102);
 +                      }
 +              }
 +      }
 +
 +      if (!USER_VERSION_ATLEAST(280, 10)) {
 +              /* Roundness */
 +              for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
 +                      btheme->tui.wcol_regular.roundness = 0.25f;
 +                      btheme->tui.wcol_tool.roundness = 0.2f;
 +                      btheme->tui.wcol_text.roundness = 0.2f;
 +                      btheme->tui.wcol_radio.roundness = 0.2f;
 +                      btheme->tui.wcol_option.roundness = 0.333333f;
 +                      btheme->tui.wcol_toggle.roundness = 0.25f;
 +                      btheme->tui.wcol_num.roundness = 0.5f;
 +                      btheme->tui.wcol_numslider.roundness = 0.5f;
 +                      btheme->tui.wcol_tab.roundness = 0.25f;
 +                      btheme->tui.wcol_menu.roundness = 0.2f;
 +                      btheme->tui.wcol_pulldown.roundness = 0.2f;
 +                      btheme->tui.wcol_menu_back.roundness = 0.25f;
 +                      btheme->tui.wcol_menu_item.roundness = 0.25f;
 +                      btheme->tui.wcol_tooltip.roundness = 0.25f;
 +                      btheme->tui.wcol_box.roundness = 0.2f;
 +                      btheme->tui.wcol_scroll.roundness = 0.5f;
 +                      btheme->tui.wcol_progress.roundness = 0.25f;
 +                      btheme->tui.wcol_list_item.roundness = 0.2f;
 +                      btheme->tui.wcol_pie_menu.roundness = 0.5f;
 +                      rgba_char_args_set_fl(btheme->tui.editor_outline, 0.25f, 0.25f, 0.25f, 1.0f);
 +              }
 +      }
 +
 +      if (((bTheme *)U.themes.first)->tui.wcol_toolbar_item.text[3] == 0) {
 +              struct uiWidgetColors wcol_toolbar_item = {
 +                      .outline = {0x0, 0x0, 0x0, 0xff},
 +                      .inner = {0x46, 0x46, 0x46, 0xff},
 +                      .inner_sel = {0xcc, 0xcc, 0xcc, 0xff},
 +                      .item = {0x0, 0x0, 0x0, 0xff},
 +
 +                      .text = {0xff, 0xff, 0xff, 0xff},
 +                      .text_sel = {0x33, 0x33, 0x33, 0xff},
 +
 +                      .shaded = 0,
 +                      .shadetop = 0,
 +                      .shadedown = 0,
 +                      .alpha_check = 0,
 +                      .roundness = 0.3f,
 +              };
 +              for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
 +                      btheme->tui.wcol_toolbar_item = wcol_toolbar_item;
 +                      btheme->tui.icon_saturation = 1.0f;
 +              }
 +      }
 +
        /**
         * Include next version bump.
         */
                /* (keep this block even if it becomes empty). */
        }
  
 +      if (((bTheme *)U.themes.first)->tui.manipulator_hi[3] == 0) {
 +              for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
 +                      ui_theme_space_init_manipulator_colors(btheme);
 +              }
 +      }
 +
        if (U.pixelsize == 0.0f)
                U.pixelsize = 1.0f;
-       
        if (U.image_draw_method == 0)
                U.image_draw_method = IMAGE_DRAW_METHOD_2DTEXTURE;
-       
 -      // keep the following until the new audaspace is default to be built with
 -#ifdef WITH_SYSTEM_AUDASPACE
        // we default to the first audio device
        U.audiodevice = 0;
 -#endif
  
        /* Not versioning, just avoid errors. */
  #ifndef WITH_CYCLES
@@@ -144,10 -144,10 +144,10 @@@ static void view2d_masks(View2D *v2d, b
                        }
                }
        }
-       
        scroll = view2d_scroll_mapped(v2d->scroll);
-       
 -      /* scrollers shrink mask area, but should be based off regionsize
 +      /* scrollers are based off regionsize
         *      - they can only be on one to two edges of the region they define
         *      - if they overlap, they must not occupy the corners (which are reserved for other widgets)
         */
                        /* on right-hand edge of region */
                        v2d->vert = v2d->mask;
                        v2d->vert.xmax++; /* one pixel extra... was leaving a minor gap... */
 -                      v2d->vert.xmin = v2d->vert.xmax - V2D_SCROLL_WIDTH;
 -                      v2d->mask.xmax = v2d->vert.xmin - 1;
 +                      v2d->vert.xmin = v2d->vert.xmax - scroll_width;
                }
-               
                /* horizontal scroller */
                if (scroll & (V2D_SCROLL_BOTTOM)) {
                        /* on bottom edge of region */
                else if (scroll & V2D_SCROLL_TOP) {
                        /* on upper edge of region */
                        v2d->hor = v2d->mask;
 -                      v2d->hor.ymin = v2d->hor.ymax - V2D_SCROLL_HEIGHT;
 -                      v2d->mask.ymax = v2d->hor.ymin - 1;
 +                      v2d->hor.ymin = v2d->hor.ymax - scroll_height;
                }
-               
                /* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
                if (scroll & V2D_SCROLL_VERTICAL) {
 -                      /* just set y min/max for vertical scroller to y min/max of mask as appropriate */
                        if (scroll & (V2D_SCROLL_BOTTOM)) {
                                /* on bottom edge of region */
 -                              v2d->vert.ymin = v2d->mask.ymin;
 +                              v2d->vert.ymin = v2d->hor.ymax;
                        }
                        else if (scroll & V2D_SCROLL_TOP) {
                                /* on upper edge of region */
@@@ -354,15 -353,10 +354,15 @@@ void UI_view2d_region_reinit(View2D *v2
        /* store view size */
        v2d->winx = winx;
        v2d->winy = winy;
-       
        /* set masks (always do), but leave scroller scheck to totrect_set */
        view2d_masks(v2d, 0);
-       
 +      if (do_init) {
 +              /* Visible by default. */
 +              v2d->alpha_hor = v2d->alpha_vert = 255;
 +      }
-       
++
        /* set 'tot' rect before setting cur? */
        /* XXX confusing stuff here still - I made this function not check scroller hide - that happens in totrect_set */
        if (tot_changed)
@@@ -817,9 -811,9 +817,9 @@@ void UI_view2d_sync(bScreen *screen, Sc
                                                v2dcur->cur.ymin = ar->v2d.cur.ymin;
                                                v2dcur->cur.ymax = ar->v2d.cur.ymax;
                                        }
-                                       
                                        /* region possibly changed, so refresh */
 -                                      ED_region_tag_redraw(ar);
 +                                      ED_region_tag_redraw_no_rebuild(ar);
                                }
                        }
                }
                                                        v2dcur->cur.xmin = ar->v2d.cur.xmin;
                                                        v2dcur->cur.xmax = ar->v2d.cur.xmax;
                                                }
-                                               
                                                /* region possibly changed, so refresh */
 -                                              ED_region_tag_redraw(ar);
 +                                              ED_region_tag_redraw_no_rebuild(ar);
                                        }
                                }
                        }
@@@ -1110,9 -1104,12 +1110,9 @@@ void UI_view2d_view_ortho(View2D *v2d
                curmasked.ymin = floorf(curmasked.ymin) - (eps + yofs);
                curmasked.ymax = floorf(curmasked.ymax) - (eps + yofs);
        }
-       
        /* set matrix on all appropriate axes */
        wmOrtho2(curmasked.xmin, curmasked.xmax, curmasked.ymin, curmasked.ymax);
 -
 -      /* XXX is this necessary? */
 -      glLoadIdentity();
  }
  
  /**
@@@ -1140,7 -1137,10 +1140,7 @@@ void UI_view2d_view_orthoSpecial(ARegio
                wmOrtho2(curmasked.xmin - xofs, curmasked.xmax - xofs, -yofs, ar->winy - yofs);
        else
                wmOrtho2(-xofs, ar->winx - xofs, curmasked.ymin - yofs, curmasked.ymax - yofs);
- } 
 -
 -      /* XXX is this necessary? */
 -      glLoadIdentity();
+ }
  
  
  /* Restore view matrices after drawing */
@@@ -1149,10 -1149,10 +1149,10 @@@ void UI_view2d_view_restore(const bCont
        ARegion *ar = CTX_wm_region(C);
        int width  = BLI_rcti_size_x(&ar->winrct) + 1;
        int height = BLI_rcti_size_y(&ar->winrct) + 1;
-       
        wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
 -      glLoadIdentity();
 +      gpuLoadIdentity();
-       
        //      ED_region_pixelspace(CTX_wm_region(C));
  }
  
@@@ -1305,10 -1305,7 +1305,10 @@@ void UI_view2d_grid_draw(View2D *v2d, V
  {
        float vec1[2], vec2[2];
        int a, step;
-       
 +      int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC),
 +              horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
 +      unsigned char grid_line_color[3];
        /* check for grid first, as it may not exist */
        if (grid == NULL)
                return;
                vec1[0] = vec2[0] = grid->startx;
                vec1[1] = grid->starty;
                vec2[1] = v2d->cur.ymax;
-               
                /* minor gridlines */
 -              step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
 -              UI_ThemeColor(TH_GRID);
 +              step = vertical_minor_step;
 +              if (step != 0) {
 +                      UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
-       
 -              for (a = 0; a < step; a++) {
 -                      glVertex2fv(vec1);
 -                      glVertex2fv(vec2);
 +                      for (a = 0; a < step; a++) {
 +                              immSkipAttrib(color);
 +                              immVertex2fv(pos, vec1);
 +                              immAttrib3ubv(color, grid_line_color);
 +                              immVertex2fv(pos, vec2);
-                               
 -                      vec2[0] = vec1[0] += grid->dx;
 +                              vec2[0] = vec1[0] += grid->dx;
 +                      }
                }
-               
                /* major gridlines */
                vec2[0] = vec1[0] -= 0.5f * grid->dx;
 -              UI_ThemeColorShade(TH_GRID, 16);
 +
 +              UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
-               
                step++;
                for (a = 0; a <= step; a++) {
 -                      glVertex2fv(vec1);
 -                      glVertex2fv(vec2);
 +                      immSkipAttrib(color);
 +                      immVertex2fv(pos, vec1);
 +                      immAttrib3ubv(color, grid_line_color);
 +                      immVertex2fv(pos, vec2);
-                       
                        vec2[0] = vec1[0] -= grid->dx;
                }
        }
                vec1[1] = vec2[1] = grid->starty;
                vec1[0] = grid->startx;
                vec2[0] = v2d->cur.xmax;
-               
 -              step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
 +              step = horizontal_major_step;
-       
++
 +              UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
  
 -              UI_ThemeColor(TH_GRID);
                for (a = 0; a <= step; a++) {
 -                      glVertex2fv(vec1);
 -                      glVertex2fv(vec2);
 +                      immSkipAttrib(color);
 +                      immVertex2fv(pos, vec1);
 +                      immAttrib3ubv(color, grid_line_color);
 +                      immVertex2fv(pos, vec2);
-                       
                        vec2[1] = vec1[1] += grid->dy;
                }
-               
                /* fine grid lines */
                vec2[1] = vec1[1] -= 0.5f * grid->dy;
                step++;
-               
                if (flag & V2D_HORIZONTAL_FINELINES) {
 -                      UI_ThemeColorShade(TH_GRID, 16);
 +                      UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
                        for (a = 0; a < step; a++) {
 -                              glVertex2fv(vec1);
 -                              glVertex2fv(vec2);
 +                              immSkipAttrib(color);
 +                              immVertex2fv(pos, vec1);
 +                              immAttrib3ubv(color, grid_line_color);
 +                              immVertex2fv(pos, vec2);
-                               
                                vec2[1] = vec1[1] -= grid->dy;
                        }
                }
        }
-       
        /* Axes are drawn as darker lines */
 -      UI_ThemeColorShade(TH_GRID, -50);
 +      UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color);
-       
        /* horizontal axis */
        if (flag & V2D_HORIZONTAL_AXIS) {
                vec1[0] = v2d->cur.xmin;
                vec2[0] = v2d->cur.xmax;
                vec1[1] = vec2[1] = 0.0f;
-               
 -              glVertex2fv(vec1);
 -              glVertex2fv(vec2);
 +              immSkipAttrib(color);
 +              immVertex2fv(pos, vec1);
 +              immAttrib3ubv(color, grid_line_color);
 +              immVertex2fv(pos, vec2);
        }
-       
        /* vertical axis */
        if (flag & V2D_VERTICAL_AXIS) {
                vec1[1] = v2d->cur.ymin;
                vec2[1] = v2d->cur.ymax;
                vec1[0] = vec2[0] = 0.0f;
-               
 -              glVertex2fv(vec1);
 -              glVertex2fv(vec2);
 +              immSkipAttrib(color);
 +              immVertex2fv(pos, vec1);
 +              immAttrib3ubv(color, grid_line_color);
 +              immVertex2fv(pos, vec2);
        }
  
 -      glEnd();
 +      immEnd();
 +      immUnbindProgram();
  }
  
  /* Draw a constant grid in given 2d-region */
  void UI_view2d_constant_grid_draw(View2D *v2d, float step)
  {
 -      float start;
 +      float start_x, start_y;
 +      int count_x, count_y;
-       
 -      UI_ThemeColorShade(TH_BACK, -10);
 +      start_x = v2d->cur.xmin;
 +      if (start_x < 0.0)
 +              start_x += -(float)fmod(v2d->cur.xmin, step);
 +      else
 +              start_x += (step - (float)fmod(v2d->cur.xmin, step));
  
 -      start = v2d->cur.xmin - (float)fmod(v2d->cur.xmin, step);
 +      if (start_x > v2d->cur.xmax)
 +              count_x = 0;
 +      else
 +              count_x = (v2d->cur.xmax - start_x) / step + 1;
  
 -      glBegin(GL_LINES);
 -      for (; start < v2d->cur.xmax; start += step) {
 -              glVertex2f(start, v2d->cur.ymin);
 -              glVertex2f(start, v2d->cur.ymax);
 -      }
 +      start_y = v2d->cur.ymin;
 +      if (start_y < 0.0)
 +              start_y += -(float)fmod(v2d->cur.ymin, step);
 +      else
 +              start_y += (step - (float)fabs(fmod(v2d->cur.ymin, step)));
  
 -      start = v2d->cur.ymin - (float)fmod(v2d->cur.ymin, step);
 -      for (; start < v2d->cur.ymax; start += step) {
 -              glVertex2f(v2d->cur.xmin, start);
 -              glVertex2f(v2d->cur.xmax, start);
 -      }
 +      if (start_y > v2d->cur.ymax)
 +              count_y = 0;
 +      else
 +              count_y = (v2d->cur.ymax - start_y) / step + 1;
-       
 -      /* X and Y axis */
 -      UI_ThemeColorShade(TH_BACK, -18);
 -      glVertex2f(0.0f, v2d->cur.ymin);
 -      glVertex2f(0.0f, v2d->cur.ymax);
 -      glVertex2f(v2d->cur.xmin, 0.0f);
 -      glVertex2f(v2d->cur.xmax, 0.0f);
 +      if (count_x > 0 || count_y > 0) {
 +              Gwn_VertFormat *format = immVertexFormat();
 +              unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +              unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
 +              float theme_color[3];
 +
 +              UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color);
-               
++
 +              immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +              immBegin(GWN_PRIM_LINES, count_x * 2 + count_y * 2 + 4);
-               
++
 +              immAttrib3fv(color, theme_color);
 +              for (int i = 0; i < count_x ; start_x += step, i++) {
 +                      immVertex2f(pos, start_x, v2d->cur.ymin);
 +                      immVertex2f(pos, start_x, v2d->cur.ymax);
 +              }
 +
 +              for (int i = 0; i < count_y; start_y += step, i++) {
 +                      immVertex2f(pos, v2d->cur.xmin, start_y);
 +                      immVertex2f(pos, v2d->cur.xmax, start_y);
 +              }
-       
 -      glEnd();
 +              /* X and Y axis */
 +              UI_GetThemeColorShade3fv(TH_BACK, -18, theme_color);
-               
++
 +              immAttrib3fv(color, theme_color);
 +              immVertex2f(pos, 0.0f, v2d->cur.ymin);
 +              immVertex2f(pos, 0.0f, v2d->cur.ymax);
 +              immVertex2f(pos, v2d->cur.xmin, 0.0f);
 +              immVertex2f(pos, v2d->cur.xmax, 0.0f);
-       
++
 +              immEnd();
 +              immUnbindProgram();
 +      }
  }
  
  /* Draw a multi-level grid in given 2d-region */
  void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_size, int totlevels)
  {
 +      /* Exit if there is nothing to draw */
 +      if (totlevels == 0)
 +              return;
 +
        int offset = -10;
        float lstep = step;
 -      int level;
 +      unsigned char grid_line_color[3];
 +
 +      /* Make an estimate of at least how many vertices will be needed */
 +      unsigned vertex_count = 4;
 +      vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
 +      vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
 +
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +      unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT);
  
        glLineWidth(1.0f);
 -      for (level = 0; level < totlevels; ++level) {
 -              int i;
 -              float start;
  
 -              UI_ThemeColorShade(colorid, offset);
 +      immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +      immBeginAtMost(GWN_PRIM_LINES, vertex_count);
  
 -              i = (v2d->cur.xmin >= 0.0f ? -(int)(-v2d->cur.xmin / lstep) : (int)(v2d->cur.xmin / lstep));
 -              start = i * lstep;
 +      for (int level = 0; level < totlevels; ++level) {
 +              UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color);
-               
++
 +              int i = (int)(v2d->cur.xmin / lstep);
 +              if (v2d->cur.xmin > 0.0f)
 +                      i++;
 +              float start = i * lstep;
-               
 -              glBegin(GL_LINES);
                for (; start < v2d->cur.xmax; start += lstep, ++i) {
                        if (i == 0 || (level < totlevels - 1 && i % level_size == 0))
                                continue;
 -                      glVertex2f(start, v2d->cur.ymin);
 -                      glVertex2f(start, v2d->cur.ymax);
 +
 +                      immSkipAttrib(color);
 +                      immVertex2f(pos, start, v2d->cur.ymin);
 +                      immAttrib3ubv(color, grid_line_color);
 +                      immVertex2f(pos, start, v2d->cur.ymax);
                }
-               
 -              i = (v2d->cur.ymin >= 0.0f ? -(int)(-v2d->cur.ymin / lstep) : (int)(v2d->cur.ymin / lstep));
 +              i = (int)(v2d->cur.ymin / lstep);
 +              if (v2d->cur.ymin > 0.0f)
 +                      i++;
                start = i * lstep;
-               
                for (; start < v2d->cur.ymax; start += lstep, ++i) {
                        if (i == 0 || (level < totlevels - 1 && i % level_size == 0))
                                continue;
 -                      glVertex2f(v2d->cur.xmin, start);
 -                      glVertex2f(v2d->cur.xmax, start);
 -              }
 -
 -              /* X and Y axis */
 -              UI_ThemeColorShade(colorid, offset - 8);
 -              glVertex2f(0.0f, v2d->cur.ymin);
 -              glVertex2f(0.0f, v2d->cur.ymax);
 -              glVertex2f(v2d->cur.xmin, 0.0f);
 -              glVertex2f(v2d->cur.xmax, 0.0f);
  
 -              glEnd();
 +                      immSkipAttrib(color);
 +                      immVertex2f(pos, v2d->cur.xmin, start);
 +                      immAttrib3ubv(color, grid_line_color);
 +                      immVertex2f(pos, v2d->cur.xmax, start);
 +              }
-               
                lstep *= level_size;
                offset -= 6;
        }
@@@ -1643,18 -1530,15 +1643,18 @@@ View2DScrollers *UI_view2d_scrollers_ca
        float fac1, fac2, totsize, scrollsize;
        int scroll = view2d_scroll_mapped(v2d->scroll);
        int smaller;
-       
        /* scrollers is allocated here... */
        scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
-       
 +      /* Always update before drawing (for dynamically sized scrollers). */
 +      view2d_masks(v2d, false);
-       
++
        vert = v2d->vert;
        hor = v2d->hor;
-       
        /* slider rects need to be smaller than region */
 -      smaller = (int)(0.2f * U.widget_unit);
 +      smaller = (int)(0.1f * U.widget_unit);
        hor.xmin += smaller;
        hor.xmax -= smaller;
        if (scroll & V2D_SCROLL_BOTTOM)
@@@ -1813,39 -1697,29 +1813,39 @@@ static void scroll_printstr(Scene *scen
  /* Draw scrollbars in the given 2d-region */
  void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs)
  {
 +      bTheme *btheme = UI_GetTheme();
        Scene *scene = CTX_data_scene(C);
        rcti vert, hor;
 -      int scroll = view2d_scroll_mapped(v2d->scroll);
 +      const int scroll = view2d_scroll_mapped(v2d->scroll);
 +      const char emboss_alpha = btheme->tui.widget_emboss[3];
 +      unsigned char scrollers_back_color[4];
 +
 +      /* Color for scrollbar backs */
 +      UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
-       
        /* make copies of rects for less typing */
        vert = vs->vert;
        hor = vs->hor;
-       
        /* horizontal scrollbar */
        if (scroll & V2D_SCROLL_HORIZONTAL) {
 -              bTheme *btheme = UI_GetTheme();
                uiWidgetColors wcol = btheme->tui.wcol_scroll;
 +              const float alpha_fac = v2d->alpha_hor / 255.0f;
                rcti slider;
                int state;
-               
 -              unsigned char col[4];
                slider.xmin = vs->hor_min;
                slider.xmax = vs->hor_max;
                slider.ymin = hor.ymin;
                slider.ymax = hor.ymax;
-               
                state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-               
 +              wcol.inner[3]   *= alpha_fac;
 +              wcol.item[3]    *= alpha_fac;
 +              wcol.outline[3] *= alpha_fac;
 +              btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
-               
++
                /* show zoom handles if:
                 *      - zooming on x-axis is allowed (no scroll otherwise)
                 *      - slider bubble is large enough (no overdraw confusion)
                        state |= UI_SCROLL_ARROWS;
                }
  
 -              /* clean rect behind slider, but not with transparent background */
 -              UI_GetThemeColor4ubv(TH_BACK, col);
 -              if (col[3] == 255) {
 -                      glColor3ub(col[0], col[1], col[2]);
 -                      glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
 -              }
 -
                UI_draw_widget_scroll(&wcol, &hor, &slider, state);
-               
                /* scale indicators */
                if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
 +                      const int font_id = BLF_default();
                        View2DGrid *grid = vs->grid;
                        float fac, dfac, fac2, val;
-                       
-                       /* the numbers: convert grid->startx and -dx to scroll coordinates 
+                       /* the numbers: convert grid->startx and -dx to scroll coordinates
                         *      - fac is x-coordinate to draw to
                         *      - dfac is gap between scale markings
                         */
                        fac = (grid->startx - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
                        fac = (float)hor.xmin + fac * BLI_rcti_size_x(&hor);
-                       
                        dfac = grid->dx / BLI_rctf_size_x(&v2d->cur);
                        dfac = dfac * BLI_rcti_size_x(&hor);
-                       
                        /* set starting value, and text color */
 -                      UI_ThemeColor(TH_TEXT);
 +                      UI_FontThemeColor(font_id, TH_TEXT);
                        val = grid->startx;
-                       
                        /* if we're clamping to whole numbers only, make sure entries won't be repeated */
                        if (vs->xclamp == V2D_GRID_CLAMP) {
                                while (grid->dx < 0.9999f) {
                        if (dfac > 0.0f) {
                                float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
  
 +                              BLF_batch_draw_begin();
 +
                                for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) {
-                                       
                                        /* make prints look nicer for scrollers */
                                        if (fac < hor.xmin + 0.5f * U.widget_unit)
                                                continue;
                        }
                }
        }
-       
        /* vertical scrollbar */
        if (scroll & V2D_SCROLL_VERTICAL) {
 -              bTheme *btheme = UI_GetTheme();
                uiWidgetColors wcol = btheme->tui.wcol_scroll;
                rcti slider;
 +              const float alpha_fac = v2d->alpha_vert / 255.0f;
                int state;
-               
 -              unsigned char col[4];
                slider.xmin = vert.xmin;
                slider.xmax = vert.xmax;
                slider.ymin = vs->vert_min;
                slider.ymax = vs->vert_max;
-               
                state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-               
 +              wcol.inner[3]   *= alpha_fac;
 +              wcol.item[3]    *= alpha_fac;
 +              wcol.outline[3] *= alpha_fac;
 +              btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
-               
++
                /* show zoom handles if:
                 *      - zooming on y-axis is allowed (no scroll otherwise)
                 *      - slider bubble is large enough (no overdraw confusion)
                {
                        state |= UI_SCROLL_ARROWS;
                }
-               
 -              /* clean rect behind slider, but not with transparent background */
 -              UI_GetThemeColor4ubv(TH_BACK, col);
 -              if (col[3] == 255) {
 -                      glColor3ub(col[0], col[1], col[2]);
 -                      glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
 -              }
 -
                UI_draw_widget_scroll(&wcol, &vert, &slider, state);
-               
-               
                /* scale indiators */
                if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) {
                        View2DGrid *grid = vs->grid;
                         */
                        fac = (grid->starty - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
                        fac = vert.ymin + fac * BLI_rcti_size_y(&vert);
-                       
                        dfac = grid->dy / BLI_rctf_size_y(&v2d->cur);
                        dfac = dfac     * BLI_rcti_size_y(&vert);
-                       
                        /* set starting value, and text color */
 -                      UI_ThemeColor(TH_TEXT);
 +                      const int font_id = BLF_default();
 +                      UI_FontThemeColor(font_id, TH_TEXT);
                        val = grid->starty;
-                       
                        /* if vertical clamping (to whole numbers) is used (i.e. in Sequencer), apply correction */
                        if (vs->yclamp == V2D_GRID_CLAMP)
                                fac += 0.5f * dfac;
-                               
                        /* draw vertical steps */
                        if (dfac > 0.0f) {
 -
 -                              BLF_rotation_default(M_PI_2);
 -                              BLF_enable_default(BLF_ROTATION);
 +                              BLF_rotation(font_id, M_PI_2);
 +                              BLF_enable(font_id, BLF_ROTATION);
  
                                for (; fac < vert.ymax - 10; fac += dfac, val += grid->dy) {
-                                       
                                        /* make prints look nicer for scrollers */
                                        if (fac < vert.ymin + 10)
                                                continue;
-                                       
                                        scroll_printstr(scene, (float)(vert.xmax) - 2.0f, fac, val, grid->powery, vs->yunits, 'v');
                                }
-                               
 -                              BLF_disable_default(BLF_ROTATION);
 +                              BLF_disable(font_id, BLF_ROTATION);
                        }
                }
        }
-       
 +      /* Was changed above, so reset. */
 +      btheme->tui.widget_emboss[3] = emboss_alpha;
  }
  
  /* free temporary memory used for drawing scrollers */
@@@ -2419,11 -2296,12 +2419,11 @@@ void UI_view2d_offset(struct View2D *v2
   * - 'v' = in vertical scroller.
   * - 0 = not in scroller.
   */
 -short UI_view2d_mouse_in_scrollers(const bContext *C, View2D *v2d, int x, int y)
 +short UI_view2d_mouse_in_scrollers(const ARegion *ar, View2D *v2d, int x, int y)
  {
 -      ARegion *ar = CTX_wm_region(C);
        int co[2];
        int scroll = view2d_scroll_mapped(v2d->scroll);
-       
        /* clamp x,y to region-coordinates first */
        co[0] = x - ar->winrct.xmin;
        co[1] = y - ar->winrct.ymin;
@@@ -165,14 -165,12 +165,14 @@@ static void view_pan_apply_ex(bContext 
                v2d->cur.ymin += dy;
                v2d->cur.ymax += dy;
        }
-       
        /* validate that view is in valid configuration after this operation */
        UI_view2d_curRect_validate(v2d);
-       
 +      /* don't rebuild full tree in outliner, since we're just changing our view */
 +      ED_region_tag_redraw_no_rebuild(vpd->ar);
 +
        /* request updates to be done... */
 -      ED_region_tag_redraw(vpd->ar);
        WM_event_add_mousemove(C);
  
        UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
@@@ -636,10 -641,9 +636,10 @@@ static void view_zoomstep_apply_ex
        View2D *v2d = &ar->v2d;
        const rctf cur_old = v2d->cur;
        float dx, dy;
 +      const int snap_test = ED_region_snap_size_test(ar);
  
        /* calculate amount to move view by, ensuring symmetry so the
-        * old zoom level is restored after zooming back the same amount 
+        * old zoom level is restored after zooming back the same amount
         */
        if (facx >= 0.0f) {
                dx = BLI_rctf_size_x(&v2d->cur) * facx;
@@@ -1741,9 -1732,9 +1741,9 @@@ static void scroller_activate_init(bCon
                vsm->scrollbarwidth = scrollers->vert_max - scrollers->vert_min;
                vsm->scrollbar_orig = ((scrollers->vert_max + scrollers->vert_min) / 2) + ar->winrct.ymin;
        }
-       
        UI_view2d_scrollers_free(scrollers);
 -      ED_region_tag_redraw(ar);
 +      ED_region_tag_redraw_no_rebuild(ar);
  }
  
  /* cleanup temp customdata  */
@@@ -1753,11 -1744,11 +1753,11 @@@ static void scroller_activate_exit(bCon
                v2dScrollerMove *vsm = op->customdata;
  
                vsm->v2d->scroll_ui &= ~(V2D_SCROLL_H_ACTIVE | V2D_SCROLL_V_ACTIVE);
-               
                MEM_freeN(op->customdata);
                op->customdata = NULL;
-               
 -              ED_region_tag_redraw(CTX_wm_region(C));
 +              ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
        }
  }
  
@@@ -1812,14 -1803,14 +1812,14 @@@ static void scroller_activate_apply(bCo
                                v2d->cur.ymax += temp;
                        }
                        break;
-                       
        }
-       
        /* validate that view is in valid configuration after this operation */
        UI_view2d_curRect_validate(v2d);
-       
        /* request updates to be done... */
 -      ED_region_tag_redraw(vsm->ar);
 +      ED_region_tag_redraw_no_rebuild(vsm->ar);
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
  }
  
@@@ -1901,10 -1892,10 +1901,10 @@@ static int scroller_activate_invoke(bCo
        ARegion *ar = CTX_wm_region(C);
        View2D *v2d = &ar->v2d;
        short in_scroller = 0;
-               
        /* check if mouse in scrollbars, if they're enabled */
 -      in_scroller = UI_view2d_mouse_in_scrollers(C, v2d, event->x, event->y);
 +      in_scroller = UI_view2d_mouse_in_scrollers(ar, v2d, event->x, event->y);
-       
        /* if in a scroller, init customdata then set modal handler which will catch mousedown to start doing useful stuff */
        if (in_scroller) {
                v2dScrollerMove *vsm;