diff options
author | Julian Eisel <julian@blender.org> | 2021-11-04 14:10:58 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2021-11-04 14:20:37 +0300 |
commit | 80a46955d8212f01b77215ab12d479d934e305f4 (patch) | |
tree | 538ddd4b47c195df8006456c046d6dce6bad1a20 /source/blender/editors/screen | |
parent | bfb664b65de2c71ee3d85760ee5dcf83a7c9aa23 (diff) |
Fix T92501: Crash when dragging material assets over 3D View regions
Issue was that the context used for dropbox handling and polling didn't
match the one used for drawing the dropbox and generating the tooltip
text (which would determine the material slot under the cursor,
requiring context). The mismatch would happen with overlapping regions.
Actually, this patch includes two fixes, each fixing the crash itself:
* Store the context from handling & polling and restore it for drawing.
* Correct the hovered region lookup for drawing to account for overlayed
regions.
Note that to properly set up context for drawing, we should also account
for the operator context, which isn't done here, see
https://developer.blender.org/T92501#1247581.
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/area_query.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/source/blender/editors/screen/area_query.c b/source/blender/editors/screen/area_query.c index fd4f3964398..30e744ca174 100644 --- a/source/blender/editors/screen/area_query.c +++ b/source/blender/editors/screen/area_query.c @@ -140,6 +140,10 @@ bool ED_region_overlap_isect_xy_with_margin(const ARegion *region, ED_region_overlap_isect_y_with_margin(region, event_xy[1], margin)); } +/** + * \note: This may return true for multiple overlapping regions. If it matters, check overlapped + * regions first (#ARegion.overlap). + */ bool ED_region_contains_xy(const ARegion *region, const int event_xy[2]) { /* Only use the margin when inside the region. */ @@ -188,3 +192,44 @@ bool ED_region_contains_xy(const ARegion *region, const int event_xy[2]) } return false; } + +/** + * Similar to #BKE_area_find_region_xy() but when \a event_xy intersects an overlapping region, + * this returns the region that is visually under the cursor. E.g. when over the + * transparent part of the region, it returns the region underneath. + * + * The overlapping region is determined using the #ED_region_contains_xy() query. + */ +ARegion *ED_area_find_region_xy_visual(const ScrArea *area, + const int regiontype, + const int event_xy[2]) +{ + if (!area) { + return NULL; + } + + /* Check overlapped regions first. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (!region->overlap) { + continue; + } + if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) { + if (ED_region_contains_xy(region, event_xy)) { + return region; + } + } + } + /* Now non-overlapping ones. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->overlap) { + continue; + } + if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) { + if (ED_region_contains_xy(region, event_xy)) { + return region; + } + } + } + + return NULL; +} |