diff options
Diffstat (limited to 'source/blender/windowmanager')
25 files changed, 465 insertions, 369 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 68e2c6b38f0..eaf32c06aba 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -178,12 +178,12 @@ void WM_opengl_context_dispose(void *context); void WM_opengl_context_activate(void *context); void WM_opengl_context_release(void *context); -/* WM_window_open alignment */ -typedef enum WindowAlignment { +/* #WM_window_open alignment */ +typedef enum eWindowAlignment { WIN_ALIGN_ABSOLUTE = 0, WIN_ALIGN_LOCATION_CENTER, WIN_ALIGN_PARENT_CENTER, -} WindowAlignment; +} eWindowAlignment; struct wmWindow *WM_window_open(struct bContext *C, const char *title, @@ -195,7 +195,7 @@ struct wmWindow *WM_window_open(struct bContext *C, bool toplevel, bool dialog, bool temp, - WindowAlignment alignment); + eWindowAlignment alignment); void WM_window_set_dpi(const wmWindow *win); @@ -272,13 +272,16 @@ typedef struct wmEventHandler_KeymapResult { } wmEventHandler_KeymapResult; typedef void(wmEventHandler_KeymapDynamicFn)(wmWindowManager *wm, + struct wmWindow *win, struct wmEventHandler_Keymap *handler, struct wmEventHandler_KeymapResult *km_result); void WM_event_get_keymap_from_toolsystem_fallback(struct wmWindowManager *wm, + struct wmWindow *win, struct wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result); void WM_event_get_keymap_from_toolsystem(struct wmWindowManager *wm, + struct wmWindow *win, struct wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result); @@ -293,6 +296,7 @@ void WM_event_set_keymap_handler_post_callback(struct wmEventHandler_Keymap *han void *user_data), void *user_data); void WM_event_get_keymaps_from_handler(wmWindowManager *wm, + struct wmWindow *win, struct wmEventHandler_Keymap *handler, struct wmEventHandler_KeymapResult *km_result); @@ -302,6 +306,7 @@ wmKeyMapItem *WM_event_match_keymap_item(struct bContext *C, wmKeyMapItem *WM_event_match_keymap_item_from_handlers(struct bContext *C, struct wmWindowManager *wm, + struct wmWindow *win, struct ListBase *handlers, const struct wmEvent *event); @@ -367,8 +372,8 @@ void WM_main_remap_editor_id_reference(struct ID *old_id, struct ID *new_id); /* reports */ void WM_report_banner_show(void); void WM_report_banners_cancel(struct Main *bmain); -void WM_report(ReportType type, const char *message); -void WM_reportf(ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3); +void WM_report(eReportType type, const char *message); +void WM_reportf(eReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3); struct wmEvent *wm_event_add_ex(struct wmWindow *win, const struct wmEvent *event_to_add, @@ -592,7 +597,7 @@ void WM_operator_py_idname(char *to, const char *from); bool WM_operator_py_idname_ok_or_report(struct ReportList *reports, const char *classname, const char *idname); -char *WM_context_path_resolve_property_full(struct bContext *C, +char *WM_context_path_resolve_property_full(const struct bContext *C, const PointerRNA *ptr, PropertyRNA *prop, int index); diff --git a/source/blender/windowmanager/WM_toolsystem.h b/source/blender/windowmanager/WM_toolsystem.h index 018165634f2..eb89fca7b56 100644 --- a/source/blender/windowmanager/WM_toolsystem.h +++ b/source/blender/windowmanager/WM_toolsystem.h @@ -134,6 +134,7 @@ void WM_toolsystem_refresh_active(struct bContext *C); void WM_toolsystem_refresh_screen_area(struct WorkSpace *workspace, struct ViewLayer *view_layer, struct ScrArea *area); +void WM_toolsystem_refresh_screen_window(struct wmWindow *win); void WM_toolsystem_refresh_screen_all(struct Main *bmain); #ifdef __cplusplus diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index c4612485e5a..f4595869baf 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -462,6 +462,10 @@ typedef struct wmNotifier { #define ND_ASSET_LIST (1 << 16) #define ND_ASSET_LIST_PREVIEW (2 << 16) #define ND_ASSET_LIST_READING (3 << 16) +/* Catalog data changed, requiring a redraw of catalog UIs. Note that this doesn't denote a + * reloading of asset libraries & their catalogs should happen. That only happens on explicit user + * action. */ +#define ND_ASSET_CATALOGS (4 << 16) /* subtype, 256 entries too */ #define NOTE_SUBTYPE 0x0000FF00 @@ -593,10 +597,10 @@ typedef struct wmTabletData { * - The previous values are only set for mouse button and keyboard events. * See: #ISMOUSE_BUTTON & #ISKEYBOARD macros. * - * - Previous x/y are exceptions: #wmEvent.prevx & #wmEvent.prevy + * - Previous x/y are exceptions: #wmEvent.prev * these are set on mouse motion, see #MOUSEMOVE & track-pad events. * - * - Modal key-map handling sets `prevval` & `prevtype` to `val` & `type`, + * - Modal key-map handling sets `prev_val` & `prev_type` to `val` & `type`, * this allows modal keys-maps to check the original values (needed in some cases). */ typedef struct wmEvent { @@ -607,7 +611,7 @@ typedef struct wmEvent { /** Press, release, scroll-value. */ short val; /** Mouse pointer position, screen coord. */ - int x, y; + int xy[2]; /** Region relative mouse position (name convention before Blender 2.5). */ int mval[2]; /** @@ -628,19 +632,19 @@ typedef struct wmEvent { char is_repeat; /** The previous value of `type`. */ - short prevtype; + short prev_type; /** The previous value of `val`. */ - short prevval; + short prev_val; /** The time when the key is pressed, see #PIL_check_seconds_timer. */ - double prevclicktime; + double prev_click_time; /** The location when the key is pressed (used to enforce drag thresholds). */ - int prevclickx, prevclicky; + int prev_click_xy[2]; /** - * The previous value of #wmEvent.x #wmEvent.y, + * The previous value of #wmEvent.xy, * Unlike other previous state variables, this is set on any mouse motion. - * Use `prevclickx` & `prevclicky` for the value at time of pressing. + * Use `prev_click` for the value at time of pressing. */ - int prevx, prevy; + int prev_xy[2]; /** Modifier states. */ /** 'oskey' is apple or windows-key, value denotes order of pressed. */ @@ -654,14 +658,14 @@ typedef struct wmEvent { /* Custom data. */ /** Custom data type, stylus, 6dof, see wm_event_types.h */ short custom; - short customdatafree; + short customdata_free; int pad2; /** Ascii, unicode, mouse-coords, angles, vectors, NDOF data, drag-drop info. */ void *customdata; /** * True if the operating system inverted the delta x/y values and resulting - * `prevx`, `prevy` values, for natural scroll direction. + * `prev_xy` values, for natural scroll direction. * For absolute scroll direction, the delta must be negated again. */ char is_direction_inverted; @@ -903,6 +907,9 @@ typedef struct wmOperatorType { /** RNA integration */ ExtensionRNA rna_ext; + /** Cursor to use when waiting for cursor input, see: #OPTYPE_DEPENDS_ON_CURSOR. */ + int cursor_pending; + /** Flag last for padding */ short flag; diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h index b667872a914..ceaec94e70b 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h @@ -380,7 +380,7 @@ typedef struct wmGizmoType { /** * Returns screen-space bounding box in the window space - * (compatible with #wmEvent.x #wmEvent.y). + * (compatible with #wmEvent.xy). * * Used for tool-tip placement (otherwise the cursor location is used). */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 7772c87f71c..b6d759eb95f 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -549,8 +549,8 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->type == EVT_MODAL_MAP) { event_modal_val = evil_event->val; - evil_event->type = evil_event->prevtype; - evil_event->val = evil_event->prevval; + evil_event->type = evil_event->prev_type; + evil_event->val = evil_event->prev_val; } int modal_retval = modal_fn(C, gz, event, mtweak->flag); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 295196c701b..18e1a8420a6 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -1073,7 +1073,7 @@ void wm_gizmomap_modal_set( if ((gz->flag & WM_GIZMO_MOVE_CURSOR) && (event->tablet.is_motion_absolute == false)) { WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, true, NULL); - copy_v2_v2_int(gzmap->gzmap_context.event_xy, &event->x); + copy_v2_v2_int(gzmap->gzmap_context.event_xy, event->xy); gzmap->gzmap_context.event_grabcursor = win->grabcursor; } else { diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index b76b1672543..9af90355a79 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -311,7 +311,8 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e const int winsize_y = WM_window_pixels_y(win); /* for multiwin drags, we only do this if mouse inside */ - if (event->x < 0 || event->y < 0 || event->x > winsize_x || event->y > winsize_y) { + if (event->xy[0] < 0 || event->xy[1] < 0 || event->xy[0] > winsize_x || + event->xy[1] > winsize_y) { return; } @@ -465,7 +466,8 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag) asset_drag->path, idtype, name, - BLO_LIBLINK_APPEND_RECURSIVE | FILE_ACTIVE_COLLECTION); + BLO_LIBLINK_APPEND_RECURSIVE | FILE_ACTIVE_COLLECTION | + BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR); case FILE_ASSET_IMPORT_APPEND_REUSE: return WM_file_append_datablock(G_MAIN, scene, @@ -475,6 +477,7 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag) idtype, name, BLO_LIBLINK_APPEND_RECURSIVE | FILE_ACTIVE_COLLECTION | + BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR | BLO_LIBLINK_APPEND_LOCAL_ID_REUSE); } @@ -650,8 +653,8 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect) wmWindowManager *wm = CTX_wm_manager(C); const int winsize_y = WM_window_pixels_y(win); - int cursorx = win->eventstate->x; - int cursory = win->eventstate->y; + int cursorx = win->eventstate->xy[0]; + int cursory = win->eventstate->xy[1]; if (rect) { rect->xmin = rect->xmax = cursorx; rect->ymin = rect->ymax = cursory; diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 328950cf8f9..b5e81528e2b 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -121,7 +121,7 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region) pc->draw(C, x, y, pc->customdata); } else { - pc->draw(C, win->eventstate->x, win->eventstate->y, pc->customdata); + pc->draw(C, win->eventstate->xy[0], win->eventstate->xy[1], pc->customdata); } GPU_scissor_test(false); diff --git a/source/blender/windowmanager/intern/wm_event_query.c b/source/blender/windowmanager/intern/wm_event_query.c index 8b77c460be3..9ee114674ed 100644 --- a/source/blender/windowmanager/intern/wm_event_query.c +++ b/source/blender/windowmanager/intern/wm_event_query.c @@ -82,7 +82,7 @@ void WM_event_print(const wmEvent *event) const char *prev_val_id = unknown; event_ids_from_type_and_value(event->type, event->val, &type_id, &val_id); - event_ids_from_type_and_value(event->prevtype, event->prevval, &prev_type_id, &prev_val_id); + event_ids_from_type_and_value(event->prev_type, event->prev_val, &prev_type_id, &prev_val_id); printf( "wmEvent type:%d / %s, val:%d / %s,\n" @@ -93,9 +93,9 @@ void WM_event_print(const wmEvent *event) type_id, event->val, val_id, - event->prevtype, + event->prev_type, prev_type_id, - event->prevval, + event->prev_val, prev_val_id, event->shift, event->ctrl, @@ -103,8 +103,8 @@ void WM_event_print(const wmEvent *event) event->oskey, event->keymodifier, event->is_repeat, - event->x, - event->y, + event->xy[0], + event->xy[1], event->ascii, BLI_str_utf8_size(event->utf8_buf), event->utf8_buf, @@ -288,8 +288,8 @@ bool WM_event_is_mouse_drag_or_press(const wmEvent *event) int WM_event_drag_threshold(const struct wmEvent *event) { int drag_threshold; - if (ISMOUSE(event->prevtype)) { - BLI_assert(event->prevtype != MOUSEMOVE); + if (ISMOUSE(event->prev_type)) { + BLI_assert(event->prev_type != MOUSEMOVE); /* Using the previous type is important is we want to check the last pressed/released button, * The `event->type` would include #MOUSEMOVE which is always the case when dragging * and does not help us know which threshold to use. */ @@ -315,10 +315,8 @@ bool WM_event_drag_test_with_delta(const wmEvent *event, const int drag_delta[2] bool WM_event_drag_test(const wmEvent *event, const int prev_xy[2]) { - const int drag_delta[2] = { - prev_xy[0] - event->x, - prev_xy[1] - event->y, - }; + int drag_delta[2]; + sub_v2_v2v2_int(drag_delta, prev_xy, event->xy); return WM_event_drag_test_with_delta(event, drag_delta); } @@ -476,7 +474,7 @@ bool WM_event_is_tablet(const struct wmEvent *event) int WM_event_absolute_delta_x(const struct wmEvent *event) { - int dx = event->x - event->prevx; + int dx = event->xy[0] - event->prev_xy[0]; if (!event->is_direction_inverted) { dx = -dx; @@ -487,7 +485,7 @@ int WM_event_absolute_delta_x(const struct wmEvent *event) int WM_event_absolute_delta_y(const struct wmEvent *event) { - int dy = event->y - event->prevy; + int dy = event->xy[1] - event->prev_xy[1]; if (!event->is_direction_inverted) { dy = -dy; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 785434c301c..df976d9a4cd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -152,25 +152,22 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add) /* Logic for setting previous value is documented on the #wmEvent struct, * see #wm_event_add_ghostevent for the implementation of logic this follows. */ - - win->eventstate->x = event->x; - win->eventstate->y = event->y; + copy_v2_v2_int(win->eventstate->xy, event->xy); if (event->type == MOUSEMOVE) { - win->eventstate->prevx = event->prevx = win->eventstate->x; - win->eventstate->prevy = event->prevy = win->eventstate->y; + copy_v2_v2_int(win->eventstate->prev_xy, win->eventstate->xy); + copy_v2_v2_int(event->prev_xy, win->eventstate->xy); } else if (ISMOUSE_BUTTON(event->type) || ISKEYBOARD(event->type)) { - win->eventstate->prevval = event->prevval = win->eventstate->val; - win->eventstate->prevtype = event->prevtype = win->eventstate->type; + win->eventstate->prev_val = event->prev_val = win->eventstate->val; + win->eventstate->prev_type = event->prev_type = win->eventstate->type; win->eventstate->val = event->val; win->eventstate->type = event->type; if (event->val == KM_PRESS) { if (event->is_repeat == false) { - win->eventstate->prevclickx = event->x; - win->eventstate->prevclicky = event->y; + copy_v2_v2_int(win->eventstate->prev_click_xy, event->xy); } } } @@ -189,7 +186,7 @@ void wm_event_free(wmEvent *event) #endif if (event->customdata) { - if (event->customdatafree) { + if (event->customdata_free) { /* NOTE: pointer to listbase struct elsewhere. */ if (event->custom == EVT_DATA_DRAGDROP) { ListBase *lb = event->customdata; @@ -505,8 +502,7 @@ void wm_event_do_notifiers(bContext *C) } } - if (note->window == win || - (note->window == NULL && (note->reference == NULL || note->reference == scene))) { + if (note->window == win || (note->window == NULL && (ELEM(note->reference, NULL, scene)))) { if (note->category == NC_SCENE) { if (note->data == ND_FRAME) { do_anim = true; @@ -581,7 +577,7 @@ void wm_event_do_notifiers(bContext *C) if ((note->category == NC_SPACE) && note->reference) { /* Filter out notifiers sent to other spaces. RNA sets the reference to the owning ID * though, the screen, so let notifiers through that reference the entire screen. */ - if (!ELEM(note->reference, area->spacedata.first, screen)) { + if (!ELEM(note->reference, area->spacedata.first, screen, scene)) { continue; } } @@ -804,7 +800,7 @@ static void wm_add_reports(ReportList *reports) } } -void WM_report(ReportType type, const char *message) +void WM_report(eReportType type, const char *message) { ReportList reports; BKE_reports_init(&reports, RPT_STORE); @@ -815,7 +811,7 @@ void WM_report(ReportType type, const char *message) BKE_reports_clear(&reports); } -void WM_reportf(ReportType type, const char *format, ...) +void WM_reportf(eReportType type, const char *format, ...) { va_list args; @@ -1286,8 +1282,8 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event) ARegion *region = CTX_wm_region(C); if (region) { /* Compatibility convention. */ - event->mval[0] = event->x - region->winrct.xmin; - event->mval[1] = event->y - region->winrct.ymin; + event->mval[0] = event->xy[0] - region->winrct.xmin; + event->mval[1] = event->xy[1] - region->winrct.ymin; } else { /* These values are invalid (avoid odd behavior by relying on old mval values). */ @@ -1423,10 +1419,10 @@ static int wm_operator_invoke(bContext *C, } if (region && region->regiontype == RGN_TYPE_WINDOW && - BLI_rcti_isect_pt_v(®ion->winrct, &event->x)) { + BLI_rcti_isect_pt_v(®ion->winrct, event->xy)) { winrect = ®ion->winrct; } - else if (area && BLI_rcti_isect_pt_v(&area->totrct, &event->x)) { + else if (area && BLI_rcti_isect_pt_v(&area->totrct, event->xy)) { winrect = &area->totrct; } @@ -1809,7 +1805,7 @@ void WM_operator_name_call_ptr_with_depends_on_cursor( } } - WM_cursor_modal_set(win, WM_CURSOR_PICK_AREA); + WM_cursor_modal_set(win, ot->cursor_pending); uiOperatorWaitForInput *opwait = MEM_callocN(sizeof(*opwait), __func__); opwait->optype_params.optype = ot; @@ -1894,7 +1890,8 @@ static void wm_handler_op_context(bContext *C, wmEventHandler_Op *handler, const CTX_wm_area_set(C, area); if (op && (op->flag & OP_IS_MODAL_CURSOR_REGION)) { - region = BKE_area_find_region_xy(area, handler->context.region_type, event->x, event->y); + region = BKE_area_find_region_xy( + area, handler->context.region_type, event->xy[0], event->xy[1]); if (region) { handler->context.region = region; } @@ -2109,8 +2106,8 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap, } struct wmEvent_ModalMapStore { - short prevtype; - short prevval; + short prev_type; + short prev_val; bool dbl_click_disabled; }; @@ -2158,19 +2155,19 @@ static void wm_event_modalkeymap_begin(const bContext *C, } if (event_match != NULL) { - event_backup->prevtype = event->prevtype; - event_backup->prevval = event->prevval; + event_backup->prev_type = event->prev_type; + event_backup->prev_val = event->prev_val; - event->prevtype = event_match->type; - event->prevval = event_match->val; + event->prev_type = event_match->type; + event->prev_val = event_match->val; event->type = EVT_MODAL_MAP; event->val = kmi->propvalue; /* Avoid double-click events even in the case of 'EVT_MODAL_MAP', * since it's possible users configure double-click keymap items * which would break when modal functions expect press/release. */ - if (event->prevtype == KM_DBL_CLICK) { - event->prevtype = KM_PRESS; + if (event->prev_type == KM_DBL_CLICK) { + event->prev_type = KM_PRESS; event_backup->dbl_click_disabled = true; } } @@ -2196,11 +2193,11 @@ static void wm_event_modalkeymap_end(wmEvent *event, const struct wmEvent_ModalMapStore *event_backup) { if (event->type == EVT_MODAL_MAP) { - event->type = event->prevtype; - event->val = event->prevval; + event->type = event->prev_type; + event->val = event->prev_val; - event->prevtype = event_backup->prevtype; - event->prevval = event_backup->prevval; + event->prev_type = event_backup->prev_type; + event->prev_val = event_backup->prev_val; } if (event_backup->dbl_click_disabled) { @@ -2492,7 +2489,8 @@ static int wm_handler_fileselect_do(bContext *C, wm_window_make_drawable(wm, ctx_win); /* Ensure correct cursor position, otherwise, popups may close immediately after * opening (UI_BLOCK_MOVEMOUSE_QUIT). */ - wm_cursor_position_get(ctx_win, &ctx_win->eventstate->x, &ctx_win->eventstate->y); + wm_cursor_position_get( + ctx_win, &ctx_win->eventstate->xy[0], &ctx_win->eventstate->xy[1]); wm->winactive = ctx_win; /* Reports use this... */ if (handler->context.win == win) { handler->context.win = NULL; @@ -2812,7 +2810,7 @@ static int wm_handlers_do_gizmo_handler(bContext *C, * noticeable for the node editor - where dragging on a node should move it, see: T73212. * note we still allow for starting the gizmo drag outside, then travel 'inside' the node. */ if (region->type->clip_gizmo_events_by_ui) { - if (UI_region_block_find_mouse_over(region, &event->x, true)) { + if (UI_region_block_find_mouse_over(region, event->xy, true)) { if (gz != NULL && event->type != EVT_GIZMO_UPDATE) { if (restore_highlight_unless_activated == false) { WM_tooltip_clear(C, CTX_wm_window(C)); @@ -2977,7 +2975,7 @@ static int wm_handlers_do_gizmo_handler(bContext *C, /** \name Handle Single Event (All Handler Types) * \{ */ -static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers) +static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, ListBase *handlers) { const bool do_debug_handler = (G.debug & G_DEBUG_HANDLERS) && @@ -3020,7 +3018,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; wmEventHandler_KeymapResult km_result; - WM_event_get_keymaps_from_handler(wm, handler, &km_result); + WM_event_get_keymaps_from_handler(wm, win, handler, &km_result); int action_iter = WM_HANDLER_CONTINUE; for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) { wmKeyMap *keymap = km_result.keymaps[km_index]; @@ -3161,7 +3159,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers /* This calls handlers twice - to solve (double-)click events. */ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { - int action = wm_handlers_do_intern(C, event, handlers); + int action = wm_handlers_do_intern(C, CTX_wm_window(C), event, handlers); /* Will be NULL in the file read case. */ wmWindow *win = CTX_wm_window(C); @@ -3173,27 +3171,24 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) /* Test for CLICK_DRAG events. */ if (wm_action_not_handled(action)) { if (win->event_queue_check_drag) { - if (WM_event_drag_test(event, &event->prevclickx)) { + if (WM_event_drag_test(event, event->prev_click_xy)) { win->event_queue_check_drag_handled = true; - int x = event->x; - int y = event->y; + int xy[2] = {UNPACK2(event->xy)}; short val = event->val; short type = event->type; - event->x = event->prevclickx; - event->y = event->prevclicky; + copy_v2_v2_int(event->xy, event->prev_click_xy); event->val = KM_CLICK_DRAG; - event->type = event->prevtype; + event->type = event->prev_type; CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG"); - action |= wm_handlers_do_intern(C, event, handlers); + action |= wm_handlers_do_intern(C, win, event, handlers); event->val = val; event->type = type; - event->x = x; - event->y = y; + copy_v2_v2_int(event->xy, xy); win->event_queue_check_click = false; if (!wm_action_not_handled(action)) { @@ -3208,7 +3203,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } else if (ISMOUSE_BUTTON(event->type) || ISKEYBOARD(event->type)) { - /* All events that don't set wmEvent.prevtype must be ignored. */ + /* All events that don't set wmEvent.prev_type must be ignored. */ /* Test for CLICK events. */ if (wm_action_not_handled(action)) { @@ -3226,32 +3221,29 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) win->event_queue_check_drag = false; } - if (event->prevtype == event->type) { + if (event->prev_type == event->type) { if (event->val == KM_RELEASE) { - if (event->prevval == KM_PRESS) { + if (event->prev_val == KM_PRESS) { if (win->event_queue_check_click == true) { - if (WM_event_drag_test(event, &event->prevclickx)) { + if (WM_event_drag_test(event, event->prev_click_xy)) { win->event_queue_check_click = false; win->event_queue_check_drag = false; } else { /* Position is where the actual click happens, for more * accurate selecting in case the mouse drifts a little. */ - int x = event->x; - int y = event->y; + int xy[2] = {UNPACK2(event->xy)}; - event->x = event->prevclickx; - event->y = event->prevclicky; + copy_v2_v2_int(event->xy, event->prev_click_xy); event->val = KM_CLICK; CLOG_INFO(WM_LOG_HANDLERS, 1, "handling CLICK"); - action |= wm_handlers_do_intern(C, event, handlers); + action |= wm_handlers_do_intern(C, win, event, handlers); event->val = KM_RELEASE; - event->x = x; - event->y = y; + copy_v2_v2_int(event->xy, xy); } } } @@ -3259,7 +3251,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) else if (event->val == KM_DBL_CLICK) { /* The underlying event is a press, so try and handle this. */ event->val = KM_PRESS; - action |= wm_handlers_do_intern(C, event, handlers); + action |= wm_handlers_do_intern(C, win, event, handlers); /* revert value if not handled */ if (wm_action_not_handled(action)) { @@ -3280,7 +3272,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) /* pass */ } else { - if (ISKEYMODIFIER(event->prevtype)) { + if (ISKEYMODIFIER(event->prev_type)) { win->event_queue_check_click = false; } } @@ -3302,7 +3294,7 @@ static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect) if (wm_event_always_pass(event)) { return true; } - if (BLI_rcti_isect_pt_v(rect, &event->x)) { + if (BLI_rcti_isect_pt_v(rect, event->xy)) { return true; } return false; @@ -3313,7 +3305,7 @@ 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->x); + return ED_region_contains_xy(region, event->xy); } static ScrArea *area_event_inside(bContext *C, const int xy[2]) @@ -3372,11 +3364,11 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event) } /* If previous position was not in current region, we have to set a temp new context. */ - if (region == NULL || !BLI_rcti_isect_pt_v(®ion->winrct, &event->prevx)) { + if (region == NULL || !BLI_rcti_isect_pt_v(®ion->winrct, event->prev_xy)) { ScrArea *area = CTX_wm_area(C); - CTX_wm_area_set(C, area_event_inside(C, &event->prevx)); - CTX_wm_region_set(C, region_event_inside(C, &event->prevx)); + CTX_wm_area_set(C, area_event_inside(C, event->prev_xy)); + CTX_wm_region_set(C, region_event_inside(C, event->prev_xy)); wm_paintcursor_tag(C, wm->paintcursors.first, CTX_wm_region(C)); @@ -3407,14 +3399,14 @@ static void wm_event_drag_and_drop_test(wmWindowManager *wm, wmWindow *win, wmEv /* Create customdata, first free existing. */ if (event->customdata) { - if (event->customdatafree) { + if (event->customdata_free) { MEM_freeN(event->customdata); } } event->custom = EVT_DATA_DRAGDROP; event->customdata = &wm->drags; - event->customdatafree = 1; + event->customdata_free = true; /* Clear drop icon. */ screen->do_draw_drag = true; @@ -3638,15 +3630,15 @@ void wm_event_do_handlers(bContext *C) /* Clear tool-tip on mouse move. */ if (screen->tool_tip && screen->tool_tip->exit_on_event) { if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { - if (len_manhattan_v2v2_int(screen->tool_tip->event_xy, &event->x) > U.move_threshold) { + if (len_manhattan_v2v2_int(screen->tool_tip->event_xy, event->xy) > U.move_threshold) { WM_tooltip_clear(C, win); } } } /* We let modal handlers get active area/region, also wm_paintcursor_test needs it. */ - CTX_wm_area_set(C, area_event_inside(C, &event->x)); - CTX_wm_region_set(C, region_event_inside(C, &event->x)); + CTX_wm_area_set(C, area_event_inside(C, event->xy)); + CTX_wm_region_set(C, region_event_inside(C, event->xy)); /* MVC demands to not draw in event handlers... * but we need to leave it for ogl selecting etc. */ @@ -3683,7 +3675,7 @@ void wm_event_do_handlers(bContext *C) if (event->type == MOUSEMOVE) { /* State variables in screen, cursors. * Also used in wm_draw.c, fails for modal handlers though. */ - ED_screen_set_active_region(C, win, &event->x); + ED_screen_set_active_region(C, win, event->xy); /* For regions having custom cursors. */ wm_paintcursor_test(C, event); } @@ -3705,7 +3697,7 @@ void wm_event_do_handlers(bContext *C) /* Update azones if needed - done here because it needs to be independent from redraws. */ if (area->flag & AREA_FLAG_ACTIONZONES_UPDATE) { - ED_area_azones_update(area, &event->x); + ED_area_azones_update(area, event->xy); } if (wm_event_inside_rect(event, &area->totrct)) { @@ -3758,8 +3750,8 @@ void wm_event_do_handlers(bContext *C) if ((action & WM_HANDLER_BREAK) == 0) { /* Also some non-modal handlers need active area/region. */ - CTX_wm_area_set(C, area_event_inside(C, &event->x)); - CTX_wm_region_set(C, region_event_inside(C, &event->x)); + CTX_wm_area_set(C, area_event_inside(C, event->xy)); + CTX_wm_region_set(C, region_event_inside(C, event->xy)); wm_region_mouse_co(C, event); @@ -3788,8 +3780,7 @@ void wm_event_do_handlers(bContext *C) } /* Update previous mouse position for following events to use. */ - win->eventstate->prevx = event->x; - win->eventstate->prevy = event->y; + copy_v2_v2_int(win->eventstate->prev_xy, event->xy); /* Unlink and free here, blender-quit then frees all. */ BLI_remlink(&win->event_queue, event); @@ -3799,10 +3790,10 @@ void wm_event_do_handlers(bContext *C) /* Only add mouse-move when the event queue was read entirely. */ if (win->addmousemove && win->eventstate) { wmEvent tevent = *(win->eventstate); - // printf("adding MOUSEMOVE %d %d\n", tevent.x, tevent.y); + // printf("adding MOUSEMOVE %d %d\n", tevent.xy[0], tevent.xy[1]); tevent.type = MOUSEMOVE; - tevent.prevx = tevent.x; - tevent.prevy = tevent.y; + tevent.prev_xy[0] = tevent.xy[0]; + tevent.prev_xy[1] = tevent.xy[1]; tevent.is_repeat = false; wm_event_add(win, &tevent); win->addmousemove = 0; @@ -3837,7 +3828,7 @@ void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval } /* Operator is supposed to have a filled "path" property. */ -/* Optional property: filetype (XXX enum?) */ +/* Optional property: file-type (XXX enum?) */ /** * The idea here is to keep a handler alive on window queue, owning the operator. @@ -4020,6 +4011,7 @@ wmEventHandler_Keymap *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap * Follow #wmEventHandler_KeymapDynamicFn signature. */ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, + wmWindow *win, wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result) { @@ -4028,7 +4020,13 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, const char *keymap_id_list[ARRAY_SIZE(km_result->keymaps)]; int keymap_id_list_len = 0; - const Scene *scene = wm->winactive->scene; + /* NOTE(@campbellbarton): If `win` is NULL, this function may not behave as expected. + * Assert since this should not happen in practice. + * If it does, the window could be looked up in `wm` using the `area`. + * Keep NULL checks in run-time code since any crashes here are difficult to redo. */ + BLI_assert_msg(win != NULL, "The window should always be set for tool interactions!"); + const Scene *scene = win ? win->scene : NULL; + ScrArea *area = handler->dynamic.user_data; handler->keymap_tool = NULL; bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL; @@ -4041,7 +4039,7 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, bool is_gizmo_highlight = false; if ((tref_rt && tref_rt->keymap_fallback[0]) && - (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK)) { + (scene && (scene->toolsettings->workspace_tool_type == SCE_WORKSPACE_TOOL_FALLBACK))) { bool add_keymap = false; /* Support for the gizmo owning the tool keymap. */ @@ -4100,6 +4098,7 @@ void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, } void WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, + wmWindow *UNUSED(win), wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result) { @@ -4173,10 +4172,10 @@ wmEventHandler_Keymap *WM_event_add_keymap_handler_priority(ListBase *handlers, static bool event_or_prev_in_rect(const wmEvent *event, const rcti *rect) { - if (BLI_rcti_isect_pt(rect, event->x, event->y)) { + if (BLI_rcti_isect_pt_v(rect, event->xy)) { return true; } - if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) { + if (event->type == MOUSEMOVE && BLI_rcti_isect_pt_v(rect, event->prev_xy)) { return true; } return false; @@ -4645,14 +4644,14 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g event->custom = EVT_DATA_NDOF_MOTION; event->customdata = data; - event->customdatafree = 1; + event->customdata_free = true; } #endif /* WITH_INPUT_NDOF */ /* Imperfect but probably usable... draw/enable drags to other windows. */ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event) { - int mval[2] = {event->x, event->y}; + int mval[2] = {event->xy[0], event->xy[1]}; if (wm->windows.first == wm->windows.last) { return NULL; @@ -4674,8 +4673,7 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi wmWindow *win_other = WM_window_find_under_cursor(wm, win, win, mval, mval); if (win_other) { - event->x = mval[0]; - event->y = mval[1]; + copy_v2_v2_int(event->xy, mval); return win_other; } } @@ -4684,13 +4682,13 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi static bool wm_event_is_double_click(const wmEvent *event) { - if ((event->type == event->prevtype) && (event->prevval == KM_RELEASE) && + if ((event->type == event->prev_type) && (event->prev_val == KM_RELEASE) && (event->val == KM_PRESS)) { - if (ISMOUSE(event->type) && WM_event_drag_test(event, &event->prevclickx)) { + if (ISMOUSE(event->type) && WM_event_drag_test(event, event->prev_click_xy)) { /* Pass. */ } else { - if ((PIL_check_seconds_timer() - event->prevclicktime) * 1000 < U.dbl_click_time) { + if ((PIL_check_seconds_timer() - event->prev_click_time) * 1000 < U.dbl_click_time) { return true; } } @@ -4704,15 +4702,15 @@ static bool wm_event_is_double_click(const wmEvent *event) */ static void wm_event_prev_values_set(wmEvent *event, wmEvent *event_state) { - event->prevval = event_state->prevval = event_state->val; - event->prevtype = event_state->prevtype = event_state->type; + event->prev_val = event_state->prev_val = event_state->val; + event->prev_type = event_state->prev_type = event_state->type; } static void wm_event_prev_click_set(wmEvent *event, wmEvent *event_state) { - event->prevclicktime = event_state->prevclicktime = PIL_check_seconds_timer(); - event->prevclickx = event_state->prevclickx = event_state->x; - event->prevclicky = event_state->prevclicky = event_state->y; + event->prev_click_time = event_state->prev_click_time = PIL_check_seconds_timer(); + event->prev_click_xy[0] = event_state->prev_click_xy[0] = event_state->xy[0]; + event->prev_click_xy[1] = event_state->prev_click_xy[1] = event_state->xy[1]; } static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event) @@ -4724,6 +4722,7 @@ static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event) * them for better performance. */ if (event_last && event_last->type == MOUSEMOVE) { event_last->type = INBETWEEN_MOUSEMOVE; + event_last->is_repeat = false; } wmEvent *event_new = wm_event_add(win, event); @@ -4731,7 +4730,7 @@ static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event) event_last = win->eventstate; } - copy_v2_v2_int(&event_new->prevx, &event_last->x); + copy_v2_v2_int(event_new->prev_xy, event_last->xy); return event_new; } @@ -4741,16 +4740,16 @@ static wmEvent *wm_event_add_trackpad(wmWindow *win, const wmEvent *event, int d * for painting with mouse moves, for navigation using the accumulated value is ok. */ wmEvent *event_last = win->event_queue.last; if (event_last && event_last->type == event->type) { - deltax += event_last->x - event_last->prevx; - deltay += event_last->y - event_last->prevy; + deltax += event_last->xy[0] - event_last->prev_xy[0]; + deltay += event_last->xy[1] - event_last->prev_xy[1]; wm_event_free_last(win); } - /* Set prevx/prevy, the delta is computed from this in operators. */ + /* Set prev_xy, the delta is computed from this in operators. */ wmEvent *event_new = wm_event_add(win, event); - event_new->prevx = event_new->x - deltax; - event_new->prevy = event_new->y - deltay; + event_new->prev_xy[0] = event_new->xy[0] - deltax; + event_new->prev_xy[1] = event_new->xy[1] - deltay; return event_new; } @@ -4790,8 +4789,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void * If this was done it could leave `win->eventstate` previous and current value * set to the same key press/release state which doesn't make sense. */ - event.prevtype = event.type; - event.prevval = event.val; + event.prev_type = event.type; + event.prev_val = event.val; /* Ensure the event state is correct, any deviation from this may cause bugs. * @@ -4805,12 +4804,12 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void "Non-keyboard/mouse button found in 'win->eventstate->type = %d'", event_state->type); } - if ((event_state->prevtype || event_state->prevval) && /* Ignore cleared event state. */ - !(ISMOUSE_BUTTON(event_state->prevtype) || ISKEYBOARD(event_state->prevtype) || + if ((event_state->prev_type || event_state->prev_val) && /* Ignore cleared event state. */ + !(ISMOUSE_BUTTON(event_state->prev_type) || ISKEYBOARD(event_state->prev_type) || (event_state->type == EVENT_NONE))) { CLOG_WARN(WM_LOG_HANDLERS, - "Non-keyboard/mouse button found in 'win->eventstate->prevtype = %d'", - event_state->prevtype); + "Non-keyboard/mouse button found in 'win->eventstate->prev_type = %d'", + event_state->prev_type); } #endif @@ -4819,14 +4818,14 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void case GHOST_kEventCursorMove: { GHOST_TEventCursorData *cd = customdata; - copy_v2_v2_int(&event.x, &cd->x); - wm_stereo3d_mouse_offset_apply(win, &event.x); + copy_v2_v2_int(event.xy, &cd->x); + wm_stereo3d_mouse_offset_apply(win, event.xy); wm_tablet_data_from_ghost(&cd->tablet, &event.tablet); event.type = MOUSEMOVE; { wmEvent *event_new = wm_event_add_mousemove(win, &event); - copy_v2_v2_int(&event_state->x, &event_new->x); + copy_v2_v2_int(event_state->xy, event_new->xy); event_state->tablet.is_motion_absolute = event_new->tablet.is_motion_absolute; } @@ -4837,14 +4836,14 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void wmEvent event_other = *win_other->eventstate; /* See comment for this operation on `event` for details. */ - event_other.prevtype = event_other.type; - event_other.prevval = event_other.val; + event_other.prev_type = event_other.type; + event_other.prev_val = event_other.val; - copy_v2_v2_int(&event_other.x, &event.x); + copy_v2_v2_int(event_other.xy, event.xy); event_other.type = MOUSEMOVE; { wmEvent *event_new = wm_event_add_mousemove(win_other, &event_other); - copy_v2_v2_int(&win_other->eventstate->x, &event_new->x); + copy_v2_v2_int(win_other->eventstate->xy, event_new->xy); win_other->eventstate->tablet.is_motion_absolute = event_new->tablet.is_motion_absolute; } } @@ -4871,8 +4870,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void break; } - event.x = event_state->x = pd->x; - event.y = event_state->y = pd->y; + event.xy[0] = event_state->xy[0] = pd->x; + event.xy[1] = event_state->xy[1] = pd->y; event.val = KM_NOTHING; /* The direction is inverted from the device due to system preferences. */ @@ -4936,10 +4935,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void wmEvent event_other = *win_other->eventstate; /* See comment for this operation on `event` for details. */ - event_other.prevtype = event_other.type; - event_other.prevval = event_other.val; + event_other.prev_type = event_other.type; + event_other.prev_val = event_other.val; - copy_v2_v2_int(&event_other.x, &event.x); + copy_v2_v2_int(event_other.xy, event.xy); event_other.type = event.type; event_other.val = event.val; @@ -5117,7 +5116,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void attach_ndof_data(&event, customdata); wm_event_add(win, &event); - CLOG_INFO(WM_LOG_HANDLERS, 1, "sending NDOF_MOTION, prev = %d %d", event.x, event.y); + CLOG_INFO(WM_LOG_HANDLERS, 1, "sending NDOF_MOTION, prev = %d %d", event.xy[0], event.xy[1]); break; } @@ -5198,7 +5197,7 @@ void wm_event_add_xrevent(wmWindow *win, wmXrActionData *actiondata, short val) .is_repeat = false, .custom = EVT_DATA_XR, .customdata = actiondata, - .customdatafree = 1, + .customdata_free = true, }; wm_event_add(win, &event); @@ -5256,11 +5255,12 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock) * \{ */ void WM_event_get_keymaps_from_handler(wmWindowManager *wm, + wmWindow *win, wmEventHandler_Keymap *handler, wmEventHandler_KeymapResult *km_result) { if (handler->dynamic.keymap_fn != NULL) { - handler->dynamic.keymap_fn(wm, handler, km_result); + handler->dynamic.keymap_fn(wm, win, handler, km_result); BLI_assert(handler->keymap == NULL); } else { @@ -5286,10 +5286,8 @@ wmKeyMapItem *WM_event_match_keymap_item(bContext *C, wmKeyMap *keymap, const wm return NULL; } -wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C, - wmWindowManager *wm, - ListBase *handlers, - const wmEvent *event) +wmKeyMapItem *WM_event_match_keymap_item_from_handlers( + bContext *C, wmWindowManager *wm, wmWindow *win, ListBase *handlers, const wmEvent *event) { LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { /* During this loop, UI handlers for nested menus can tag multiple handlers free. */ @@ -5300,7 +5298,7 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C, if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; wmEventHandler_KeymapResult km_result; - WM_event_get_keymaps_from_handler(wm, handler, &km_result); + WM_event_get_keymaps_from_handler(wm, win, handler, &km_result); for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) { wmKeyMap *keymap = km_result.keymaps[km_index]; if (WM_keymap_poll(C, keymap)) { @@ -5530,7 +5528,8 @@ void WM_window_cursor_keymap_status_refresh(bContext *C, wmWindow *win) wm_eventemulation(&test_event, true); wmKeyMapItem *kmi = NULL; for (int handler_index = 0; handler_index < ARRAY_SIZE(handlers); handler_index++) { - kmi = WM_event_match_keymap_item_from_handlers(C, wm, handlers[handler_index], &test_event); + kmi = WM_event_match_keymap_item_from_handlers( + C, wm, win, handlers[handler_index], &test_event); if (kmi) { break; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 564f869581a..e203281297b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -75,6 +75,7 @@ #include "BKE_addon.h" #include "BKE_appdir.h" +#include "BKE_asset_library.h" #include "BKE_autoexec.h" #include "BKE_blender.h" #include "BKE_blendfile.h" @@ -105,6 +106,7 @@ #include "IMB_imbuf_types.h" #include "IMB_thumbs.h" +#include "ED_asset.h" #include "ED_datafiles.h" #include "ED_fileselect.h" #include "ED_image.h" @@ -168,9 +170,13 @@ void WM_file_tag_modified(void) } } -bool wm_file_or_image_is_modified(const Main *bmain, const wmWindowManager *wm) +/** + * Check if there is data that would be lost when closing the current file without saving. + */ +bool wm_file_or_session_data_has_unsaved_changes(const Main *bmain, const wmWindowManager *wm) { - return !wm->file_saved || ED_image_should_save_modified(bmain); + return !wm->file_saved || ED_image_should_save_modified(bmain) || + BKE_asset_library_has_any_unsaved_catalogs(); } /** \} */ @@ -526,7 +532,7 @@ static int wm_read_exotic(const char *name) /* check for compressed .blend */ FileReader *compressed_file = NULL; if (BLI_file_magic_is_gzip(header)) { - /* In earlier versions of Blender (before 3.0), compressed files used Gzip instead of Zstd. + /* In earlier versions of Blender (before 3.0), compressed files used `Gzip` instead of `Zstd`. * While these files will no longer be written, there still needs to be reading support. */ compressed_file = BLI_filereader_new_gzip(rawfile); } @@ -3598,6 +3604,14 @@ static void wm_block_file_close_save_button(uiBlock *block, wmGenericCallback *p static const char *close_file_dialog_name = "file_close_popup"; +static void save_catalogs_when_file_is_closed_set_fn(bContext *UNUSED(C), + void *arg1, + void *UNUSED(arg2)) +{ + char *save_catalogs_when_file_is_closed = arg1; + ED_asset_catalogs_set_save_catalogs_when_file_is_saved(*save_catalogs_when_file_is_closed != 0); +} + static uiBlock *block_create__close_file_dialog(struct bContext *C, struct ARegion *region, void *arg1) @@ -3654,11 +3668,17 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, MEM_freeN(message); } + /* Used to determine if extra separators are needed. */ + bool has_extra_checkboxes = false; + /* Modified Images Checkbox. */ if (modified_images_count > 0) { char message[64]; BLI_snprintf(message, sizeof(message), "Save %u modified image(s)", modified_images_count); - uiItemS(layout); + /* Only the first checkbox should get extra separation. */ + if (!has_extra_checkboxes) { + uiItemS(layout); + } uiDefButBitC(block, UI_BTYPE_CHECKBOX, 1, @@ -3674,11 +3694,41 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, 0, 0, ""); + has_extra_checkboxes = true; + } + + if (BKE_asset_library_has_any_unsaved_catalogs()) { + static char save_catalogs_when_file_is_closed; + + save_catalogs_when_file_is_closed = ED_asset_catalogs_get_save_catalogs_when_file_is_saved(); + + /* Only the first checkbox should get extra separation. */ + if (!has_extra_checkboxes) { + uiItemS(layout); + } + uiBut *but = uiDefButBitC(block, + UI_BTYPE_CHECKBOX, + 1, + 0, + "Save modified asset catalogs", + 0, + 0, + 0, + UI_UNIT_Y, + &save_catalogs_when_file_is_closed, + 0, + 0, + 0, + 0, + ""); + UI_but_func_set( + but, save_catalogs_when_file_is_closed_set_fn, &save_catalogs_when_file_is_closed, NULL); + has_extra_checkboxes = true; } BKE_reports_clear(&reports); - uiItemS_ex(layout, modified_images_count > 0 ? 2.0f : 4.0f); + uiItemS_ex(layout, has_extra_checkboxes ? 2.0f : 4.0f); /* Buttons. */ #ifdef _WIN32 @@ -3759,7 +3809,7 @@ bool wm_operator_close_file_dialog_if_needed(bContext *C, wmGenericCallbackFn post_action_fn) { if (U.uiflag & USER_SAVE_PROMPT && - wm_file_or_image_is_modified(CTX_data_main(C), CTX_wm_manager(C))) { + wm_file_or_session_data_has_unsaved_changes(CTX_data_main(C), CTX_wm_manager(C))) { wmGenericCallback *callback = MEM_callocN(sizeof(*callback), __func__); callback->exec = post_action_fn; callback->user_data = IDP_CopyProperty(op->properties); diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 260ea73cc3b..c88e577df6a 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -312,31 +312,6 @@ static bool object_in_any_collection(Main *bmain, Object *ob) return false; } -/** - * Shared operations to perform on the object's base after adding it to the scene. - */ -static void wm_append_loose_data_instantiate_object_base_instance_init( - Object *ob, bool set_selected, bool set_active, ViewLayer *view_layer, const View3D *v3d) -{ - Base *base = BKE_view_layer_base_find(view_layer, ob); - - if (v3d != NULL) { - base->local_view_bits |= v3d->local_view_uuid; - } - - if (set_selected) { - if (base->flag & BASE_SELECTABLE) { - base->flag |= BASE_SELECTED; - } - } - - if (set_active) { - view_layer->basact = base; - } - - BKE_scene_object_base_flag_sync_from_base(base); -} - static ID *wm_append_loose_data_instantiate_process_check(WMLinkAppendDataItem *item) { /* We consider that if we either kept it linked, or re-used already local data, instantiation @@ -402,7 +377,6 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data, Collection *active_collection = NULL; const bool do_obdata = (lapp_data->flag & BLO_LIBLINK_OBDATA_INSTANCE) != 0; - const bool object_set_selected = (lapp_data->flag & FILE_AUTOSELECT) != 0; /* Do NOT make base active here! screws up GUI stuff, * if you want it do it at the editor level. */ const bool object_set_active = false; @@ -462,7 +436,8 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data, * children. */ Collection *collection = (Collection *)id; - bool do_add_collection = false; + /* We always add collections directly selected by the user. */ + bool do_add_collection = (item->append_tag & WM_APPEND_TAG_INDIRECT) == 0; LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) { Object *ob = coll_ob->ob; if (!object_in_any_scene(bmain, ob)) { @@ -483,14 +458,12 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data, ob->type = OB_EMPTY; ob->empty_drawsize = U.collection_instance_empty_size; - BKE_collection_object_add(bmain, active_collection, ob); - const bool set_selected = (lapp_data->flag & FILE_AUTOSELECT) != 0; /* TODO: why is it OK to make this active here but not in other situations? * See other callers of #object_base_instance_init */ const bool set_active = set_selected; - wm_append_loose_data_instantiate_object_base_instance_init( - ob, set_selected, set_active, view_layer, v3d); + BLO_object_instantiate_object_base_instance_init( + bmain, active_collection, ob, view_layer, v3d, lapp_data->flag, set_active); /* Assign the collection. */ ob->instance_collection = collection; @@ -537,10 +510,8 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data, CLAMP_MIN(ob->id.us, 0); ob->mode = OB_MODE_OBJECT; - BKE_collection_object_add(bmain, active_collection, ob); - - wm_append_loose_data_instantiate_object_base_instance_init( - ob, object_set_selected, object_set_active, view_layer, v3d); + BLO_object_instantiate_object_base_instance_init( + bmain, active_collection, ob, view_layer, v3d, lapp_data->flag, object_set_active); } if (!do_obdata) { @@ -571,10 +542,8 @@ static void wm_append_loose_data_instantiate(WMLinkAppendData *lapp_data, id_us_plus(id); BKE_object_materials_test(bmain, ob, ob->data); - BKE_collection_object_add(bmain, active_collection, ob); - - wm_append_loose_data_instantiate_object_base_instance_init( - ob, object_set_selected, object_set_active, view_layer, v3d); + BLO_object_instantiate_object_base_instance_init( + bmain, active_collection, ob, view_layer, v3d, lapp_data->flag, object_set_active); copy_v3_v3(ob->loc, scene->cursor.location); @@ -619,6 +588,13 @@ static int foreach_libblock_append_callback(LibraryIDLinkCallbackData *cb_data) return IDWALK_RET_NOP; } + const bool do_recursive = (data->lapp_data->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0; + if (!do_recursive && cb_data->id_owner->lib != id->lib) { + /* When `do_recursive` is false, we only make local IDs from same library(-ies) as the + * initially directly linked ones. */ + return IDWALK_RET_NOP; + } + WMLinkAppendDataItem *item = BLI_ghash_lookup(data->lapp_data->new_id_to_item, id); if (item == NULL) { item = wm_link_append_data_item_add(data->lapp_data, id->name, GS(id->name), NULL); @@ -651,10 +627,15 @@ static void wm_append_do(WMLinkAppendData *lapp_data, { BLI_assert((lapp_data->flag & FILE_LINK) == 0); - const bool do_recursive = (lapp_data->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0; const bool set_fakeuser = (lapp_data->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0; const bool do_reuse_local_id = (lapp_data->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) != 0; + const int make_local_common_flags = LIB_ID_MAKELOCAL_FULL_LIBRARY | + ((lapp_data->flag & BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR) != + 0 ? + LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR : + 0); + LinkNode *itemlink; /* Generate a mapping between newly linked IDs and their items, and tag linked IDs used as @@ -723,8 +704,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data, /* Only check dependencies if we are not keeping linked data, nor re-using existing local data. */ - if (do_recursive && - !ELEM(item->append_action, WM_APPEND_ACT_KEEP_LINKED, WM_APPEND_ACT_REUSE_LOCAL)) { + if (!ELEM(item->append_action, WM_APPEND_ACT_KEEP_LINKED, WM_APPEND_ACT_REUSE_LOCAL)) { WMLinkAppendDataCallBack cb_data = { .lapp_data = lapp_data, .item = item, .reports = reports}; BKE_library_foreach_ID_link( @@ -757,16 +737,14 @@ static void wm_append_do(WMLinkAppendData *lapp_data, BLI_strncpy(lib_id_name, id->name, sizeof(lib_id_name)); switch (item->append_action) { - case WM_APPEND_ACT_COPY_LOCAL: { - BKE_lib_id_make_local( - bmain, id, LIB_ID_MAKELOCAL_FULL_LIBRARY | LIB_ID_MAKELOCAL_FORCE_COPY); + case WM_APPEND_ACT_COPY_LOCAL: + BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_COPY); local_appended_new_id = id->newid; break; - } case WM_APPEND_ACT_MAKE_LOCAL: BKE_lib_id_make_local(bmain, id, - LIB_ID_MAKELOCAL_FULL_LIBRARY | LIB_ID_MAKELOCAL_FORCE_LOCAL | + make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL | LIB_ID_MAKELOCAL_OBJECT_NO_PROXY_CLEARING); BLI_assert(id->newid == NULL); local_appended_new_id = id; diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index ae2cdb5608c..ab971901a20 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -73,14 +73,14 @@ wmGesture *WM_gesture_new(wmWindow *window, const ARegion *region, const wmEvent rcti *rect = MEM_callocN(sizeof(rcti), "gesture rect new"); gesture->customdata = rect; - rect->xmin = event->x - gesture->winrct.xmin; - rect->ymin = event->y - gesture->winrct.ymin; + rect->xmin = event->xy[0] - gesture->winrct.xmin; + rect->ymin = event->xy[1] - gesture->winrct.ymin; if (type == WM_GESTURE_CIRCLE) { /* caller is responsible for initializing 'xmax' to radius. */ } else { - rect->xmax = event->x - gesture->winrct.xmin; - rect->ymax = event->y - gesture->winrct.ymin; + rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymax = event->xy[1] - gesture->winrct.ymin; } } else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) { @@ -88,8 +88,8 @@ wmGesture *WM_gesture_new(wmWindow *window, const ARegion *region, const wmEvent gesture->points_alloc = 1024; gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points"); - lasso[0] = event->x - gesture->winrct.xmin; - lasso[1] = event->y - gesture->winrct.ymin; + lasso[0] = event->xy[0] - gesture->winrct.xmin; + lasso[1] = event->xy[1] - gesture->winrct.ymin; gesture->points = 1; } diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c index 578699dda60..19b678d79d8 100644 --- a/source/blender/windowmanager/intern/wm_gesture_ops.c +++ b/source/blender/windowmanager/intern/wm_gesture_ops.c @@ -245,17 +245,17 @@ int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case MOUSEMOVE: { if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) { - rect->xmin = rect->xmax = event->x - gesture->winrct.xmin; - rect->ymin = rect->ymax = event->y - gesture->winrct.ymin; + rect->xmin = rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymin = rect->ymax = event->xy[1] - gesture->winrct.ymin; } else if (gesture->move) { BLI_rcti_translate(rect, - (event->x - gesture->winrct.xmin) - rect->xmax, - (event->y - gesture->winrct.ymin) - rect->ymax); + (event->xy[0] - gesture->winrct.xmin) - rect->xmax, + (event->xy[1] - gesture->winrct.ymin) - rect->ymax); } else { - rect->xmax = event->x - gesture->winrct.xmin; - rect->ymax = event->y - gesture->winrct.ymin; + rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymax = event->xy[1] - gesture->winrct.ymin; } gesture_box_apply_rect(op); @@ -365,8 +365,8 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->type == MOUSEMOVE) { - rect->xmin = event->x - gesture->winrct.xmin; - rect->ymin = event->y - gesture->winrct.ymin; + rect->xmin = event->xy[0] - gesture->winrct.xmin; + rect->ymin = event->xy[1] - gesture->winrct.ymin; wm_gesture_tag_redraw(win); @@ -381,7 +381,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->val) { case GESTURE_MODAL_CIRCLE_SIZE: - fac = 0.3f * (event->y - event->prevy); + fac = 0.3f * (event->xy[1] - event->prev_xy[1]); if (fac > 0) { rect->xmax += ceil(fac); } @@ -500,8 +500,8 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event) case MOUSEMOVE: case INBETWEEN_MOUSEMOVE: { - rect->xmax = event->x - gesture->winrct.xmin; - rect->ymax = event->y - gesture->winrct.ymin; + rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymax = event->xy[1] - gesture->winrct.ymin; const int val = wm_gesture_evaluate(gesture, event); if (val != 0) { @@ -510,8 +510,8 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event) wm_event_init_from_window(window, &tevent); /* We want to get coord from start of drag, * not from point where it becomes a tweak event, see T40549. */ - tevent.x = rect->xmin + gesture->winrct.xmin; - tevent.y = rect->ymin + gesture->winrct.ymin; + tevent.xy[0] = rect->xmin + gesture->winrct.xmin; + tevent.xy[1] = rect->ymin + gesture->winrct.ymin; if (gesture->event_type == LEFTMOUSE) { tevent.type = EVT_TWEAK_L; } @@ -696,8 +696,8 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event) { short(*lasso)[2] = gesture->customdata; - const int x = ((event->x - gesture->winrct.xmin) - lasso[gesture->points - 1][0]); - const int y = ((event->y - gesture->winrct.ymin) - lasso[gesture->points - 1][1]); + const int x = ((event->xy[0] - gesture->winrct.xmin) - lasso[gesture->points - 1][0]); + const int y = ((event->xy[1] - gesture->winrct.ymin) - lasso[gesture->points - 1][1]); /* move the lasso */ if (gesture->move) { @@ -709,8 +709,8 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Make a simple distance check to get a smoother lasso * add only when at least 2 pixels between this and previous location. */ else if ((x * x + y * y) > pow2f(2.0f * UI_DPI_FAC)) { - lasso[gesture->points][0] = event->x - gesture->winrct.xmin; - lasso[gesture->points][1] = event->y - gesture->winrct.ymin; + lasso[gesture->points][0] = event->xy[0] - gesture->winrct.xmin; + lasso[gesture->points][1] = event->xy[1] - gesture->winrct.ymin; gesture->points++; } } @@ -981,18 +981,18 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev switch (event->type) { case MOUSEMOVE: { if (gesture->is_active == false) { - rect->xmin = rect->xmax = event->x - gesture->winrct.xmin; - rect->ymin = rect->ymax = event->y - gesture->winrct.ymin; + rect->xmin = rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymin = rect->ymax = event->xy[1] - gesture->winrct.ymin; } else if (gesture->move) { BLI_rcti_translate(rect, - (event->x - gesture->winrct.xmin) - rect->xmax, - (event->y - gesture->winrct.ymin) - rect->ymax); + (event->xy[0] - gesture->winrct.xmin) - rect->xmax, + (event->xy[1] - gesture->winrct.ymin) - rect->ymax); gesture_straightline_apply(C, op); } else { - rect->xmax = event->x - gesture->winrct.xmin; - rect->ymax = event->y - gesture->winrct.ymin; + rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymax = event->xy[1] - gesture->winrct.ymin; gesture_straightline_apply(C, op); } @@ -1072,17 +1072,17 @@ int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmE switch (event->type) { case MOUSEMOVE: { if (gesture->is_active == false) { - rect->xmin = rect->xmax = event->x - gesture->winrct.xmin; - rect->ymin = rect->ymax = event->y - gesture->winrct.ymin; + rect->xmin = rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymin = rect->ymax = event->xy[1] - gesture->winrct.ymin; } else if (gesture->move) { BLI_rcti_translate(rect, - (event->x - gesture->winrct.xmin) - rect->xmax, - (event->y - gesture->winrct.ymin) - rect->ymax); + (event->xy[0] - gesture->winrct.xmin) - rect->xmax, + (event->xy[1] - gesture->winrct.ymin) - rect->ymax); } else { - rect->xmax = event->x - gesture->winrct.xmin; - rect->ymax = event->y - gesture->winrct.ymin; + rect->xmax = event->xy[0] - gesture->winrct.xmin; + rect->ymax = event->xy[1] - gesture->winrct.ymin; } if (gesture->use_snap) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index d4ef14bbf5d..d0693d37ef4 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -119,6 +119,7 @@ #include "ED_space_api.h" #include "ED_undo.h" #include "ED_util.h" +#include "ED_view3d.h" #include "BLF_api.h" #include "BLT_lang.h" @@ -547,6 +548,7 @@ void WM_exit_ex(bContext *C, const bool do_python) ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */ ED_assetlist_storage_exit(); + ED_view3d_cursor_snap_exit(); if (wm) { /* Before BKE_blender_free! - since the ListBases get freed there. */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index e5aedfc7f47..658424b84a6 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -1390,6 +1390,8 @@ static wmKeyMapItem *wm_keymap_item_find_in_keymap(wmKeyMap *keymap, } static wmKeyMapItem *wm_keymap_item_find_handlers(const bContext *C, + wmWindowManager *wm, + wmWindow *win, ListBase *handlers, const char *opname, int UNUSED(opcontext), @@ -1398,14 +1400,12 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(const bContext *C, const struct wmKeyMapItemFind_Params *params, wmKeyMap **r_keymap) { - wmWindowManager *wm = CTX_wm_manager(C); - /* find keymap item in handlers */ LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; wmEventHandler_KeymapResult km_result; - WM_event_get_keymaps_from_handler(wm, handler, &km_result); + WM_event_get_keymaps_from_handler(wm, win, handler, &km_result); for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) { wmKeyMap *keymap = km_result.keymaps[km_index]; if (WM_keymap_poll((bContext *)C, keymap)) { @@ -1436,6 +1436,7 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, const struct wmKeyMapItemFind_Params *params, wmKeyMap **r_keymap) { + wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -1443,17 +1444,25 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, /* look into multiple handler lists to find the item */ if (win) { - found = wm_keymap_item_find_handlers( - C, &win->modalhandlers, opname, opcontext, properties, is_strict, params, r_keymap); + found = wm_keymap_item_find_handlers(C, + wm, + win, + &win->modalhandlers, + opname, + opcontext, + properties, + is_strict, + params, + r_keymap); if (found == NULL) { found = wm_keymap_item_find_handlers( - C, &win->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + C, wm, win, &win->handlers, opname, opcontext, properties, is_strict, params, r_keymap); } } if (area && found == NULL) { found = wm_keymap_item_find_handlers( - C, &area->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + C, wm, win, &area->handlers, opname, opcontext, properties, is_strict, params, r_keymap); } if (found == NULL) { @@ -1464,8 +1473,16 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, } if (region) { - found = wm_keymap_item_find_handlers( - C, ®ion->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + found = wm_keymap_item_find_handlers(C, + wm, + win, + ®ion->handlers, + opname, + opcontext, + properties, + is_strict, + params, + r_keymap); } } } @@ -1475,8 +1492,16 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, } if (region) { - found = wm_keymap_item_find_handlers( - C, ®ion->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + found = wm_keymap_item_find_handlers(C, + wm, + win, + ®ion->handlers, + opname, + opcontext, + properties, + is_strict, + params, + r_keymap); } } else if (ELEM(opcontext, WM_OP_EXEC_REGION_PREVIEW, WM_OP_INVOKE_REGION_PREVIEW)) { @@ -1485,14 +1510,30 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, } if (region) { - found = wm_keymap_item_find_handlers( - C, ®ion->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + found = wm_keymap_item_find_handlers(C, + wm, + win, + ®ion->handlers, + opname, + opcontext, + properties, + is_strict, + params, + r_keymap); } } else { if (region) { - found = wm_keymap_item_find_handlers( - C, ®ion->handlers, opname, opcontext, properties, is_strict, params, r_keymap); + found = wm_keymap_item_find_handlers(C, + wm, + win, + ®ion->handlers, + opname, + opcontext, + properties, + is_strict, + params, + r_keymap); } } } diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index 39435721d1a..0e30df4ec99 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -110,6 +110,7 @@ static wmOperatorType *wm_operatortype_append__begin(void) /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT); ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT; + ot->cursor_pending = WM_CURSOR_PICK_AREA; return ot; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 81dcc5ccea0..89f0206d72e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -423,7 +423,9 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr * `object.data.bones["Bones"].use_deform` such paths are not useful for key-shortcuts, * so this function supports returning data-paths directly to context members that aren't ID types. */ -static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr, bool *r_is_id) +static const char *wm_context_member_from_ptr(const bContext *C, + const PointerRNA *ptr, + bool *r_is_id) { const char *member_id = NULL; bool is_id = false; @@ -541,50 +543,52 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr case ID_SCR: { CTX_TEST_PTR_ID(C, "screen", ptr->owner_id); - SpaceLink *space_data = CTX_wm_space_data(C); - - TEST_PTR_DATA_TYPE("space_data", RNA_Space, ptr, space_data); TEST_PTR_DATA_TYPE("area", RNA_Area, ptr, CTX_wm_area(C)); TEST_PTR_DATA_TYPE("region", RNA_Region, ptr, CTX_wm_region(C)); - switch (space_data->spacetype) { - case SPACE_VIEW3D: { - const View3D *v3d = (View3D *)space_data; - const View3DShading *shading = &v3d->shading; + SpaceLink *space_data = CTX_wm_space_data(C); + if (space_data != NULL) { + TEST_PTR_DATA_TYPE("space_data", RNA_Space, ptr, space_data); - TEST_PTR_DATA_TYPE("space_data.overlay", RNA_View3DOverlay, ptr, v3d); - TEST_PTR_DATA_TYPE("space_data.shading", RNA_View3DShading, ptr, shading); - break; - } - case SPACE_GRAPH: { - const SpaceGraph *sipo = (SpaceGraph *)space_data; - const bDopeSheet *ads = sipo->ads; - TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); - break; - } - case SPACE_FILE: { - const SpaceFile *sfile = (SpaceFile *)space_data; - const FileSelectParams *params = ED_fileselect_get_active_params(sfile); - TEST_PTR_DATA_TYPE("space_data.params", RNA_FileSelectParams, ptr, params); - break; - } - case SPACE_IMAGE: { - const SpaceImage *sima = (SpaceImage *)space_data; - TEST_PTR_DATA_TYPE("space_data.overlay", RNA_SpaceImageOverlay, ptr, sima); - TEST_PTR_DATA_TYPE("space_data.uv_editor", RNA_SpaceUVEditor, ptr, sima); - break; - } - case SPACE_NLA: { - const SpaceNla *snla = (SpaceNla *)space_data; - const bDopeSheet *ads = snla->ads; - TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); - break; - } - case SPACE_ACTION: { - const SpaceAction *sact = (SpaceAction *)space_data; - const bDopeSheet *ads = &sact->ads; - TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); - break; + switch (space_data->spacetype) { + case SPACE_VIEW3D: { + const View3D *v3d = (View3D *)space_data; + const View3DShading *shading = &v3d->shading; + + TEST_PTR_DATA_TYPE("space_data.overlay", RNA_View3DOverlay, ptr, v3d); + TEST_PTR_DATA_TYPE("space_data.shading", RNA_View3DShading, ptr, shading); + break; + } + case SPACE_GRAPH: { + const SpaceGraph *sipo = (SpaceGraph *)space_data; + const bDopeSheet *ads = sipo->ads; + TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); + break; + } + case SPACE_FILE: { + const SpaceFile *sfile = (SpaceFile *)space_data; + const FileSelectParams *params = ED_fileselect_get_active_params(sfile); + TEST_PTR_DATA_TYPE("space_data.params", RNA_FileSelectParams, ptr, params); + break; + } + case SPACE_IMAGE: { + const SpaceImage *sima = (SpaceImage *)space_data; + TEST_PTR_DATA_TYPE("space_data.overlay", RNA_SpaceImageOverlay, ptr, sima); + TEST_PTR_DATA_TYPE("space_data.uv_editor", RNA_SpaceUVEditor, ptr, sima); + break; + } + case SPACE_NLA: { + const SpaceNla *snla = (SpaceNla *)space_data; + const bDopeSheet *ads = snla->ads; + TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); + break; + } + case SPACE_ACTION: { + const SpaceAction *sact = (SpaceAction *)space_data; + const bDopeSheet *ads = &sact->ads; + TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads); + break; + } } } @@ -607,7 +611,7 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr /** * Calculate the path to `ptr` from context `C`, or return NULL if it can't be calculated. */ -char *WM_context_path_resolve_property_full(bContext *C, +char *WM_context_path_resolve_property_full(const bContext *C, const PointerRNA *ptr, PropertyRNA *prop, int index) @@ -2270,11 +2274,8 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e float d[2] = {0, 0}; float zoom[2] = {1, 1}; - rc->initial_mouse[0] = event->x; - rc->initial_mouse[1] = event->y; - - rc->initial_co[0] = event->x; - rc->initial_co[1] = event->y; + copy_v2_v2_int(rc->initial_mouse, event->xy); + copy_v2_v2_int(rc->initial_co, event->xy); switch (rc->subtype) { case PROP_NONE: @@ -2950,14 +2951,12 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even if (!has_numInput) { if (rc->slow_mode) { if (rc->subtype == PROP_ANGLE) { - const float position[2] = {event->x, event->y}; - /* calculate the initial angle here first */ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1]; /* precision angle gets calculated from dial and gets added later */ - angle_precision = -0.1f * BLI_dial_angle(rc->dial, position); + angle_precision = -0.1f * BLI_dial_angle(rc->dial, (float[2]){UNPACK2(event->xy)}); } else { delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0]; @@ -2970,7 +2969,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even dist = len_v2(delta); - delta[0] = event->x - rc->slow_mouse[0]; + delta[0] = event->xy[0] - rc->slow_mouse[0]; if (rc->zoom_prop) { delta[0] /= zoom[0]; @@ -2980,8 +2979,8 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even } } else { - delta[0] = rc->initial_mouse[0] - event->x; - delta[1] = rc->initial_mouse[1] - event->y; + delta[0] = (float)(rc->initial_mouse[0] - event->xy[0]); + delta[1] = (float)(rc->initial_mouse[1] - event->xy[1]); if (rc->zoom_prop) { RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); delta[0] /= zoom[0]; @@ -3048,8 +3047,8 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even case EVT_LEFTSHIFTKEY: case EVT_RIGHTSHIFTKEY: { if (event->val == KM_PRESS) { - rc->slow_mouse[0] = event->x; - rc->slow_mouse[1] = event->y; + rc->slow_mouse[0] = event->xy[0]; + rc->slow_mouse[1] = event->xy[1]; rc->slow_mode = true; if (rc->subtype == PROP_ANGLE) { const float initial_position[2] = {UNPACK2(rc->initial_mouse)}; diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index a7cdc0602bc..16a17484f4f 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -181,7 +181,7 @@ bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check) * If needed, adjust \a r_mouse_xy * so that drawn cursor and handled mouse position are matching visually. */ -void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy) +void wm_stereo3d_mouse_offset_apply(wmWindow *win, int r_mouse_xy[2]) { if (!WM_stereo3d_enabled(win, false)) { return; diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index 0c24520d565..3ac1a7c0be1 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -572,25 +572,29 @@ void WM_toolsystem_refresh_screen_area(WorkSpace *workspace, ViewLayer *view_lay } } +void WM_toolsystem_refresh_screen_window(wmWindow *win) +{ + WorkSpace *workspace = WM_window_get_active_workspace(win); + bool space_type_has_tools[SPACE_TYPE_LAST + 1] = {0}; + LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { + space_type_has_tools[tref->space_type] = true; + } + bScreen *screen = WM_window_get_active_screen(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + area->runtime.tool = NULL; + area->runtime.is_tool_set = true; + if (space_type_has_tools[area->spacetype]) { + WM_toolsystem_refresh_screen_area(workspace, view_layer, area); + } + } +} + void WM_toolsystem_refresh_screen_all(Main *bmain) { /* Update all ScrArea's tools */ for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) { LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { - WorkSpace *workspace = WM_window_get_active_workspace(win); - bool space_type_has_tools[SPACE_TYPE_LAST + 1] = {0}; - LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { - space_type_has_tools[tref->space_type] = true; - } - bScreen *screen = WM_window_get_active_screen(win); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - area->runtime.tool = NULL; - area->runtime.is_tool_set = true; - if (space_type_has_tools[area->spacetype]) { - WM_toolsystem_refresh_screen_area(workspace, view_layer, area); - } - } } } } diff --git a/source/blender/windowmanager/intern/wm_tooltip.c b/source/blender/windowmanager/intern/wm_tooltip.c index a9f0e01cfb5..3bcd122f08d 100644 --- a/source/blender/windowmanager/intern/wm_tooltip.c +++ b/source/blender/windowmanager/intern/wm_tooltip.c @@ -131,7 +131,7 @@ void WM_tooltip_init(bContext *C, wmWindow *win) CTX_wm_region_set(C, region_prev); } - copy_v2_v2_int(screen->tool_tip->event_xy, &win->eventstate->x); + copy_v2_v2_int(screen->tool_tip->event_xy, win->eventstate->xy); if (pass_prev != screen->tool_tip->pass) { /* The pass changed, add timer for next pass. */ wmWindowManager *wm = CTX_wm_manager(C); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 8baf4a0e013..5f684a752d8 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -49,6 +49,7 @@ #include "BKE_icons.h" #include "BKE_layer.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BKE_screen.h" #include "BKE_workspace.h" @@ -368,7 +369,8 @@ void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win) CTX_wm_window_set(C, win); if (U.uiflag & USER_SAVE_PROMPT) { - if (wm_file_or_image_is_modified(CTX_data_main(C), CTX_wm_manager(C)) && !G.background) { + if (wm_file_or_session_data_has_unsaved_changes(CTX_data_main(C), CTX_wm_manager(C)) && + !G.background) { wm_window_raise(win); wm_confirm_quit(C); } @@ -520,7 +522,7 @@ void WM_window_set_dpi(const wmWindow *win) static void wm_window_update_eventstate(wmWindow *win) { /* Update mouse position when a window is activated. */ - wm_cursor_position_get(win, &win->eventstate->x, &win->eventstate->y); + wm_cursor_position_get(win, &win->eventstate->xy[0], &win->eventstate->xy[1]); } static void wm_window_ensure_eventstate(wmWindow *win) @@ -772,7 +774,7 @@ wmWindow *WM_window_open(bContext *C, bool toplevel, bool dialog, bool temp, - WindowAlignment alignment) + eWindowAlignment alignment) { Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); @@ -852,7 +854,8 @@ wmWindow *WM_window_open(bContext *C, /* Set scene and view layer to match original window. */ STRNCPY(win->view_layer_name, view_layer->name); if (WM_window_get_active_scene(win) != scene) { - ED_screen_scene_change(C, win, scene); + /* No need to refresh the tool-system as the window has not yet finished being setup. */ + ED_screen_scene_change(C, win, scene, false); } screen->temp = temp; @@ -913,7 +916,7 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -int wm_window_new_exec(bContext *C, wmOperator *UNUSED(op)) +int wm_window_new_exec(bContext *C, wmOperator *op) { wmWindow *win_src = CTX_wm_window(C); ScrArea *area = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0); @@ -930,16 +933,23 @@ int wm_window_new_exec(bContext *C, wmOperator *UNUSED(op)) false, WIN_ALIGN_PARENT_CENTER) != NULL); - return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + if (!ok) { + BKE_report(op->reports, RPT_ERROR, "Failed to create window"); + return OPERATOR_CANCELLED; + } + return OPERATOR_FINISHED; } -int wm_window_new_main_exec(bContext *C, wmOperator *UNUSED(op)) +int wm_window_new_main_exec(bContext *C, wmOperator *op) { wmWindow *win_src = CTX_wm_window(C); bool ok = (wm_window_copy_test(C, win_src, true, false) != NULL); - - return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + if (!ok) { + BKE_report(op->reports, RPT_ERROR, "Failed to create window"); + return OPERATOR_CANCELLED; + } + return OPERATOR_FINISHED; } /* fullscreen operator callback */ @@ -989,8 +999,8 @@ void wm_cursor_position_to_ghost(wmWindow *win, int *x, int *y) void wm_cursor_position_get(wmWindow *win, int *r_x, int *r_y) { if (UNLIKELY(G.f & G_FLAG_EVENT_SIMULATE)) { - *r_x = win->eventstate->x; - *r_y = win->eventstate->y; + *r_x = win->eventstate->xy[0]; + *r_y = win->eventstate->xy[1]; return; } GHOST_GetCursorPosition(g_system, r_x, r_y); @@ -1265,8 +1275,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr wmEvent event; wm_event_init_from_window(win, &event); event.type = MOUSEMOVE; - event.prevx = event.x; - event.prevy = event.y; + copy_v2_v2_int(event.prev_xy, event.xy); event.is_repeat = false; wm_event_add(win, &event); @@ -1397,8 +1406,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr /* activate region */ event.type = MOUSEMOVE; - event.prevx = event.x; - event.prevy = event.y; + copy_v2_v2_int(event.prev_xy, event.xy); event.is_repeat = false; /* No context change! C->wm->windrawable is drawable, or for area queues. */ @@ -1413,7 +1421,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr event.val = KM_RELEASE; event.custom = EVT_DATA_DRAGDROP; event.customdata = &wm->drags; - event.customdatafree = 1; + event.customdata_free = true; wm_event_add(win, &event); @@ -2098,11 +2106,11 @@ void WM_cursor_warp(wmWindow *win, int x, int y) wm_cursor_position_to_ghost(win, &x, &y); GHOST_SetCursorPosition(g_system, x, y); - win->eventstate->prevx = oldx; - win->eventstate->prevy = oldy; + win->eventstate->prev_xy[0] = oldx; + win->eventstate->prev_xy[1] = oldy; - win->eventstate->x = oldx; - win->eventstate->y = oldy; + win->eventstate->xy[0] = oldx; + win->eventstate->xy[1] = oldy; } } @@ -2264,13 +2272,13 @@ void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene * /* Set scene in parent and its child windows. */ if (win_parent->scene != scene) { - ED_screen_scene_change(C, win_parent, scene); + ED_screen_scene_change(C, win_parent, scene, true); changed = true; } LISTBASE_FOREACH (wmWindow *, win_child, &wm->windows) { if (win_child->parent == win_parent && win_child->scene != scene) { - ED_screen_scene_change(C, win_child, scene); + ED_screen_scene_change(C, win_child, scene, true); changed = true; } } diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index af696ddd8f9..cfef70b7dcc 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -86,7 +86,7 @@ void WM_OT_splash_about(wmOperatorType *ot); void wm_stereo3d_draw_sidebyside(wmWindow *win, int view); void wm_stereo3d_draw_topbottom(wmWindow *win, int view); -void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy); +void wm_stereo3d_mouse_offset_apply(wmWindow *win, int r_mouse_xy[2]); int wm_stereo3d_set_exec(bContext *C, wmOperator *op); int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *event); void wm_stereo3d_set_draw(bContext *C, wmOperator *op); diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index 2fa5a68829e..135f31cf8ac 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -79,7 +79,7 @@ void wm_close_file_dialog(bContext *C, struct wmGenericCallback *post_action); bool wm_operator_close_file_dialog_if_needed(bContext *C, wmOperator *op, wmGenericCallbackFn exec_fn); -bool wm_file_or_image_is_modified(const Main *bmain, const wmWindowManager *wm); +bool wm_file_or_session_data_has_unsaved_changes(const Main *bmain, const wmWindowManager *wm); void WM_OT_save_homefile(struct wmOperatorType *ot); void WM_OT_save_userpref(struct wmOperatorType *ot); diff --git a/source/blender/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c index ba347c537ec..b5a606b4298 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_action.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c @@ -118,7 +118,7 @@ static wmXrAction *action_create(const char *action_name, action->states = MEM_calloc_arrayN(count, size, "XrAction_States"); action->states_prev = MEM_calloc_arrayN(count, size, "XrAction_StatesPrev"); - const bool is_float_action = (type == XR_FLOAT_INPUT || type == XR_VECTOR2F_INPUT); + const bool is_float_action = ELEM(type, XR_FLOAT_INPUT, XR_VECTOR2F_INPUT); const bool is_button_action = (is_float_action || type == XR_BOOLEAN_INPUT); if (is_float_action) { action->float_thresholds = MEM_calloc_arrayN( |