Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2008-12-02 17:22:52 +0300
committerTon Roosendaal <ton@blender.org>2008-12-02 17:22:52 +0300
commit54908979c54ab332156f438e995d5dce8ee8420c (patch)
tree94558d3acad12b5c0f08e902d967ce3d6d0f0723
parentc4fe6d0f00aa2a9656445ebb53161768e0c51342 (diff)
Lots of stuff; couldn't commit in parts because of refactor work.
* 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.
-rw-r--r--source/blender/blenkernel/intern/screen.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/editors/interface/interface_ops.c50
-rw-r--r--source/blender/editors/interface/view2d_ops.c3
-rw-r--r--source/blender/editors/screen/screen_edit.c15
-rw-r--r--source/blender/editors/screen/screen_ops.c43
-rw-r--r--source/blender/editors/space_time/ed_markers.c4
-rw-r--r--source/blender/editors/space_time/time_ops.c3
-rw-r--r--source/blender/makesdna/DNA_screen_types.h14
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h1
-rw-r--r--source/blender/nodes/intern/CMP_util.h9
-rw-r--r--source/blender/nodes/intern/SHD_util.h7
-rw-r--r--source/blender/nodes/intern/TEX_util.h4
-rw-r--r--source/blender/windowmanager/WM_api.h7
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c130
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c16
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c8
-rw-r--r--source/blender/windowmanager/wm_event_system.h7
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);