diff options
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r-- | source/blender/windowmanager/intern/wm_dragdrop.c | 49 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 152 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 30 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 8 |
5 files changed, 172 insertions, 71 deletions
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 96cb66b44ea..3bc77db45ca 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -226,6 +226,30 @@ void wm_drags_exit(wmWindowManager *wm, wmWindow *win) } } +static bContextStore *wm_drop_ui_context_create(const bContext *C) +{ + uiBut *active_but = UI_region_active_but_get(CTX_wm_region(C)); + if (!active_but) { + return NULL; + } + + bContextStore *but_context = UI_but_context_get(active_but); + if (!but_context) { + return NULL; + } + + return CTX_store_copy(but_context); +} + +static void wm_drop_ui_context_free(bContextStore **context_store) +{ + if (!*context_store) { + return; + } + CTX_store_free(*context_store); + *context_store = NULL; +} + void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy) { drag->imb = imb; @@ -259,6 +283,7 @@ void WM_drag_free(wmDrag *drag) if (drag->flags & WM_DRAG_FREE_DATA) { WM_drag_data_free(drag->type, drag->poin); } + wm_drop_ui_context_free(&drag->drop_state.ui_context); if (drag->drop_state.free_disabled_info) { MEM_SAFE_FREE(drag->drop_state.disabled_info); } @@ -317,6 +342,10 @@ static wmDropBox *dropbox_active(bContext *C, } const wmOperatorCallContext opcontext = wm_drop_operator_context_get(drop); + if (drag->drop_state.ui_context) { + CTX_store_set(C, drag->drop_state.ui_context); + } + if (WM_operator_poll_context(C, drop->ot, opcontext)) { return drop; } @@ -367,6 +396,10 @@ static void wm_drop_update_active(bContext *C, wmDrag *drag, const wmEvent *even return; } + /* Update UI context, before polling so polls can query this context. */ + wm_drop_ui_context_free(&drag->drop_state.ui_context); + drag->drop_state.ui_context = wm_drop_ui_context_create(C); + wmDropBox *drop_prev = drag->drop_state.active_dropbox; wmDropBox *drop = wm_dropbox_active(C, drag, event); if (drop != drop_prev) { @@ -381,11 +414,20 @@ static void wm_drop_update_active(bContext *C, wmDrag *drag, const wmEvent *even drag->drop_state.area_from = drop ? CTX_wm_area(C) : NULL; drag->drop_state.region_from = drop ? CTX_wm_region(C) : NULL; } + + if (!drag->drop_state.active_dropbox) { + wm_drop_ui_context_free(&drag->drop_state.ui_context); + } } void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop) { const wmOperatorCallContext opcontext = wm_drop_operator_context_get(drop); + + if (drag->drop_state.ui_context) { + CTX_store_set(C, drag->drop_state.ui_context); + } + /* Optionally copy drag information to operator properties. Don't call it if the * operator fails anyway, it might do more than just set properties (e.g. * typically import an asset). */ @@ -396,6 +438,11 @@ void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop) wm_drags_exit(CTX_wm_manager(C), CTX_wm_window(C)); } +void wm_drop_end(bContext *C, wmDrag *UNUSED(drag), wmDropBox *UNUSED(drop)) +{ + CTX_store_set(C, NULL); +} + void wm_drags_check_ops(bContext *C, const wmEvent *event) { wmWindowManager *wm = CTX_wm_manager(C); @@ -897,6 +944,7 @@ void wm_drags_draw(bContext *C, wmWindow *win) if (drag->drop_state.active_dropbox) { CTX_wm_area_set(C, drag->drop_state.area_from); CTX_wm_region_set(C, drag->drop_state.region_from); + CTX_store_set(C, drag->drop_state.ui_context); /* Drawing should be allowed to assume the context from handling and polling (that's why we * restore it above). */ @@ -915,4 +963,5 @@ void wm_drags_draw(bContext *C, wmWindow *win) GPU_blend(GPU_BLEND_NONE); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); + CTX_store_set(C, NULL); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 28d8413fe0b..5210b315af6 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -51,6 +51,7 @@ #include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -312,28 +313,39 @@ void WM_main_remove_notifier_reference(const void *reference) } } -void WM_main_remap_editor_id_reference(ID *old_id, ID *new_id) +static void wm_main_remap_assetlist(ID *old_id, ID *new_id, void *UNUSED(user_data)) +{ + ED_assetlist_storage_id_remap(old_id, new_id); +} + +static void wm_main_remap_msgbus_notify(ID *old_id, ID *new_id, void *user_data) +{ + struct wmMsgBus *mbus = user_data; + if (new_id != NULL) { + WM_msg_id_update(mbus, old_id, new_id); + } + else { + WM_msg_id_remove(mbus, old_id); + } +} + +void WM_main_remap_editor_id_reference(const struct IDRemapper *mappings) { Main *bmain = G_MAIN; LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - ED_spacedata_id_remap(area, sl, old_id, new_id); + ED_spacedata_id_remap(area, sl, mappings); } } } - ED_assetlist_storage_id_remap(old_id, new_id); + + BKE_id_remapper_iter(mappings, wm_main_remap_assetlist, NULL); wmWindowManager *wm = bmain->wm.first; if (wm && wm->message_bus) { - struct wmMsgBus *mbus = wm->message_bus; - if (new_id != NULL) { - WM_msg_id_update(mbus, old_id, new_id); - } - else { - WM_msg_id_remove(mbus, old_id); - } + BKE_id_remapper_iter(mappings, wm_main_remap_msgbus_notify, wm->message_bus); } } @@ -633,6 +645,20 @@ static int wm_event_always_pass(const wmEvent *event) return ISTIMER(event->type) || (event->type == WINDEACTIVATE); } +/** + * Debug only sanity check for the return value of event handlers. Checks that "always pass" events + * don't cause non-passing handler return values, and thus actually pass. + * + * Can't be executed if the handler just loaded a file (typically identified by `CTX_wm_window(C)` + * returning `NULL`), because the event will have been freed then. + */ +BLI_INLINE void wm_event_handler_return_value_check(const wmEvent *event, const int action) +{ + BLI_assert_msg(!wm_event_always_pass(event) || (action != WM_HANDLER_BREAK), + "Return value for events that should always pass should never be BREAK."); + UNUSED_VARS_NDEBUG(event, action); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1055,7 +1081,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons } } - /* XXX(mont29) Disabled the repeat check to address part 2 of T31840. + /* XXX(@mont29): Disabled the repeat check to address part 2 of T31840. * Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason * why this was needed, but worth to note it in case something turns bad. */ if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED) /* && repeat == 0 */) { @@ -2953,9 +2979,9 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis wmWindowManager *wm = CTX_wm_manager(C); int action = WM_HANDLER_CONTINUE; - int always_pass; if (handlers == NULL) { + wm_event_handler_return_value_check(event, action); return action; } @@ -2976,7 +3002,7 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis } else if (handler_base->poll == NULL || handler_base->poll(CTX_wm_region(C), event)) { /* In advance to avoid access to freed event on window close. */ - always_pass = wm_event_always_pass(event); + const int always_pass = wm_event_always_pass(event); /* Modal+blocking handler_base. */ if (handler_base->flag & WM_HANDLER_BLOCKING) { @@ -3050,6 +3076,8 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis event->customdata = NULL; event->custom = 0; + wm_drop_end(C, drag, drop); + /* XXX fileread case. */ if (CTX_wm_window(C) == NULL) { return action; @@ -3118,6 +3146,10 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis wm_cursor_arrow_move(CTX_wm_window(C), event); } + /* Do some extra sanity checking before returning the action. */ + if (CTX_wm_window(C) != NULL) { + wm_event_handler_return_value_check(event, action); + } return action; } @@ -3245,6 +3277,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } + wm_event_handler_return_value_check(event, action); return action; } @@ -3267,14 +3300,6 @@ static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect) return false; } -static bool wm_event_inside_region(const wmEvent *event, const ARegion *region) -{ - if (wm_event_always_pass(event)) { - return true; - } - return ED_region_contains_xy(region, event->xy); -} - static ScrArea *area_event_inside(bContext *C, const int xy[2]) { wmWindow *win = CTX_wm_window(C); @@ -3488,6 +3513,55 @@ static void wm_event_handle_xrevent(bContext *C, } #endif /* WITH_XR_OPENXR */ +static int wm_event_do_region_handlers(bContext *C, wmEvent *event, ARegion *region) +{ + CTX_wm_region_set(C, region); + + /* Call even on non mouse events, since the */ + wm_region_mouse_co(C, event); + + const wmWindowManager *wm = CTX_wm_manager(C); + if (!BLI_listbase_is_empty(&wm->drags)) { + /* Does polls for drop regions and checks #uiButs. */ + /* Need to be here to make sure region context is true. */ + if (ELEM(event->type, MOUSEMOVE, EVT_DROP) || ISKEYMODIFIER(event->type)) { + wm_drags_check_ops(C, event); + } + } + + return wm_handlers_do(C, event, ®ion->handlers); +} + +/** + * Send event to region handlers in \a area. + * + * Two cases: + * 1) Always pass events (#wm_event_always_pass()) are sent to all regions. + * 2) Event is passed to the region visually under the cursor (#ED_area_find_region_xy_visual()). + */ +static int wm_event_do_handlers_area_regions(bContext *C, wmEvent *event, ScrArea *area) +{ + /* Case 1. */ + if (wm_event_always_pass(event)) { + int action = WM_HANDLER_CONTINUE; + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + action |= wm_event_do_region_handlers(C, event, region); + } + + wm_event_handler_return_value_check(event, action); + return action; + } + + /* Case 2. */ + ARegion *region_hovered = ED_area_find_region_xy_visual(area, RGN_TYPE_ANY, event->xy); + if (!region_hovered) { + return WM_HANDLER_CONTINUE; + } + + return wm_event_do_region_handlers(C, event, region_hovered); +} + void wm_event_do_handlers(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); @@ -3517,7 +3591,7 @@ void wm_event_do_handlers(bContext *C) if (scene_eval != NULL) { const int is_playing_sound = BKE_sound_scene_playing(scene_eval); - if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) { + if (scene_eval->id.recalc & ID_RECALC_FRAME_CHANGE) { /* Ignore seek here, the audio will be updated to the scene frame after jump during next * dependency graph update. */ } @@ -3670,36 +3744,12 @@ void wm_event_do_handlers(bContext *C) if (wm_event_inside_rect(event, &area->totrct)) { CTX_wm_area_set(C, area); - if ((action & WM_HANDLER_BREAK) == 0) { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (wm_event_inside_region(event, region)) { - - CTX_wm_region_set(C, region); + action |= wm_event_do_handlers_area_regions(C, event, area); - /* Call even on non mouse events, since the */ - wm_region_mouse_co(C, event); - - if (!BLI_listbase_is_empty(&wm->drags)) { - /* Does polls for drop regions and checks #uiButs. */ - /* Need to be here to make sure region context is true. */ - if (ELEM(event->type, MOUSEMOVE, EVT_DROP) || ISKEYMODIFIER(event->type)) { - wm_drags_check_ops(C, event); - } - } - - action |= wm_handlers_do(C, event, ®ion->handlers); - - /* Fileread case (python), T29489. */ - if (CTX_wm_window(C) == NULL) { - wm_event_free_and_remove_from_queue_if_valid(event); - return; - } - - if (action & WM_HANDLER_BREAK) { - break; - } - } - } + /* Fileread case (python), T29489. */ + if (CTX_wm_window(C) == NULL) { + wm_event_free_and_remove_from_queue_if_valid(event); + return; } CTX_wm_region_set(C, NULL); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1478712c3cd..9b9aa37a251 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -874,18 +874,16 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) duration_lib_override_recursive_resync_seconds); } - if (bf_reports->count.linked_proxies != 0 || - bf_reports->count.proxies_to_lib_overrides_success != 0 || + if (bf_reports->count.proxies_to_lib_overrides_success != 0 || bf_reports->count.proxies_to_lib_overrides_failures != 0) { - BKE_reportf(bf_reports->reports, - RPT_WARNING, - "Proxies are deprecated (%d proxies were automatically converted to library " - "overrides, %d proxies could not be converted and %d linked proxies were kept " - "untouched). If you need to keep proxies for the time being, please disable the " - "`Proxy to Override Auto Conversion` in Experimental user preferences", - bf_reports->count.proxies_to_lib_overrides_success, - bf_reports->count.proxies_to_lib_overrides_failures, - bf_reports->count.linked_proxies); + BKE_reportf( + bf_reports->reports, + RPT_WARNING, + "Proxies have been removed from Blender (%d proxies were automatically converted " + "to library overrides, %d proxies could not be converted and were cleared). " + "Please also consider re-saving any library .blend file with the newest Blender version.", + bf_reports->count.proxies_to_lib_overrides_success, + bf_reports->count.proxies_to_lib_overrides_failures); } if (bf_reports->count.sequence_strips_skipped != 0) { @@ -2706,7 +2704,7 @@ static char *wm_open_mainfile_description(struct bContext *UNUSED(C), BLI_stat_t stats; if (BLI_stat(path, &stats) == -1) { - return BLI_sprintfN("%s\n\n%s", path, N_("File Not Found")); + return BLI_sprintfN("%s\n\n%s", path, TIP_("File Not Found")); } /* Date. */ @@ -2716,7 +2714,7 @@ static char *wm_open_mainfile_description(struct bContext *UNUSED(C), BLI_filelist_entry_datetime_to_string( NULL, (int64_t)stats.st_mtime, false, time_st, date_st, &is_today, &is_yesterday); if (is_today || is_yesterday) { - BLI_strncpy(date_st, is_today ? N_("Today") : N_("Yesterday"), sizeof(date_st)); + BLI_strncpy(date_st, is_today ? TIP_("Today") : TIP_("Yesterday"), sizeof(date_st)); } /* Size. */ @@ -2724,7 +2722,7 @@ static char *wm_open_mainfile_description(struct bContext *UNUSED(C), BLI_filelist_entry_size_to_string(NULL, (uint64_t)stats.st_size, false, size_str); return BLI_sprintfN( - "%s\n\n%s: %s %s\n%s: %s", path, N_("Modified"), date_st, time_st, N_("Size"), size_str); + "%s\n\n%s: %s %s\n%s: %s", path, TIP_("Modified"), date_st, time_st, TIP_("Size"), size_str); } /* currently fits in a pointer */ @@ -3171,8 +3169,8 @@ static char *wm_save_as_mainfile_get_description(bContext *UNUSED(C), PointerRNA *ptr) { if (RNA_boolean_get(ptr, "copy")) { - return BLI_strdup( - "Save the current file in the desired location but do not make the saved file active"); + return BLI_strdup(TIP_( + "Save the current file in the desired location but do not make the saved file active")); } return NULL; } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 957ec7d800d..1d26c58bcf9 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -252,7 +252,7 @@ void WM_init(bContext *C, int argc, const char **argv) BKE_region_callback_free_gizmomap_set(wm_gizmomap_remove); BKE_region_callback_refresh_tag_gizmomap_set(WM_gizmomap_tag_refresh); BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); - BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); + BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap_single); DEG_editors_set_update_cb(ED_render_id_flush_update, ED_render_scene_update); ED_spacetypes_init(); @@ -594,9 +594,7 @@ void WM_exit_ex(bContext *C, const bool do_python) DRW_opengl_context_destroy(); } -#ifdef WITH_INTERNATIONAL BLT_lang_free(); -#endif ANIM_keyingset_infos_exit(); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a1854a8ed86..a7b5b9bddda 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1483,7 +1483,11 @@ static bool wm_window_timer(const bContext *C) wt->delta = time - wt->ltime; wt->duration += wt->delta; wt->ltime = time; - wt->ntime = wt->stime + wt->timestep * ceil(wt->duration / wt->timestep); + + wt->ntime = wt->stime; + if (wt->timestep != 0.0f) { + wt->ntime += wt->timestep * ceil(wt->duration / wt->timestep); + } if (wt->event_type == TIMERJOBS) { wm_jobs_timer(wm, wt); @@ -1596,6 +1600,7 @@ void WM_event_timer_sleep(wmWindowManager *wm, wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); + BLI_assert(timestep >= 0.0f); wt->event_type = event_type; wt->ltime = PIL_check_seconds_timer(); @@ -1615,6 +1620,7 @@ wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); + BLI_assert(timestep >= 0.0f); wt->event_type = TIMERNOTIFIER; wt->ltime = PIL_check_seconds_timer(); |