Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Fri, 28 Jul 2017 20:44:04 +0000 (06:44 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 28 Jul 2017 20:44:04 +0000 (06:44 +1000)
1  2 
source/blender/editors/interface/resources.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/windowmanager/intern/wm_event_system.c

index b1343ce489bac70faa53e772784bfae6c36dbcfa,4b47d0da13ee96f9fe1725426017b40ddd55eccd..274429d53900b10405693f545c71b9f4dde4b922
@@@ -53,8 -53,6 +53,8 @@@
  
  #include "BIF_gl.h"
  
 +#include "BLF_api.h"
 +
  #include "UI_interface.h"
  #include "UI_interface_icons.h"
  
@@@ -1274,35 -1272,25 +1274,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)
  {
@@@ -1401,12 -1372,6 +1401,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)
@@@ -1505,111 -1470,6 +1505,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])
  {
@@@ -1798,9 -1658,11 +1798,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) {
                        btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
                }
        }
 +      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;
 +              }
 +      }
  
        if (!USER_VERSION_ATLEAST(278, 6)) {
                /* Clear preference flags for re-use. */
                U.flag &= ~(
-                   (1 << 1) | (1 << 2) | (1 << 3) |
-                   (1 << 6) | (1 << 7) |
-                   (1 << 9) | (1 << 10));
+                   USER_FLAG_DEPRECATED_1 | USER_FLAG_DEPRECATED_2 | USER_FLAG_DEPRECATED_3 |
+                   USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 |
+                   USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10);
                U.uiflag &= ~(
-                   (1 << 7));
+                   USER_UIFLAG_DEPRECATED_7);
                U.transopts &= ~(
-                   (1 << 2) | (1 << 3) | (1 << 4) |
-                   (1 << 7));
+                   USER_TR_DEPRECATED_2 | USER_TR_DEPRECATED_3 | USER_TR_DEPRECATED_4 |
+                   USER_TR_DEPRECATED_6 | USER_TR_DEPRECATED_7);
                U.gameflags &= ~(
-                   (1 << 0) | (1 << 1) |
-                   (1 << 3) | (1 << 4));
+                   USER_GL_RENDER_DEPRECATED_0 | USER_GL_RENDER_DEPRECATED_1 |
+                   USER_GL_RENDER_DEPRECATED_3 | USER_GL_RENDER_DEPRECATED_4);
  
                U.uiflag |= USER_LOCK_CURSOR_ADJUST;
        }
index 922e72467f2f0277b8d531790996655c57661062,f0c1203004e994b3a024fa44d7745f1a806c5a16..ac1c16f1d76c6d21079cffaad05903a0d8e5fbe1
@@@ -57,6 -57,7 +57,6 @@@
  #include "BKE_brush.h"
  #include "BKE_ccg.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_image.h"
  #include "BKE_key.h"
@@@ -72,8 -73,6 +72,8 @@@
  #include "BKE_subsurf.h"
  #include "BKE_colortools.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "WM_api.h"
  #include "WM_types.h"
  
@@@ -627,7 -626,8 +627,7 @@@ static bool sculpt_get_redraw_rect(AReg
        return 1;
  }
  
 -void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
 -                                 RegionView3D *rv3d, Object *ob)
 +void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, Object *ob)
  {
        PBVH *pbvh = ob->sculpt->pbvh;
        /* copy here, original will be used below */
  
        sculpt_extend_redraw_rect_previous(ob, &rect);
  
 -      paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect);
 +      paint_calc_redraw_planes(planes, ar, ob, &rect);
  
        /* we will draw this rect, so now we can set it as the previous partial rect.
         * Note that we don't update with the union of previous/current (rect), only with
@@@ -2044,10 -2044,6 +2044,10 @@@ static void do_draw_brush(Sculpt *sd, O
        mul_v3_v3(offset, ss->cache->scale);
        mul_v3_fl(offset, bstrength);
  
 +      /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
 +       * initialize before threads so they can do curve mapping */
 +      curvemapping_initialize(brush->curve);
 +
        /* threaded loop over nodes */
        SculptThreadedTaskData data = {
            .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
@@@ -4394,13 -4390,10 +4394,13 @@@ static void sculpt_stroke_modifiers_che
        SculptSession *ss = ob->sculpt;
  
        if (ss->kb || ss->modifiers_active) {
 +              EvaluationContext eval_ctx;
                Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
                Brush *brush = BKE_paint_brush(&sd->paint);
  
 -              BKE_sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob,
 +              CTX_data_eval_ctx(C, &eval_ctx);
 +
 +              BKE_sculpt_update_mesh_elements(&eval_ctx, CTX_data_scene(C), sd, ob,
                                            sculpt_any_smooth_mode(brush, ss->cache, 0), false);
        }
  }
@@@ -4557,15 -4550,12 +4557,15 @@@ static bool sculpt_brush_stroke_init(bC
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
 +      EvaluationContext eval_ctx;
        SculptSession *ss = CTX_data_active_object(C)->sculpt;
        Brush *brush = BKE_paint_brush(&sd->paint);
        int mode = RNA_enum_get(op->ptr, "mode");
        bool is_smooth;
        bool need_mask = false;
  
 +      CTX_data_eval_ctx(C, &eval_ctx);
 +
        if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
                need_mask = true;
        }
        sculpt_brush_init_tex(scene, sd, ss);
  
        is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
 -      BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
 +      BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, is_smooth, need_mask);
  
        return 1;
  }
@@@ -4618,7 -4608,7 +4618,7 @@@ static void sculpt_flush_update(bContex
                GPU_drawobject_free(ob->derivedFinal);
  
        if (ss->kb || ss->modifiers_active) {
 -              DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +              DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                ED_region_tag_redraw(ar);
        }
        else {
                        ED_region_tag_redraw_partial(ar, &r);
                }
        }
 +
 +      /* 2.8x - avoid full mesh update! */
 +      BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
  }
  
  /* Returns whether the mouse/stylus is over the mesh (1)
@@@ -4669,8 -4656,11 +4669,11 @@@ static bool sculpt_stroke_test_start(bC
                                      const float mouse[2])
  {
        /* Don't start the stroke until mouse goes over the mesh.
-        * note: mouse will only be null when re-executing the saved stroke. */
-       if (!mouse || over_mesh(C, op, mouse[0], mouse[1])) {
+        * note: mouse will only be null when re-executing the saved stroke.
+        * We have exception for 'exec' strokes since they may not set 'mouse', only 'location', see: T52195. */
+       if (((op->flag & OP_IS_INVOKE) == 0) ||
+           (mouse == NULL) || over_mesh(C, op, mouse[0], mouse[1]))
+       {
                Object *ob = CTX_data_active_object(C);
                SculptSession *ss = ob->sculpt;
                Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@@ -4805,7 -4795,7 +4808,7 @@@ static void sculpt_stroke_done(const bC
  
                /* try to avoid calling this, only for e.g. linked duplicates now */
                if (((Mesh *)ob->data)->id.us > 1)
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
  
                WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
        }
@@@ -5001,13 -4991,10 +5004,13 @@@ void sculpt_update_after_dynamic_topolo
  {
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
 +      EvaluationContext eval_ctx;
        Sculpt *sd = scene->toolsettings->sculpt;
  
 +      CTX_data_eval_ctx(C, &eval_ctx);
 +
        /* Create the PBVH */
 -      BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false);
 +      BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, false);
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
  }
  
@@@ -5341,15 -5328,11 +5344,15 @@@ static void SCULPT_OT_symmetrize(wmOper
  
  /**** Toggle operator for turning sculpt mode on or off ****/
  
 -static void sculpt_init_session(Scene *scene, Object *ob)
 +static void sculpt_init_session(const bContext *C, Scene *scene, Object *ob)
  {
 +      EvaluationContext eval_ctx;
 +
 +      CTX_data_eval_ctx(C, &eval_ctx);
 +
        ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
  
 -      BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
 +      BKE_sculpt_update_mesh_elements(&eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
  }
  
  
@@@ -5385,7 -5368,7 +5388,7 @@@ static int sculpt_mode_toggle_exec(bCon
                 * a consistent state.
                 */
                if (true || flush_recalc || (ob->sculpt && ob->sculpt->bm)) {
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                }
  
                if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
                ob->mode |= mode_flag;
  
                if (flush_recalc)
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
  
                /* Create persistent sculpt mode data */
                if (!ts->sculpt) {
                if (ob->sculpt)
                        BKE_sculptsession_free(ob);
  
 -              sculpt_init_session(scene, ob);
 +              sculpt_init_session(C, scene, ob);
  
                /* Mask layer is required */
                if (mmd) {
index e2eb1364be294fb3540374017958a817b5d5cb14,62c1eb0b91b5cf693da6c6dca1d7fdbcb422cb7b..4aba028fbd625c1cbaf139b51c59bfaf1ed68ea1
@@@ -162,7 -162,7 +162,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;
        
@@@ -497,8 -497,7 +497,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 pad3;
        short textimeout, texcollectrate;
        short wmdrawmethod; /* eWM_DrawMethod */
        short dragthreshold;
@@@ -601,12 -600,16 +601,16 @@@ typedef enum eUserPref_Section 
  /* UserDef.flag */
  typedef enum eUserPref_Flag {
        USER_AUTOSAVE                   = (1 << 0),
-       /* 1..3 */
+       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),
-       /* 6..7 */
+       USER_FLAG_DEPRECATED_6  = (1 << 6),  /* cleared */
+       USER_FLAG_DEPRECATED_7  = (1 << 7),  /* cleared */
        USER_MAT_ON_OB                  = (1 << 8),
-       /* 9..10 */
+       USER_FLAG_DEPRECATED_9  = (1 << 9),   /* cleared */
+       USER_FLAG_DEPRECATED_10 = (1 << 10),  /* cleared */
        USER_TOOLTIPS                   = (1 << 11),
        USER_TWOBUTTONMOUSE             = (1 << 12),
        USER_NONUMPAD                   = (1 << 13),
@@@ -663,7 -666,7 +667,7 @@@ typedef enum eUserpref_UI_Flag 
        USER_DRAWVIEWINFO               = (1 << 4),
        USER_PLAINMENUS                 = (1 << 5),
        USER_LOCK_CURSOR_ADJUST = (1 << 6),
-       /* flag 7 is free  */
+       USER_UIFLAG_DEPRECATED_7        = (1 << 7),  /* cleared */
        USER_ALLWINCODECS               = (1 << 8),
        USER_MENUOPENAUTO               = (1 << 9),
        USER_ZBUF_CURSOR                = (1 << 10),
@@@ -736,10 -739,12 +740,12 @@@ typedef enum eAutokey_Flag 
  typedef enum eUserpref_Translation_Flags {
        USER_TR_TOOLTIPS                = (1 << 0),
        USER_TR_IFACE                   = (1 << 1),
-       /* 2..4 */
+       USER_TR_DEPRECATED_2    = (1 << 2),  /* cleared */
+       USER_TR_DEPRECATED_3    = (1 << 3),  /* cleared */
+       USER_TR_DEPRECATED_4    = (1 << 4),  /* cleared */
        USER_DOTRANSLATE                = (1 << 5),
-       USER_USETEXTUREFONT             = (1 << 6),
-       /* 7 */
+       USER_TR_DEPRECATED_6    = (1 << 6),  /* cleared */
+       USER_TR_DEPRECATED_7    = (1 << 7),  /* cleared */
        USER_TR_NEWDATANAME             = (1 << 8),
  } eUserpref_Translation_Flags;
  
@@@ -761,7 -766,11 +767,11 @@@ typedef enum eDupli_ID_Flags 
  
  /* UserDef.gameflags */
  typedef enum eOpenGL_RenderingOptions {
-       USER_DISABLE_MIPMAP             = (1 << 2),
+       USER_GL_RENDER_DEPRECATED_0                     = (1 << 0),
+       USER_GL_RENDER_DEPRECATED_1                     = (1 << 1),
+       USER_DISABLE_MIPMAP                                     = (1 << 2),
+       USER_GL_RENDER_DEPRECATED_3                     = (1 << 3),
+       USER_GL_RENDER_DEPRECATED_4                     = (1 << 4),
  } eOpenGL_RenderingOptions;
  
  /* selection method for opengl gpu_select_method */
@@@ -796,11 -805,6 +806,11 @@@ typedef enum eGP_UserdefSettings 
        GP_PAINT_DOSIMPLIFY             = (1 << 1),
  } eGP_UserdefSettings;
  
 +enum {
 +      USER_MANIPULATOR_DRAW        = (1 << 0),
 +      USER_MANIPULATOR_SHADED      = (1 << 1),
 +};
 +
  /* Color Picker Types.
   * UserDef.color_picker_type */
  typedef enum eColorPicker_Types {
index 6ba5fe4fabff66095c4c30d032e14cc4b537854c,f2ed79cb5ff05a0e3769c8d986c784ee891b9482..0a4e69934b7c690923110f6ead7197c1e2e7956c
@@@ -98,14 -98,13 +98,14 @@@ static EnumPropertyItem rna_enum_langua
  #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"
  
@@@ -176,12 -175,10 +176,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;
 +                                      }
                                }
                        }
                }
@@@ -366,7 -363,7 +366,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);
@@@ -505,7 -502,7 +505,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);
                }
        }
  }
@@@ -3338,6 -3335,11 +3338,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");
  
        /* 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");
  
 +      /* 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);
@@@ -3983,11 -3990,6 +3983,6 @@@ static void rna_def_userdef_system(Blen
        RNA_def_property_ui_text(prop, "Translate New Names", "Translate new data names (when adding/creating some)");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
  
-       prop = RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT);
-       RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts");
-       RNA_def_property_update(prop, 0, "rna_userdef_update");
        /* System & OpenGL */
  
        prop = RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE);
index 739f05ee9a1354a1f896455b29f7ee9e7bd59ea5,4f68e7ccccae1e35ba69be64e10893daea4582ff..b1e4b6a1d868fffc1bffc1c5ab03f1e5dda12885
@@@ -39,7 -39,6 +39,7 @@@
  #include "DNA_screen_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_windowmanager_types.h"
 +#include "DNA_workspace_types.h"
  #include "DNA_userdef_types.h"
  
  #include "MEM_guardedalloc.h"
  #include "BKE_context.h"
  #include "BKE_idprop.h"
  #include "BKE_global.h"
 +#include "BKE_layer.h"
  #include "BKE_main.h"
  #include "BKE_report.h"
  #include "BKE_scene.h"
  #include "BKE_screen.h"
 +#include "BKE_workspace.h"
  
  #include "BKE_sound.h"
  
@@@ -71,6 -68,8 +71,6 @@@
  
  #include "RNA_access.h"
  
 -#include "GPU_debug.h"
 -
  #include "UI_interface.h"
  
  #include "PIL_time.h"
@@@ -277,7 -276,6 +277,7 @@@ void wm_event_do_notifiers(bContext *C
        
        /* cache & catch WM level notifiers, such as frame change, scene/screen set */
        for (win = wm->windows.first; win; win = win->next) {
 +              Scene *scene = WM_window_get_active_scene(win);
                bool do_anim = false;
                
                CTX_wm_window_set(C, win);
                        }
                        if (note->window == win) {
                                if (note->category == NC_SCREEN) {
 -                                      if (note->data == ND_SCREENBROWSE) {
 +                                      if (note->data == ND_WORKSPACE_SET) {
 +                                              WorkSpace *ref_ws = note->reference;
 +
 +                                              UI_popup_handlers_remove_all(C, &win->modalhandlers);
 +
 +                                              ED_workspace_change(ref_ws, C, wm, win);
 +                                              if (G.debug & G_DEBUG_EVENTS)
 +                                                      printf("%s: Workspace set %p\n", __func__, note->reference);
 +                                      }
 +                                      else if (note->data == ND_LAYOUTBROWSE) {
 +                                              bScreen *ref_screen = BKE_workspace_layout_screen_get(note->reference);
 +
                                                /* free popup handlers only [#35434] */
                                                UI_popup_handlers_remove_all(C, &win->modalhandlers);
  
  
 -                                              ED_screen_set(C, note->reference);  // XXX hrms, think this over!
 +                                              ED_screen_change(C, ref_screen);  /* XXX hrms, think this over! */
                                                if (G.debug & G_DEBUG_EVENTS)
                                                        printf("%s: screen set %p\n", __func__, note->reference);
                                        }
 -                                      else if (note->data == ND_SCREENDELETE) {
 -                                              ED_screen_delete(C, note->reference);   // XXX hrms, think this over!
 +                                      else if (note->data == ND_LAYOUTDELETE) {
 +                                              WorkSpace *workspace = WM_window_get_active_workspace(win);
 +                                              WorkSpaceLayout *layout = note->reference;
 +
 +                                              ED_workspace_layout_delete(workspace, layout, C);   // XXX hrms, think this over!
                                                if (G.debug & G_DEBUG_EVENTS)
                                                        printf("%s: screen delete %p\n", __func__, note->reference);
                                        }
                        }
  
                        if (note->window == win ||
 -                          (note->window == NULL && (note->reference == NULL || note->reference == win->screen->scene)))
 +                          (note->window == NULL && (note->reference == NULL || note->reference == scene)))
                        {
                                if (note->category == NC_SCENE) {
                                        if (note->data == ND_FRAME)
                                }
                        }
                        if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) {
 -                              ED_info_stats_clear(win->screen->scene);
 +                              SceneLayer *sl = CTX_data_scene_layer(C);
 +                              ED_info_stats_clear(sl);
                                WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
                        }
                }
                        if (G.is_rendering == false) {
  
                                /* depsgraph gets called, might send more notifiers */
 -                              ED_update_for_newframe(CTX_data_main(C), win->screen->scene, 1);
 +                              ED_update_for_newframe(CTX_data_main(C), scene, 1);
                        }
                }
        }
        /* the notifiers are sent without context, to keep it clean */
        while ((note = BLI_pophead(&wm->queue))) {
                for (win = wm->windows.first; win; win = win->next) {
 -                      
 +                      Scene *scene = WM_window_get_active_scene(win);
 +                      bScreen *screen = WM_window_get_active_screen(win);
 +
                        /* filter out notifiers */
 -                      if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) {
 +                      if (note->category == NC_SCREEN &&
 +                          note->reference &&
 +                          note->reference != screen &&
 +                          note->reference != WM_window_get_active_workspace(win) &&
 +                          note->reference != WM_window_get_active_layout(win))
 +                      {
                                /* pass */
                        }
 -                      else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) {
 +                      else if (note->category == NC_SCENE && note->reference && note->reference != scene) {
                                /* pass */
                        }
                        else {
                                /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name + 2, note->category); */
                                ED_screen_do_listen(C, note);
  
 -                              for (ar = win->screen->regionbase.first; ar; ar = ar->next) {
 -                                      ED_region_do_listen(win->screen, NULL, ar, note);
 +                              for (ar = screen->regionbase.first; ar; ar = ar->next) {
 +                                      ED_region_do_listen(screen, NULL, ar, note, scene);
                                }
                                
 -                              for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 -                                      ED_area_do_listen(win->screen, sa, note);
 +                              for (sa = screen->areabase.first; sa; sa = sa->next) {
 +                                      ED_area_do_listen(screen, sa, note, scene);
                                        for (ar = sa->regionbase.first; ar; ar = ar->next) {
 -                                              ED_region_do_listen(win->screen, sa, ar, note);
 +                                              ED_region_do_listen(screen, sa, ar, note, scene);
                                        }
                                }
                        }
                
                MEM_freeN(note);
        }
 -      
 +
        /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */
        for (win = wm->windows.first; win; win = win->next) {
 -              win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen);
 +              const Scene *scene = WM_window_get_active_scene(win);
 +              const bScreen *screen = WM_window_get_active_screen(win);
 +
 +              win_combine_v3d_datamask |= ED_view3d_screen_datamask(scene, screen);
        }
  
        /* cached: editor refresh callbacks now, they get context */
        for (win = wm->windows.first; win; win = win->next) {
 +              const bScreen *screen = WM_window_get_active_screen(win);
 +              Scene *scene = WM_window_get_active_scene(win);
                ScrArea *sa;
                
                CTX_wm_window_set(C, win);
 -              for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 +              for (sa = screen->areabase.first; sa; sa = sa->next) {
                        if (sa->do_refresh) {
                                CTX_wm_area_set(C, sa);
                                ED_area_do_refresh(C, sa);
                        Main *bmain = CTX_data_main(C);
  
                        /* copied to set's in scene_update_tagged_recursive() */
 -                      win->screen->scene->customdata_mask = win_combine_v3d_datamask;
 +                      scene->customdata_mask = win_combine_v3d_datamask;
  
                        /* XXX, hack so operators can enforce datamasks [#26482], gl render */
 -                      win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal;
 +                      scene->customdata_mask |= scene->customdata_mask_modal;
  
 -                      BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene);
 +                      BKE_scene_update_tagged(bmain->eval_ctx, bmain, scene);
                }
        }
  
@@@ -1118,6 -1089,9 +1118,9 @@@ bool WM_operator_last_properties_store(
  
  #endif
  
+ /**
+  * Also used for exec when 'event' is NULL.
+  */
  static int wm_operator_invoke(
          bContext *C, wmOperatorType *ot, wmEvent *event,
          PointerRNA *properties, ReportList *reports, const bool poll_only)
                wmOperator *op = wm_operator_create(wm, ot, properties, reports); /* if reports == NULL, they'll be initialized */
                const bool is_nested_call = (wm->op_undo_depth != 0);
                
-               op->flag |= OP_IS_INVOKE;
+               if (event != NULL) {
+                       op->flag |= OP_IS_INVOKE;
+               }
  
                /* initialize setting from previous run */
                if (!is_nested_call) { /* not called by py script */
@@@ -1584,36 -1560,6 +1589,36 @@@ int WM_userdef_event_map(int kmitype
        return kmitype;
  }
  
 +/**
 + * Use so we can check if 'wmEvent.type' is released in modal operators.
 + *
 + * An alternative would be to add a 'wmEvent.type_nokeymap'... or similar.
 + */
 +int WM_userdef_event_type_from_keymap_type(int kmitype)
 +{
 +      switch (kmitype) {
 +              case SELECTMOUSE:
 +                      return (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE;
 +              case ACTIONMOUSE:
 +                      return (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE;
 +              case EVT_TWEAK_S:
 +                      return (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE;
 +              case EVT_TWEAK_A:
 +                      return (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE;
 +              case EVT_TWEAK_L:
 +                      return LEFTMOUSE;
 +              case EVT_TWEAK_M:
 +                      return MIDDLEMOUSE;
 +              case EVT_TWEAK_R:
 +                      return RIGHTMOUSE;
 +              case WHEELOUTMOUSE:
 +                      return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELUPMOUSE : WHEELDOWNMOUSE;
 +              case WHEELINMOUSE:
 +                      return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELDOWNMOUSE : WHEELUPMOUSE;
 +      }
 +
 +      return kmitype;
 +}
  
  static int wm_eventmatch(const wmEvent *winevent, wmKeyMapItem *kmi)
  {
@@@ -1762,7 -1708,7 +1767,7 @@@ static int wm_handler_operator_call(bCo
                        wm_handler_op_context(C, handler, event);
                        wm_region_mouse_co(C, event);
                        wm_event_modalkeymap(C, op, event, &dbl_click_disabled);
 -                      
 +
                        if (ot->flag & OPTYPE_UNDO)
                                wm->op_undo_depth++;
  
                                        CTX_wm_region_set(C, NULL);
                                }
  
 +                              /* update manipulators during modal handlers */
 +                              wm_manipulatormaps_handled_modal_update(C, event, handler);
 +
                                /* remove modal handler, operator itself should have been canceled and freed */
                                if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
                                        WM_cursor_grab_disable(CTX_wm_window(C), NULL);
@@@ -2186,133 -2129,6 +2191,133 @@@ static int wm_handlers_do_intern(bConte
                                        }
                                }
                        }
 +                      else if (handler->manipulator_map) {
 +                              ScrArea *area = CTX_wm_area(C);
 +                              ARegion *region = CTX_wm_region(C);
 +                              wmManipulatorMap *mmap = handler->manipulator_map;
 +                              wmManipulator *mpr = wm_manipulatormap_highlight_get(mmap);
 +
 +                              wm_manipulatormap_handler_context(C, handler);
 +                              wm_region_mouse_co(C, event);
 +
 +                              /* handle manipulator highlighting */
 +                              if (event->type == MOUSEMOVE && !wm_manipulatormap_modal_get(mmap)) {
 +                                      int part;
 +                                      mpr = wm_manipulatormap_highlight_find(mmap, C, event, &part);
 +                                      wm_manipulatormap_highlight_set(mmap, C, mpr, part);
 +                              }
 +                              /* handle user configurable manipulator-map keymap */
 +                              else {
 +                                      /* Either we operate on a single highlighted item
 +                                       * or groups attached to the selected manipulators.
 +                                       * To simplify things both cases loop over an array of items. */
 +                                      wmManipulatorGroup *mgroup_first;
 +                                      bool is_mgroup_single;
 +
 +                                      if (ISMOUSE(event->type)) {
 +                                              /* Keep mpr set as-is, just fake single selection. */
 +                                              if (mpr) {
 +                                                      mgroup_first = mpr->parent_mgroup;
 +                                              }
 +                                              else {
 +                                                      mgroup_first = NULL;
 +                                              }
 +                                              is_mgroup_single = true;
 +                                      }
 +                                      else {
 +                                              if (WM_manipulatormap_is_any_selected(mmap)) {
 +                                                      const ListBase *groups = WM_manipulatormap_group_list(mmap);
 +                                                      mgroup_first = groups->first;
 +                                              }
 +                                              else {
 +                                                      mgroup_first = NULL;
 +                                              }
 +                                              is_mgroup_single = false;
 +                                      }
 +
 +                                      /* Don't use from now on. */
 +                                      mpr = NULL;
 +
 +                                      for (wmManipulatorGroup *mgroup = mgroup_first; mgroup; mgroup = mgroup->next) {
 +                                              /* get user customized keymap from default one */
 +
 +                                              if ((is_mgroup_single == false) &&
 +                                                  /* We might want to change the logic here and use some kind of manipulator edit-mode.
 +                                                   * For now just use keymap when a selection exists. */
 +                                                  wm_manipulatorgroup_is_any_selected(mgroup) == false)
 +                                              {
 +                                                      continue;
 +                                              }
 +
 +                                              const wmKeyMap *keymap = WM_keymap_active(wm, mgroup->type->keymap);
 +                                              wmKeyMapItem *kmi;
 +
 +                                              PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
 +
 +                                              if (!keymap->poll || keymap->poll(C)) {
 +                                                      PRINT("pass\n");
 +                                                      for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
 +                                                              if (wm_eventmatch(event, kmi)) {
 +                                                                      wmOperator *op = handler->op;
 +
 +                                                                      PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
 +
 +                                                                      /* weak, but allows interactive callback to not use rawkey */
 +                                                                      event->keymap_idname = kmi->idname;
 +
 +                                                                      CTX_wm_manipulator_group_set(C, mgroup);
 +
 +                                                                      /* handler->op is called later, we want keymap op to be triggered here */
 +                                                                      handler->op = NULL;
 +                                                                      action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
 +                                                                      handler->op = op;
 +
 +                                                                      CTX_wm_manipulator_group_set(C, NULL);
 +
 +                                                                      if (action & WM_HANDLER_BREAK) {
 +                                                                              if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
 +                                                                                      printf("%s:       handled - and pass on! '%s'\n",
 +                                                                                             __func__, kmi->idname);
 +                                                                              }
 +                                                                              break;
 +                                                                      }
 +                                                                      else {
 +                                                                              if (action & WM_HANDLER_HANDLED) {
 +                                                                                      if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
 +                                                                                              printf("%s:       handled - and pass on! '%s'\n",
 +                                                                                                     __func__, kmi->idname);
 +                                                                                      }
 +                                                                              }
 +                                                                              else {
 +                                                                                      PRINT("%s:       un-handled '%s'\n",
 +                                                                                            __func__, kmi->idname);
 +                                                                              }
 +                                                                      }
 +                                                              }
 +                                                      }
 +                                              }
 +                                              else {
 +                                                      PRINT("fail\n");
 +                                              }
 +
 +                                              if (action & WM_HANDLER_BREAK) {
 +                                                      break;
 +                                              }
 +
 +                                              if (is_mgroup_single) {
 +                                                      break;
 +                                              }
 +                                      }
 +                              }
 +
 +                              /* restore the area */
 +                              CTX_wm_area_set(C, area);
 +                              CTX_wm_region_set(C, region);
 +
 +                              if (handler->op) {
 +                                      action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
 +                              }
 +                      }
                        else {
                                /* modal, swallows all */
                                action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
@@@ -2486,19 -2302,17 +2491,19 @@@ static void wm_paintcursor_test(bContex
  
  static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *event)
  {
 +      bScreen *screen = WM_window_get_active_screen(win);
 +
        if (BLI_listbase_is_empty(&wm->drags)) {
                return;
        }
        
        if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) {
 -              win->screen->do_draw_drag = true;
 +              screen->do_draw_drag = true;
        }
        else if (event->type == ESCKEY) {
                WM_drag_free_list(&wm->drags);
  
 -              win->screen->do_draw_drag = true;
 +              screen->do_draw_drag = true;
        }
        else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
                event->type = EVT_DROP;
                event->customdatafree = 1;
                
                /* clear drop icon */
 -              win->screen->do_draw_drag = true;
 +              screen->do_draw_drag = true;
                
                /* restore cursor (disabled, see wm_dragdrop.c) */
                // WM_cursor_modal_restore(win);
        }
        
        /* overlap fails otherwise */
 -      if (win->screen->do_draw_drag)
 +      if (screen->do_draw_drag)
                if (win->drawmethod == USER_DRAW_OVERLAP)
 -                      win->screen->do_draw = true;
 +                      screen->do_draw = true;
        
  }
  
@@@ -2553,28 -2367,22 +2558,28 @@@ void wm_event_do_handlers(bContext *C
  
        /* update key configuration before handling events */
        WM_keyconfig_update(wm);
 +      WM_manipulatorconfig_update(CTX_data_main(C));
  
        for (win = wm->windows.first; win; win = win->next) {
 +              bScreen *screen = WM_window_get_active_screen(win);
                wmEvent *event;
 -              
 -              if (win->screen == NULL)
 +
 +              /* some safty checks - these should always be set! */
 +              BLI_assert(WM_window_get_active_scene(win));
 +              BLI_assert(WM_window_get_active_screen(win));
 +              BLI_assert(WM_window_get_active_workspace(win));
 +
 +              if (screen == NULL)
                        wm_event_free_all(win);
                else {
 -                      Scene *scene = win->screen->scene;
 +                      Scene *scene = WM_window_get_active_scene(win);
                        
                        if (scene) {
 -                              int is_playing_sound = BKE_sound_scene_playing(win->screen->scene);
 +                              int is_playing_sound = BKE_sound_scene_playing(scene);
                                
                                if (is_playing_sound != -1) {
                                        bool is_playing_screen;
                                        CTX_wm_window_set(C, win);
 -                                      CTX_wm_screen_set(C, win->screen);
                                        CTX_data_scene_set(C, scene);
                                        
                                        is_playing_screen = (ED_screen_animation_playing(wm) != NULL);
                while ( (event = win->queue.first) ) {
                        int action = WM_HANDLER_CONTINUE;
  
 +                      /* active screen might change during handlers, update pointer */
 +                      screen = WM_window_get_active_screen(win);
 +
                        if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
                                printf("\n%s: Handling event\n", __func__);
                                WM_event_print(event);
                                }
  #endif
  
 -                              for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 +                              for (sa = screen->areabase.first; sa; sa = sa->next) {
                                        /* after restoring a screen from SCREENMAXIMIZED we have to wait
                                         * with the screen handling till the region coordinates are updated */
 -                                      if (win->screen->skip_handling == true) {
 +                                      if (screen->skip_handling == true) {
                                                /* restore for the next iteration of wm_event_do_handlers */
 -                                              win->screen->skip_handling = false;
 +                                              screen->skip_handling = false;
                                                break;
                                        }
  
  
        /* update key configuration after handling events */
        WM_keyconfig_update(wm);
 -
 -      GPU_ASSERT_NO_GL_ERRORS("wm_event_do_handlers");
 +      WM_manipulatorconfig_update(CTX_data_main(C));
  }
  
  /* ********** filesector handling ************ */
@@@ -2879,34 -2685,6 +2884,34 @@@ wmEventHandler *WM_event_add_modal_hand
        return handler;
  }
  
 +/**
 + * Modal handlers store a pointer to an area which might be freed while the handler runs.
 + * Use this function to NULL all handler pointers to \a old_area.
 + */
 +void WM_event_modal_handler_area_replace(wmWindow *win, const ScrArea *old_area, ScrArea *new_area)
 +{
 +      for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
 +              /* fileselect handler is quite special... it needs to keep old area stored in handler, so don't change it */
 +              if ((handler->op_area == old_area) && (handler->type != WM_HANDLER_FILESELECT)) {
 +                      handler->op_area = new_area;
 +              }
 +      }
 +}
 +
 +/**
 + * Modal handlers store a pointer to a region which might be freed while the handler runs.
 + * Use this function to NULL all handler pointers to \a old_region.
 + */
 +void WM_event_modal_handler_region_replace(wmWindow *win, const ARegion *old_region, ARegion *new_region)
 +{
 +      for (wmEventHandler *handler = win->modalhandlers.first; handler; handler = handler->next) {
 +              if (handler->op_region == old_region) {
 +                      handler->op_region = new_region;
 +                      handler->op_region_type = new_region ? new_region->regiontype : RGN_TYPE_WINDOW;
 +              }
 +      }
 +}
 +
  wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
  {
        wmEventHandler *handler;