[Bf-blender-cvs] [87c13ac68c4] master: UX: Prevent click-through panels and used header area

Julian Eisel noreply at git.blender.org
Thu Jan 27 18:41:32 CET 2022


Commit: 87c13ac68c477486adecd8d548a016309fc2b54d
Author: Julian Eisel
Date:   Thu Jan 27 18:35:43 2022 +0100
Branches: master
https://developer.blender.org/rB87c13ac68c477486adecd8d548a016309fc2b54d

UX: Prevent click-through panels and used header area

Does two main changes:
* Handle regions in the order as visible on screen. Practically this
  just means handling overlapping regions before non-overlapping ones.
* Don't handle any other regions after having found one containing the
  mouse pointer.

Fixes: T94016, T91538, T91579, T71899 (and a whole bunch of duplicates)
Addresses: T92364

Differential Revision: https://developer.blender.org/D13539

Reviewed by: Campbell Barton

===================================================================

M	source/blender/windowmanager/intern/wm_event_system.c

===================================================================

diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 91701a62e00..9d2c97e151f 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -3298,14 +3298,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);
@@ -3519,6 +3511,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);
@@ -3701,36 +3742,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)) {
+            action |= wm_event_do_handlers_area_regions(C, event, area);
 
-                  CTX_wm_region_set(C, region);
-
-                  /* 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);



More information about the Bf-blender-cvs mailing list