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:
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c49
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c152
-rw-r--r--source/blender/windowmanager/intern/wm_files.c30
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c4
-rw-r--r--source/blender/windowmanager/intern/wm_window.c8
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, &region->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, &region->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();