Operators: Add option to give a modal operator priority in event handling
This may be used by add-ons like screencast keys, to log events before a modal operator like transform handles them. Pull Request: https://projects.blender.org/blender/blender/pulls/122226
This commit is contained in:
committed by
Brecht Van Lommel
parent
412671a765
commit
6efd7a6a50
@@ -493,6 +493,12 @@ const EnumPropertyItem rna_enum_operator_type_flag_items[] = {
|
||||
"before beginning the operation"},
|
||||
{OPTYPE_PRESET, "PRESET", 0, "Preset", "Display a preset button with the operators settings"},
|
||||
{OPTYPE_INTERNAL, "INTERNAL", 0, "Internal", "Removes the operator from search results"},
|
||||
{OPTYPE_MODAL_PRIORITY,
|
||||
"MODAL_PRIORITY",
|
||||
0,
|
||||
"Modal Priority",
|
||||
"Handle events before other modal operators without this option. Use with caution, do not "
|
||||
"modify data that other modal operators assume is unchanged during their operation"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
|
||||
@@ -196,6 +196,9 @@ enum {
|
||||
* Even so, accessing from the menu should behave usefully.
|
||||
*/
|
||||
OPTYPE_DEPENDS_ON_CURSOR = (1 << 11),
|
||||
|
||||
/** Handle events before modal operators without this flag. */
|
||||
OPTYPE_MODAL_PRIORITY = (1 << 12),
|
||||
};
|
||||
|
||||
/** For #WM_cursor_grab_enable wrap axis. */
|
||||
|
||||
@@ -2465,6 +2465,36 @@ static void wm_event_modalkeymap_end(wmEvent *event, const wmEvent_ModalMapStore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert modal operator into list of modal handlers, respecting priority.
|
||||
*/
|
||||
static void wm_handler_operator_insert(wmWindow *win, wmEventHandler_Op *handler)
|
||||
{
|
||||
if (handler->op->type->flag & OPTYPE_MODAL_PRIORITY) {
|
||||
BLI_addhead(&win->modalhandlers, handler);
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (wmEventHandler *, handler_iter, &win->modalhandlers) {
|
||||
if (handler_iter->type == WM_HANDLER_TYPE_UI) {
|
||||
/* UI always has priority. */
|
||||
continue;
|
||||
}
|
||||
if (handler_iter->type == WM_HANDLER_TYPE_OP) {
|
||||
wmEventHandler_Op *handler_iter_op = (wmEventHandler_Op *)handler_iter;
|
||||
if (handler_iter_op->op->type->flag & OPTYPE_MODAL_PRIORITY) {
|
||||
/* Keep priority operators in front. */
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_insertlinkbefore(&win->modalhandlers, handler_iter, handler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_addtail(&win->modalhandlers, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* \warning this function removes a modal handler, when finished.
|
||||
*/
|
||||
@@ -4373,7 +4403,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
|
||||
handler->context.area = root_area;
|
||||
handler->context.region = root_region;
|
||||
|
||||
BLI_addhead(&root_win->modalhandlers, handler);
|
||||
wm_handler_operator_insert(root_win, handler);
|
||||
|
||||
/* Check props once before invoking if check is available
|
||||
* ensures initial properties are valid. */
|
||||
@@ -4476,7 +4506,7 @@ wmEventHandler_Op *WM_event_add_modal_handler_ex(wmWindow *win,
|
||||
handler->context.region_type = handler->context.region ? handler->context.region->regiontype :
|
||||
-1;
|
||||
|
||||
BLI_addhead(&win->modalhandlers, handler);
|
||||
wm_handler_operator_insert(win, handler);
|
||||
|
||||
if (op->type->modalkeymap) {
|
||||
WM_window_status_area_tag_redraw(win);
|
||||
|
||||
Reference in New Issue
Block a user