Lots of stuff; couldn't commit in parts because of refactor work.
authorTon Roosendaal <ton@blender.org>
Tue, 2 Dec 2008 14:22:52 +0000 (14:22 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 2 Dec 2008 14:22:52 +0000 (14:22 +0000)
* Changes in interface/ module

This commit brings back the way how buttons/menus work under control
of WM event system. The previous implementation extended usage of
handlers and operators in an interesting but confusing way. Better to
try it first according the design specs. :)

Most obviously:
- modal-handler operators are not stored anymore in regions/areas/windows.
  such modal handlers own their operator, and should remove it themselves.
- removed code to move handlers from one queue to another.
  (needs review with brecht!)
- WM fix: the API call to remove a modal handler got removed. This was a
  dangerous thing anyway, and you should leave that to the event system.
  Now, if a handler modal() call gets a cancel/finish return, it frees
  itself in event system. WM_event_remove_modal_handler was a confusing
  call anyway!

Todo:

- allow button-activate to refresh after using button
- re-enable arrow keys for menus
  (do both after commit)

- review return values of operator callbacks in interface_ops.c

* Fixes in WM system

- Freeing areas/regions/windows, also on quit, now correctly closes
  running modal handlers
- On starting a modal handler, the handler now stores previous area
  and region context, so they send proper notifiers etc.

* Other fixes

- Area-split operator had bug, wrong minimal size checking. This
  solves error when trying to split a very narrow area.
- removed DNA_USHORT_FIX from screen_types.h, gave warning
- operators didn't get ID name copied when activated, needed for
  later re-use or saving.

18 files changed:
source/blender/blenkernel/intern/screen.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_time/ed_markers.c
source/blender/editors/space_time/time_ops.c
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/nodes/intern/CMP_util.h
source/blender/nodes/intern/SHD_util.h
source/blender/nodes/intern/TEX_util.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/wm_event_system.h

index 7975e357938f0cf019e50f2d1e8b85c14b069d65..266a387732ee68278c6e4300d73cae6e5ebc569d 100644 (file)
@@ -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);
index 097c654de510c00fe1f825ae3d67aca0d38088bc..70e06627449574a192aeda643fce0587fb9d5d24 100644 (file)
@@ -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;
index 90f888e652d38b4ac06c81d1c051207c5ac8e837..2d515aafc13c88ea88821ff983e30132cf49c9f9 100644 (file)
@@ -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;
 
index 2ddbaeeb79bff1c42ce1fa58728064a1aade5ad6..9e6a9a6dada9d77d6063ba6e82494928625f47f1 100644 (file)
@@ -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;
                        }
index 742022ea37050d96b2df888d29d5a7d1123bb61a..31ac5d63835fd6512365954f39a1d18e6ace734c 100644 (file)
@@ -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);
 }
 
 
index 4c7a98e97c399b900d47cb149672e53102b8b4dd..095f6e1a74bd6c8df784dfe2cf2d79643d625a30 100644 (file)
@@ -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;
index 83ede8693604ea4138c4e5f8bb7d3df57aa1e646..1829435bf8db584fbac1e6e0745aef5108f1c0d1 100644 (file)
@@ -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;
                        }
index bc30d07f878b6e455afb4f335deb2fc8881af642..27e89422f98a920b99573141bffbbf87b676d748 100644 (file)
@@ -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;
index 28ec73a00d1b46a88095075b00c15bac2560c5bf..2cce4d398b97e4dce5c596978f267f18438ec4c6 100644 (file)
@@ -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;
index 07abe9fd75fe43c21d4be550b055ccf9658b0bd2..c67a482ccaab3bc96fb3573107b86bdb6cbab96b 100644 (file)
@@ -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 */
index 1433c37ae9e60c6e6facd3946cf7c8551377b0d6..19e41f5c11870f38ae209da305434a522318ecdd 100644 (file)
@@ -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 */
index 8bcd6e40038c9e09e3cfb3cf5075888613b6285e..a6fe5f4e9cc5b8244c664e9409339da100218966 100644 (file)
@@ -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"
 
 #include "GPU_material.h"
 
-//XXX #include "butspace.h"
-//XXX #include "wm_event_types.h"
-
-
 /* ********* exec data struct, remains internal *********** */
 
 typedef struct ShaderCallData {
index 69cf20794c93296fb84542a192b62d0fad63dcba..9203b950364d9d0f1656b7f876719637ee2c9937 100644 (file)
@@ -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"
 #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"
index 9b2c14098872869ffc1c56463ea41ce7a59dd27e..4b9c01b3e333c7d334f0eb0b86d0b814971c0d24 100644 (file)
@@ -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);
index e4c4406b8aeb545973a67a84cfabd9be867d2141..9432036b4bc760e22dd4789e458edf312850872b 100644 (file)
@@ -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;
index c196f7a4fff8389dbb0da7c2c5de9c5c64c7436c..fb8101168e21aed4ec9235ad69bb553b965e40e0 100644 (file)
@@ -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 */
index 7dacae6da91024cfb720a0d489f6d44ef178673a..7a4b30af3849b3a7a848c34381353caf5ae382e1 100644 (file)
@@ -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);
        
 }
index cbaef2a8c30a2d47c994c08ae914a9d4a2862719..1b3b7ce8efb5f38942706eb6cd5ae4ba45a5074d 100644 (file)
@@ -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);