Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_operators.c
index cd3bebb48ee29e535fd1ae16184b9de32b69dce5..38d122aff5fd0148f759d5e2db0f5a5e95e6f0af 100644 (file)
@@ -70,7 +70,6 @@
 #include "BKE_blender_version.h"
 #include "BKE_brush.h"
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
 #include "BKE_icons.h"
 #include "BKE_idprop.h"
 #include "BKE_image.h"
 
 #include "BKE_idcode.h"
 
-#include "BIF_glutil.h" /* for paint cursor */
 #include "BLF_api.h"
 
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
@@ -97,8 +99,6 @@
 #include "ED_util.h"
 #include "ED_view3d.h"
 
-#include "GPU_basic_shader.h"
-
 #include "RNA_access.h"
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
@@ -158,18 +158,20 @@ void WM_operatortype_iter(GHashIterator *ghi)
        BLI_ghashIterator_init(ghi, global_ops_hash);
 }
 
-/* all ops in 1 list (for time being... needs evaluation later) */
-void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
+/** \name Operator Type Append
+ * \{ */
+
+static wmOperatorType *wm_operatortype_append__begin(void)
 {
-       wmOperatorType *ot;
-       
-       ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
+       wmOperatorType *ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
        ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
        /* Set the default i18n context now, so that opfunc can redefine it if needed! */
        RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
        ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
-       opfunc(ot);
-
+       return ot;
+}
+static void wm_operatortype_append__end(wmOperatorType *ot)
+{
        if (ot->name == NULL) {
                fprintf(stderr, "ERROR: Operator %s has no name property!\n", ot->idname);
                ot->name = N_("Dummy Name");
@@ -182,22 +184,23 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
        BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
 }
 
-void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
+/* all ops in 1 list (for time being... needs evaluation later) */
+void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
 {
-       wmOperatorType *ot;
+       wmOperatorType *ot = wm_operatortype_append__begin();
+       opfunc(ot);
+       wm_operatortype_append__end(ot);
+}
 
-       ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
-       ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
-       /* Set the default i18n context now, so that opfunc can redefine it if needed! */
-       RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
-       ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
+void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
+{
+       wmOperatorType *ot = wm_operatortype_append__begin();
        opfunc(ot, userdata);
-       RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
-       RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
-
-       BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
+       wm_operatortype_append__end(ot);
 }
 
+/** \} */
+
 /* ********************* macro operator ******************** */
 
 typedef struct {
@@ -1123,46 +1126,70 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
        return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_REGION_WIN);
 }
 
+struct EnumSearchMenu {
+       wmOperator *op; /* the operator that will be executed when selecting an item */
+
+       bool use_previews;
+       short prv_cols, prv_rows;
+};
 
 /* generic enum search invoke popup */
-static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
+static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg)
 {
-       static char search[256] = "";
-       wmEvent event;
+       struct EnumSearchMenu *search_menu = arg;
        wmWindow *win = CTX_wm_window(C);
+       wmOperator *op = search_menu->op;
+       /* template_ID uses 4 * widget_unit for width, we use a bit more, some items may have a suffix to show */
+       const int width = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_cols : UI_searchbox_size_x();
+       const int height = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_rows : UI_searchbox_size_y();
+       static char search[256] = "";
        uiBlock *block;
        uiBut *but;
-       wmOperator *op = (wmOperator *)arg_op;
 
        block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
        UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
 
        search[0] = '\0';
+       BLI_assert(search_menu->use_previews || (search_menu->prv_cols == 0 && search_menu->prv_rows == 0));
 #if 0 /* ok, this isn't so easy... */
        uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 #endif
        but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
-                                 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
+                                 10, 10, width, UI_UNIT_Y, search_menu->prv_rows, search_menu->prv_cols, "");
 
        /* fake button, it holds space for search items */
-       uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
+       uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), width, height, NULL, 0, 0, 0, 0, NULL);
 
        UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
-
-       wm_event_init_from_window(win, &event);
-       event.type = EVT_BUT_OPEN;
-       event.val = KM_PRESS;
-       event.customdata = but;
-       event.customdatafree = false;
-       wm_event_add(win, &event);
+       UI_but_focus_on_enter_event(win, but);
 
        return block;
 }
 
+/**
+ * Similar to #WM_enum_search_invoke, but draws previews. Also, this can't
+ * be used as invoke callback directly since it needs additional info.
+ */
+int WM_enum_search_invoke_previews(
+        bContext *C, wmOperator *op, short prv_cols, short prv_rows)
+{
+       static struct EnumSearchMenu search_menu;
+
+       search_menu.op = op;
+       search_menu.use_previews = true;
+       search_menu.prv_cols = prv_cols;
+       search_menu.prv_rows = prv_rows;
+
+       UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
+
+       return OPERATOR_INTERFACE;
+}
 
 int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
-       UI_popup_block_invoke(C, wm_enum_search_menu, op);
+       static struct EnumSearchMenu search_menu;
+       search_menu.op = op;
+       UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
        return OPERATOR_INTERFACE;
 }
 
@@ -2089,8 +2116,11 @@ static void WM_OT_call_menu_pie(wmOperatorType *ot)
 static int wm_operator_winactive_normal(bContext *C)
 {
        wmWindow *win = CTX_wm_window(C);
+       bScreen *screen;
 
-       if (win == NULL || win->screen == NULL || win->screen->state != SCREENNORMAL)
+       if (win == NULL)
+               return 0;
+       if (!((screen = WM_window_get_active_screen(win)) && (screen->state == SCREENNORMAL)))
                return 0;
 
        return 1;
@@ -2107,14 +2137,22 @@ static void WM_OT_window_close(wmOperatorType *ot)
        ot->poll = WM_operator_winactive;
 }
 
-static void WM_OT_window_duplicate(wmOperatorType *ot)
+static void WM_OT_window_new(wmOperatorType *ot)
 {
-       ot->name = "Duplicate Window";
-       ot->idname = "WM_OT_window_duplicate";
-       ot->description = "Duplicate the current Blender window";
-               
-       ot->exec = wm_window_duplicate_exec;
+       PropertyRNA *prop;
+
+       ot->name = "New Window";
+       ot->idname = "WM_OT_window_new";
+       ot->description = "Create a new Blender window";
+
+       ot->exec = wm_window_new_exec;
+       ot->invoke = wm_window_new_invoke;
        ot->poll = wm_operator_winactive_normal;
+
+       prop = RNA_def_enum(ot->srna, "screen", DummyRNA_NULL_items, 0, "Screen", "");
+       RNA_def_enum_funcs(prop, wm_window_new_screen_itemf);
+       RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+       ot->prop = prop;
 }
 
 static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
@@ -3017,8 +3055,8 @@ static void radial_control_set_tex(RadialControl *rc)
                        if ((ibuf = BKE_brush_gen_radial_control_imbuf(rc->image_id_ptr.data, rc->use_secondary_tex))) {
                                glGenTextures(1, &rc->gltex);
                                glBindTexture(GL_TEXTURE_2D, rc->gltex);
-                               glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, ibuf->x, ibuf->y, 0,
-                                            GL_ALPHA, GL_FLOAT, ibuf->rect_float);
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ibuf->x, ibuf->y, 0,
+                                            GL_RED, GL_FLOAT, ibuf->rect_float);
                                MEM_freeN(ibuf->rect_float);
                                MEM_freeN(ibuf);
                        }
@@ -3051,43 +3089,63 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
 
                RNA_property_float_get_array(fill_ptr, fill_prop, col);
        }
-       glColor4f(col[0], col[1], col[2], alpha);
+               
+       Gwn_VertFormat *format = immVertexFormat();
+       unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 
        if (rc->gltex) {
+
+               unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
                glBindTexture(GL_TEXTURE_2D, rc->gltex);
 
-               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+               GLint swizzleMask[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
+               glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
+
+               immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR);
+
+               immUniformColor3fvAlpha(col, alpha);
+               immUniform1i("image", GL_TEXTURE0);
 
                /* set up rotation if available */
                if (rc->rot_prop) {
                        rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
-                       glPushMatrix();
-                       glRotatef(RAD2DEGF(rot), 0, 0, 1);
+                       gpuPushMatrix();
+                       gpuRotate2D(RAD2DEGF(rot));
                }
 
                /* draw textured quad */
-               GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
-               glBegin(GL_QUADS);
-               glTexCoord2f(0, 0);
-               glVertex2f(-radius, -radius);
-               glTexCoord2f(1, 0);
-               glVertex2f(radius, -radius);
-               glTexCoord2f(1, 1);
-               glVertex2f(radius, radius);
-               glTexCoord2f(0, 1);
-               glVertex2f(-radius, radius);
-               glEnd();
-               GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+               immBegin(GWN_PRIM_TRI_FAN, 4);
+
+               immAttrib2f(texCoord, 0, 0);
+               immVertex2f(pos, -radius, -radius);
+
+               immAttrib2f(texCoord, 1, 0);
+               immVertex2f(pos, radius, -radius);
+               
+               immAttrib2f(texCoord, 1, 1);
+               immVertex2f(pos, radius, radius);
+               
+               immAttrib2f(texCoord, 0, 1);
+               immVertex2f(pos, -radius, radius);
+
+               immEnd();
 
                /* undo rotation */
                if (rc->rot_prop)
-                       glPopMatrix();
+                       gpuPopMatrix();
        }
        else {
                /* flat color if no texture available */
-               glutil_draw_filled_arc(0, M_PI * 2, radius, 40);
+               immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+               immUniformColor3fvAlpha(col, alpha);
+               imm_draw_circle_fill(pos, 0.0f, 0.0f, radius, 40);
        }
+       
+       immUnbindProgram();
 }
 
 static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata)
@@ -3146,7 +3204,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
        /* Keep cursor in the original place */
        x = rc->initial_mouse[0] - ar->winrct.xmin;
        y = rc->initial_mouse[1] - ar->winrct.ymin;
-       glTranslatef((float)x, (float)y, 0.0f);
+       gpuTranslate2f((float)x, (float)y);
 
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
@@ -3154,7 +3212,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
        /* apply zoom if available */
        if (rc->zoom_prop) {
                RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
-               glScalef(zoom[0], zoom[1], 1);
+               gpuScale2fv(zoom);
        }
 
        /* draw rotated texture */
@@ -3163,24 +3221,39 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
        /* set line color */
        if (rc->col_prop)
                RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col);
-       glColor4f(col[0], col[1], col[2], 0.5);
+
+       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);
+       immUniformColor3fvAlpha(col, 0.5f);
 
        if (rc->subtype == PROP_ANGLE) {
-               glPushMatrix();
+               gpuPushMatrix();
+
                /* draw original angle line */
-               glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1);
-               fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+               gpuRotate2D(RAD2DEGF(rc->initial_value));
+               immBegin(GWN_PRIM_LINES, 2);
+               immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
+               immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+               immEnd();
+
                /* draw new angle line */
-               glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1);
-               fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
-               glPopMatrix();
+               gpuRotate2D(RAD2DEGF(rc->current_value - rc->initial_value));
+               immBegin(GWN_PRIM_LINES, 2);
+               immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
+               immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
+               immEnd();
+
+               gpuPopMatrix();
        }
 
        /* draw circles on top */
-       glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r1, 40);
-       glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r2, 40);
+       imm_draw_circle_wire(pos, 0.0f, 0.0f, r1, 40);
+       imm_draw_circle_wire(pos, 0.0f, 0.0f, r2, 40);
        if (rmin > 0.0f)
-               glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), rmin, 40);
+               imm_draw_circle_wire(pos, 0.0, 0.0f, rmin, 40);
+       immUnbindProgram();
 
        BLF_size(fontid, 1.5 * fstyle_points * U.pixelsize, U.dpi);
        BLF_enable(fontid, BLF_SHADOW);
@@ -3196,6 +3269,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
 
        glDisable(GL_BLEND);
        glDisable(GL_LINE_SMOOTH);
+
 }
 
 typedef enum {
@@ -3774,11 +3848,12 @@ static void redraw_timer_step(
                CTX_wm_window_set(C, win);  /* XXX context manipulation warning! */
        }
        else if (type == eRTDrawWindow) {
+               bScreen *screen = WM_window_get_active_screen(win);
                ScrArea *sa_iter;
 
                CTX_wm_menu_set(C, NULL);
 
-               for (sa_iter = win->screen->areabase.first; sa_iter; sa_iter = sa_iter->next) {
+               for (sa_iter = screen->areabase.first; sa_iter; sa_iter = sa_iter->next) {
                        ARegion *ar_iter;
                        CTX_wm_area_set(C, sa_iter);
 
@@ -3801,7 +3876,7 @@ static void redraw_timer_step(
        }
        else if (type == eRTAnimationStep) {
                scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1;
-               BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+               BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
        }
        else if (type == eRTAnimationPlay) {
                /* play anim, return on same frame as started with */
@@ -3813,7 +3888,7 @@ static void redraw_timer_step(
                        if (scene->r.cfra > scene->r.efra)
                                scene->r.cfra = scene->r.sfra;
 
-                       BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
+                       BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
                        redraw_timer_window_swap(C);
                }
        }
@@ -3901,28 +3976,6 @@ static void WM_OT_memory_statistics(wmOperatorType *ot)
        ot->exec = memory_statistics_exec;
 }
 
-/* ************************** memory statistics for testing ***************** */
-
-static int dependency_relations_exec(bContext *C, wmOperator *UNUSED(op))
-{
-       Main *bmain = CTX_data_main(C);
-       Scene *scene = CTX_data_scene(C);
-       Object *ob = CTX_data_active_object(C);
-
-       DAG_print_dependencies(bmain, scene, ob);
-
-       return OPERATOR_FINISHED;
-}
-
-static void WM_OT_dependency_relations(wmOperatorType *ot)
-{
-       ot->name = "Dependency Relations";
-       ot->idname = "WM_OT_dependency_relations";
-       ot->description = "Print dependency graph relations to the console";
-       
-       ot->exec = dependency_relations_exec;
-}
-
 /* *************************** Mat/tex/etc. previews generation ************* */
 
 typedef struct PreviewsIDEnsureData {
@@ -4169,12 +4222,13 @@ void wm_operatortype_init(void)
        global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
 
        WM_operatortype_append(WM_OT_window_close);
-       WM_operatortype_append(WM_OT_window_duplicate);
+       WM_operatortype_append(WM_OT_window_new);
        WM_operatortype_append(WM_OT_read_history);
        WM_operatortype_append(WM_OT_read_homefile);
        WM_operatortype_append(WM_OT_read_factory_settings);
        WM_operatortype_append(WM_OT_save_homefile);
        WM_operatortype_append(WM_OT_save_userpref);
+       WM_operatortype_append(WM_OT_save_workspace_file);
        WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
        WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
        WM_operatortype_append(WM_OT_window_fullscreen_toggle);
@@ -4191,7 +4245,6 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_save_mainfile);
        WM_operatortype_append(WM_OT_redraw_timer);
        WM_operatortype_append(WM_OT_memory_statistics);
-       WM_operatortype_append(WM_OT_dependency_relations);
        WM_operatortype_append(WM_OT_debug_menu);
        WM_operatortype_append(WM_OT_operator_defaults);
        WM_operatortype_append(WM_OT_splash);
@@ -4206,6 +4259,10 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_previews_ensure);
        WM_operatortype_append(WM_OT_previews_clear);
        WM_operatortype_append(WM_OT_doc_view_manual_ui_context);
+
+       /* manipulators */
+       WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_select);
+       WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_tweak);
 }
 
 /* circleselect-like modal operators */
@@ -4407,7 +4464,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
        wmKeyMapItem *kmi;
        
        /* note, this doesn't replace existing keymap items */
-       WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
+       WM_keymap_verify_item(keymap, "WM_OT_window_new", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
 #ifdef __APPLE__
        WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);
        WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
@@ -4511,6 +4568,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
        RNA_float_set(kmi->ptr, "value", 1.0f / 1.5f);
 #endif /* WITH_INPUT_NDOF */
 
+       wm_manipulators_keymap(keyconf);
        gesture_circle_modal_keymap(keyconf);
        gesture_border_modal_keymap(keyconf);
        gesture_zoom_border_modal_keymap(keyconf);