This avoids clicking buttons that are not in the foreground/modal
window. At the same time the onBroadcastMouseMessage() functionality
was expanded in such a way that added widgets to the broadcast are the
only ones allowed to re-capture the mouse (even if they are not in the
current foreground window). This is required so the Editor can be
scrolled when we are visualizing a Filter window with preview.
New functions added to simplify some code:
* Manager::transferAsMouseDownMessage()
* Manager::allowCapture()
* base::contains()
Related to #4963 and #4973.
When running multiple UI tests, if the mouse was moved on a created
window, it made the ui::details::removeWidget() fail because the
widget was still ui::Manager::widgetAssociatedToManager().
Prior to this fix, if all of the following conditions were met:
+ While a modal window (such as the Preferences dialog) was open.
+ 'Multiple window UI' was enabled.
+ A non-modal window (such as the Preview window) overlapped the modal
window.
+ The non-modal window was selected, so this window is on top of
the modal window.
Caused mouse clicks and movements within the overlay area of the
non-modal window to be incorrectly passed to the window below, i.e.
the modal window.
Instead, it would be expected that no action would be taken.
* Replaced ui::Overlays with ui::UILayer
* Refactored BrushPreview to use its own UILayer (+ new blender shader
for the negative black & white effect).
* Add a default back UILayer to each ui::Display
* Use ui::move_region() in this "back layer" when GPU is disabled.
Although we should completely remove ui::move_region in a future, for
CPU rendering sometimes it's faster to just move memory instead of
redrawing the widgets.
This patch includes a new ui::Manager::dontWaitEvents() function to
avoid waiting for any user interaction. The old editor_benchmark now
uses this new function too.
Now each widget is responsible to enable/disable its own HAS_MOUSE flag
in response to the kMouseEnter/Leave message received. Also there is no
need to iterate over the parents since these messages are propagated
to the parent
Instead of wrapping the MouseEnter and MouseLeave OS events handling
inside a UI CallbackMessage, we now enqueue the corresponding
kMouseEnterMessage and kMouseLeaveMessage
Callback messages were not being handled and since MouseEnter and
MouseLeave events were wrapped into CallbackMessages they were lost
and so never got called
Added REPORT_MOUSE/PAINT/TIMER_MESSAGES macros, and change _EVENTS to
_MESSAGES to avoid confusion with the current terminology.
The output string for each message was also simplified.
When we received a MouseEnter/Leave, we were processing those laf-os
events immediately without taking care of all the MouseMove/Down/Up
events in the middle. Now we enqueue all the events as
messages (MouseEnter -> MouseMove/Down/Up -> MouseLeave).
This is important because when we process MouseLeave we are calling
setMouse(nullptr), which resets the mouse widget HAS_MOUSE flag, and
some widgets needs to know if they have the mouse above before the
MouseUp event. With this change we can remove the
Widget::hasMouseOver() function (that was checking the global
ui::get_mouse_position() instead of the HAS_MOUSE flag directly).
Another change was introduced to keep the old behavior now that
hasMouseOver() is not available: the ui::Manager doesn't assign the
HAS_MOUSE flag if the mouse is captured (it only assign the HAS_MOUSE
to the widget with the mouse captured, or to no widget, at least until
the capture is released).
With multiple windows on, if a modal/foreground window like Canvas
Size (which has a special onBroadcastMouseMessage()) were running, and
there was a script dialog also opened on the background, the
non-foreground dialog could receive clicks. This patch fixes this
particular scenario (no other window than the actual foreground window
can receive mouse clicks).
Added properties needed to know where the mouse position is on the
editor canvas + a method to cancel app.editor:askPoint() from Lua.
Related to aseprite/Attachment-System#102
This is necessary to prevent the manager to invalidate a window whose relayout is not finished. This can happen when a script opens a new window when another is currently opening. For instance a script whose canvas.onpaint handler opens another dialog.
This might be a fix for two frequently reported crashes from Sentry:
1) In Manager::_closeWindow() (#3491): We can reproduce this bug (without
this patch) pressing Ctrl+S to save the active sprite and clicking
randomly in the menu bar (File, Edit, etc. options) to open other menu
boxes (a crash can happen when multiple windows UI is enabled).
2) In set_native_cursor_on_all_displays() (#2907): We weren't able to
reproduce this bug.
It looks like processing a specific kPaintMessage with
ui::Widget::sendMessage() might re-create the os::Surface and destroy
the previous one, so we need to keep a reference to the previous
surface just in case to keep it alive.
We aren't able to reproduce this crash, but we've received several
Sentry reports about it, only on Windows and since v1.2.34.1 (not sure
if it's related to that). We'll see if this does fix the crashes or we
have some kind of regression in the future.