diff options
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 12 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_cursors.c | 13 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 22 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 171 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 36 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 91 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 98 |
10 files changed, 278 insertions, 179 deletions
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 5b7f892592b..1d173005d85 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -209,8 +209,10 @@ void wm_check(bContext *C) if(wm->windows.first==NULL) return; /* case: fileread */ - if((wm->initialized & WM_INIT_WINDOW) == 0) + if((wm->initialized & WM_INIT_WINDOW) == 0) { WM_keymap_init(C); + WM_autosave_init(C); + } /* case: no open windows at all, for old file reads */ wm_window_add_ghostwindows(wm); @@ -269,12 +271,15 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) wmWindow *win; wmOperator *op; wmKeyConfig *keyconf; - + + if(wm->autosavetimer) + wm_autosave_timer_ended(wm); + while((win= wm->windows.first)) { BLI_remlink(&wm->windows, win); win->screen= NULL; /* prevent draw clear to use screen */ wm_draw_window_clear(win); - wm_window_free(C, win); + wm_window_free(C, wm, win); } while((op= wm->operators.first)) { @@ -290,6 +295,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm) BLI_freelistN(&wm->queue); BLI_freelistN(&wm->paintcursors); + BKE_reports_clear(&wm->reports); if(C && CTX_wm_manager(C)==wm) CTX_wm_manager_set(C, NULL); } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index c1dfd9ee9fb..e2aedf42bd8 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -163,21 +163,26 @@ void WM_cursor_wait(int val) } } -void WM_cursor_grab(wmWindow *win, int warp) +void WM_cursor_grab(wmWindow *win, int wrap, int hide, int *bounds) { /* Only grab cursor when not running debug. * It helps not to get a stuck WM when hitting a breakpoint * */ + GHOST_TGrabCursorMode mode = GHOST_kGrabNormal; + + if(hide) mode = GHOST_kGrabHide; + else if(wrap) mode = GHOST_kGrabWrap; + if ((G.f & G_DEBUG) == 0) if(win) - GHOST_SetCursorGrab(win->ghostwin, 1, warp, -1); + GHOST_SetCursorGrab(win->ghostwin, mode, bounds); } -void WM_cursor_ungrab(wmWindow *win, int restore) +void WM_cursor_ungrab(wmWindow *win) { if ((G.f & G_DEBUG) == 0) if(win) - GHOST_SetCursorGrab(win->ghostwin, 0, -1, restore); + GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL); } /* afer this you can call restore too */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 1df567e3c92..e7c04141ad3 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -44,6 +44,8 @@ #include "ED_screen.h" +#include "GPU_extensions.h" + #include "WM_api.h" #include "WM_types.h" #include "wm.h" @@ -376,7 +378,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) triple->x[0]= win->sizex; triple->y[0]= win->sizey; } - else if(GLEW_ARB_texture_non_power_of_two) { + else if(GPU_non_power_of_two_support()) { triple->target= GL_TEXTURE_2D; triple->nx= 1; triple->ny= 1; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f1104feaf5b..f301a20a7c1 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -463,8 +463,20 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P else if(retval & OPERATOR_RUNNING_MODAL) { /* grab cursor during blocking modal ops (X11) */ if(ot->flag & OPTYPE_BLOCKING) { - int warp = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER)); - WM_cursor_grab(CTX_wm_window(C), warp); + int bounds[4] = {-1,-1,-1,-1}; + int wrap = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER)); + + if(wrap) { + ARegion *ar= CTX_wm_region(C); + if(ar) { + bounds[0]= ar->winrct.xmin; + bounds[1]= ar->winrct.ymax; + bounds[2]= ar->winrct.xmax; + bounds[3]= ar->winrct.ymin; + } + } + + WM_cursor_grab(CTX_wm_window(C), wrap, FALSE, bounds); } } else @@ -660,7 +672,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) CTX_wm_region_set(C, region); } - WM_cursor_ungrab(CTX_wm_window(C), TRUE); + WM_cursor_ungrab(CTX_wm_window(C)); WM_operator_free(handler->op); } else if(handler->ui_remove) { @@ -779,7 +791,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi) static int wm_event_always_pass(wmEvent *event) { /* some events we always pass on, to ensure proper communication */ - return ELEM5(event->type, TIMER, TIMER0, TIMER1, TIMER2, TIMERJOBS); + return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2); } /* operator exists */ @@ -858,7 +870,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* remove modal handler, operator itself should have been cancelled and freed */ if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) { - WM_cursor_ungrab(CTX_wm_window(C), TRUE); + WM_cursor_ungrab(CTX_wm_window(C)); BLI_remlink(handlers, handler); wm_event_free_handler(handler); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index ff0e69b74d4..b2e55c8532e 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -95,6 +95,7 @@ #include "WM_types.h" #include "wm.h" #include "wm_window.h" +#include "wm_event_system.h" static void writeBlog(void); @@ -348,49 +349,6 @@ int WM_read_homefile(bContext *C, wmOperator *op) } -static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE]) -{ - char pidstr[32]; -#ifdef WIN32 - char subdir[9]; - char savedir[FILE_MAXDIR]; -#endif - - sprintf(pidstr, "%d.blend", abs(getpid())); - -#ifdef WIN32 - if (!BLI_exists(U.tempdir)) { - BLI_strncpy(subdir, "autosave", sizeof(subdir)); - BLI_make_file_string("/", savedir, BLI_gethome(), subdir); - - /* create a new autosave dir - * function already checks for existence or not */ - BLI_recurdir_fileops(savedir); - - BLI_make_file_string("/", buf, savedir, pidstr); - return; - } -#endif - - BLI_make_file_string("/", buf, U.tempdir, pidstr); -} - -void WM_read_autosavefile(bContext *C) -{ - char tstr[FILE_MAX], scestr[FILE_MAX]; - int save_over; - - BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */ - - get_autosave_location(tstr); - - save_over = G.save_over; - BKE_read_file(C, tstr, NULL, NULL); - G.save_over = save_over; - BLI_strncpy(G.sce, scestr, FILE_MAX); -} - - void read_Blog(void) { char name[FILE_MAX]; @@ -496,10 +454,10 @@ static void do_history(char *name, ReportList *reports) BKE_report(reports, RPT_ERROR, "Unable to make version backup"); } -void WM_write_file(bContext *C, char *target, int compress, ReportList *reports) +void WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports) { Library *li; - int writeflags, len; + int len; char di[FILE_MAX]; len = strlen(target); @@ -537,20 +495,14 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports) do_history(di, reports); - writeflags= G.fileflags; - - /* set compression flag */ - if(compress) writeflags |= G_FILE_COMPRESS; - else writeflags &= ~G_FILE_COMPRESS; - - if (BLO_write_file(CTX_data_main(C), di, writeflags, reports)) { + if (BLO_write_file(CTX_data_main(C), di, fileflags, reports)) { strcpy(G.sce, di); G.relbase_valid = 1; strcpy(G.main->name, di); /* is guaranteed current file */ G.save_over = 1; /* disable untitled.blend convention */ - if(compress) G.fileflags |= G_FILE_COMPRESS; + if(fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS; else G.fileflags &= ~G_FILE_COMPRESS; writeBlog(); @@ -562,56 +514,125 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports) /* operator entry */ int WM_write_homefile(bContext *C, wmOperator *op) { + wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win= CTX_wm_window(C); char tstr[FILE_MAXDIR+FILE_MAXFILE]; - int write_flags; + int fileflags; /* check current window and close it if temp */ - if(win->screen->full == SCREENTEMP) { - wm_window_close(C, win); - } + if(win->screen->full == SCREENTEMP) + wm_window_close(C, wm, win); BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend"); /* force save as regular blend file */ - write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); + fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); - BLO_write_file(CTX_data_main(C), tstr, write_flags, op->reports); + BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports); G.save_over= 0; return OPERATOR_FINISHED; } -void WM_write_autosave(bContext *C) +/************************ autosave ****************************/ + +void wm_autosave_location(char *filename) { - char tstr[FILE_MAXDIR+FILE_MAXFILE]; - int write_flags; + char pidstr[32]; +#ifdef WIN32 + char subdir[9]; + char savedir[FILE_MAXDIR]; +#endif + + sprintf(pidstr, "%d.blend", abs(getpid())); + +#ifdef WIN32 + if (!BLI_exists(U.tempdir)) { + BLI_strncpy(subdir, "autosave", sizeof(subdir)); + BLI_make_file_string("/", savedir, BLI_gethome(), subdir); + + /* create a new autosave dir + * function already checks for existence or not */ + BLI_recurdir_fileops(savedir); + + BLI_make_file_string("/", filename, savedir, pidstr); + return; + } +#endif - get_autosave_location(tstr); + BLI_make_file_string("/", filename, U.tempdir, pidstr); +} - /* force save as regular blend file */ - write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); +void WM_autosave_init(bContext *C) +{ + wmWindowManager *wm= CTX_wm_manager(C); + wm_autosave_timer_ended(wm); - /* error reporting to console */ - BLO_write_file(CTX_data_main(C), tstr, write_flags, NULL); + if(U.flag & USER_AUTOSAVE) + wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0); } -/* if global undo; remove tempsave, otherwise rename */ -void delete_autosave(void) +void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { - char tstr[FILE_MAXDIR+FILE_MAXFILE]; + wmWindow *win; + wmEventHandler *handler; + char filename[FILE_MAX]; + int fileflags; + + WM_event_remove_timer(wm, NULL, wm->autosavetimer); + + /* if a modal operator is running, don't autosave, but try again in 10 seconds */ + for(win=wm->windows.first; win; win=win->next) { + for(handler=win->modalhandlers.first; handler; handler=handler->next) { + if(handler->op) { + wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0); + return; + } + } + } - get_autosave_location(tstr); + wm_autosave_location(filename); + + /* force save as regular blend file */ + fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_LOCK|G_FILE_SIGN); + + /* no error reporting to console */ + BLO_write_file(CTX_data_main(C), filename, fileflags, NULL); - if (BLI_exists(tstr)) { + /* do timer after file write, just in case file write takes a long time */ + wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0); +} + +void wm_autosave_timer_ended(wmWindowManager *wm) +{ + if(wm->autosavetimer) { + WM_event_remove_timer(wm, NULL, wm->autosavetimer); + wm->autosavetimer= NULL; + } +} + +void wm_autosave_delete(void) +{ + char filename[FILE_MAX]; + + wm_autosave_location(filename); + + if(BLI_exists(filename)) { char str[FILE_MAXDIR+FILE_MAXFILE]; BLI_make_file_string("/", str, U.tempdir, "quit.blend"); - if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0); - else BLI_rename(tstr, str); + /* if global undo; remove tempsave, otherwise rename */ + if(U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0); + else BLI_rename(filename, str); } } -/***/ +void wm_autosave_read(bContext *C, ReportList *reports) +{ + char filename[FILE_MAX]; + + wm_autosave_location(filename); + WM_read_file(C, filename, reports); +} diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index bdafedfb65e..b24ad19649d 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -287,7 +287,7 @@ void WM_exit(bContext *C) BLI_cellalloc_destroy(); MEM_printmemlist(); } -// delete_autosave(); + wm_autosave_delete(); printf("\nBlender quit\n"); diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 9e16ce4082f..8ad63d6ba15 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -192,7 +192,6 @@ static void *do_job_thread(void *job_v) { wmJob *steve= job_v; - steve->stop= steve->ready= 0; steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update); steve->ready= 1; @@ -245,6 +244,9 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve) if(steve->initjob) steve->initjob(steve->run_customdata); + steve->stop= 0; + steve->ready= 0; + BLI_init_threads(&steve->threads, do_job_thread, 1); BLI_insert_thread(&steve->threads, steve); @@ -253,7 +255,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve) /* restarted job has timer already */ if(steve->wt==NULL) - steve->wt= WM_event_add_window_timer(steve->win, TIMERJOBS, steve->timestep); + steve->wt= WM_event_add_timer(wm, steve->win, TIMERJOBS, steve->timestep); } else printf("job fails, not initialized\n"); } @@ -269,7 +271,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve) } if(steve->wt) - WM_event_remove_window_timer(steve->win, steve->wt); + WM_event_remove_timer(wm, steve->win, steve->wt); if(steve->customdata) steve->free(steve->customdata); if(steve->run_customdata) @@ -315,14 +317,14 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt) } /* hardcoded to event TIMERJOBS */ -static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) +void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { - wmWindowManager *wm= CTX_wm_manager(C); - wmJob *steve= wm->jobs.first; + wmJob *steve= wm->jobs.first, *stevenext; - for(; steve; steve= steve->next) { + for(; steve; steve= stevenext) { + stevenext= steve->next; - if(evt->customdata==steve->wt) { + if(steve->wt==wt) { /* running threads */ if(steve->threads.first) { @@ -356,7 +358,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) WM_jobs_start(wm, steve); } else { - WM_event_remove_window_timer(steve->win, steve->wt); + WM_event_remove_timer(wm, steve->win, steve->wt); steve->wt= NULL; /* remove steve */ @@ -368,23 +370,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) else if(steve->suspended) { WM_jobs_start(wm, steve); } - - return OPERATOR_FINISHED; } } - return OPERATOR_PASS_THROUGH; } -void WM_OT_jobs_timer(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Jobs timer"; - ot->idname= "WM_OT_jobs_timer"; - ot->description="Jobs timer operator."; - - /* api callbacks */ - ot->invoke= wm_jobs_timer; - - ot->poll= ED_operator_screenactive; - -} diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index eedacb056b7..3caca041be7 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -415,15 +415,19 @@ wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) /* first user defined keymaps */ km= wm_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) + if(km) { + km->poll= keymap->poll; /* lazy init */ return km; + } /* then user key config */ keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); if(keyconf) { km= wm_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) + if(km) { + km->poll= keymap->poll; /* lazy init */ return km; + } } /* then use default */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5ad138c3890..e37b6e919c6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -972,7 +972,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op) WM_read_file(C, path, op->reports); - return 0; + return OPERATOR_FINISHED; } static void WM_OT_open_mainfile(wmOperatorType *ot) @@ -1154,12 +1154,9 @@ static void WM_OT_link_append(wmOperatorType *ot) static int wm_recover_last_session_exec(bContext *C, wmOperator *op) { - char scestr[FILE_MAX], filename[FILE_MAX]; - int save_over; + char filename[FILE_MAX]; - /* back up some values */ - BLI_strncpy(scestr, G.sce, sizeof(scestr)); - save_over = G.save_over; + G.fileflags |= G_FILE_RECOVER; // XXX wm in context is not set correctly after WM_read_file -> crash // do it before for now, but is this correct with multiple windows? @@ -1169,11 +1166,9 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op) BLI_make_file_string("/", filename, btempdir, "quit.blend"); WM_read_file(C, filename, op->reports); - /* restore */ - G.save_over = save_over; - BLI_strncpy(G.sce, scestr, sizeof(G.sce)); + G.fileflags &= ~G_FILE_RECOVER; - return 0; + return OPERATOR_FINISHED; } static void WM_OT_recover_last_session(wmOperatorType *ot) @@ -1186,6 +1181,52 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) ot->poll= WM_operator_winactive; } +/* *************** recover auto save **************** */ + +static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) +{ + char path[FILE_MAX]; + + RNA_string_get(op->ptr, "path", path); + + G.fileflags |= G_FILE_RECOVER; + + // XXX wm in context is not set correctly after WM_read_file -> crash + // do it before for now, but is this correct with multiple windows? + WM_event_add_notifier(C, NC_WINDOW, NULL); + + /* load file */ + WM_read_file(C, path, op->reports); + + G.fileflags &= ~G_FILE_RECOVER; + + return OPERATOR_FINISHED; +} + +static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + char filename[FILE_MAX]; + + wm_autosave_location(filename); + RNA_string_set(op->ptr, "path", filename); + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static void WM_OT_recover_auto_save(wmOperatorType *ot) +{ + ot->name= "Recover Auto Save"; + ot->idname= "WM_OT_recover_auto_save"; + ot->description="Open an automatically saved file to recover it."; + + ot->exec= wm_recover_auto_save_exec; + ot->invoke= wm_recover_auto_save_invoke; + ot->poll= WM_operator_winactive; + + WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER); +} + /* *************** save file as **************** */ static void untitled(char *name) @@ -1229,10 +1270,9 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) { char path[FILE_MAX]; - int compress; + int fileflags; save_set_compress(op); - compress= RNA_boolean_get(op->ptr, "compress"); if(RNA_property_is_set(op->ptr, "path")) RNA_string_get(op->ptr, "path", path); @@ -1241,7 +1281,15 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) untitled(path); } - WM_write_file(C, path, compress, op->reports); + fileflags= G.fileflags; + + /* set compression flag */ + if(RNA_boolean_get(op->ptr, "compress")) + fileflags |= G_FILE_COMPRESS; + else + fileflags &= ~G_FILE_COMPRESS; + + WM_write_file(C, path, fileflags, op->reports); WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL); @@ -1273,8 +1321,12 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); RNA_string_set(op->ptr, "path", name); - uiPupMenuSaveOver(C, op, name); - + + if (G.save_over) + uiPupMenuSaveOver(C, op, name); + else + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; } @@ -2173,7 +2225,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_open_mainfile); WM_operatortype_append(WM_OT_link_append); WM_operatortype_append(WM_OT_recover_last_session); - WM_operatortype_append(WM_OT_jobs_timer); + WM_operatortype_append(WM_OT_recover_auto_save); WM_operatortype_append(WM_OT_save_as_mainfile); WM_operatortype_append(WM_OT_save_mainfile); WM_operatortype_append(WM_OT_redraw_timer); @@ -2188,9 +2240,6 @@ void wm_window_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0); wmKeyMapItem *km; - /* items to make WM work */ - WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0); - /* note, this doesn't replace existing keymap items */ WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); #ifdef __APPLE__ @@ -2205,9 +2254,13 @@ void wm_window_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + WM_keymap_add_item(keymap, "WM_OT_link_append", F1KEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_save_mainfile", WKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index f7116a2bd1f..70d40df4532 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -130,37 +130,39 @@ static void wm_ghostwindow_destroy(wmWindow *win) /* including window itself, C can be NULL. ED_screen_exit should have been called */ -void wm_window_free(bContext *C, wmWindow *win) +void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win) { wmTimer *wt, *wtnext; /* update context */ if(C) { - wmWindowManager *wm= CTX_wm_manager(C); - - if(wm->windrawable==win) - wm->windrawable= NULL; - if(wm->winactive==win) - wm->winactive= NULL; - if(CTX_wm_window(C)==win) - CTX_wm_window_set(C, NULL); - WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); - /* end running jobs, a job end also removes its timer */ - for(wt= win->timers.first; wt; wt= wtnext) { - wtnext= wt->next; - if(wt->event_type==TIMERJOBS) - wm_jobs_timer_ended(wm, wt); - } + if(CTX_wm_window(C)==win) + CTX_wm_window_set(C, NULL); } - - if(win->eventstate) MEM_freeN(win->eventstate); + + if(wm->windrawable==win) + wm->windrawable= NULL; + if(wm->winactive==win) + wm->winactive= NULL; + + /* end running jobs, a job end also removes its timer */ + for(wt= wm->timers.first; wt; wt= wtnext) { + wtnext= wt->next; + if(wt->win==win && wt->event_type==TIMERJOBS) + wm_jobs_timer_ended(wm, wt); + } /* timer removing, need to call this api function */ - while((wt= win->timers.first)) - WM_event_remove_window_timer(win, wt); + for(wt= wm->timers.first; wt; wt=wtnext) { + wtnext= wt->next; + if(wt->win==win) + WM_event_remove_timer(wm, win, wt); + } + + if(win->eventstate) MEM_freeN(win->eventstate); wm_event_free_all(win); wm_subwindows_free(win); @@ -223,14 +225,13 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) } /* this is event from ghost, or exit-blender op */ -void wm_window_close(bContext *C, wmWindow *win) +void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { - wmWindowManager *wm= CTX_wm_manager(C); BLI_remlink(&wm->windows, win); wm_draw_window_clear(win); ED_screen_exit(C, win, win->screen); - wm_window_free(C, win); + wm_window_free(C, wm, win); /* check remaining windows */ if(wm->windows.first) { @@ -544,6 +545,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win) static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) { bContext *C= private; + wmWindowManager *wm= CTX_wm_manager(C); GHOST_TEventType type= GHOST_GetEventType(evt); if (type == GHOST_kEventQuit) { @@ -576,7 +578,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) GHOST_TEventKeyData kdata; int cx, cy, wx, wy; - CTX_wm_manager(C)->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */ + wm->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */ win->active= 1; // window_handle(win, INPUTCHANGE, win->active); @@ -619,7 +621,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) break; } case GHOST_kEventWindowClose: { - wm_window_close(C, win); + wm_window_close(C, wm, win); break; } case GHOST_kEventWindowUpdate: { @@ -719,22 +721,29 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) static int wm_window_timer(const bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); + wmTimer *wt, *wtnext; wmWindow *win; double time= PIL_check_seconds_timer(); int retval= 0; - for(win= wm->windows.first; win; win= win->next) { - wmTimer *wt; - for(wt= win->timers.first; wt; wt= wt->next) { - if(wt->sleep==0) { - if(time > wt->ntime) { + for(wt= wm->timers.first; wt; wt= wtnext) { + wtnext= wt->next; /* in case timer gets removed */ + win= wt->win; + + if(wt->sleep==0) { + if(time > wt->ntime) { + wt->delta= time - wt->ltime; + wt->duration += wt->delta; + wt->ltime= time; + wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep); + + if(wt->event_type == TIMERJOBS) + wm_jobs_timer(C, wm, wt); + else if(wt->event_type == TIMERAUTOSAVE) + wm_autosave_timer(C, wm, wt); + else if(win) { wmEvent event= *(win->eventstate); - wt->delta= time - wt->ltime; - wt->duration += wt->delta; - wt->ltime= time; - wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep); - event.type= wt->event_type; event.custom= EVT_DATA_TIMER; event.customdata= wt; @@ -810,19 +819,19 @@ void wm_ghost_exit(void) /* **************** timer ********************** */ /* to (de)activate running timers temporary */ -void WM_event_window_timer_sleep(wmWindow *win, wmTimer *timer, int dosleep) +void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *win, wmTimer *timer, int dosleep) { wmTimer *wt; - for(wt= win->timers.first; wt; wt= wt->next) + for(wt= wm->timers.first; wt; wt= wt->next) if(wt==timer) break; - if(wt) { + + if(wt) wt->sleep= dosleep; - } } -wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timestep) +wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep) { wmTimer *wt= MEM_callocN(sizeof(wmTimer), "window timer"); @@ -831,23 +840,24 @@ wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timeste wt->ntime= wt->ltime + timestep; wt->stime= wt->ltime; wt->timestep= timestep; + wt->win= win; - BLI_addtail(&win->timers, wt); + BLI_addtail(&wm->timers, wt); return wt; } -void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer) +void WM_event_remove_timer(wmWindowManager *wm, wmWindow *win, wmTimer *timer) { wmTimer *wt; /* extra security check */ - for(wt= win->timers.first; wt; wt= wt->next) + for(wt= wm->timers.first; wt; wt= wt->next) if(wt==timer) break; if(wt) { - BLI_remlink(&win->timers, wt); + BLI_remlink(&wm->timers, wt); if(wt->customdata) MEM_freeN(wt->customdata); MEM_freeN(wt); |