Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Jan 2018 13:35:36 +0000 (14:35 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 11 Jan 2018 13:35:36 +0000 (14:35 +0100)
Conflicts:
source/blender/blenkernel/intern/blender.c
source/blender/makesdna/DNA_ID.h

1  2 
release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenkernel/intern/blender.c
source/blender/editors/interface/resources.c
source/blender/editors/screen/area.c
source/blender/editors/transform/transform_orientations.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c

index 0abb187679856953ef6ba291aff451f2823610d1,3d44c624a7b87c0f7b9a74cd0aee65c1dc5653f2..1089b5c699d48e8b403a4c7ed7ffe04324ea27af
@@@ -57,9 -57,7 +57,9 @@@ class USERPREF_HT_header(Header)
  
          layout.operator_context = 'INVOKE_DEFAULT'
  
 -        if userpref.active_section == 'INPUT':
 +        if userpref.active_section == 'INTERFACE':
 +            layout.operator("wm.save_workspace_file")
 +        elif userpref.active_section == 'INPUT':
              layout.operator("wm.keyconfig_import")
              layout.operator("wm.keyconfig_export")
          elif userpref.active_section == 'ADDONS':
@@@ -227,6 -225,7 +227,6 @@@ class USERPREF_PT_interface(Panel)
          col.prop(view, "show_large_cursors")
          col.prop(view, "show_view_name", text="View Name")
          col.prop(view, "show_playback_fps", text="Playback FPS")
 -        col.prop(view, "use_global_scene")
          col.prop(view, "object_origin_size")
  
          col.separator()
          #col.prop(view, "open_left_mouse_delay", text="Hold LMB")
          #col.prop(view, "open_right_mouse_delay", text="Hold RMB")
          col.prop(view, "show_manipulator")
 +        col.prop(view, "show_manipulator_navigate")
 +        ## Currently not working
 +        # col.prop(view, "show_manipulator_shaded")
          sub = col.column()
          sub.active = view.show_manipulator
          sub.prop(view, "manipulator_size", text="Size")
 -        sub.prop(view, "manipulator_handle_size", text="Handle Size")
 -        sub.prop(view, "manipulator_hotspot", text="Hotspot")
  
          col.separator()
          col.separator()
          col.separator()
          col.separator()
  
+         col.label(text="Screen:")
+         col.prop(view, "show_layout_ui")
          col.prop(view, "show_splash")
  
  
@@@ -861,7 -862,6 +864,7 @@@ class USERPREF_PT_theme(Panel)
              colsub.row().prop(ui_state, "inner_anim_sel")
              colsub.row().prop(ui_state, "inner_driven")
              colsub.row().prop(ui_state, "inner_driven_sel")
 +            colsub.row().prop(ui_state, "blend")
  
              subsplit = row.split(percentage=0.85)
  
              colsub = padding.column()
              colsub.row().prop(ui_state, "inner_key")
              colsub.row().prop(ui_state, "inner_key_sel")
 -            colsub.row().prop(ui_state, "blend")
 +            colsub.row().prop(ui_state, "inner_overridden")
 +            colsub.row().prop(ui_state, "inner_overridden_sel")
  
              col.separator()
              col.separator()
              col.separator()
              col.separator()
  
 -            col.label("Axis Colors:")
 +            col.label("Axis & Manipulator Colors:")
  
              row = col.row()
  
              padding = subsplit.split(percentage=0.15)
              colsub = padding.column()
              colsub = padding.column()
 +            colsub.row().prop(ui, "manipulator_primary")
 +            colsub.row().prop(ui, "manipulator_secondary")
 +            colsub.row().prop(ui, "manipulator_a")
 +            colsub.row().prop(ui, "manipulator_b")
  
 -            layout.separator()
 -            layout.separator()
 +            col.separator()
 +            col.separator()
          elif theme.theme_area == 'BONE_COLOR_SETS':
              col = split.column()
  
index 0b368df57eddf3c11552d21ab0eb00f1fbf319fd,bc47cfde143f7c176251ff0490846e25f55d68c7..d03be79baade1514ab06b866758df0f5865952fb
  #include "BKE_brush.h"
  #include "BKE_cachefile.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_idprop.h"
  #include "BKE_image.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_node.h"
  #include "BKE_report.h"
@@@ -62,8 -62,6 +62,8 @@@
  #include "BKE_screen.h"
  #include "BKE_sequencer.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "RE_pipeline.h"
  #include "RE_render_ext.h"
  
@@@ -89,7 -87,7 +89,7 @@@ void BKE_blender_free(void
        IMB_exit();
        BKE_cachefiles_exit();
        BKE_images_exit();
 -      DAG_exit();
 +      DEG_free_node_types();
  
        BKE_brush_system_exit();
        RE_texture_rng_exit();  
@@@ -98,8 -96,6 +98,8 @@@
  
        BKE_sequencer_cache_destruct();
        IMB_moviecache_destruct();
 +
 +      BKE_layer_exit();
        
        free_nodesystem();
  }
@@@ -262,6 -258,16 +262,16 @@@ void BKE_blender_userdef_app_template_d
        SWAP(ListBase, userdef_a->id, userdef_b->id); \
  } ((void)0)
  
+ #define FLAG_SWAP(id, ty, flags) { \
+       CHECK_TYPE(&(userdef_a->id), ty *); \
+       const ty f = flags; \
+       const ty a = userdef_a->id; \
+       const ty b = userdef_b->id; \
+        userdef_a->id = (userdef_a->id & ~f) | (b & f); \
+        userdef_b->id = (userdef_b->id & ~f) | (a & f); \
+ } ((void)0)
        LIST_SWAP(uistyles);
        LIST_SWAP(uifonts);
        LIST_SWAP(themes);
        DATA_SWAP(font_path_ui_mono);
        DATA_SWAP(keyconfigstr);
  
- #undef LIST_SWAP
 +      DATA_SWAP(manipulator_flag);
 +
+       FLAG_SWAP(uiflag, int, USER_LOCK_UI_LAYOUT);
 +#undef SWAP_TYPELESS
  #undef DATA_SWAP
+ #undef LIST_SWAP
+ #undef FLAG_SWAP
  }
  
  void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
index 2eae452debb358bb1aca508bb5744b683a724711,09b0906f1345ea950a4f5da94d3248296f4a8a39..788c5fb3913f4b7ec3b8fd30096cc0a93bca20f6
@@@ -53,8 -53,6 +53,8 @@@
  
  #include "BIF_gl.h"
  
 +#include "BLF_api.h"
 +
  #include "UI_interface.h"
  #include "UI_interface_icons.h"
  
@@@ -667,17 -665,6 +667,17 @@@ const unsigned char *UI_ThemeGetColorPt
                                case TH_AXIS_Z:
                                        cp = btheme->tui.zaxis; break;
  
 +                              case TH_MANIPULATOR_HI:
 +                                      cp = btheme->tui.manipulator_hi; break;
 +                              case TH_MANIPULATOR_PRIMARY:
 +                                      cp = btheme->tui.manipulator_primary; break;
 +                              case TH_MANIPULATOR_SECONDARY:
 +                                      cp = btheme->tui.manipulator_secondary; break;
 +                              case TH_MANIPULATOR_A:
 +                                      cp = btheme->tui.manipulator_a; break;
 +                              case TH_MANIPULATOR_B:
 +                                      cp = btheme->tui.manipulator_b; break;
 +
                                case TH_INFO_SELECTED:
                                        cp = ts->info_selected;
                                        break;
@@@ -848,15 -835,6 +848,15 @@@ static void ui_theme_space_init_handles
        rgba_char_args_set(theme_space->act_spline, 0xdb, 0x25, 0x12, 255);
  }
  
 +static void ui_theme_space_init_manipulator_colors(bTheme *btheme)
 +{
 +      rgba_char_args_set(btheme->tui.manipulator_hi, 255, 255, 255, 255);
 +      rgba_char_args_set(btheme->tui.manipulator_primary, 222, 255, 13, 255);
 +      rgba_char_args_set(btheme->tui.manipulator_secondary, 0, 255, 255, 255);
 +      rgba_char_args_set(btheme->tui.manipulator_a, 23, 127, 23, 255);
 +      rgba_char_args_set(btheme->tui.manipulator_b, 127, 23, 23, 255);
 +}
 +
  /**
   * initialize default theme
   * \note: when you add new colors, created & saved themes need initialized
@@@ -897,9 -875,6 +897,9 @@@ void ui_theme_init_default(void
        /* 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);
@@@ -1297,35 -1272,25 +1297,35 @@@ void UI_ThemeColor4(int colorid
        
        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;
        CLAMP(b, 0, 255);
        a = alphaoffset + (int) cp[3];
        CLAMP(a, 0, 255);
 -      glColor4ub(r, g, b, a);
 +
 +      col[0] = r;
 +      col[1] = g;
 +      col[2] = b;
 +      col[3] = a;
  }
  
  void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3])
        col[2] = floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
  }
  
 +void UI_GetThemeColorBlend3f(int colorid1, int colorid2, float fac, float r_col[3])
 +{
 +      const unsigned char *cp1, *cp2;
 +
 +      cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
 +      cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
 +
 +      CLAMP(fac, 0.0f, 1.0f);
 +      r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
 +      r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
 +      r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
 +}
 +
  /* blend between to theme colors, and set it */
  void UI_ThemeColorBlend(int colorid1, int colorid2, float fac)
  {
@@@ -1424,12 -1372,6 +1424,12 @@@ void UI_ThemeColorBlendShadeAlpha(int c
        glColor4ub(r, g, b, a);
  }
  
 +void UI_FontThemeColor(int fontid, int colorid)
 +{
 +      unsigned char color[4];
 +      UI_GetThemeColor4ubv(colorid, color);
 +      BLF_color4ubv(fontid, color);
 +}
  
  /* get individual values, not scaled */
  float UI_GetThemeValuef(int colorid)
@@@ -1528,111 -1470,6 +1528,111 @@@ void UI_GetThemeColorShade3ubv(int colo
        col[2] = b;
  }
  
 +void UI_GetThemeColorBlendShade3ubv(int colorid1, int colorid2, float fac, int offset, unsigned char col[3])
 +{
 +      const unsigned char *cp1, *cp2;
 +
 +      cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
 +      cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
 +
 +      CLAMP(fac, 0.0f, 1.0f);
 +
 +      float blend[3];
 +      blend[0] = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
 +      blend[1] = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
 +      blend[2] = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
 +
 +      F3TOCHAR3(blend, col);
 +}
 +
 +void UI_GetThemeColorShade4ubv(int colorid, int offset, unsigned char col[4])
 +{
 +      int r, g, b;
 +      const unsigned char *cp;
 +
 +      cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
 +      r = offset + (int) cp[0];
 +      CLAMP(r, 0, 255);
 +      g = offset + (int) cp[1];
 +      CLAMP(g, 0, 255);
 +      b = offset + (int) cp[2];
 +      CLAMP(b, 0, 255);
 +
 +      col[0] = r;
 +      col[1] = g;
 +      col[2] = b;
 +      col[3] = cp[3];
 +}
 +
 +void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4])
 +{
 +      int r, g, b, a;
 +      const unsigned char *cp;
 +
 +      cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
 +
 +      r = coloffset + (int) cp[0];
 +      CLAMP(r, 0, 255);
 +      g = coloffset + (int) cp[1];
 +      CLAMP(g, 0, 255);
 +      b = coloffset + (int) cp[2];
 +      CLAMP(b, 0, 255);
 +      a = alphaoffset + (int) cp[3];
 +      CLAMP(b, 0, 255);
 +
 +      col[0] = ((float)r) / 255.0f;
 +      col[1] = ((float)g) / 255.0f;
 +      col[2] = ((float)b) / 255.0f;
 +      col[3] = ((float)a) / 255.0f;
 +}
 +
 +void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3])
 +{
 +      int r, g, b;
 +      const unsigned char *cp1, *cp2;
 +
 +      cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
 +      cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
 +
 +      CLAMP(fac, 0.0f, 1.0f);
 +
 +      r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
 +      CLAMP(r, 0, 255);
 +      g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
 +      CLAMP(g, 0, 255);
 +      b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
 +      CLAMP(b, 0, 255);
 +
 +      col[0] = ((float)r) / 255.0f;
 +      col[1] = ((float)g) / 255.0f;
 +      col[2] = ((float)b) / 255.0f;
 +}
 +
 +void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
 +{
 +      int r, g, b, a;
 +      const unsigned char *cp1, *cp2;
 +
 +      cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
 +      cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
 +
 +      CLAMP(fac, 0.0f, 1.0f);
 +
 +      r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
 +      CLAMP(r, 0, 255);
 +      g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
 +      CLAMP(g, 0, 255);
 +      b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
 +      CLAMP(b, 0, 255);
 +      a = offset + floorf((1.0f - fac) * cp1[3] + fac * cp2[3]);
 +      CLAMP(a, 0, 255);
 +
 +      col[0] = ((float)r) / 255.0f;
 +      col[1] = ((float)g) / 255.0f;
 +      col[2] = ((float)b) / 255.0f;
 +      col[3] = ((float)a) / 255.0f;
 +}
 +
  /* get the color, in char pointer */
  void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
  {
@@@ -1821,9 -1658,11 +1821,9 @@@ void init_userdef_do_versions(void
                U.savetime = 1;
  // XXX                error(STRINGIFY(BLENDER_STARTUP_FILE)" is buggy, please consider removing it.\n");
        }
 -      /* transform widget settings */
 -      if (U.tw_hotspot == 0) {
 -              U.tw_hotspot = 14;
 -              U.tw_size = 25;          /* percentage of window size */
 -              U.tw_handlesize = 16;    /* percentage of widget radius */
 +      if (U.manipulator_size == 0) {
 +              U.manipulator_size = 75;
 +              U.manipulator_flag |= USER_MANIPULATOR_DRAW;
        }
        if (U.pad_rot_angle == 0.0f)
                U.pad_rot_angle = 15.0f;
        
        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) {
                    USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 |
                    USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10);
                U.uiflag &= ~(
-                   USER_UIFLAG_DEPRECATED_7);
+                   USER_LOCK_UI_LAYOUT);
                U.transopts &= ~(
                    USER_TR_DEPRECATED_2 | USER_TR_DEPRECATED_3 | USER_TR_DEPRECATED_4 |
                    USER_TR_DEPRECATED_6 | USER_TR_DEPRECATED_7);
                U.uiflag |= USER_LOCK_CURSOR_ADJUST;
        }
  
 +      if (!USER_VERSION_ATLEAST(280, 1)) {
 +              /* interface_widgets.c */
 +              struct uiWidgetColors wcol_tab = {
 +                      {255, 255, 255, 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) {
 +                      btheme->tui.wcol_tab = wcol_tab;
 +              }
 +      }
 +
        /**
         * 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)
        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
  
        /* funny name, but it is GE stuff, moves userdef stuff to engine */
  // XXX        space_set_commmandline_options();
index 08d92dfc9ff1363ca515d85a77d1c854a25dba37,e8dc220667a4d0c969ad7ea3b48c09609e4e2b32..e097cd34eac4575f166f4e04c7afce7a59ceec81
  
  #include "WM_api.h"
  #include "WM_types.h"
 +#include "WM_message.h"
  #include "wm_subwindow.h"
  
  #include "ED_screen.h"
  #include "ED_screen_types.h"
  #include "ED_space_api.h"
  
 -#include "BIF_gl.h"
 -#include "BIF_glutil.h"
 +#include "GPU_immediate.h"
 +#include "GPU_immediate_util.h"
 +#include "GPU_matrix.h"
 +#include "GPU_draw.h"
 +
  #include "BLF_api.h"
  
  #include "IMB_imbuf.h"
@@@ -75,7 -71,7 +75,7 @@@
  
  #include "screen_intern.h"
  
 -extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
 +extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3, const float color[4]); /* xxx temp */
  
  /* general area and region code */
  
@@@ -93,30 -89,21 +93,30 @@@ static void region_draw_emboss(const AR
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, 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);
 +      unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +      immBegin(GWN_PRIM_LINE_STRIP, 5);
 +      
        /* right  */
 -      glColor4ub(0, 0, 0, 30);
 -      sdrawline(rect.xmax, rect.ymin, rect.xmax, rect.ymax);
 +      immAttrib4ub(color, 0, 0, 0, 30);
 +      immVertex2f(pos, rect.xmax, rect.ymax);
 +      immVertex2f(pos, rect.xmax, rect.ymin);
        
        /* bottom  */
 -      glColor4ub(0, 0, 0, 30);
 -      sdrawline(rect.xmin, rect.ymin, rect.xmax, rect.ymin);
 +      immVertex2f(pos, rect.xmin, rect.ymin);
        
 -      /* top  */
 -      glColor4ub(255, 255, 255, 30);
 -      sdrawline(rect.xmin, rect.ymax, rect.xmax, rect.ymax);
 -
        /* left  */
 -      glColor4ub(255, 255, 255, 30);
 -      sdrawline(rect.xmin, rect.ymin, rect.xmin, rect.ymax);
 +      immAttrib4ub(color, 255, 255, 255, 30);
 +      immVertex2f(pos, rect.xmin, rect.ymax);
 +
 +      /* top  */
 +      immVertex2f(pos, rect.xmax, rect.ymax);
 +      
 +      immEnd();
 +      immUnbindProgram();
        
        glDisable(GL_BLEND);
  }
  void ED_region_pixelspace(ARegion *ar)
  {
        wmOrtho2_region_pixelspace(ar);
 -      glLoadIdentity();
 +      gpuLoadIdentity();
  }
  
  /* only exported for WM */
 -void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note)
 +void ED_region_do_listen(bScreen *sc, ScrArea *sa, ARegion *ar, wmNotifier *note, const Scene *scene)
  {
        /* generic notes first */
        switch (note->category) {
        }
  
        if (ar->type && ar->type->listener)
 -              ar->type->listener(sc, sa, ar, note);
 +              ar->type->listener(sc, sa, ar, note, scene);
  }
  
  /* only exported for WM */
 -void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note)
 +void ED_area_do_listen(bScreen *sc, ScrArea *sa, wmNotifier *note, Scene *scene, WorkSpace *workspace)
  {
        /* no generic notes? */
        if (sa->type && sa->type->listener) {
 -              sa->type->listener(sc, sa, note);
 +              sa->type->listener(sc, sa, note, scene, workspace);
        }
  }
  
@@@ -219,27 -206,15 +219,27 @@@ static void area_draw_azone_fullscreen(
        if (G.debug_value == 1) {
                rcti click_rect;
                float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC;
 -              char alpha_debug = 255 * alpha;
 +              unsigned char alpha_debug = 255 * alpha;
  
                BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size);
  
 -              glColor4ub(255, 0, 0, alpha_debug);
 -              fdrawbox(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
 -              glColor4ub(0, 255, 255, alpha_debug);
 -              fdrawline(click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
 -              fdrawline(click_rect.xmin, click_rect.ymax, click_rect.xmax, click_rect.ymin);
 +              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);
 +
 +              immAttrib4ub(color, 255, 0, 0, alpha_debug);
 +              immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +              imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax);
 +
 +              immAttrib4ub(color, 0, 255, 255, alpha_debug);
 +              immBegin(GWN_PRIM_LINES, 4);
 +              immVertex2f(pos, click_rect.xmin, click_rect.ymin);
 +              immVertex2f(pos, click_rect.xmax, click_rect.ymax);
 +              immVertex2f(pos, click_rect.xmin, click_rect.ymax);
 +              immVertex2f(pos, click_rect.xmax, click_rect.ymin);
 +              immEnd();
 +
 +              immUnbindProgram();
        }
  }
  
@@@ -254,96 -229,69 +254,96 @@@ static void area_draw_azone(short x1, s
        dx = copysign(ceilf(0.3f * abs(dx)), dx);
        dy = copysign(ceilf(0.3f * abs(dy)), dy);
  
 -      glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
 +
 +      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, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +      immBegin(GWN_PRIM_LINES, 12);
 +
 +      immAttrib4ub(col, 255, 255, 255, 180);
 +      immVertex2f(pos, x1, y2);
 +      immVertex2f(pos, x2, y1);
 +
 +      immAttrib4ub(col, 255, 255, 255, 130);
 +      immVertex2f(pos, x1, y2 - dy);
 +      immVertex2f(pos, x2 - dx, y1);
 +
 +      immAttrib4ub(col, 255, 255, 255, 80);
 +      immVertex2f(pos, x1, y2 - 2 * dy);
 +      immVertex2f(pos, x2 - 2 * dx, y1);
        
 -      glColor4ub(255, 255, 255, 180);
 -      fdrawline(x1, y2, x2, y1);
 -      glColor4ub(255, 255, 255, 130);
 -      fdrawline(x1, y2 - dy, x2 - dx, y1);
 -      glColor4ub(255, 255, 255, 80);
 -      fdrawline(x1, y2 - 2 * dy, x2 - 2 * dx, y1);
 -      
 -      glColor4ub(0, 0, 0, 210);
 -      fdrawline(x1, y2 + 1, x2 + 1, y1);
 -      glColor4ub(0, 0, 0, 180);
 -      fdrawline(x1, y2 - dy + 1, x2 - dx + 1, y1);
 -      glColor4ub(0, 0, 0, 150);
 -      fdrawline(x1, y2 - 2 * dy + 1, x2 - 2 * dx + 1, y1);
 +      immAttrib4ub(col, 0, 0, 0, 210);
 +      immVertex2f(pos, x1, y2 + 1);
 +      immVertex2f(pos, x2 + 1, y1);
 +
 +      immAttrib4ub(col, 0, 0, 0, 180);
 +      immVertex2f(pos, x1, y2 - dy + 1);
 +      immVertex2f(pos, x2 - dx + 1, y1);
 +
 +      immAttrib4ub(col, 0, 0, 0, 150);
 +      immVertex2f(pos, x1, y2 - 2 * dy + 1);
 +      immVertex2f(pos, x2 - 2 * dx + 1, y1);
 +
 +      immEnd();
 +      immUnbindProgram();
  
        glDisable(GL_LINE_SMOOTH);
 -      glDisable(GL_BLEND);
  }
  
  static void region_draw_azone_icon(AZone *az)
  {
 -      GLUquadricObj *qobj = NULL; 
 -      short midx = az->x1 + (az->x2 - az->x1) / 2;
 -      short midy = az->y1 + (az->y2 - az->y1) / 2;
 -              
 -      qobj = gluNewQuadric();
 -      
 -      glPushMatrix();
 -      glTranslatef(midx, midy, 0.0);
 -      
 -      /* outlined circle */
 -      glEnable(GL_LINE_SMOOTH);
 +      float midx = az->x1 + (az->x2 - az->x1) * 0.5f;
 +      float midy = az->y1 + (az->y2 - az->y1) * 0.5f;
  
 -      glColor4f(1.f, 1.f, 1.f, 0.8f);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
  
 -      gluQuadricDrawStyle(qobj, GLU_FILL); 
 -      gluDisk(qobj, 0.0,  4.25f, 16, 1);
 +      /* outlined circle */
 +      GPU_enable_program_point_size(); /* TODO: make a fixed-size shader to avoid this */
 +      immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
 +      immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
 +      immUniform4f("outlineColor", 0.2f, 0.2f, 0.2f, 0.9f);
 +      immUniform1f("outlineWidth", 1.0f);
 +      immUniform1f("size", 9.5f);
 +      immBegin(GWN_PRIM_POINTS, 1);
 +      immVertex2f(pos, midx, midy);
 +      immEnd();
 +      immUnbindProgram();
 +      GPU_disable_program_point_size();
  
 -      glColor4f(0.2f, 0.2f, 0.2f, 0.9f);
 -      
 -      gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
 -      gluDisk(qobj, 0.0,  4.25f, 16, 1);
 -      
 -      glDisable(GL_LINE_SMOOTH);
 -      
 -      glPopMatrix();
 -      gluDeleteQuadric(qobj);
 -      
        /* + */
 -      sdrawline(midx, midy - 2, midx, midy + 3);
 -      sdrawline(midx - 2, midy, midx + 3, midy);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4f(0.2f, 0.2f, 0.2f, 0.9f);
 +      immBegin(GWN_PRIM_LINES, 4);
 +      immVertex2f(pos, midx, midy - 2);
 +      immVertex2f(pos, midx, midy + 3);
 +      immVertex2f(pos, midx - 2, midy);
 +      immVertex2f(pos, midx + 3, midy);
 +      immEnd();
 +      immUnbindProgram();
  }
  
  static void draw_azone_plus(float x1, float y1, float x2, float y2)
  {
        float width = 0.1f * U.widget_unit;
        float pad = 0.2f * U.widget_unit;
 -      
 -      glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
 -      glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
 -      glRectf((x1 + x2 + width) * 0.5f, (y1 + y2 - width) * 0.5f, x2 - pad, (y1 + y2 + width) * 0.5f);
 +
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
 +      glEnable(GL_BLEND);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4f(0.8f, 0.8f, 0.8f, 0.4f);
 +
 +      immRectf(pos, (x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
 +      immRectf(pos, x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
 +      immRectf(pos, (x1 + x2 + width) * 0.5f, (y1 + y2 - width) * 0.5f, x2 - pad, (y1 + y2 + width) * 0.5f);
 +
 +      immUnbindProgram();
 +      glDisable(GL_BLEND);
  }
  
  static void region_draw_azone_tab_plus(AZone *az)
                        break;
        }
  
 -      glColor4f(0.05f, 0.05f, 0.05f, 0.4f);
 -      UI_draw_roundbox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
 +      float color[4] = {0.05f, 0.05f, 0.05f, 0.4f};
 +      UI_draw_roundbox_aa(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color);
  
 -      glEnable(GL_BLEND);
 -
 -      glColor4f(0.8f, 0.8f, 0.8f, 0.4f);
        draw_azone_plus((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2);
 -
 -      glDisable(GL_BLEND);
  }
  
  static void region_draw_azone_tab(AZone *az)
  {
 -      float col[3];
 +      float col[4], black[4] = {0.0f, 0.0f, 0.0f, 0.5f};
        
        glEnable(GL_BLEND);
        UI_GetThemeColor3fv(TH_HEADER, col);
 -      glColor4f(col[0], col[1], col[2], 0.5f);
 -      
 +      col[3] = 0.5f;
 +
        /* add code to draw region hidden as 'too small' */
        switch (az->edge) {
                case AE_TOP_TO_BOTTOMRIGHT:
 -                      UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA);
 -                      
 -                      UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
 -                      glColor4ub(0, 0, 0, 255);
 -                      UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
 +                      UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
 +                      UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
 +                      UI_draw_roundbox_aa(false, (float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f, black);
                        break;
                case AE_BOTTOM_TO_TOPLEFT:
 -                      UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
 -                      
 -                      UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
 -                      glColor4ub(0, 0, 0, 255);
 -                      UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
 +                      UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
 +                      UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
 +                      UI_draw_roundbox_aa(false, (float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f, black);
                        break;
                case AE_LEFT_TO_TOPRIGHT:
 -                      UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
 -                      
 -                      UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
 -                      glColor4ub(0, 0, 0, 255);
 -                      UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
 +                      UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
 +                      UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
 +                      UI_draw_roundbox_aa(false, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, black);
                        break;
                case AE_RIGHT_TO_TOPLEFT:
 -                      UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA);
 -                      
 -                      UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
 -                      glColor4ub(0, 0, 0, 255);
 -                      UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
 +                      UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
 +                      UI_draw_roundbox_shade_x(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f, col);
 +                      UI_draw_roundbox_aa(false, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, black);
                        break;
        }
        
@@@ -411,24 -372,24 +411,24 @@@ static void region_draw_azone_tria(AZon
  {
        glEnable(GL_BLEND);
        //UI_GetThemeColor3fv(TH_HEADER, col);
 -      glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
 +      float color[4] = {0.0f, 0.0f, 0.0f, 0.35f};
        
        /* add code to draw region hidden as 'too small' */
        switch (az->edge) {
                case AE_TOP_TO_BOTTOMRIGHT:
 -                      ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y1, (float)(az->x1 + az->x2) / 2, (float)az->y2);
 +                      ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y1, (float)(az->x1 + az->x2) / 2, (float)az->y2, color);
                        break;
                        
                case AE_BOTTOM_TO_TOPLEFT:
 -                      ui_draw_anti_tria((float)az->x1, (float)az->y2, (float)az->x2, (float)az->y2, (float)(az->x1 + az->x2) / 2, (float)az->y1);
 +                      ui_draw_anti_tria((float)az->x1, (float)az->y2, (float)az->x2, (float)az->y2, (float)(az->x1 + az->x2) / 2, (float)az->y1, color);
                        break;
  
                case AE_LEFT_TO_TOPRIGHT:
 -                      ui_draw_anti_tria((float)az->x2, (float)az->y1, (float)az->x2, (float)az->y2, (float)az->x1, (float)(az->y1 + az->y2) / 2);
 +                      ui_draw_anti_tria((float)az->x2, (float)az->y1, (float)az->x2, (float)az->y2, (float)az->x1, (float)(az->y1 + az->y2) / 2, color);
                        break;
                        
                case AE_RIGHT_TO_TOPLEFT:
 -                      ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x1, (float)az->y2, (float)az->x2, (float)(az->y1 + az->y2) / 2);
 +                      ui_draw_anti_tria((float)az->x1, (float)az->y1, (float)az->x1, (float)az->y2, (float)az->x2, (float)(az->y1 + az->y2) / 2, color);
                        break;
                        
        }
@@@ -452,8 -413,8 +452,8 @@@ static void region_draw_azones(ScrArea 
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
 -      glPushMatrix();
 -      glTranslatef(-ar->winrct.xmin, -ar->winrct.ymin, 0.0f);
 +      gpuPushMatrix();
 +      gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
        
        for (az = sa->actionzones.first; az; az = az->next) {
                /* test if action zone is over this region */
                }
        }
  
 -      glPopMatrix();
 +      gpuPopMatrix();
  
        glDisable(GL_BLEND);
  }
@@@ -512,33 -473,6 +512,33 @@@ void ED_region_set(const bContext *C, A
        ED_region_pixelspace(ar);
  }
  
 +/* Follow wmMsgNotifyFn spec */
 +void ED_region_do_msg_notify_tag_redraw(
 +        bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
 +{
 +      ARegion *ar = msg_val->owner;
 +      ED_region_tag_redraw(ar);
 +
 +      /* This avoids _many_ situations where header/properties control display settings.
 +       * the common case is space properties in the header */
 +      if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_UI)) {
 +              while (ar && ar->prev) {
 +                      ar = ar->prev;
 +              }
 +              for (; ar; ar = ar->next) {
 +                      if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS)) {
 +                              ED_region_tag_redraw(ar);
 +                      }
 +              }
 +      }
 +}
 +/* Follow wmMsgNotifyFn spec */
 +void ED_area_do_msg_notify_tag_refresh(
 +        bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
 +{
 +      ScrArea *sa = msg_val->user_data;
 +      ED_area_tag_refresh(sa);
 +}
  
  /* only exported for WM */
  void ED_region_do_draw(bContext *C, ARegion *ar)
                UI_ThemeClearColor(TH_HEADER);
                glClear(GL_COLOR_BUFFER_BIT);
                
 -              UI_ThemeColor(TH_TEXT);
 +              UI_FontThemeColor(BLF_default(), TH_TEXT);
                BLF_draw_default(UI_UNIT_X, 0.4f * UI_UNIT_Y, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
        }
        else if (at->draw) {
        /* for debugging unneeded area redraws and partial redraw */
  #if 0
        glEnable(GL_BLEND);
 -      glColor4f(drand48(), drand48(), drand48(), 0.1f);
 -      glRectf(ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
 +      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(drand48(), drand48(), drand48(), 0.1f);
 +      immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin,
                ar->drawrct.xmax - ar->winrct.xmin, ar->drawrct.ymax - ar->winrct.ymin);
 +      immUnbindProgram();
        glDisable(GL_BLEND);
  #endif
  
        UI_blocklist_free_inactive(C, &ar->uiblocks);
  
        if (sa) {
 +              const bScreen *screen = WM_window_get_active_screen(win);
 +
                /* disable emboss when the area is full,
                 * unless we need to see division between regions (quad-split for eg) */
 -              if (((win->screen->state == SCREENFULL) && (ar->alignment == RGN_ALIGN_NONE)) == 0) {
 +              if (((screen->state == SCREENFULL) && (ar->alignment == RGN_ALIGN_NONE)) == 0) {
                        region_draw_emboss(ar, &ar->winrct);
                }
        }
 +
 +      /* We may want to detach message-subscriptions from drawing. */
 +      {
 +              WorkSpace *workspace = CTX_wm_workspace(C);
 +              wmWindowManager *wm = CTX_wm_manager(C);
 +              bScreen *screen = WM_window_get_active_screen(win);
 +              Scene *scene = CTX_data_scene(C);
 +              struct wmMsgBus *mbus = wm->message_bus;
 +              WM_msgbus_clear_by_owner(mbus, ar);
 +
 +              /* Cheat, always subscribe to this space type properties.
 +               *
 +               * This covers most cases and avoids copy-paste similar code for each space type.
 +               */
 +              if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS, RGN_TYPE_UI, RGN_TYPE_TOOLS)) {
 +                      SpaceLink *sl = sa->spacedata.first;
 +
 +                      PointerRNA ptr;
 +                      RNA_pointer_create(&screen->id, &RNA_Space, sl, &ptr);
 +
 +                      wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
 +                              .owner = ar,
 +                              .user_data = ar,
 +                              .notify = ED_region_do_msg_notify_tag_redraw,
 +                      };
 +                      /* All properties for this space type. */
 +                      WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__);
 +              }
 +
 +              ED_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
 +      }
  }
  
  /* **********************************
@@@ -758,7 -655,7 +758,7 @@@ void ED_area_headerprint(ScrArea *sa, c
  /* ************************************************************ */
  
  
 -static void area_azone_initialize(wmWindow *win, bScreen *screen, ScrArea *sa)
 +static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *sa)
  {
        AZone *az;
        
                return;
        }
  
+       if (U.uiflag & USER_LOCK_UI_LAYOUT) {
+               return;
+       }
        /* can't click on bottom corners on OS X, already used for resizing */
  #ifdef __APPLE__
        if (!(sa->totrct.xmin == 0 && sa->totrct.ymin == 0) || WM_window_is_fullscreen(win))
@@@ -1414,9 -1315,7 +1418,9 @@@ static void region_rect_recursive(wmWin
                 * must be minimum '4' */
        }
        else {
 -              if (ELEM(win->screen->state, SCREENNORMAL, SCREENMAXIMIZED)) {
 +              const bScreen *screen = WM_window_get_active_screen(win);
 +
 +              if (ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) {
                        region_azone_add(sa, ar, alignment, false);
                }
                else {
@@@ -1540,7 -1439,6 +1544,7 @@@ static void ed_default_handlers(wmWindo
  /* called in screen_refresh, or screens_init, also area size changes */
  void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
  {
 +      const bScreen *screen = WM_window_get_active_screen(win);
        ARegion *ar;
        rcti rect;
        
        area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win));
        
        /* clear all azones, add the area triange widgets */
 -      area_azone_initialize(win, win->screen, sa);
 +      area_azone_initialize(win, screen, sa);
  
        /* region rect sizes */
        rect = sa->totrct;
                        /* default region handlers */
                        ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag);
                        /* own handlers */
 -                      if (ar->type->init)
 +                      if (ar->type->init) {
                                ar->type->init(wm, ar);
 +                      }
                }
                else {
                        /* prevent uiblocks to run */
@@@ -2075,12 -1972,8 +2079,12 @@@ void ED_region_panels(const bContext *C
                /* view should be in pixelspace */
                UI_view2d_view_restore(C);
                glEnable(GL_BLEND);
 -              UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
 -              glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct) + 1);
 +              Gwn_VertFormat *format = immVertexFormat();
 +              unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +              immUniformThemeColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
 +              immRecti(pos, 0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct) + 1);
 +              immUnbindProgram();
                glDisable(GL_BLEND);
        }
        else {
@@@ -2184,37 -2077,22 +2188,37 @@@ int ED_area_headersize(void
        return (int)(HEADERY * UI_DPI_FAC);
  }
  
 -void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw)
 +void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float fill_color[4], const bool full_redraw)
  {
        const int header_height = UI_UNIT_Y;
        uiStyle *style = UI_style_get_dpi();
        int fontid = style->widget.uifont_id;
        GLint scissor[4];
        rcti rect;
 +      int num_lines = 0;
  
        /* background box */
        ED_region_visible_rect(ar, &rect);
 -      rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height;
  
 -      /* box fill entire width or just around text */
 -      if (!full_redraw)
 -              rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit);
 +      /* Box fill entire width or just around text. */
 +      if (!full_redraw) {
 +              const char **text = &text_array[0];
 +              while (*text) {
 +                      rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, *text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit);
 +                      text++;
 +                      num_lines++;
 +              }
 +      }
 +      /* Just count the line number. */
 +      else {
 +              const char **text = &text_array[0];
 +              while (*text) {
 +                      text++;
 +                      num_lines++;
 +              }
 +      }
  
 +      rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height * num_lines;
        rect.ymax = BLI_rcti_size_y(&ar->winrct);
  
        /* setup scissor */
  
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 -      glColor4fv(fill_color);
 -      glRecti(rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4fv(fill_color);
 +      immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
 +      immUnbindProgram();
        glDisable(GL_BLEND);
  
        /* text */
 -      UI_ThemeColor(TH_TEXT_HI);
 +      UI_FontThemeColor(fontid, TH_TEXT_HI);
        BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
        BLF_enable(fontid, BLF_CLIPPING);
 -      BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit, 0.0f);
 -
 -      BLF_draw(fontid, text, BLF_DRAW_STR_DUMMY_MAX);
 +      int offset = num_lines - 1;
 +      {
 +              const char **text = &text_array[0];
 +              while (*text) {
 +                      BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit + offset * header_height, 0.0f);
 +                      BLF_draw(fontid, *text, BLF_DRAW_STR_DUMMY_MAX);
 +                      text++;
 +                      offset--;
 +              }
 +      }
  
        BLF_disable(fontid, BLF_CLIPPING);
  
        glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  }
  
 +void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw)
 +{
 +      ED_region_info_draw_multiline(ar, (const char *[2]){text, NULL}, fill_color, full_redraw);
 +}
 +
  #define MAX_METADATA_STR    1024
  
  static const char *meta_data_list[] =
@@@ -2426,11 -2288,11 +2430,11 @@@ void ED_region_image_metadata_draw(int 
                return;
  
        /* find window pixel coordinates of origin */
 -      glPushMatrix();
 +      gpuPushMatrix();
  
        /* offset and zoom using ogl */
 -      glTranslatef(x, y, 0.0f);
 -      glScalef(zoomx, zoomy, 1.0f);
 +      gpuTranslate2f(x, y);
 +      gpuScale2f(zoomx, zoomy);
  
        BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
  
        box_y = metadata_box_height_get(ibuf, blf_mono_font, true);
  
        if (box_y) {
 -              UI_ThemeColor(TH_METADATA_BG);
 -
                /* set up rect */
                BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y);
                /* draw top box */
 -              glRectf(rect.xmin, rect.ymin, rect.xmax, rect.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);
 +              immUniformThemeColor(TH_METADATA_BG);
 +              immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 +              immUnbindProgram();
  
                BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
                BLF_enable(blf_mono_font, BLF_CLIPPING);
  
 -              UI_ThemeColor(TH_METADATA_TEXT);
 +              UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT);
                metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true);
  
                BLF_disable(blf_mono_font, BLF_CLIPPING);
        box_y = metadata_box_height_get(ibuf, blf_mono_font, false);
  
        if (box_y) {
 -              UI_ThemeColor(TH_METADATA_BG);
 -
                /* set up box rect */
                BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin);
                /* draw top box */
 -              glRectf(rect.xmin, rect.ymin, rect.xmax, rect.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);
 +              immUniformThemeColor(TH_METADATA_BG);
 +              immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 +              immUnbindProgram();
  
                BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
                BLF_enable(blf_mono_font, BLF_CLIPPING);
  
 -              UI_ThemeColor(TH_METADATA_TEXT);
 +              UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT);
                metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false);
  
                BLF_disable(blf_mono_font, BLF_CLIPPING);
        }
  
 -      glPopMatrix();
 +      gpuPopMatrix();
  }
  
  void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
        int x1, y1, x2, y2;
  
        /* the image is located inside (0, 0), (1, 1) as set by view2d */
 -      UI_ThemeColorShade(TH_BACK, 20);
 -
        UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1);
        UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2);
 -      glRectf(x1, y1, x2, y2);
 +
 +      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);
 +      immUniformThemeColorShade(TH_BACK, 20);
 +      immRectf(pos, x1, y1, x2, y2);
 +      immUnbindProgram();
  
        /* gridsize adapted to zoom level */
        gridsize = 0.5f * (zoomx + zoomy);
                }
        }
  
 -      /* the fine resolution level */
        blendfac = 0.25f * gridsize - floorf(0.25f * gridsize);
        CLAMP(blendfac, 0.0f, 1.0f);
 -      UI_ThemeColorShade(TH_BACK, (int)(20.0f * (1.0f - blendfac)));
  
 -      fac = 0.0f;
 -      glBegin(GL_LINES);
 -      while (fac < 1.0f) {
 -              glVertex2f(x1, y1 * (1.0f - fac) + y2 * fac);
 -              glVertex2f(x2, y1 * (1.0f - fac) + y2 * fac);
 -              glVertex2f(x1 * (1.0f - fac) + x2 * fac, y1);
 -              glVertex2f(x1 * (1.0f - fac) + x2 * fac, y2);
 -              fac += gridstep;
 -      }
 +      int count_fine = 1.0f / gridstep;
 +      int count_large = 1.0f / (4.0f * gridstep);
 +
 +      if (count_fine > 0) {
 +              GWN_vertformat_clear(format);
 +              pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +              unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
 +              
 +              immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
 +              immBegin(GWN_PRIM_LINES, 4 * count_fine + 4 * count_large);
 +              
 +              float theme_color[3];
 +              UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color);
 +              immAttrib3fv(color, theme_color);
 +              fac = 0.0f;
 +              
 +              /* the fine resolution level */
 +              for (int i = 0; i < count_fine; i++) {
 +                      immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac);
 +                      immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac);
 +                      immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1);
 +                      immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2);
 +                      fac += gridstep;
 +              }
  
 -      /* the large resolution level */
 -      UI_ThemeColor(TH_BACK);
 +              if (count_large > 0) {
 +                      UI_GetThemeColor3fv(TH_BACK, theme_color);
 +                      immAttrib3fv(color, theme_color);
 +                      fac = 0.0f;
 +                      
 +                      /* the large resolution level */
 +                      for (int i = 0; i < count_large; i++) {
 +                              immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac);
 +                              immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac);
 +                              immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1);
 +                              immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2);
 +                              fac += 4.0f * gridstep;
 +                      }
 +              }
  
 -      fac = 0.0f;
 -      while (fac < 1.0f) {
 -              glVertex2f(x1, y1 * (1.0f - fac) + y2 * fac);
 -              glVertex2f(x2, y1 * (1.0f - fac) + y2 * fac);
 -              glVertex2f(x1 * (1.0f - fac) + x2 * fac, y1);
 -              glVertex2f(x1 * (1.0f - fac) + x2 * fac, y2);
 -              fac += 4.0f * gridstep;
 +              immEnd();
 +              immUnbindProgram();
        }
 -      glEnd();
  }
  
  /* If the area has overlapping regions, it returns visible rect for Region *ar */
@@@ -2605,11 -2437,8 +2609,11 @@@ void ED_region_visible_rect(ARegion *ar
  
  void ED_region_cache_draw_background(const ARegion *ar)
  {
 -      glColor4ub(128, 128, 255, 64);
 -      glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
 +      unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor4ub(128, 128, 255, 64);
 +      immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC);
 +      immUnbindProgram();
  }
  
  void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y)
  
        BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]);
  
 -      glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
 +      unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformThemeColor(TH_CFRAME);
 +      immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
 +      immUnbindProgram();
  
 -      UI_ThemeColor(TH_TEXT);
 +      UI_FontThemeColor(fontid, TH_TEXT);
        BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
        BLF_draw(fontid, numstr, sizeof(numstr));
  }
  void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra)
  {
        if (num_segments) {
 -              int a;
 +              unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +              immUniformColor4ub(128, 128, 255, 128);
  
 -              glColor4ub(128, 128, 255, 128);
 +              for (int a = 0; a < num_segments; a++) {
 +                      float x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
 +                      float x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
  
 -              for (a = 0; a < num_segments; a++) {
 -                      float x1, x2;
 +                      immRecti(pos, x1, 0, x2, 8 * UI_DPI_FAC);
 +                      /* TODO(merwin): use primitive restart to draw multiple rects more efficiently */
 +              }
  
 -                      x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
 -                      x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
 +              immUnbindProgram();
 +      }
 +}
  
 -                      glRecti(x1, 0, x2, 8 * UI_DPI_FAC);
 -              }
 +/**
 + * Generate subscriptions for this region.
 + */
 +void ED_region_message_subscribe(
 +        bContext *C,
 +        struct WorkSpace *workspace, struct Scene *scene,
 +        struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
 +        struct wmMsgBus *mbus)
 +{
 +      if (ar->manipulator_map != NULL) {
 +              WM_manipulatormap_message_subscribe(C, ar->manipulator_map, ar, mbus);
 +      }
 +
 +      if (BLI_listbase_is_empty(&ar->uiblocks)) {
 +              UI_region_message_subscribe(ar, mbus);
 +      }
 +
 +      if (ar->type->message_subscribe != NULL) {
 +              ar->type->message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
        }
  }
index 63cd5291193b1e4883febef0ddb0a2a1df88ec4e,f3078eb7824beaf4f3615c8e17fb9890a16c74a7..f8b11a0bcae4ec83705144f1dbb2a6c7c894e2cf
@@@ -38,7 -38,6 +38,7 @@@
  #include "DNA_screen_types.h"
  #include "DNA_space_types.h"
  #include "DNA_view3d_types.h"
 +#include "DNA_workspace_types.h"
  
  #include "BLI_math.h"
  #include "BLI_listbase.h"
@@@ -53,7 -52,6 +53,7 @@@
  #include "BKE_report.h"
  #include "BKE_main.h"
  #include "BKE_screen.h"
 +#include "BKE_workspace.h"
  
  #include "BLT_translation.h"
  
  
  void BIF_clearTransformOrientation(bContext *C)
  {
 +      WorkSpace *workspace = CTX_wm_workspace(C);
 +      ListBase *transform_orientations = BKE_workspace_transform_orientations_get(workspace);
        View3D *v3d = CTX_wm_view3d(C);
  
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
 -      BLI_freelistN(transform_spaces);
 +      BLI_freelistN(transform_orientations);
        
        // Need to loop over all view3d
 -      if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
 -              v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global   */
 +      if (v3d && v3d->twmode == V3D_MANIP_CUSTOM) {
 +              v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
 +              v3d->custom_orientation_index = -1;
        }
  }
  
@@@ -322,24 -318,23 +322,24 @@@ void BIF_createTransformOrientation(bCo
  TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3],
                                       const char *name, const bool overwrite)
  {
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
        TransformOrientation *ts = NULL;
 +      WorkSpace *workspace = CTX_wm_workspace(C);
 +      ListBase *transform_orientations = BKE_workspace_transform_orientations_get(workspace);
        char name_unique[sizeof(ts->name)];
  
        if (overwrite) {
 -              ts = findOrientationName(transform_spaces, name);
 +              ts = findOrientationName(transform_orientations, name);
        }
        else {
                BLI_strncpy(name_unique, name, sizeof(name_unique));
 -              uniqueOrientationName(transform_spaces, name_unique);
 +              uniqueOrientationName(transform_orientations, name_unique);
                name = name_unique;
        }
  
        /* if not, create a new one */
        if (ts == NULL) {
                ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix");
 -              BLI_addtail(transform_spaces, ts);
 +              BLI_addtail(transform_orientations, ts);
                BLI_strncpy(ts->name, name, sizeof(ts->name));
        }
  
  
  void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target)
  {
 -      Scene *scene = CTX_data_scene(C);
 -      ListBase *transform_spaces = &scene->transform_spaces;
 -      const int i = BLI_findindex(transform_spaces, target);
 -
 -      if (i != -1) {
 -              Main *bmain = CTX_data_main(C);
 -              BKE_screen_view3d_main_twmode_remove(&bmain->screen, scene, i);
 -              BLI_freelinkN(transform_spaces, target);
 -      }
 +      BKE_workspace_transform_orientation_remove(CTX_wm_workspace(C), target);
  }
  
  void BIF_removeTransformOrientationIndex(bContext *C, int index)
  {
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
 -      TransformOrientation *ts = BLI_findlink(transform_spaces, index);
 -
 -      if (ts) {
 -              BIF_removeTransformOrientation(C, ts);
 -      }
 +      TransformOrientation *target = BKE_workspace_transform_orientation_find(CTX_wm_workspace(C), index);
 +      BIF_removeTransformOrientation(C, target);
  }
  
  void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target)
  {
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
 -      const int i = BLI_findindex(transform_spaces, target);
 +      int index = BKE_workspace_transform_orientation_get_index(CTX_wm_workspace(C), target);
 +      View3D *v3d = CTX_wm_view3d(C);
  
 -      if (i != -1) {
 -              View3D *v3d = CTX_wm_view3d(C);
 -              v3d->twmode = V3D_MANIP_CUSTOM + i;
 -      }
 +      BLI_assert(index != -1);
 +
 +      v3d->twmode = V3D_MANIP_CUSTOM;
 +      v3d->custom_orientation_index = index;
  }
  
 -void BIF_selectTransformOrientationValue(bContext *C, int orientation)
 +/**
 + * Activate a transform orientation in a 3D view based on an enum value.
 + *
 + * \param orientation: If this is #V3D_MANIP_CUSTOM or greater, the custom transform orientation
 + *                     with index \a orientation - #V3D_MANIP_CUSTOM gets activated.
 + */
 +void BIF_selectTransformOrientationValue(View3D *v3d, int orientation)
  {
 -      View3D *v3d = CTX_wm_view3d(C);
 -      if (v3d) /* currently using generic poll */
 -              v3d->twmode = orientation;
 +      const bool is_custom = orientation >= V3D_MANIP_CUSTOM;
 +
 +      v3d->twmode = is_custom ? V3D_MANIP_CUSTOM : orientation;
 +      v3d->custom_orientation_index = is_custom ? (orientation - V3D_MANIP_CUSTOM) : -1;
  }
  
  int BIF_countTransformOrientation(const bContext *C)
  {
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
 -      return BLI_listbase_count(transform_spaces);
 +      WorkSpace *workspace = CTX_wm_workspace(C);
 +      ListBase *transform_orientations = BKE_workspace_transform_orientations_get(workspace);
 +      return BLI_listbase_count(transform_orientations);
  }
  
 -bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name, int index)
 +bool applyTransformOrientation(const TransformOrientation *ts, float r_mat[3][3], char *r_name)
  {
 -      ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
 -      TransformOrientation *ts = BLI_findlink(transform_spaces, index);
 -
 -      BLI_assert(index >= 0);
 -
 -      if (ts) {
 -              if (r_name) {
 -                      BLI_strncpy(r_name, ts->name, MAX_NAME);
 -              }
 -
 -              copy_m3_m3(mat, ts->mat);
 -              return true;
 -      }
 -      else {
 -              /* invalid index, can happen sometimes */
 -              return false;
 +      if (r_name) {
 +              BLI_strncpy(r_name, ts->name, MAX_NAME);
        }
 +      copy_m3_m3(r_mat, ts->mat);
 +
 +      return true;
  }
  
  static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it)
@@@ -482,10 -492,8 +482,10 @@@ void initTransformOrientation(bContext 
                                unit_m3(t->spacemtx);
                        }
                        break;
 -              default: /* V3D_MANIP_CUSTOM */
 -                      if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_MANIP_CUSTOM)) {
 +              case V3D_MANIP_CUSTOM:
 +                      BLI_strncpy(t->spacename, t->custom_orientation->name, sizeof(t->spacename));
 +
 +                      if (applyTransformOrientation(t->custom_orientation, t->spacemtx, t->spacename)) {
                                /* pass */
                        }
                        else {
@@@ -578,10 -586,10 +578,10 @@@ static unsigned int bm_mesh_faces_selec
  
  int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
  {
 -      Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        Object *obedit = CTX_data_edit_object(C);
        Base *base;
 -      Object *ob = OBACT;
 +      Object *ob = OBACT(view_layer);
        int result = ORIENTATION_NONE;
        const bool activeOnly = (around == V3D_AROUND_ACTIVE);
  
                                                        SWAP(BMVert *, v_pair[0], v_pair[1]);
                                                }
  
-                                               add_v3_v3v3(normal, v_pair[0]->no, v_pair[1]->no);
-                                               sub_v3_v3v3(plane, v_pair[0]->co, v_pair[1]->co);
-                                               /* flip the plane normal so we point outwards */
-                                               negate_v3(plane);
+                                               add_v3_v3v3(normal, v_pair[1]->no, v_pair[0]->no);
+                                               sub_v3_v3v3(plane, v_pair[1]->co, v_pair[0]->co);
+                                               if (normalize_v3(plane) != 0.0f) {
+                                                       /* For edges it'd important the resulting matrix can rotate around the edge,
+                                                        * project onto the plane so we can use a fallback value. */
+                                                       project_plane_normalized_v3_v3v3(normal, normal, plane);
+                                                       if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
+                                                               /* in the case the normal and plane are aligned,
+                                                                * use a fallback normal which is orthogonal to the plane. */
+                                                               ortho_v3_v3(normal, plane);
+                                                       }
+                                               }
                                        }
  
                                        result = ORIENTATION_EDGE;
        }
        else {
                /* we need the one selected object, if its not active */
 -              View3D *v3d = CTX_wm_view3d(C);
 -              ob = OBACT;
 -              if (ob && (ob->flag & SELECT)) {
 +              base = BASACT(view_layer);
 +              ob = OBACT(view_layer);
 +              if (base && ((base->flag & BASE_SELECTED) != 0)) {
                        /* pass */
                }
                else {
                        /* first selected */
                        ob = NULL;
 -                      for (base = scene->base.first; base; base = base->next) {
 -                              if (TESTBASELIB(v3d, base)) {
 +                      for (base = view_layer->object_bases.first; base; base = base->next) {
 +                              if (TESTBASELIB(base)) {
                                        ob = base->object;
                                        break;
                                }
index 89761ee6ced1c72c90b0df15f4bcd1b0311a7b94,93fab4da5664367487875cc7558fab668d68bcff..237091e1391b59263eed156cd23e8129ea890a75
@@@ -140,8 -140,6 +140,8 @@@ typedef struct uiWidgetStateColors 
        char inner_key_sel[4];
        char inner_driven[4];
        char inner_driven_sel[4];
 +      char inner_overridden[4];
 +      char inner_overridden_sel[4];
        float blend, pad;
  } uiWidgetStateColors;
  
@@@ -164,7 -162,7 +164,7 @@@ typedef struct ThemeUI 
        /* Interface Elements (buttons, menus, icons) */
        uiWidgetColors wcol_regular, wcol_tool, wcol_text;
        uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
 -      uiWidgetColors wcol_num, wcol_numslider;
 +      uiWidgetColors wcol_num, wcol_numslider, wcol_tab;
        uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item, wcol_tooltip;
        uiWidgetColors wcol_box, wcol_scroll, wcol_progress, wcol_list_item, wcol_pie_menu;
        
  
        /* Axis Colors */
        char xaxis[4], yaxis[4], zaxis[4];
 +
 +      /* Manipulator Colors. */
 +      char manipulator_hi[4];
 +      char manipulator_primary[4];
 +      char manipulator_secondary[4];
 +      char manipulator_a[4];
 +      char manipulator_b[4];
 +      char pad2[4];
  } ThemeUI;
  
  /* try to put them all in one, if needed a special struct can be created as well
@@@ -509,8 -499,7 +509,8 @@@ typedef struct UserDef 
        short gp_settings;  /* eGP_UserdefSettings */
        short tb_leftmouse, tb_rightmouse;
        struct SolidLight light[3];
 -      short tw_hotspot, tw_flag, tw_handlesize, tw_size;
 +      short manipulator_flag, manipulator_size;
 +      int pad6;
        short textimeout, texcollectrate;
        short wmdrawmethod; /* eWM_DrawMethod */
        short dragthreshold;
@@@ -616,7 -605,7 +616,7 @@@ typedef enum eUserPref_Flag 
        USER_FLAG_DEPRECATED_1  = (1 << 1),  /* cleared */
        USER_FLAG_DEPRECATED_2  = (1 << 2),  /* cleared */
        USER_FLAG_DEPRECATED_3  = (1 << 3),  /* cleared */
 -      USER_SCENEGLOBAL                = (1 << 4),
 +/*    USER_SCENEGLOBAL         = (1 << 4), deprecated */
        USER_TRACKBALL                  = (1 << 5),
        USER_FLAG_DEPRECATED_6  = (1 << 6),  /* cleared */
        USER_FLAG_DEPRECATED_7  = (1 << 7),  /* cleared */
@@@ -679,7 -668,9 +679,9 @@@ typedef enum eUserpref_UI_Flag 
        USER_DRAWVIEWINFO               = (1 << 4),
        USER_PLAINMENUS                 = (1 << 5),
        USER_LOCK_CURSOR_ADJUST = (1 << 6),
-       USER_UIFLAG_DEPRECATED_7        = (1 << 7),  /* cleared */
+       /* Avoid accidentally adjusting the layout
+        * (exact behavior may change based on whats considered reasonable to lock down). */
+       USER_LOCK_UI_LAYOUT     = (1 << 7),
        USER_ALLWINCODECS               = (1 << 8),
        USER_MENUOPENAUTO               = (1 << 9),
        USER_ZBUF_CURSOR                = (1 << 10),
@@@ -818,12 -809,6 +820,12 @@@ typedef enum eGP_UserdefSettings 
        GP_PAINT_DOSIMPLIFY             = (1 << 1),
  } eGP_UserdefSettings;
  
 +enum {
 +      USER_MANIPULATOR_DRAW            = (1 << 0),
 +      USER_MANIPULATOR_DRAW_NAVIGATE   = (1 << 1),
 +      USER_MANIPULATOR_SHADED          = (1 << 8),
 +};
 +
  /* Color Picker Types.
   * UserDef.color_picker_type */
  typedef enum eColorPicker_Types {
index 25ce04229ed1b6d3f144eb45d21c7583ebccb1cd,3aed3a1edb1870640cdd9fa0ece4aea35571c005..e2a0769490d8bc3ac5776c16467fe0513453e622
@@@ -68,7 -68,16 +68,7 @@@ static const EnumPropertyItem opensubdi
  #endif
  
  static const EnumPropertyItem audio_device_items[] = {
 -      {0, "NONE", 0, "None", "Null device - there will be no audio output"},
 -#ifdef WITH_SDL
 -      {1, "SDL", 0, "SDL", "SDL device - simple direct media layer, recommended for sequencer usage"},
 -#endif
 -#ifdef WITH_OPENAL
 -      {2, "OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage"},
 -#endif
 -#ifdef WITH_JACK
 -      {3, "JACK", 0, "JACK", "JACK Audio Connection Kit, recommended for pro audio users"},
 -#endif
 +      {0, "Null", 0, "None", "Null device - there will be no audio output"},
        {0, NULL, 0, NULL, NULL}
  };
  
@@@ -91,14 -100,13 +91,14 @@@ static const EnumPropertyItem rna_enum_
  #include "DNA_screen_types.h"
  
  #include "BKE_blender.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_main.h"
  #include "BKE_idprop.h"
  #include "BKE_pbvh.h"
  #include "BKE_paint.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "GPU_draw.h"
  #include "GPU_select.h"
  
@@@ -147,6 -155,12 +147,12 @@@ static void rna_userdef_dpi_update(Mai
        WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);    /* refresh region sizes */
  }
  
+ static void rna_userdef_update_ui(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+ {
+       WM_main_add_notifier(NC_WINDOW, NULL);
+       WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);    /* refresh region sizes */
+ }
  static void rna_userdef_language_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
  {
        BLF_cache_clear();
@@@ -169,12 -183,10 +175,12 @@@ static void rna_userdef_show_manipulato
                        for (sl = sa->spacedata.first; sl; sl = sl->next) {
                                if (sl->spacetype == SPACE_VIEW3D) {
                                        View3D *v3d = (View3D *)sl;
 -                                      if (userdef->tw_flag & V3D_USE_MANIPULATOR)
 -                                              v3d->twflag |= V3D_USE_MANIPULATOR;
 -                                      else
 -                                              v3d->twflag &= ~V3D_USE_MANIPULATOR;
 +                                      if (userdef->manipulator_flag & USER_MANIPULATOR_DRAW) {
 +                                              v3d->twflag |= V3D_MANIPULATOR_DRAW;
 +                                      }
 +                                      else {
 +                                              v3d->twflag &= ~V3D_MANIPULATOR_DRAW;
 +                                      }
                                }
                        }
                }
@@@ -359,7 -371,7 +365,7 @@@ static void rna_UserDef_weight_color_up
  
        for (ob = bmain->object.first; ob; ob = ob->id.next) {
                if (ob->mode & OB_MODE_WEIGHT_PAINT)
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        }
  
        rna_userdef_update(bmain, scene, ptr);
@@@ -498,7 -510,7 +504,7 @@@ static void rna_userdef_opensubdiv_upda
                if (object->derivedFinal != NULL &&
                    object->derivedFinal->type == DM_TYPE_CCGDM)
                {
 -                      DAG_id_tag_update(&object->id, OB_RECALC_OB);
 +                      DEG_id_tag_update(&object->id, OB_RECALC_OB);
                }
        }
  }
@@@ -512,6 -524,7 +518,6 @@@ static const EnumPropertyItem *rna_user
        int totitem = 0;
        EnumPropertyItem *item = NULL;
  
 -#ifdef WITH_SYSTEM_AUDASPACE
        int i;
  
        char **names = BKE_sound_get_device_names();
                EnumPropertyItem new_item = {i, names[i], 0, names[i], names[i]};
                RNA_enum_item_add(&item, &totitem, &new_item);
        }
 -#else
 -      /* NONE */
 -      RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
 -
 -#ifdef WITH_SDL
 -#  ifdef WITH_SDL_DYNLOAD
 -      if (sdlewInit() == SDLEW_SUCCESS)
 -#  endif
 -      {
 -              RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
 -      }
 -      index++;
 -#endif
 -
 -#ifdef WITH_OPENAL
 -      RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
 -#endif
 -
 -#ifdef WITH_JACK
 -      if (BKE_sound_is_jack_supported()) {
 -              RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
 -      }
 -      index++;
 -#endif
 -#endif
  
        /* may be unused */
        UNUSED_VARS(index, audio_device_items);
@@@ -850,16 -888,6 +856,16 @@@ static void rna_def_userdef_theme_ui_wc
        RNA_def_property_ui_text(prop, "Driven Selected", "");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
 +      prop = RNA_def_property(srna, "inner_overridden", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Overridden", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      prop = RNA_def_property(srna, "inner_overridden_sel", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Overridden Selected", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
        prop = RNA_def_property(srna, "blend", PROP_FLOAT, PROP_FACTOR);
        RNA_def_property_ui_text(prop, "Blend", "");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
@@@ -1071,37 -1099,6 +1077,37 @@@ static void rna_def_userdef_theme_ui(Bl
        RNA_def_property_array(prop, 3);
        RNA_def_property_ui_text(prop, "Z Axis", "");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      /* Generic manipulator colors. */
 +      prop = RNA_def_property(srna, "manipulator_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_float_sdna(prop, NULL, "manipulator_hi");
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Manipulator Highlight", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      prop = RNA_def_property(srna, "manipulator_primary", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_float_sdna(prop, NULL, "manipulator_primary");
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Manipulator Primary", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      prop = RNA_def_property(srna, "manipulator_secondary", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_float_sdna(prop, NULL, "manipulator_secondary");
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Manipulator Secondary", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      prop = RNA_def_property(srna, "manipulator_a", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_float_sdna(prop, NULL, "manipulator_a");
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Manipulator A", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +
 +      prop = RNA_def_property(srna, "manipulator_b", PROP_FLOAT, PROP_COLOR_GAMMA);
 +      RNA_def_property_float_sdna(prop, NULL, "manipulator_b");
 +      RNA_def_property_array(prop, 3);
 +      RNA_def_property_ui_text(prop, "Manipulator B", "");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
  }
  
  static void rna_def_userdef_theme_space_common(StructRNA *srna)
@@@ -1305,7 -1302,7 +1311,7 @@@ static void rna_def_userdef_theme_space
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
        prop = RNA_def_property(srna, "vertex_size", PROP_INT, PROP_NONE);
 -      RNA_def_property_range(prop, 1, 10);
 +      RNA_def_property_range(prop, 1, 32);
        RNA_def_property_ui_text(prop, "Vertex Size", "");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
@@@ -1527,7 -1524,7 +1533,7 @@@ static void rna_def_userdef_theme_space
                RNA_def_property_update(prop, 0, "rna_userdef_update");
  
                prop = RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE);
 -              RNA_def_property_range(prop, 0, 255);
 +              RNA_def_property_range(prop, 1, 100);
                RNA_def_property_ui_text(prop, "Handle Vertex Size", "");
                RNA_def_property_update(prop, 0, "rna_userdef_update");
        }
@@@ -3379,6 -3376,11 +3385,6 @@@ static void rna_def_userdef_view(Blende
        RNA_def_property_ui_text(prop, "Display Object Info", "Display objects name and frame number in 3D view");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
 -      prop = RNA_def_property(srna, "use_global_scene", PROP_BOOLEAN, PROP_NONE);
 -      RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_SCENEGLOBAL);
 -      RNA_def_property_ui_text(prop, "Global Scene", "Force the current Scene to be displayed in all Screens");
 -      RNA_def_property_update(prop, 0, "rna_userdef_update");
 -
        prop = RNA_def_property(srna, "show_large_cursors", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "curssize", 0);
        RNA_def_property_ui_text(prop, "Large Cursors", "Use large mouse cursors when available");
        RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_SPLASH_DISABLE);
        RNA_def_property_ui_text(prop, "Show Splash", "Display splash screen on startup");
  
+       prop = RNA_def_property(srna, "show_layout_ui", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_LOCK_UI_LAYOUT);
+       RNA_def_property_ui_text(prop, "Show Layout Widgets", "Show screen layout editing UI");
+       RNA_def_property_update(prop, 0, "rna_userdef_update_ui");
        prop = RNA_def_property(srna, "show_playback_fps", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_SHOW_FPS);
        RNA_def_property_ui_text(prop, "Show Playback FPS",
  
        /* 3D transform widget */
        prop = RNA_def_property(srna, "show_manipulator", PROP_BOOLEAN, PROP_NONE);
 -      RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", V3D_USE_MANIPULATOR);
 +      RNA_def_property_boolean_sdna(prop, NULL, "manipulator_flag", USER_MANIPULATOR_DRAW);
        RNA_def_property_ui_text(prop, "Manipulator", "Use 3D transform manipulator");
        RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
  
 +      prop = RNA_def_property(srna, "show_manipulator_navigate", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "manipulator_flag", USER_MANIPULATOR_DRAW_NAVIGATE);
 +      RNA_def_property_ui_text(prop, "Navigate Manipulator", "Use 3D navigation manipulator");
 +      RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
 +      
 +      /* TODO, expose once it's working. */
 +#if 0
 +      prop = RNA_def_property(srna, "show_manipulator_shaded", PROP_BOOLEAN, PROP_NONE);
 +      RNA_def_property_boolean_sdna(prop, NULL, "manipulator_flag", USER_MANIPULATOR_SHADED);
 +      RNA_def_property_ui_text(prop, "Manipulator Shaded", "Use 3D transform manipulator");
 +      RNA_def_property_update(prop, 0, "rna_userdef_update");
 +#endif
 +
        prop = RNA_def_property(srna, "manipulator_size", PROP_INT, PROP_PIXEL);
 -      RNA_def_property_int_sdna(prop, NULL, "tw_size");
 +      RNA_def_property_int_sdna(prop, NULL, "manipulator_size");
        RNA_def_property_range(prop, 10, 200);
        RNA_def_property_int_default(prop, 75);
        RNA_def_property_ui_text(prop, "Manipulator Size", "Diameter of the manipulator");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
 -      prop = RNA_def_property(srna, "manipulator_handle_size", PROP_INT, PROP_PERCENTAGE);
 -      RNA_def_property_int_sdna(prop, NULL, "tw_handlesize");
 -      RNA_def_property_range(prop, 2, 40);
 -      RNA_def_property_int_default(prop, 25);
 -      RNA_def_property_ui_text(prop, "Manipulator Handle Size", "Size of manipulator handles as percentage of the radius");
 -      RNA_def_property_update(prop, 0, "rna_userdef_update");
 -
 -      prop = RNA_def_property(srna, "manipulator_hotspot", PROP_INT, PROP_PIXEL);
 -      RNA_def_property_int_sdna(prop, NULL, "tw_hotspot");
 -      RNA_def_property_range(prop, 4, 40);
 -      RNA_def_property_int_default(prop, 14);
 -      RNA_def_property_ui_text(prop, "Manipulator Hotspot", "Distance around the handles to accept mouse clicks");
 -
        prop = RNA_def_property(srna, "object_origin_size", PROP_INT, PROP_PIXEL);
        RNA_def_property_int_sdna(prop, NULL, "obcenter_dia");
        RNA_def_property_range(prop, 4, 10);
@@@ -4216,7 -4223,6 +4227,7 @@@ static void rna_def_userdef_system(Blen
        RNA_def_property_enum_items(prop, multi_sample_levels);
        RNA_def_property_ui_text(prop, "MultiSample",
                                 "Enable OpenGL multi-sampling, only for systems that support it, requires restart");
 +      RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
  
        prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);