diff --git a/core/src/player.rs b/core/src/player.rs index 57fe5963e162..05aec51e4fbe 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -1542,6 +1542,9 @@ impl Player { for (object, event) in events { let display_object = object.as_displayobject(); if !display_object.avm1_removed() { + if event == ClipEvent::Press { + Self::update_focus_on_mouse_press(context, display_object); + } object.handle_clip_event(context, event); if display_object.movie().is_action_script_3() { object.event_dispatch_to_avm2(context, event); @@ -1575,6 +1578,23 @@ impl Player { needs_render } + fn update_focus_on_mouse_press(context: &mut UpdateContext, pressed_object: DisplayObject) { + let is_avm2 = context.swf.is_action_script_3(); + + // Update AVM1 focus + if !is_avm2 { + let tracker = context.focus_tracker; + // In AVM1 text fields are somewhat special when handling focus. + // When a text field is clicked, it gains focus, + // when something else is clicked, it loses the focus. + // However, this logic only applies to text fields, other objects + // (buttons, movie clips) neither gain focus nor lose it upon press. + if tracker.get_as_edit_text().is_some() && pressed_object.as_edit_text().is_none() { + tracker.set(None, context); + } + } + } + //Checks if two displayObjects have the same depth and id and accur in the same movie.s fn check_display_object_equality(object1: DisplayObject, object2: DisplayObject) -> bool { object1.depth() == object2.depth() diff --git a/tests/tests/swfs/avm1/focus_mouse/input.json b/tests/tests/swfs/avm1/focus_mouse/input.json new file mode 100644 index 000000000000..100832d87fc3 --- /dev/null +++ b/tests/tests/swfs/avm1/focus_mouse/input.json @@ -0,0 +1,34 @@ +[ + { "type": "MouseMove", "pos": [5, 5] }, + { "type": "MouseDown", "pos": [5, 5], "btn": "Left" }, { "type": "MouseUp", "pos": [5, 5], "btn": "Left" }, + + { "type": "MouseMove", "pos": [70, 175] }, + { "type": "MouseDown", "pos": [70, 175], "btn": "Left" }, { "type": "MouseUp", "pos": [70, 175], "btn": "Left" }, + { "type": "MouseMove", "pos": [5, 5] }, + { "type": "MouseDown", "pos": [5, 5], "btn": "Left" }, { "type": "MouseUp", "pos": [5, 5], "btn": "Left" }, + + { "type": "MouseMove", "pos": [230, 175] }, + { "type": "MouseDown", "pos": [230, 175], "btn": "Left" }, { "type": "MouseUp", "pos": [230, 175], "btn": "Left" }, + { "type": "MouseMove", "pos": [5, 5] }, + { "type": "MouseDown", "pos": [5, 5], "btn": "Left" }, { "type": "MouseUp", "pos": [5, 5], "btn": "Left" }, + + { "type": "MouseMove", "pos": [360, 190] }, + { "type": "MouseDown", "pos": [360, 190], "btn": "Left" }, { "type": "MouseUp", "pos": [360, 190], "btn": "Left" }, + { "type": "MouseMove", "pos": [5, 5] }, + { "type": "MouseDown", "pos": [5, 5], "btn": "Left" }, { "type": "MouseUp", "pos": [5, 5], "btn": "Left" }, + + { "type": "MouseMove", "pos": [360, 190] }, + { "type": "MouseDown", "pos": [360, 190], "btn": "Left" }, { "type": "MouseUp", "pos": [360, 190], "btn": "Left" }, + { "type": "MouseMove", "pos": [230, 175] }, + { "type": "MouseDown", "pos": [230, 175], "btn": "Left" }, { "type": "MouseUp", "pos": [230, 175], "btn": "Left" }, + + { "type": "MouseMove", "pos": [360, 190] }, + { "type": "MouseDown", "pos": [360, 190], "btn": "Left" }, { "type": "MouseUp", "pos": [360, 190], "btn": "Left" }, + { "type": "MouseMove", "pos": [70, 175] }, + { "type": "MouseDown", "pos": [70, 175], "btn": "Left" }, { "type": "MouseUp", "pos": [70, 175], "btn": "Left" }, + + { "type": "MouseMove", "pos": [360, 190] }, + { "type": "MouseDown", "pos": [360, 190], "btn": "Left" }, { "type": "MouseUp", "pos": [360, 190], "btn": "Left" }, + { "type": "MouseMove", "pos": [360, 190] }, + { "type": "MouseDown", "pos": [360, 190], "btn": "Left" }, { "type": "MouseUp", "pos": [360, 190], "btn": "Left" } +] diff --git a/tests/tests/swfs/avm1/focus_mouse/output.txt b/tests/tests/swfs/avm1/focus_mouse/output.txt new file mode 100644 index 000000000000..87c64f62c9a4 --- /dev/null +++ b/tests/tests/swfs/avm1/focus_mouse/output.txt @@ -0,0 +1,45 @@ +_level0.clip.onMouseDown +_level0.clip.onMouseUp +_level0.clip.onMouseDown +_level0.clip.onPress +_level0.clip.onMouseUp +_level0.clip.onRelease +_level0.clip.onMouseDown +_level0.clip.onMouseUp +_level0.clip.onMouseDown +press +_level0.button.onPress +_level0.clip.onMouseUp +release +_level0.button.onRelease +_level0.clip.onMouseDown +_level0.clip.onMouseUp +_level0.clip.onMouseDown +Focus at: _level0.text +_level0.clip.onMouseUp +_level0.clip.onMouseDown +Focus at: null +_level0.clip.onMouseUp +_level0.clip.onMouseDown +Focus at: _level0.text +_level0.clip.onMouseUp +_level0.clip.onMouseDown +Focus at: null +press +_level0.button.onPress +_level0.clip.onMouseUp +release +_level0.button.onRelease +_level0.clip.onMouseDown +Focus at: _level0.text +_level0.clip.onMouseUp +_level0.clip.onMouseDown +Focus at: null +_level0.clip.onPress +_level0.clip.onMouseUp +_level0.clip.onRelease +_level0.clip.onMouseDown +Focus at: _level0.text +_level0.clip.onMouseUp +_level0.clip.onMouseDown +_level0.clip.onMouseUp diff --git a/tests/tests/swfs/avm1/focus_mouse/test.as b/tests/tests/swfs/avm1/focus_mouse/test.as new file mode 100644 index 000000000000..4ba65cfe90a0 --- /dev/null +++ b/tests/tests/swfs/avm1/focus_mouse/test.as @@ -0,0 +1,20 @@ +var listener = new Object(); +listener.onSetFocus = function(oldFocus, newFocus) { + trace("Focus at: " + newFocus); +}; +Selection.addListener(listener); + +function setHandlers(obj) { + obj.onRelease = function () { trace(obj + ".onRelease"); } + obj.onKeyDown = function () { trace(obj + ".onKeyDown"); } + obj.onKeyUp = function () { trace(obj + ".onKeyUp"); } + obj.onPress = function () { trace(obj + ".onPress"); } + obj.onReleaseOutside = function () { trace(obj + ".onReleaseOutside"); } + obj.onMouseDown = function () { trace(obj + ".onMouseDown") } + obj.onMouseUp = function () { trace(obj + ".onMouseUp") } +} + +clip.focusEnabled = true; +setHandlers(clip); +setHandlers(button); +setHandlers(text); diff --git a/tests/tests/swfs/avm1/focus_mouse/test.swf b/tests/tests/swfs/avm1/focus_mouse/test.swf new file mode 100644 index 000000000000..8d86d3bc5503 Binary files /dev/null and b/tests/tests/swfs/avm1/focus_mouse/test.swf differ diff --git a/tests/tests/swfs/avm1/focus_mouse/test.toml b/tests/tests/swfs/avm1/focus_mouse/test.toml new file mode 100644 index 000000000000..cf6123969a1d --- /dev/null +++ b/tests/tests/swfs/avm1/focus_mouse/test.toml @@ -0,0 +1 @@ +num_ticks = 1