diff options
18 files changed, 148 insertions, 181 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 7975e357938..266a387732e 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -127,6 +127,11 @@ void BKE_screen_area_free(ScrArea *sa) void free_screen(bScreen *sc) { ScrArea *sa; + ARegion *ar; + + for(ar=sc->regionbase.first; ar; ar=ar->next) + BKE_area_region_free(ar); + BLI_freelistN(&sc->regionbase); for(sa= sc->areabase.first; sa; sa= sa->next) BKE_screen_area_free(sa); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 097c654de51..70e06627449 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3780,7 +3780,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->queue.first= win->queue.last= NULL; win->handlers.first= win->handlers.last= NULL; - win->modalops.first= win->modalops.last= NULL; win->subwindows.first= win->subwindows.last= NULL; } @@ -4207,7 +4206,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) link_list(fd, &(sa->regionbase)); sa->handlers.first= sa->handlers.last= NULL; - sa->modalops.first= sa->modalops.last= NULL; sa->uiblocks.first= sa->uiblocks.last= NULL; sa->type= NULL; /* spacetype callbacks */ @@ -4287,7 +4285,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) for(ar= sa->regionbase.first; ar; ar= ar->next) { ar->handlers.first= ar->handlers.last= NULL; - ar->modalops.first= ar->modalops.last= NULL; ar->uiblocks.first= ar->uiblocks.last= NULL; ar->regiondata= NULL; ar->swinid= 0; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 90f888e652d..2d515aafc13 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -2627,13 +2627,15 @@ static void button_activate_state(bContext *C, uiBut *but, uiActivateButState st ui_blockopen_begin(C, but, data); /* note we move the handler to the region when the block is open, * so we don't interfere with the events as long as it's open */ - WM_event_remove_modal_handler(&C->window->handlers, data->operator); - WM_event_add_modal_handler(&data->region->handlers, data->operator); + /* XXX (to brecht) removing this makes thing work proper */ + //WM_event_remove_modal_handler(&C->window->handlers, data->operator); + //WM_event_add_modal_handler(C, &data->region->handlers, data->operator); } else if(data->state == BUTTON_STATE_BLOCK_OPEN) { ui_blockopen_end(C, but, data); - WM_event_remove_modal_handler(&data->region->handlers, data->operator); - WM_event_add_modal_handler(&C->window->handlers, data->operator); + /* XXX (to brecht) removing this makes thing work proper */ + //WM_event_remove_modal_handler(&data->region->handlers, data->operator); + //WM_event_add_modal_handler(C, &C->window->handlers, data->operator); } if(state == BUTTON_STATE_WAIT_FLASH) { @@ -2673,9 +2675,9 @@ static void button_activate_init(bContext *C, ARegion *ar, wmOperator *op, uiBut if(!lastbut && but->block->auto_open) if(but->block->auto_open_last+BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer()) but->block->auto_open= 0; - + /* modal handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); @@ -2708,10 +2710,7 @@ static void button_activate_exit(bContext *C, uiActivateBut *data, wmOperator *o if(data->state == BUTTON_STATE_BLOCK_OPEN) { ui_blockopen_end(C, but, data); - WM_event_remove_modal_handler(&data->region->handlers, data->operator); } - else - WM_event_remove_modal_handler(&C->window->handlers, op); if(but) { /* if someone is expecting a message */ @@ -2792,7 +2791,7 @@ static int button_activate_try_exit(bContext *C, wmOperator *op, wmEvent *event) ARegion *ar; uiActivateBut *data; uiBut *but; - int state; + int state= OPERATOR_FINISHED; data= op->customdata; ar= data->region; @@ -2801,7 +2800,8 @@ static int button_activate_try_exit(bContext *C, wmOperator *op, wmEvent *event) /* exit the current button, but try to re-init as well */ button_activate_exit(C, op->customdata, op); - state= button_activate_try_init(C, ar, op, event, but); + /* XXX re-init has to be done differently... */ + /* XXX state= button_activate_try_init(C, ar, op, event, but); */ return (state != OPERATOR_RUNNING_MODAL); } @@ -2830,7 +2830,10 @@ static int button_activate_modal(bContext *C, wmOperator *op, wmEvent *event) int handled= 0; data= op->customdata; - + /* XXX (for brecht) this happens when cancel() frees, and modal handler still runs */ + if(data==NULL) + return OPERATOR_FINISHED; + /* check if the button dissappeared somehow */ if(!(but= ui_but_find_activated(data->region, data, &block))) { data->cancel= 1; @@ -3031,7 +3034,6 @@ static int menu_block_handle_cancel(bContext *C, wmOperator *op) if(op->customdata) { MEM_freeN(op->customdata); op->customdata= NULL; - WM_event_remove_modal_handler(&C->window->handlers, op); } return OPERATOR_CANCELLED; @@ -3057,7 +3059,7 @@ static int menu_block_handle_invoke(bContext *C, wmOperator *op, wmEvent *event) handle->region= C->region; op->customdata= handle; - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH; } @@ -3077,13 +3079,25 @@ static int menu_block_handle_block_open(uiBlock *block) return 0; } +#include "wm_event_system.h" +static void testing123(bContext *C) +{ + wmEventHandler *handler; + + for(handler= C->window->handlers.first; handler; handler= handler->next) { + if(handler->op) + printf("handler has op %s\n", handler->op->type->idname); + } +} + +/* moves focus on button/menu from mousemove-based to hotkey */ static void menu_block_handle_activate_button(bContext *C, wmEvent *event, ARegion *butregion, uiBut *but, int activateflag) { wmOperatorType *ot; ot= WM_operatortype_find("ED_UI_OT_button_activate"); - - WM_operator_cancel(C, &butregion->modalops, ot); + testing123(C); +// XXX WM_operator_cancel(C, &butregion->modalops, ot); but->activateflag= activateflag; SWAP(ARegion*, C->region, butregion); /* XXX 2.50 bad state manipulation? */ @@ -3173,6 +3187,10 @@ static int menu_block_handle_modal(bContext *C, wmOperator *op, wmEvent *event) int inside, act, count, mx, my, handled; bhandle= op->customdata; + /* XXX (for brecht) this happens when cancel() frees, and modal handler still runs */ + if(bhandle==NULL) + return OPERATOR_FINISHED; + ar= bhandle->region; block= ar->uiblocks.first; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 2ddbaeeb79b..9e6a9a6dada 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -184,7 +184,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) #endif // XXX - enable this when cursors are working properly /* add temp handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); return OPERATOR_RUNNING_MODAL; } @@ -216,7 +216,6 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) view_pan_exit(C, op); //WM_set_cursor(C, CURSOR_STD); // XXX - enable this when cursors are working properly - WM_event_remove_modal_handler(&C->window->handlers, op); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 742022ea370..31ac5d63835 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -268,8 +268,8 @@ static short testsplitpoint(wmWindow *win, ScrArea *sa, char dir, float fac) short x, y; // area big enough? - if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0; - if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0; + if(dir=='v' && (sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX)) return 0; + if(dir=='h' && (sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY)) return 0; // to be sure if(fac<0.0) fac= 0.0; @@ -305,7 +305,7 @@ ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac ScrVert *sv1, *sv2; short split; - if(sa==0) return NULL; + if(sa==NULL) return NULL; split= testsplitpoint(win, sa, dir, fac); if(split==0) return NULL; @@ -920,8 +920,7 @@ void ED_screens_initialize(wmWindowManager *wm) void ED_region_exit(bContext *C, ARegion *ar) { - WM_operator_cancel(C, &ar->modalops, NULL); - WM_event_remove_handlers(&ar->handlers); + WM_event_remove_handlers(C, &ar->handlers); } void ED_area_exit(bContext *C, ScrArea *sa) @@ -931,8 +930,7 @@ void ED_area_exit(bContext *C, ScrArea *sa) for(ar= sa->regionbase.first; ar; ar= ar->next) ED_region_exit(C, ar); - WM_operator_cancel(C, &sa->modalops, NULL); - WM_event_remove_handlers(&sa->handlers); + WM_event_remove_handlers(C, &sa->handlers); } void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) @@ -946,8 +944,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) for(sa= screen->areabase.first; sa; sa= sa->next) ED_area_exit(C, sa); - WM_operator_cancel(C, &window->modalops, NULL); - WM_event_remove_handlers(&window->handlers); + WM_event_remove_handlers(C, &window->handlers); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 4c7a98e97c3..095f6e1a74b 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -125,7 +125,7 @@ static AZone *is_in_area_actionzone(ScrArea *sa, int x, int y) int i= 0; for(az= sa->actionzones.first, i= 0; az; az= az->next, i++) { - if(az && az->type == AZONE_TRI) { + if(az->type == AZONE_TRI) { if(IsPointInTri2DInts(az->x1, az->y1, az->x2, az->y2, x, y)) break; } @@ -154,7 +154,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event) sad->x= event->x; sad->y= event->y; /* add modal handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); return OPERATOR_RUNNING_MODAL; } @@ -209,15 +209,12 @@ static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event) actionzone_apply(C, op); actionzone_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); - return OPERATOR_FINISHED; } break; case ESCKEY: case LEFTMOUSE: actionzone_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); return OPERATOR_CANCELLED; } @@ -560,14 +557,13 @@ static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; /* add temp handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); return OPERATOR_RUNNING_MODAL; } static int area_move_cancel(bContext *C, wmOperator *op) { - WM_event_remove_modal_handler(&C->window->handlers, op); RNA_int_set(op->ptr, "delta", 0); area_move_apply(C, op); @@ -599,7 +595,6 @@ static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: if(event->val==0) { area_move_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); return OPERATOR_FINISHED; } break; @@ -740,8 +735,8 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb) } -/* do the split */ -static void area_split_apply(bContext *C, wmOperator *op) +/* do the split, return success */ +static int area_split_apply(bContext *C, wmOperator *op) { sAreaSplitData *sd= (sAreaSplitData *)op->customdata; float fac; @@ -767,10 +762,12 @@ static void area_split_apply(bContext *C, wmOperator *op) if(dir=='h') sd->origval= sd->nedge->v1->vec.y; else sd->origval= sd->nedge->v1->vec.x; + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + + return 1; } - WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); - + return 0; } static void area_split_exit(bContext *C, wmOperator *op) @@ -826,13 +823,14 @@ static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event) sd->y= event->y; /* do the split */ - area_split_apply(C, op); - area_move_set_limits(C->screen, dir, &sd->bigger, &sd->smaller); - - /* add temp handler for edge move or cancel */ - WM_event_add_modal_handler(&C->window->handlers, op); - - return OPERATOR_RUNNING_MODAL; + if(area_split_apply(C, op)) { + area_move_set_limits(C->screen, dir, &sd->bigger, &sd->smaller); + + /* add temp handler for edge move or cancel */ + WM_event_add_modal_handler(C, &C->window->handlers, op); + + return OPERATOR_RUNNING_MODAL; + } } else { @@ -861,8 +859,6 @@ static int area_split_cancel(bContext *C, wmOperator *op) { sAreaSplitData *sd= (sAreaSplitData *)op->customdata; - WM_event_remove_modal_handler(&C->window->handlers, op); - if (screen_area_join(C->screen,sd->sarea, sd->narea)) { if (C->area == sd->narea) { C->area = NULL; @@ -893,7 +889,6 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: if(event->val==0) { /* mouse up */ area_split_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); return OPERATOR_FINISHED; } break; @@ -1070,7 +1065,7 @@ static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; /* add temp handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); return OPERATOR_RUNNING_MODAL; } @@ -1092,7 +1087,6 @@ static int area_join_cancel(bContext *C, wmOperator *op) } WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL); - WM_event_remove_modal_handler(&C->window->handlers, op); area_join_exit(C, op); @@ -1174,7 +1168,6 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event) area_join_apply(C, op); WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); area_join_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); return OPERATOR_FINISHED; } break; diff --git a/source/blender/editors/space_time/ed_markers.c b/source/blender/editors/space_time/ed_markers.c index 83ede869360..1829435bf8d 100644 --- a/source/blender/editors/space_time/ed_markers.c +++ b/source/blender/editors/space_time/ed_markers.c @@ -297,7 +297,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt) mm->event_type= evt->type; /* add temp handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); /* reset frs delta */ RNA_int_set(op->ptr, "frs", 0); @@ -333,7 +333,6 @@ static void ed_marker_move_cancel(bContext *C, wmOperator *op) ed_marker_move_apply(C, op); ed_marker_move_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); WM_event_add_notifier(C->wm, C->window, mm->swinid, WM_NOTE_AREA_REDRAW, 0, NULL); } @@ -376,7 +375,6 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) case RIGHTMOUSE: if(WM_modal_tweak_check(evt, mm->event_type)) { ed_marker_move_exit(C, op); - WM_event_remove_modal_handler(&C->window->handlers, op); WM_event_add_notifier(C->wm, C->window, mm->swinid, WM_NOTE_AREA_REDRAW, 0, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index bc30d07f878..27e89422f98 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -126,7 +126,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) change_frame_apply(C, op); /* add temp handler */ - WM_event_add_modal_handler(&C->region->handlers, op); // XXX should be for window, but we crash otherwise + WM_event_add_modal_handler(C, &C->region->handlers, op);// XXX should be for window, but we crash otherwise return OPERATOR_RUNNING_MODAL; } @@ -149,7 +149,6 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: if(event->val==0) { change_frame_exit(C, op); - WM_event_remove_modal_handler(&C->region->handlers, op); // XXX should be for window, but we crash otherwise return OPERATOR_FINISHED; } break; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 28ec73a00d1..2cce4d398b9 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -75,18 +75,6 @@ typedef struct ScrEdge { int pad; } ScrEdge; -#ifndef DNA_USHORT_FIX -#define DNA_USHORT_FIX -/** - * @deprecated This typedef serves to avoid badly typed functions when - * @deprecated compiling while delivering a proper dna.c. Do not use - * @deprecated it in any case. - */ -/*typedef unsigned short dna_ushort_fix;*/ -#endif - - - typedef struct Panel { /* the part from uiBlock that needs saved in file */ struct Panel *next, *prev; @@ -125,7 +113,6 @@ typedef struct ScrArea { ListBase panels; ListBase regionbase; /* ARegion */ ListBase handlers; /* wmEventHandler */ - ListBase modalops; /* wmOperator */ ListBase actionzones; /* AZone */ } ScrArea; @@ -152,7 +139,6 @@ typedef struct ARegion { ListBase uiblocks; ListBase handlers; /* wmEventHandler */ - ListBase modalops; /* wmOperator */ void *regiondata; /* XXX 2.50, need spacedata equivalent? */ } ARegion; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 07abe9fd75f..c67a482ccaa 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -100,7 +100,6 @@ typedef struct wmWindow { ListBase queue; /* all events (ghost level events were handled) */ ListBase handlers; /* window+screen handlers, overriding all queues */ - ListBase modalops; /* wmOperator, operators running modal */ ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ ListBase gesture; /* gesture stuff */ diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 1433c37ae9e..19e41f5c118 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -37,9 +37,7 @@ #include "MEM_guardedalloc.h" #include "DNA_camera_types.h" /* qdn: defocus node, need camera info */ -//#include "DNA_action_types.h" #include "DNA_color_types.h" -//#include "DNA_ipo_types.h" #include "DNA_ID.h" #include "DNA_image_types.h" #include "DNA_material_types.h" @@ -47,7 +45,6 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "DNA_userdef_types.h" #include "BKE_blender.h" #include "BKE_colortools.h" @@ -63,9 +60,6 @@ #include "../CMP_node.h" #include "node_util.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" - #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_rand.h" @@ -78,9 +72,6 @@ #include "RE_shader_ext.h" #include "RE_render_ext.h" -//XXX #include "butspace.h" -//XXX #include "wm_event_types.h" - /* *************************** operations support *************************** */ /* general signal that's in output sockets, and goes over the wires */ diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/intern/SHD_util.h index 8bcd6e40038..a6fe5f4e9cc 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/intern/SHD_util.h @@ -36,9 +36,7 @@ #include "MEM_guardedalloc.h" -//#include "DNA_action_types.h" #include "DNA_color_types.h" -//#include "DNA_ipo_types.h" #include "DNA_ID.h" #include "DNA_image_types.h" #include "DNA_material_types.h" @@ -46,7 +44,6 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "DNA_userdef_types.h" #include "BKE_blender.h" #include "BKE_colortools.h" @@ -74,10 +71,6 @@ #include "GPU_material.h" -//XXX #include "butspace.h" -//XXX #include "wm_event_types.h" - - /* ********* exec data struct, remains internal *********** */ typedef struct ShaderCallData { diff --git a/source/blender/nodes/intern/TEX_util.h b/source/blender/nodes/intern/TEX_util.h index 69cf20794c9..9203b950364 100644 --- a/source/blender/nodes/intern/TEX_util.h +++ b/source/blender/nodes/intern/TEX_util.h @@ -34,7 +34,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_action_types.h" #include "DNA_color_types.h" #include "DNA_ipo_types.h" #include "DNA_ID.h" @@ -43,10 +42,7 @@ #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_space_types.h" -#include "DNA_screen_types.h" #include "DNA_texture_types.h" -#include "DNA_userdef_types.h" #include "BKE_blender.h" #include "BKE_colortools.h" diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 9b2c1409887..4b9c01b3e33 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -69,9 +69,9 @@ void WM_keymap_add_item (ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier); struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap); void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); -struct wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op); -void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op); -void WM_event_remove_handlers(ListBase *handlers); + +struct wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op); +void WM_event_remove_handlers (bContext *C, ListBase *handlers); void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdatafree); @@ -97,7 +97,6 @@ wmOperatorType *WM_operatortype_find(const char *idname); void WM_operatortype_append (void (*opfunc)(wmOperatorType*)); int WM_operator_invoke (struct bContext *C, wmOperatorType *ot, struct wmEvent *event); -void WM_operator_cancel (struct bContext *C, ListBase *modalops, wmOperatorType *ot); /* default operator callbacks for border/lasso */ int WM_border_select_invoke (struct bContext *C, wmOperator *op, struct wmEvent *event); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e4c4406b8ae..9432036b4bc 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -279,17 +279,6 @@ void wm_draw_update(bContext *C) /* ********************* operators ******************* */ -static ListBase *wm_modalops_list(bContext *C) -{ - if(C->region) - return &C->region->modalops; - else if(C->area) - return &C->area->modalops; - else if(C->window) - return &C->window->modalops; - else - return NULL; -} int WM_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event) { @@ -298,8 +287,10 @@ int WM_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event) if(ot->poll==NULL || ot->poll(C)) { wmOperator *op= MEM_callocN(sizeof(wmOperator), "wmOperator"); + /* XXX adding new operator could be function, only happens here now */ op->type= ot; - + BLI_strncpy(op->idname, ot->idname, OP_MAX_TYPENAME); + op->ptr= MEM_callocN(sizeof(PointerRNA), "wmOperatorPtrRNA"); RNA_pointer_create(&RNA_WindowManager, &C->wm->id, ot->srna, op, op->ptr); @@ -314,59 +305,38 @@ int WM_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event) else if(!(retval & OPERATOR_RUNNING_MODAL)) { wm_operator_free(op); } - else { - op->modallist= wm_modalops_list(C); - BLI_addtail(op->modallist, op); - } } return retval; } -void WM_operator_cancel(bContext *C, ListBase *lb, wmOperatorType *type) -{ - wmOperator *op, *nextop; - - if(!lb) - lb= wm_modalops_list(C); - if(!lb) - return; - - for(op=lb->first; op; op=nextop) { - nextop= op->next; - - if(type == NULL || op->type == type) { - if(op->type->cancel) - op->type->cancel(C, op); - - BLI_remlink(op->modallist, op); - op->modallist= NULL; - - wm_operator_free(op); - } - } -} - /* ********************* handlers *************** */ -/* not handler itself */ + +/* not handler itself, is called by UI to move handlers to other queues, so don't close modal ones */ static void wm_event_free_handler(wmEventHandler *handler) { + } -void wm_event_free_handlers(ListBase *lb) +/* called on exit or remove area, only here call cancel callback */ +void WM_event_remove_handlers(bContext *C, ListBase *handlers) { wmEventHandler *handler; - for(handler= lb->first; handler; handler= handler->next) + /* C is zero on freeing database, modal handlers then already were freed */ + while((handler=handlers->first)) { + /* we have to remove the handler first, to prevent op->type->cancel() to remove modal handler too */ + BLI_remlink(handlers, handler); + + if(C && handler->op) { + if(handler->op->type->cancel) + handler->op->type->cancel(C, handler->op); + wm_operator_free(handler->op); + } wm_event_free_handler(handler); - - BLI_freelistN(lb); -} - -void WM_event_remove_handlers(ListBase *handlers) -{ - wm_event_free_handlers(handlers); + MEM_freeN(handler); + } } static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km) @@ -389,8 +359,8 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km) return 1; } -/* note: this might free the handler from the operator */ -static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEvent *event) +/* Warning: this function removes a modal handler, when finished */ +static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event) { int retval= OPERATOR_PASS_THROUGH; @@ -400,18 +370,38 @@ static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEven wmOperatorType *ot= op->type; if(ot->modal) { + /* we set context to where modal handler came from */ + ScrArea *area= C->area; + ARegion *region= C->region; + + C->area= handler->op_area; + C->region= handler->op_region; + retval= ot->modal(C, op, event); + /* putting back screen context */ + C->area= area; + C->region= region; + if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) { - BLI_remlink(op->modallist, op); - op->modallist= NULL; wm_operator_register(C->wm, op); + handler->op= NULL; } else if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { - BLI_remlink(op->modallist, op); - op->modallist= NULL; wm_operator_free(op); + handler->op= NULL; } + + /* remove modal handler, operator itself should have been cancelled and freed */ + if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { + BLI_remlink(handlers, handler); + wm_event_free_handler(handler); + MEM_freeN(handler); + + /* prevent silly errors from operator users */ + retval &= ~OPERATOR_PASS_THROUGH; + } + } else printf("wm_handler_operator_call error\n"); @@ -442,8 +432,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) if(handlers==NULL) return action; - /* in this loop, the handler might be freed in wm_handler_operator_call, - * and new handler might be added to the head of the list */ + /* modal handlers can get removed in this loop, we keep the loop this way */ for(handler= handlers->first; handler; handler= nexthandler) { nexthandler= handler->next; @@ -461,15 +450,15 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) event->keymap_idname= km->idname; /* weak, but allows interactive callback to not use rawkey */ - action= wm_handler_operator_call(C, handler, event); - if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK) + action= wm_handler_operator_call(C, handlers, handler, event); + if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ break; } } } else { /* modal, swallows all */ - action= wm_handler_operator_call(C, handler, event); + action= wm_handler_operator_call(C, handlers, handler, event); } if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK) @@ -587,7 +576,7 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag) handler->flag= flag; } -wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op) +wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op) { /* debug test; operator not in registry */ if(op->type->flag & OPTYPE_REGISTER) { @@ -596,6 +585,9 @@ wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op) else { wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler"); handler->op= op; + handler->op_area= C->area; /* means frozen screen context for modal handlers! */ + handler->op_region= C->region; + BLI_addhead(handlers, handler); return handler; @@ -603,20 +595,6 @@ wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op) return NULL; } -void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op) -{ - wmEventHandler *handler; - - for(handler= handlers->first; handler; handler= handler->next) { - if(handler->op==op) { - BLI_remlink(handlers, handler); - wm_event_free_handler(handler); - MEM_freeN(handler); - break; - } - } -} - wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap) { wmEventHandler *handler; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c196f7a4fff..fb8101168e2 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -74,6 +74,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "wm_event_system.h" #include "wm.h" #include "wm_files.h" #include "wm_window.h" @@ -157,6 +158,21 @@ extern wchar_t *copybufinfo; /* called in creator.c even... tsk, split this! */ void WM_exit(bContext *C) { + wmWindow *win; + + /* first wrap up running stuff, we assume only the active WM is running */ + /* modal handlers are on window level freed, others too? */ + if(C && C->wm) { + for(win= C->wm->windows.first; win; win= win->next) { + ARegion *ar; + + C->window= win; /* needed by operator close callbacks */ + WM_event_remove_handlers(C, &win->handlers); + + for(ar= win->screen->regionbase.first; ar; ar= ar->next) + WM_event_remove_handlers(C, &ar->handlers); + } + } wm_operatortype_free(); free_ttfont(); /* bke_font.h */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7dacae6da91..7a4b30af384 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -182,7 +182,7 @@ static void border_select_end(bContext *C, wmOperator *op) WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */ op->customdata= NULL; - WM_event_remove_modal_handler(&C->window->handlers, op); + WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_AREA_REDRAW, 0, NULL); } @@ -192,7 +192,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT); /* add modal handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); WM_event_add_notifier(C->wm, C->window, C->screen->subwinactive, WM_NOTE_GESTURE_REDRAW, 0, NULL); @@ -252,7 +252,7 @@ static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK); /* add modal handler */ - WM_event_add_modal_handler(&C->window->handlers, op); + WM_event_add_modal_handler(C, &C->window->handlers, op); WM_event_add_notifier(C->wm, C->window, C->screen->subwinactive, WM_NOTE_GESTURE_REDRAW, 0, NULL); @@ -265,7 +265,7 @@ static void tweak_gesture_end(bContext *C, wmOperator *op) WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */ op->customdata= NULL; - WM_event_remove_modal_handler(&C->window->handlers, op); + WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_AREA_REDRAW, 0, NULL); } diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index cbaef2a8c30..1b3b7ce8efb 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -32,6 +32,8 @@ #define WM_HANDLER_CONTINUE 0 #define WM_HANDLER_BREAK 1 +struct ScrArea; +struct ARegion; /* wmKeyMap is in DNA_windowmanager.h, it's savable */ @@ -44,7 +46,9 @@ typedef struct wmEventHandler { rctf boundbox; /* float, in bContext space (window, area, region) */ - wmOperator *op; /* for derived handlers */ + wmOperator *op; /* for derived/modal handlers */ + struct ScrArea *op_area; /* for derived/modal handlers */ + struct ARegion *op_region; /* for derived/modal handlers */ } wmEventHandler; @@ -65,7 +69,6 @@ enum { void wm_event_add(wmWindow *win, wmEvent *event_to_add); void wm_event_free_all (wmWindow *win); wmEvent *wm_event_next (wmWindow *win); -void wm_event_free_handlers (ListBase *lb); /* goes over entire hierarchy: events -> window -> screen -> area -> region */ void wm_event_do_handlers (bContext *C); |