From 1d4778ee90de04912515100467392070c0696db9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 31 Jan 2010 23:33:04 +0000 Subject: Fix #19888: tooltip would stay visible when starting e.g. panning the view, and be stuck there permantenly when leaving the region. Now the button interaction is cancelled when starting a modal operator, not too happy about this, but couldn't think of another way to detect this well. --- .../blender/windowmanager/intern/wm_event_system.c | 99 ++++++++++++++-------- source/blender/windowmanager/wm_event_types.h | 1 + 2 files changed, 63 insertions(+), 37 deletions(-) (limited to 'source/blender/windowmanager') diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 9d7a58c457c..133038db43e 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -281,6 +281,61 @@ void wm_event_do_notifiers(bContext *C) CTX_wm_window_set(C, NULL); } +/* ********************* ui handler ******************* */ + +static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *event, int always_pass) +{ + ScrArea *area= CTX_wm_area(C); + ARegion *region= CTX_wm_region(C); + ARegion *menu= CTX_wm_menu(C); + int retval; + + /* we set context to where ui handler came from */ + if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area); + if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region); + if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); + + retval= handler->ui_handle(C, event, handler->ui_userdata); + + /* putting back screen context */ + if((retval != WM_UI_HANDLER_BREAK) || always_pass) { + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + CTX_wm_menu_set(C, menu); + } + else { + /* this special cases is for areas and regions that get removed */ + CTX_wm_area_set(C, NULL); + CTX_wm_region_set(C, NULL); + CTX_wm_menu_set(C, NULL); + } + + if(retval == WM_UI_HANDLER_BREAK) + return WM_HANDLER_BREAK; + + return WM_HANDLER_CONTINUE; +} + +static void wm_handler_ui_cancel(bContext *C) +{ + wmWindow *win= CTX_wm_window(C); + ARegion *ar= CTX_wm_region(C); + wmEventHandler *handler, *nexthandler; + + if(!ar) + return; + + for(handler= ar->handlers.first; handler; handler= nexthandler) { + nexthandler= handler->next; + + if(handler->ui_handle) { + wmEvent event= *(win->eventstate); + event.type= EVT_BUT_CANCEL; + handler->ui_handle(C, &event, handler->ui_userdata); + } + } +} + /* ********************* operators ******************* */ int WM_operator_poll(bContext *C, wmOperatorType *ot) @@ -553,6 +608,12 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P WM_cursor_grab(CTX_wm_window(C), wrap, FALSE, bounds); } + + /* cancel UI handlers, typically tooltips that can hang around + while dragging the view or worse, that stay there permanently + after the modal operator has swallowed all events and passed + none to the UI handler */ + wm_handler_ui_cancel(C); } else WM_operator_free(op); @@ -1040,42 +1101,6 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand return WM_HANDLER_BREAK; } -static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *event) -{ - ScrArea *area= CTX_wm_area(C); - ARegion *region= CTX_wm_region(C); - ARegion *menu= CTX_wm_menu(C); - int retval, always_pass; - - /* we set context to where ui handler came from */ - if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area); - if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region); - if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); - - /* in advance to avoid access to freed event on window close */ - always_pass= wm_event_always_pass(event); - - retval= handler->ui_handle(C, event, handler->ui_userdata); - - /* putting back screen context */ - if((retval != WM_UI_HANDLER_BREAK) || always_pass) { - CTX_wm_area_set(C, area); - CTX_wm_region_set(C, region); - CTX_wm_menu_set(C, menu); - } - else { - /* this special cases is for areas and regions that get removed */ - CTX_wm_area_set(C, NULL); - CTX_wm_region_set(C, NULL); - CTX_wm_menu_set(C, NULL); - } - - if(retval == WM_UI_HANDLER_BREAK) - return WM_HANDLER_BREAK; - - return WM_HANDLER_CONTINUE; -} - /* fileselect handlers are only in the window queue, so it's save to switch screens or area types */ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event) { @@ -1277,7 +1302,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } else if(handler->ui_handle) { - action |= wm_handler_ui_call(C, handler, event); + action |= wm_handler_ui_call(C, handler, event, always_pass); } else if(handler->type==WM_HANDLER_FILESELECT) { /* screen context changes here */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index be0f5abbc47..c2fe3cc8017 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -267,6 +267,7 @@ #define EVT_BUT_OPEN 0x5021 #define EVT_MODAL_MAP 0x5022 #define EVT_DROP 0x5023 +#define EVT_BUT_CANCEL 0x5024 /* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ #define GESTURE_MODAL_CANCEL 1 -- cgit v1.2.3