rename api functions...
[blender.git] / source / blender / editors / interface / interface_handlers.c
index 1ac02958bd24736dcbee5dfed82a57684ec2fcbf..dc7ea930e4505688c41073f8595c0f620d35b8c5 100644 (file)
@@ -78,6 +78,9 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+/* place the mouse at the scaled down location when un-grabbing */
+#define USE_CONT_MOUSE_CORRECT
+
 /* proto */
 static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
 static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
@@ -152,6 +155,12 @@ typedef struct uiHandleButtonData {
        float dragf, dragfstart;
        CBData *dragcbd;
 
+#ifdef USE_CONT_MOUSE_CORRECT
+       /* when ungrabbing buttons which are #ui_is_a_warp_but(), we may want to position them
+        * FLT_MAX signifies do-nothing, use #ui_block_to_window_fl() to get this into a usable space  */
+       float ungrab_mval[2];
+#endif
+
        /* menu open (watch uiFreeActiveButtons) */
        uiPopupBlockHandle *menu;
        int menuretval;
@@ -695,7 +704,9 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
        
        BLI_rcti_rctf_copy(&rect, &but->rect);
        
-       if (but->imb) ;  /* use button size itself */
+       if (but->imb) {
+               /* use button size itself */
+       }
        else if (but->flag & UI_ICON_LEFT) {
                rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect));
        }
@@ -763,7 +774,7 @@ static void ui_delete_active_linkline(uiBlock *block)
                                                                        (*(link->ppoin))[b] = (*(link->ppoin))[a];
                                                                        b++;
                                                                }
-                                                       }       
+                                                       }
                                                        (*(link->totlink))--;
                                                }
                                        }
@@ -808,6 +819,8 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
 
        uiLink *link = from->link;
 
+       PointerRNA props_ptr, object_ptr;
+       
        if (link->ppoin)
                sens_from_links = (bController ***)(link->ppoin);
        else return;
@@ -836,9 +849,15 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
 
        /* only works if the sensor and the actuator are from the same object */
        if (!act_iter) return;
+       
+       /* in case the linked controller is not the active one */
+       RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
+       
+       WM_operator_properties_create(&props_ptr, "LOGIC_OT_controller_add");
+       RNA_string_set(&props_ptr, "object", ob->id.name + 2);
 
        /* (3) add a new controller */
-       if (WM_operator_name_call(C, "LOGIC_OT_controller_add", WM_OP_EXEC_DEFAULT, NULL) & OPERATOR_FINISHED) {
+       if (WM_operator_name_call(C, "LOGIC_OT_controller_add", WM_OP_EXEC_DEFAULT, &props_ptr) & OPERATOR_FINISHED) {
                cont = (bController *)ob->controllers.last;
                cont->type = CONT_LOGIC_AND; /* Quick fix to make sure we always have an AND controller. It might be nicer to make sure the operator gives us the right one though... */
 
@@ -858,6 +877,7 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
                MEM_freeN(tmp_but->link);
                MEM_freeN(tmp_but);
        }
+       WM_operator_properties_free(&props_ptr);
 }
 
 static void ui_add_link(bContext *C, uiBut *from, uiBut *to)
@@ -1043,7 +1063,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
                        break;
                case HSVSLI:
                        break;
-               case TOG3:      
+               case TOG3:
                        ui_apply_but_TOG3(C, but, data);
                        break;
                case MENU:
@@ -1089,10 +1109,10 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
                case INLINK:
                        ui_apply_but_LINK(C, but, data);
                        break;
-               case BUT_IMAGE: 
+               case BUT_IMAGE:
                        ui_apply_but_IMAGE(C, but, data);
                        break;
-               case HISTOGRAM: 
+               case HISTOGRAM:
                        ui_apply_but_HISTOGRAM(C, but, data);
                        break;
                case WAVEFORM:
@@ -1166,7 +1186,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
        /* numeric value */
        if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) {
                
-               if (but->poin == NULL && but->rnapoin.data == NULL) ;
+               if (but->poin == NULL && but->rnapoin.data == NULL) {
+                       /* pass */
+               }
                else if (mode == 'c') {
                        ui_get_but_string(but, buf, sizeof(buf));
                        WM_clipboard_text_set(buf, 0);
@@ -1187,7 +1209,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
        else if (but->type == COLOR) {
                float rgb[3];
                
-               if (but->poin == NULL && but->rnapoin.data == NULL) ;
+               if (but->poin == NULL && but->rnapoin.data == NULL) {
+                       /* pass */
+               }
                else if (mode == 'c') {
 
                        ui_get_but_vectorf(but, rgb);
@@ -1216,7 +1240,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
        else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
                uiHandleButtonData *active_data = but->active;
 
-               if (but->poin == NULL && but->rnapoin.data == NULL) ;
+               if (but->poin == NULL && but->rnapoin.data == NULL) {
+                       /* pass */
+               }
                else if (mode == 'c') {
                        button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
                        BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR);
@@ -1317,7 +1343,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
        }
        
        /* mouse dragged outside the widget to the left */
-       if (x < startx && but->ofs > 0) {       
+       if (x < startx && but->ofs > 0) {
                int i = but->ofs;
 
                origstr[but->ofs] = 0;
@@ -1350,7 +1376,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
 
                while (TRUE) {
                        /* XXX does not take zoom level into account */
-                       cdist = startx + aspect_sqrt *BLF_width(fstyle->uifont_id, origstr + but->ofs);
+                       cdist = startx + aspect_sqrt * BLF_width(fstyle->uifont_id, origstr + but->ofs);
 
                        /* check if position is found */
                        if (cdist < x) {
@@ -1386,13 +1412,13 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
 
 static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, short x)
 {
-       if (x > data->selstartx) data->selextend = EXTEND_RIGHT;
+       if      (x > data->selstartx) data->selextend = EXTEND_RIGHT;
        else if (x < data->selstartx) data->selextend = EXTEND_LEFT;
 
        ui_textedit_set_cursor_pos(but, data, x);
 
-       if (data->selextend == EXTEND_RIGHT) but->selend = but->pos;
-       if (data->selextend == EXTEND_LEFT) but->selsta = but->pos;
+       if      (data->selextend == EXTEND_RIGHT) but->selend = but->pos;
+       else if (data->selextend == EXTEND_LEFT)  but->selsta = but->pos;
 
        ui_check_but(but);
 }
@@ -1561,7 +1587,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio
                                but->pos -= step;
                                changed = 1;
                        }
-               } 
+               }
        }
 
        return changed;
@@ -1596,6 +1622,7 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
        
        /* paste */
        if (paste) {
+               /* TODO, ensure UTF8 ui_is_but_utf8() - campbell */
                /* extract the first line from the clipboard */
                p = pbuf = WM_clipboard_text_get(0);
 
@@ -1649,7 +1676,7 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
                if (cut)
                        if ((but->selend - but->selsta) > 0)
                                changed = ui_textedit_delete_selection(but, data);
-       } 
+       }
 
        return changed;
 }
@@ -1955,8 +1982,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 
        if (changed) {
                /* only update when typing for TAB key */
-               if (update && data->interactive) ui_apply_button(C, block, but, data, 1);
-               else ui_check_but(but);
+               if (update && data->interactive) {
+                       ui_apply_button(C, block, but, data, 1);
+               }
+               else {
+                       ui_check_but(but);
+               }
                but->changed = TRUE;
                
                if (data->searchbox)
@@ -2047,8 +2078,12 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data)
 
 static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
 {
-       if (data->interactive) ui_apply_button(C, block, but, data, 1);
-       else ui_check_but(but);
+       if (data->interactive) {
+               ui_apply_button(C, block, but, data, 1);
+       }
+       else {
+               ui_check_but(but);
+       }
 
        ED_region_tag_redraw(data->region);
 }
@@ -2122,7 +2157,7 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
        }
 
        /* this makes adjacent blocks auto open from now on */
-       //if (but->block->auto_open ==) but->block->auto_open = 1;
+       //if (but->block->auto_open == 0) but->block->auto_open = 1;
 }
 
 static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
@@ -2140,6 +2175,16 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
        }
 }
 
+int ui_button_open_menu_direction(uiBut *but)
+{
+       uiHandleButtonData *data = but->active;
+
+       if (data && data->menu)
+               return data->menu->direction;
+       
+       return 0;
+}
+
 /* ***************** events for different button types *************** */
 
 static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
@@ -2209,7 +2254,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
                ED_region_tag_redraw(data->region);
                        
                if (event->val == KM_PRESS) {
-                       if (ISHOTKEY(event->type)) { 
+                       if (ISHOTKEY(event->type)) {
                                
                                if (WM_key_event_string(event->type)[0])
                                        ui_set_but_val(but, event->type);
@@ -2260,7 +2305,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 {
        if (data->state == BUTTON_STATE_HIGHLIGHT) {
                if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
-                       if (but->dt == UI_EMBOSSN && !event->ctrl) ;
+                       if (but->dt == UI_EMBOSSN && !event->ctrl) {
+                               /* pass */
+                       }
                        else {
                                button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
                                return WM_UI_HANDLER_BREAK;
@@ -2373,14 +2420,14 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
                }
 
                if (snap == 1) {
-                       if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
+                       if      (softrange < 2.10f) tempf = 0.1f  * floorf(10.0f * tempf);
                        else if (softrange < 21.0f) tempf = floorf(tempf);
-                       else tempf = 10.0f * floorf(tempf / 10.0f);
+                       else                        tempf = 10.0f * floorf(tempf / 10.0f);
                }
                else if (snap == 2) {
-                       if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
-                       else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
-                       else tempf = floor(tempf);
+                       if      (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
+                       else if (softrange < 21.0f) tempf = 0.1f  * floorf(10.0f * tempf);
+                       else                        tempf = floor(tempf);
                }
                
                if (fac != 1.0f)
@@ -2459,9 +2506,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                        }
                }
                else {
-                       if (softrange > 256) fac = 1.0;             /* 1px == 1 */
-                       else if (softrange > 32) fac = 1.0 / 2.0;   /* 2px == 1 */
-                       else fac = 1.0 / 16.0;                  /* 16px == 1? */
+                       if      (softrange > 256) fac = 1.0;        /* 1px == 1 */
+                       else if (softrange >  32) fac = 1.0 / 2.0;  /* 2px == 1 */
+                       else                      fac = 1.0 / 16.0; /* 16px == 1? */
 
                        temp = data->startvalue + (((double)mx - data->dragstartx) * (double)fac);
                        temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@@ -2493,10 +2540,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                deler = 500;
                if (!ui_is_but_float(but)) {
                        /* prevent large ranges from getting too out of control */
-                       if (softrange > 600) deler = powf(softrange, 0.75);
-                       
-                       if (softrange < 100) deler = 200.0;
-                       if (softrange < 25) deler = 50.0;
+                       if      (softrange > 600) deler = powf(softrange, 0.75);
+                       else if (softrange < 100) deler = 200.0;
+                       else if (softrange <  25) deler = 50.0;
                }
                deler /= fac;
 
@@ -2582,8 +2628,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
                                button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
                                retval = WM_UI_HANDLER_BREAK;
                        }
-                       else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS)
+                       else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
                                click = 1;
+                       }
                        else if (event->type == MINUSKEY && event->val == KM_PRESS) {
                                button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
                                data->value = -data->value;
@@ -2611,7 +2658,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
                        fac = 1.0f;
                        if (event->shift) fac /= 10.0f;
-                       if (event->alt) fac /= 20.0f;
+                       if (event->alt)   fac /= 20.0f;
                        
                        snap = (event->ctrl) ? (event->shift) ? 2 : 1 : 0;
 
@@ -2661,8 +2708,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                        }
-                       else
+                       else {
                                button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+                       }
                }
                else {
                        if (mx < (but->rect.xmin + BLI_rctf_size_x(&but->rect) / 3 - 3)) {
@@ -2683,8 +2731,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                        }
-                       else
+                       else {
                                button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+                       }
                }
 
                retval = WM_UI_HANDLER_BREAK;
@@ -2702,14 +2751,20 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
        softmax = but->softmax;
        softrange = softmax - softmin;
 
-       if (but->type == NUMSLI) deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
-       else if (but->type == HSVSLI) deler = (BLI_rctf_size_x(&but->rect) / 2.0f - 5.0f * but->aspect);
+       if (but->type == NUMSLI) {
+               deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+       }
+       else if (but->type == HSVSLI) {
+               deler = (BLI_rctf_size_x(&but->rect) / 2.0f - 5.0f * but->aspect);
+       }
        else if (but->type == SCROLL) {
                int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
                float size = (horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
                deler = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1);
        }
-       else deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+       else {
+               deler = (BLI_rctf_size_x(&but->rect) - 5.0f * but->aspect);
+       }
 
        f = (float)(mx - data->dragstartx) / deler + data->dragfstart;
        
@@ -2721,19 +2776,21 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, const short
        temp = floorf(tempf + 0.5f);
 
        if (ctrl) {
-               if (tempf == softmin || tempf == softmax) ;
+               if (tempf == softmin || tempf == softmax) {
+                       /* pass */
+               }
                else if (ui_is_but_float(but)) {
 
                        if (shift) {
-                               if (tempf == softmin || tempf == softmax) ;
+                               if      (tempf == softmin || tempf == softmax) {}
                                else if (softmax - softmin < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
-                               else if (softmax - softmin < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
-                               else tempf = floorf(tempf);
+                               else if (softmax - softmin < 21.0f) tempf = 0.1f  * floorf(10.0f * tempf);
+                               else                                tempf = floorf(tempf);
                        }
                        else {
-                               if (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
+                               if      (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
                                else if (softmax - softmin < 21.0f) tempf = floorf(tempf);
-                               else tempf = 10.0f * floorf(tempf / 10.0f);
+                               else                                tempf = 10.0f * floorf(tempf / 10.0f);
                        }
                }
                else {
@@ -2805,8 +2862,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
                                button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
                                retval = WM_UI_HANDLER_BREAK;
                        }
-                       else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS)
+                       else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
                                click = 1;
+                       }
                        else if (event->type == MINUSKEY && event->val == KM_PRESS) {
                                button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
                                data->value = -data->value;
@@ -2877,7 +2935,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
                                        data->value = temp;
                                else
                                        data->cancel = TRUE;
-                       } 
+                       }
                        else {
                                if (f < tempf) tempf -= 0.01f;
                                else tempf += 0.01f;
@@ -2903,7 +2961,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
 static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
-       int mx, my /*, click= 0 */;
+       int mx, my /*, click = 0 */;
        int retval = WM_UI_HANDLER_CONTINUE;
        int horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
        
@@ -3076,7 +3134,9 @@ static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, i
                mdx = 2.0f * mrad * fp[0] - (rad * fp[0]);
                mdy = 2.0f * mrad * fp[1] - (rad * fp[1]);
        }
-       else mdx = mdy = 0;
+       else {
+               mdx = mdy = 0;
+       }
        
        dx = (float)(mx + mdx - data->dragstartx);
        dy = (float)(my + mdy - data->dragstarty);
@@ -3140,8 +3200,9 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
                                        ui_numedit_apply(C, block, but, data);
                        }
                }
-               else if (event->type == LEFTMOUSE && event->val != KM_PRESS)
+               else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
 
                return WM_UI_HANDLER_BREAK;
        }
@@ -3160,6 +3221,15 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
        
        ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
 
+#ifdef USE_CONT_MOUSE_CORRECT
+       if (ui_is_a_warp_but(but)) {
+               /* OK but can go outside bounds */
+               data->ungrab_mval[0] = mx_fl;
+               data->ungrab_mval[1] = my_fl;
+               BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+       }
+#endif
+
        if (but->rnaprop) {
                if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
                        color_profile = FALSE;
@@ -3266,7 +3336,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF
                case UI_GRAD_V:
                        hsv[2] += ndof->ry * sensitivity;
                        break;
-               case UI_GRAD_V_ALT:     
+               case UI_GRAD_V_ALT:
                        /* vertical 'value' strip */
                        
                        /* exception only for value strip - use the range set in but->min/max */
@@ -3364,8 +3434,9 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
                                        ui_numedit_apply(C, block, but, data);
                        }
                }
-               else if (event->type == LEFTMOUSE && event->val != KM_PRESS)
+               else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
                
                return WM_UI_HANDLER_BREAK;
        }
@@ -3383,6 +3454,22 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float
        
        ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
 
+#ifdef USE_CONT_MOUSE_CORRECT
+       if (ui_is_a_warp_but(but)) {
+               /* OK but can go outside bounds */
+               data->ungrab_mval[0] = mx_fl;
+               data->ungrab_mval[1] = my_fl;
+               {       /* clamp */
+                       const float radius = min_ff(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f;
+                       const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)};
+                       const float len = len_v2v2(cent, data->ungrab_mval);
+                       if (len > radius) {
+                               dist_ensure_v2_v2fl(data->ungrab_mval, cent, radius);
+                       }
+               }
+       }
+#endif
+
        BLI_rcti_rctf_copy(&rect, &but->rect);
 
        ui_get_but_vectorf(but, rgb);
@@ -3639,8 +3726,9 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                        ui_numedit_apply(C, block, but, data);
                        }
                }
-               else if (event->type == LEFTMOUSE && event->val != KM_PRESS)
+               else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
                
                return WM_UI_HANDLER_BREAK;
        }
@@ -3659,8 +3747,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
 
        zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr);
        zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr);
-       /* offsx= cumap->curr.xmin; */
-       /* offsy= cumap->curr.ymin; */
+       /* offsx = cumap->curr.xmin; */
+       /* offsy = cumap->curr.ymin; */
 
        if (snap) {
                float d[2];
@@ -3673,9 +3761,10 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
        }
 
        if (data->dragsel != -1) {
+               CurveMapPoint *cmp_last = NULL;
                const float mval_factor = ui_mouse_scale_warp_factor(shift);
                int moved_point = 0;     /* for ctrl grid, can't use orig coords because of sorting */
-               
+
                fx = (mx - data->draglastx) / zoomx;
                fy = (my - data->draglasty) / zoomy;
 
@@ -3693,6 +3782,8 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
                                }
                                if (cmp[a].x != origx || cmp[a].y != origy)
                                        moved_point = 1;
+
+                               cmp_last = &cmp[a];
                        }
                }
 
@@ -3702,6 +3793,18 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
                        data->draglastx = mx;
                        data->draglasty = my;
                        changed = 1;
+
+#ifdef USE_CONT_MOUSE_CORRECT
+                       /* note: using 'cmp_last' is weak since there may be multiple points selected,
+                        * but in practice this isnt really an issue */
+                       if (ui_is_a_warp_but(but)) {
+                               /* OK but can go outside bounds */
+                               data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
+                               data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy);
+                               BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+                       }
+#endif
+
                }
 
                data->dragchange = 1; /* mark for selection */
@@ -3801,7 +3904,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
 
                                                changed = 1;
                                                
-                                               /* reset cmp back to the curve points again, rather than drawing segments */            
+                                               /* reset cmp back to the curve points again, rather than drawing segments */
                                                cmp = cuma->curve;
                                                
                                                /* find newly added point and make it 'sel' */
@@ -3818,12 +3921,14 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
                                /* ok, we move a point */
                                /* deselect all if this one is deselect. except if we hold shift */
                                if (event->shift == FALSE) {
-                                       for (a = 0; a < cuma->totpoint; a++)
+                                       for (a = 0; a < cuma->totpoint; a++) {
                                                cmp[a].flag &= ~CUMA_SELECT;
+                                       }
                                        cmp[sel].flag |= CUMA_SELECT;
                                }
-                               else
+                               else {
                                        cmp[sel].flag ^= CUMA_SELECT;
+                               }
                        }
                        else {
                                /* move the view */
@@ -3903,7 +4008,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
        }
        else {
                /* scale histogram values (dy / 10 for better control) */
-               const float yfac = minf(powf(hist->ymax, 2.0f), 1.0f) * 0.5f;
+               const float yfac = min_ff(powf(hist->ymax, 2.0f), 1.0f) * 0.5f;
                hist->ymax += (dy * 0.1f) * yfac;
        
                /* 0.1 allows us to see HDR colors up to 10 */
@@ -3973,7 +4078,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
        Scopes *scopes = (Scopes *)but->poin;
        /* rcti rect; */
        int changed = 1;
-       float /* dx, */ dy /* , yfac=1.f */; /* UNUSED */
+       float /* dx, */ dy /* , yfac =1.0f */; /* UNUSED */
 
        /* BLI_rcti_rctf_copy(&rect, &but->rect); */
 
@@ -4403,11 +4508,11 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
        int kmi_id;
        
        /* XXX this guess_opname can potentially return a different keymap than being found on adding later... */
-       km = WM_keymap_guess_opname(C, but->optype->idname);            
+       km = WM_keymap_guess_opname(C, but->optype->idname);
        kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
        kmi_id = kmi->id;
 
-       /* copy properties, prop can be NULL for reset */       
+       /* copy properties, prop can be NULL for reset */
        if (prop)
                prop = IDP_CopyProperty(prop);
        WM_keymap_properties_reset(kmi, prop);
@@ -4415,7 +4520,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
        /* update and get pointers again */
        WM_keyconfig_update(wm);
 
-       km = WM_keymap_guess_opname(C, but->optype->idname);            
+       km = WM_keymap_guess_opname(C, but->optype->idname);
        kmi = WM_keymap_item_find_id(km, kmi_id);
 
        RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
@@ -4466,6 +4571,7 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
 
 static int ui_but_menu(bContext *C, uiBut *but)
 {
+       ARegion *ar = CTX_wm_region(C);
        uiPopupMenu *pup;
        uiLayout *layout;
        int length;
@@ -4477,17 +4583,8 @@ static int ui_but_menu(bContext *C, uiBut *but)
        
        button_timers_tooltip_remove(C, but);
 
-#if 0
-       if (but->rnaprop)
-               name = RNA_property_ui_name(but->rnaprop);
-       else if (but->optype && but->optype->srna)
-               name = RNA_struct_ui_name(but->optype->srna);
-       else
-               name = IFACE_("<needs_name>");  // XXX - should never happen.
-#else
        uiButGetStrInfo(C, but, 1, &label);
        name = label.strinfo;
-#endif
 
        pup = uiPupMenuBegin(C, name, ICON_NONE);
        layout = uiPupMenuLayout(pup);
@@ -4531,7 +4628,9 @@ static int ui_but_menu(bContext *C, uiBut *but)
                        
                        
                }
-               else if (but->flag & UI_BUT_DRIVEN) ;
+               else if (but->flag & UI_BUT_DRIVEN) {
+                       /* pass */
+               }
                else if (is_anim) {
                        if (length) {
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
@@ -4539,9 +4638,10 @@ static int ui_but_menu(bContext *C, uiBut *but)
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
                                               ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
                        }
-                       else
+                       else {
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
                                               ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+                       }
                }
                
                if (but->flag & UI_BUT_ANIMATED) {
@@ -4567,17 +4667,21 @@ static int ui_but_menu(bContext *C, uiBut *but)
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
                                               ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
                        }
-                       else
+                       else {
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
                                               ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
+                       }
 
                        uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
                                ICON_NONE, "ANIM_OT_copy_driver_button");
-                       if (ANIM_driver_can_paste())
+                       if (ANIM_driver_can_paste()) {
                                uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
                                        ICON_NONE, "ANIM_OT_paste_driver_button");
+                       }
+               }
+               else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
+                       /* pass */
                }
-               else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) ;
                else if (is_anim) {
                        uiItemS(layout);
 
@@ -4587,13 +4691,15 @@ static int ui_but_menu(bContext *C, uiBut *but)
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single Driver"),
                                               ICON_NONE, "ANIM_OT_driver_button_add", "all", 0);
                        }
-                       else
+                       else {
                                uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
                                               ICON_NONE, "ANIM_OT_driver_button_add", "all", 0);
+                       }
 
-                       if (ANIM_driver_can_paste())
+                       if (ANIM_driver_can_paste()) {
                                uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
                                        ICON_NONE, "ANIM_OT_paste_driver_button");
+                       }
                }
                
                /* Keying Sets */
@@ -4621,8 +4727,8 @@ static int ui_but_menu(bContext *C, uiBut *but)
                
                /* Property Operators */
                
-               /*Copy Property Value
-                *Paste Property Value */
+               /* Copy Property Value
+                * Paste Property Value */
                
                if (length) {
                        uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
@@ -4630,9 +4736,10 @@ static int ui_but_menu(bContext *C, uiBut *but)
                        uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
                                       ICON_NONE, "UI_OT_reset_default_button", "all", 0);
                }
-               else
+               else {
                        uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
                                ICON_NONE, "UI_OT_reset_default_button");
+               }
                
                uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
                        ICON_NONE, "UI_OT_copy_data_path_button");
@@ -4679,7 +4786,12 @@ static int ui_but_menu(bContext *C, uiBut *but)
                uiItemS(layout);
        }
 
-       
+       /* Show header tools for header buttons. */
+       if (ar->regiontype == RGN_TYPE_HEADER) {
+               uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
+               uiItemS(layout);
+       }
+
        {   /* Docs */
                char buf[512];
                PointerRNA ptr_props;
@@ -4842,7 +4954,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                                return WM_UI_HANDLER_BREAK;
                        }
-               } 
+               }
                else if (but->pointype && but->poin == NULL) {
                        /* there's a pointer needed */
                        BKE_reportf(NULL, RPT_WARNING, "DoButton pointer error: %s", but->str);
@@ -5237,12 +5349,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
 
                /* automatic open pulldown block timer */
                if (ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) {
-                       if ((data->used_mouse == TRUE) &&
-                           (data->autoopentimer == FALSE) &&
-                           /* don't popup the first time,
-                            * see description on this member for info */
-                           (but->block->auto_is_first_event == FALSE))
-                       {
+                       if (data->used_mouse && !data->autoopentimer) {
                                int time;
 
                                if (but->block->auto_open == TRUE) {  /* test for toolbox */
@@ -5262,8 +5369,6 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
                                        data->autoopentimer = WM_event_add_timer(data->wm, data->window, TIMER, 0.02 * (double)time);
                                }
                        }
-
-                       but->block->auto_is_first_event = FALSE;
                }
        }
        else {
@@ -5287,8 +5392,24 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
        }
        else if (data->state == BUTTON_STATE_NUM_EDITING) {
                ui_numedit_end(but, data);
-               if (ui_is_a_warp_but(but))
-                       WM_cursor_grab_disable(CTX_wm_window(C));
+               if (ui_is_a_warp_but(but)) {
+
+#ifdef USE_CONT_MOUSE_CORRECT
+                       if (data->ungrab_mval[0] != FLT_MAX) {
+                               int mouse_ungrab_xy[2];
+                               ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
+                               mouse_ungrab_xy[0] = data->ungrab_mval[0];
+                               mouse_ungrab_xy[1] = data->ungrab_mval[1];
+
+                               WM_cursor_grab_disable(data->window, mouse_ungrab_xy);
+                       }
+                       else {
+                               WM_cursor_grab_disable(data->window, NULL);
+                       }
+#else
+                       WM_cursor_grab_disable(data->window, );
+#endif
+               }
        }
        /* menu open */
        if (state == BUTTON_STATE_MENU_OPEN)
@@ -5351,6 +5472,10 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
        data->window = CTX_wm_window(C);
        data->region = ar;
 
+#ifdef USE_CONT_MOUSE_CORRECT
+       copy_v2_fl(data->ungrab_mval, FLT_MAX);
+#endif
+
        if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) {
                /* XXX curve is temp */
        }
@@ -5632,20 +5757,24 @@ void uiContextAnimUpdate(const bContext *C)
                                ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
                                ED_region_tag_redraw(ar);
                                
-                               if (but->active)
+                               if (but->active) {
                                        activebut = but;
-                               else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE))
+                               }
+                               else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) {
                                        activebut = but;
+                               }
                        }
                }
 
                if (activebut) {
                        /* always recurse into opened menu, so all buttons update (like colorpicker) */
                        uiHandleButtonData *data = activebut->active;
-                       if (data && data->menu)
+                       if (data && data->menu) {
                                ar = data->menu->region;
-                       else
+                       }
+                       else {
                                return;
+                       }
                }
                else {
                        /* no active button */
@@ -5675,8 +5804,9 @@ static int ui_handle_button_over(bContext *C, wmEvent *event, ARegion *ar)
 
        if (event->type == MOUSEMOVE) {
                but = ui_but_find_mouse_over(ar, event->x, event->y);
-               if (but)
+               if (but) {
                        button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+               }
        }
        else if (event->type == EVT_BUT_OPEN) {
                but = uit_but_find_open_event(ar, event);
@@ -5897,7 +6027,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
        }
        else {
                retval = ui_do_button(C, block, but, event);
-               // retval= WM_UI_HANDLER_BREAK; XXX why ? 
+               // retval = WM_UI_HANDLER_BREAK; XXX why ?
        }
 
        if (data->state == BUTTON_STATE_EXIT) {
@@ -6179,7 +6309,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my)
        return 0;
 }
 
-static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int UNUSED(topmenu))
+static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
 {
        ARegion *ar;
        uiBlock *block;
@@ -6224,10 +6354,22 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                }
                
                /* first block own event func */
-               if (block->block_event_func && block->block_event_func(C, block, event)) ;
-               /* events not for active search menu button */
+               if (block->block_event_func && block->block_event_func(C, block, event)) {
+                       /* pass */
+               }   /* events not for active search menu button */
                else if (but == NULL || but->type != SEARCH_MENU) {
                        switch (event->type) {
+
+
+                       /* let the parent menu get the event */
+#define     PASS_EVENT_TO_PARENT_IF_NONACTIVE                                 \
+                               if ((level != 0) && (but == NULL)) {                          \
+                                       menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT;  \
+                                       BLI_assert(retval == WM_UI_HANDLER_CONTINUE);             \
+                                       break;                                                    \
+                               } (void)0
+
+
                                /* closing sublevels of pulldowns */
                                case LEFTARROWKEY:
                                        if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP))
@@ -6238,8 +6380,11 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                        break;
 
                                /* opening sublevels of pulldowns */
-                               case RIGHTARROWKEY:     
+                               case RIGHTARROWKEY:
                                        if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
+
+                                               PASS_EVENT_TO_PARENT_IF_NONACTIVE;
+
                                                but = ui_but_find_activated(ar);
 
                                                if (!but) {
@@ -6265,6 +6410,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                        }
                                        else if (inside || (block->flag & UI_BLOCK_LOOP)) {
                                                if (event->val == KM_PRESS) {
+
+                                                       PASS_EVENT_TO_PARENT_IF_NONACTIVE;
+
                                                        but = ui_but_find_activated(ar);
                                                        if (but) {
                                                                /* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
@@ -6344,6 +6492,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                        if (act == 0) act = 10;
 
                                        if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
+
+                                               PASS_EVENT_TO_PARENT_IF_NONACTIVE;
+
                                                if (event->alt) act += 10;
 
                                                count = 0;
@@ -6421,6 +6572,8 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                            (event->ctrl  == FALSE) &&
                                            (event->oskey == FALSE))
                                        {
+                                               PASS_EVENT_TO_PARENT_IF_NONACTIVE;
+
                                                for (but = block->buttons.first; but; but = but->next) {
 
                                                        if (but->menu_key == event->type) {
@@ -6468,7 +6621,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                }
                        }
 
-                       if (menu->menuretval) ;
+                       if (menu->menuretval) {
+                               /* pass */
+                       }
                        else if (event->type == ESCKEY && event->val == KM_PRESS) {
                                /* esc cancels this and all preceding menus */
                                menu->menuretval = UI_RETURN_CANCEL;
@@ -6510,6 +6665,10 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
                                                retval = WM_UI_HANDLER_BREAK;
                                }
                        }
+
+                       /* end switch */
+#undef PASS_EVENT_TO_PARENT_IF_NONACTIVE
+
                }
        }
 
@@ -6598,7 +6757,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
                return WM_UI_HANDLER_BREAK;
 }
 
-static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu)
+static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int level)
 {
        uiBut *but;
        uiHandleButtonData *data;
@@ -6611,14 +6770,24 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
        submenu = (data) ? data->menu : NULL;
 
        if (submenu)
-               retval = ui_handle_menus_recursive(C, event, submenu);
+               retval = ui_handle_menus_recursive(C, event, submenu, level + 1);
 
        /* now handle events for our own menu */
        if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
-               if (submenu && submenu->menuretval)
+               if (submenu && submenu->menuretval) {
+                       int do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT);
                        retval = ui_handle_menu_return_submenu(C, event, menu);
-               else
-                       retval = ui_handle_menu_event(C, event, menu, (submenu == NULL));
+                       submenu = NULL;  /* hint not to use this, it may be freed by call above */
+                       (void)submenu;
+                       /* we may wan't to quit the submenu and handle the even in this menu,
+                        * if its important to use it, check 'data->menu' first */
+                       if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) {
+                               retval = ui_handle_menu_event(C, event, menu, level);
+                       }
+               }
+               else {
+                       retval = ui_handle_menu_event(C, event, menu, level);  /* same as above */
+               }
        }
 
        return retval;
@@ -6706,7 +6875,7 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
                if (data->state == BUTTON_STATE_MENU_OPEN) {
                        /* handle events for menus and their buttons recursively,
                         * this will handle events from the top to the bottom menu */
-                       retval = ui_handle_menus_recursive(C, event, data->menu);
+                       retval = ui_handle_menus_recursive(C, event, data->menu, 0);
 
                        /* handle events for the activated button */
                        if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
@@ -6750,7 +6919,7 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
                retval = WM_UI_HANDLER_CONTINUE;
        }
 
-       ui_handle_menus_recursive(C, event, menu);
+       ui_handle_menus_recursive(C, event, menu, 0);
 
        /* free if done, does not free handle itself */
        if (menu->menuretval) {