Skip to content

Commit dcb8877

Browse files
committed
core: Fix focusing behavior in SWF 8- vs 9+
As explained in the comment in player.rs, in SWF 9+, when needing to clear the focus, the focus only actually resets if the stage was clicked and the movie is AVM2.
1 parent 02be676 commit dcb8877

27 files changed

Lines changed: 409 additions & 3 deletions

File tree

core/src/focus_tracker.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ impl<'gc> FocusTracker<'gc> {
102102
&self,
103103
new: Option<InteractiveObject<'gc>>,
104104
context: &mut UpdateContext<'gc>,
105+
should_reset_focus: bool,
105106
) {
106107
let old = self.0.focus.get();
107108

@@ -117,6 +118,10 @@ impl<'gc> FocusTracker<'gc> {
117118
return;
118119
}
119120

121+
if !should_reset_focus {
122+
return;
123+
}
124+
120125
// When clicking an object that is not focusable by mouse,
121126
// the real object will be used to dispatch focus change events,
122127
// but `None` will be used when setting the focus.

core/src/player.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,13 +1909,19 @@ impl Player {
19091909
|| int.is_focusable_by_mouse(context)
19101910
});
19111911
if should_focus {
1912-
tracker.set_by_mouse(pressed_object, context);
1912+
tracker.set_by_mouse(pressed_object, context, true);
19131913
} else if tracker
19141914
.get()
19151915
.is_some_and(|int| int.is_focusable_by_mouse(context))
19161916
{
1917-
// Need to clear the focus if an object focusable by mouse was un-focused.
1918-
tracker.set_by_mouse(None, context);
1917+
// In SWF version 9 and above, when the pressed object is not
1918+
// focusable, the focus is not cleared, but only in AVM2 does
1919+
// clicking the stage (pressed_object.is_none()) clear the focus.
1920+
// (See the avm1/focus_swf8, avm1/focus_swf9, and avm2/focus_mixed_avm
1921+
// tests for examples of this behavior)
1922+
let should_reset_focus = context.root_swf.version() < 9
1923+
|| (pressed_object.is_none() && context.root_swf.is_action_script_3());
1924+
tracker.set_by_mouse(None, context, should_reset_focus);
19191925
}
19201926
}
19211927

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{ "type": "Wait" },
3+
{ "type": "Wait" },
4+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
5+
{ "type": "MouseDown", "pos": [1, 101], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 101], "btn": "Left" },
6+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
7+
{ "type": "MouseDown", "pos": [1, 151], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 151], "btn": "Left" },
8+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
9+
{ "type": "MouseDown", "pos": [1, 201], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 201], "btn": "Left" },
10+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
11+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
12+
{ "type": "MouseDown", "pos": [1, 101], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 101], "btn": "Left" },
13+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
14+
{ "type": "MouseDown", "pos": [1, 151], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 151], "btn": "Left" },
15+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
16+
{ "type": "MouseDown", "pos": [1, 201], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 201], "btn": "Left" }
17+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
null _level0.txt1
2+
_level0.txt1 null
3+
null _level0.txt1
4+
_level0.txt1 null
5+
btn clicked
6+
null _level0.txt1
7+
_level0.txt1 null
8+
null _level0.txt1
9+
_level0.txt1 _level0.txt2
10+
_level0.txt2 null
11+
null _level0.txt2
12+
_level0.txt2 null
13+
btn clicked
14+
null _level0.txt2
15+
_level0.txt2 null
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function drawRect(m, color) {
2+
with(m) {
3+
beginFill(color);
4+
lineTo(200, 0);
5+
lineTo(200, 50);
6+
lineTo(0, 50);
7+
lineTo(0, 0);
8+
endFill();
9+
}
10+
}
11+
12+
var txt1 = this.createTextField("txt1", 1, 0, 0, 200, 50);
13+
txt1.type = "input";
14+
15+
var txt2 = this.createTextField("txt2", 2, 0, 50, 200, 50);
16+
17+
this.createEmptyMovieClip("mc", 3);
18+
mc._y = 100;
19+
drawRect(mc, 0xFF0000);
20+
mc.focusEnabled = true;
21+
mc.tabEnabled = true;
22+
23+
this.createEmptyMovieClip("btn", 4);
24+
btn._y = 150;
25+
drawRect(btn, 0x00FF00);
26+
btn.onRelease = function() {
27+
trace("btn clicked");
28+
}
29+
30+
function onSetFocus(oldfocus, newfocus) {
31+
trace(oldfocus + " " + newfocus);
32+
}
33+
34+
Selection.addListener(this);
418 Bytes
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
num_ticks = 3
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{ "type": "Wait" },
3+
{ "type": "Wait" },
4+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
5+
{ "type": "MouseDown", "pos": [1, 101], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 101], "btn": "Left" },
6+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
7+
{ "type": "MouseDown", "pos": [1, 151], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 151], "btn": "Left" },
8+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
9+
{ "type": "MouseDown", "pos": [1, 201], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 201], "btn": "Left" },
10+
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
11+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
12+
{ "type": "MouseDown", "pos": [1, 101], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 101], "btn": "Left" },
13+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
14+
{ "type": "MouseDown", "pos": [1, 151], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 151], "btn": "Left" },
15+
{ "type": "MouseDown", "pos": [1, 51], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 51], "btn": "Left" },
16+
{ "type": "MouseDown", "pos": [1, 201], "btn": "Left" }, { "type": "MouseUp", "pos": [1, 201], "btn": "Left" }
17+
]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
null _level0.txt1
2+
btn clicked
3+
_level0.txt1 _level0.txt2
4+
btn clicked
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function drawRect(m, color) {
2+
with(m) {
3+
beginFill(color);
4+
lineTo(200, 0);
5+
lineTo(200, 50);
6+
lineTo(0, 50);
7+
lineTo(0, 0);
8+
endFill();
9+
}
10+
}
11+
12+
var txt1 = this.createTextField("txt1", 1, 0, 0, 200, 50);
13+
txt1.type = "input";
14+
15+
var txt2 = this.createTextField("txt2", 2, 0, 50, 200, 50);
16+
17+
this.createEmptyMovieClip("mc", 3);
18+
mc._y = 100;
19+
drawRect(mc, 0xFF0000);
20+
mc.focusEnabled = true;
21+
mc.tabEnabled = true;
22+
23+
this.createEmptyMovieClip("btn", 4);
24+
btn._y = 150;
25+
drawRect(btn, 0x00FF00);
26+
btn.onRelease = function() {
27+
trace("btn clicked");
28+
}
29+
30+
function onSetFocus(oldfocus, newfocus) {
31+
trace(oldfocus + " " + newfocus);
32+
}
33+
34+
Selection.addListener(this);

0 commit comments

Comments
 (0)