Skip to content

Commit 05f91dd

Browse files
committed
Make sure focus_lost messages is received
Fixes #42
1 parent b57609f commit 05f91dd

8 files changed

+278
-1
lines changed

example/example.collection

+5
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ embedded_instances {
281281
" type: PROPERTY_TYPE_URL\n"
282282
" }\n"
283283
" properties {\n"
284+
" id: \"focus_url\"\n"
285+
" value: \"about:/go#about\"\n"
286+
" type: PROPERTY_TYPE_URL\n"
287+
" }\n"
288+
" properties {\n"
284289
" id: \"preload\"\n"
285290
" value: \"true\"\n"
286291
" type: PROPERTY_TYPE_BOOLEAN\n"

monarch/monarch.lua

+15
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ local function pcallfn(fn, ...)
6767
if not ok then print(err) end
6868
end
6969
end
70+
71+
local function cowait(delay)
72+
local co = coroutine.running()
73+
assert(co, "You must run this form within a coroutine")
74+
timer.delay(delay, false, function()
75+
coroutine.resume(co)
76+
end)
77+
coroutine.yield()
78+
end
79+
7080
local function notify_transition_listeners(message_id, message)
7181
log("notify_transition_listeners()", message_id)
7282
for _,url in pairs(transition_listeners) do
@@ -364,6 +374,11 @@ local function focus_lost(screen, next_screen)
364374
log("focus_lost()", screen.id)
365375
if screen.focus_url then
366376
msg.post(screen.focus_url, M.FOCUS.LOST, { id = next_screen and next_screen.id })
377+
-- if there's no transition on the screen losing focus and it gets
378+
-- unloaded this will happen before the focus_lost message reaches
379+
-- the focus_url
380+
-- we add a delay to ensure the message queue has time to be processed
381+
cowait(0)
367382
else
368383
log("focus_lost() no focus url - ignoring")
369384
end

test/data/focus1.collection

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "focus1"
2+
scale_along_z: 0
3+
embedded_instances {
4+
id: "go"
5+
data: "components {\n"
6+
" id: \"focus1\"\n"
7+
" component: \"/test/data/focus1.gui\"\n"
8+
" position {\n"
9+
" x: 0.0\n"
10+
" y: 0.0\n"
11+
" z: 0.0\n"
12+
" }\n"
13+
" rotation {\n"
14+
" x: 0.0\n"
15+
" y: 0.0\n"
16+
" z: 0.0\n"
17+
" w: 1.0\n"
18+
" }\n"
19+
"}\n"
20+
""
21+
position {
22+
x: 0.0
23+
y: 0.0
24+
z: 0.0
25+
}
26+
rotation {
27+
x: 0.0
28+
y: 0.0
29+
z: 0.0
30+
w: 1.0
31+
}
32+
scale3 {
33+
x: 1.0
34+
y: 1.0
35+
z: 1.0
36+
}
37+
}

test/data/focus1.gui

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
script: "/test/data/focus1.gui_script"
2+
fonts {
3+
name: "example"
4+
font: "/assets/example.font"
5+
}
6+
background_color {
7+
x: 0.0
8+
y: 0.0
9+
z: 0.0
10+
w: 0.0
11+
}
12+
nodes {
13+
position {
14+
x: 320.0
15+
y: 568.0
16+
z: 0.0
17+
w: 1.0
18+
}
19+
rotation {
20+
x: 0.0
21+
y: 0.0
22+
z: 0.0
23+
w: 1.0
24+
}
25+
scale {
26+
x: 1.0
27+
y: 1.0
28+
z: 1.0
29+
w: 1.0
30+
}
31+
size {
32+
x: 200.0
33+
y: 100.0
34+
z: 0.0
35+
w: 1.0
36+
}
37+
color {
38+
x: 1.0
39+
y: 1.0
40+
z: 1.0
41+
w: 1.0
42+
}
43+
type: TYPE_BOX
44+
blend_mode: BLEND_MODE_ALPHA
45+
texture: ""
46+
id: "box"
47+
xanchor: XANCHOR_NONE
48+
yanchor: YANCHOR_NONE
49+
pivot: PIVOT_CENTER
50+
adjust_mode: ADJUST_MODE_FIT
51+
layer: ""
52+
inherit_alpha: true
53+
slice9 {
54+
x: 0.0
55+
y: 0.0
56+
z: 0.0
57+
w: 0.0
58+
}
59+
clipping_mode: CLIPPING_MODE_NONE
60+
clipping_visible: true
61+
clipping_inverted: false
62+
alpha: 1.0
63+
template_node_child: false
64+
size_mode: SIZE_MODE_AUTO
65+
}
66+
nodes {
67+
position {
68+
x: 0.0
69+
y: 0.0
70+
z: 0.0
71+
w: 1.0
72+
}
73+
rotation {
74+
x: 0.0
75+
y: 0.0
76+
z: 0.0
77+
w: 1.0
78+
}
79+
scale {
80+
x: 1.0
81+
y: 1.0
82+
z: 1.0
83+
w: 1.0
84+
}
85+
size {
86+
x: 200.0
87+
y: 100.0
88+
z: 0.0
89+
w: 1.0
90+
}
91+
color {
92+
x: 0.0
93+
y: 0.0
94+
z: 0.0
95+
w: 1.0
96+
}
97+
type: TYPE_TEXT
98+
blend_mode: BLEND_MODE_ALPHA
99+
text: "1"
100+
font: "example"
101+
id: "text"
102+
xanchor: XANCHOR_NONE
103+
yanchor: YANCHOR_NONE
104+
pivot: PIVOT_CENTER
105+
outline {
106+
x: 1.0
107+
y: 1.0
108+
z: 1.0
109+
w: 1.0
110+
}
111+
shadow {
112+
x: 1.0
113+
y: 1.0
114+
z: 1.0
115+
w: 1.0
116+
}
117+
adjust_mode: ADJUST_MODE_FIT
118+
line_break: false
119+
parent: "box"
120+
layer: ""
121+
inherit_alpha: true
122+
alpha: 1.0
123+
outline_alpha: 1.0
124+
shadow_alpha: 1.0
125+
template_node_child: false
126+
text_leading: 1.0
127+
text_tracking: 0.0
128+
}
129+
material: "/builtins/materials/gui.material"
130+
adjust_reference: ADJUST_REFERENCE_PARENT
131+
max_nodes: 512

test/data/focus1.gui_script

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
local monarch = require "monarch.monarch"
2+
3+
function on_message(self, message_id, message, sender)
4+
if message_id == monarch.FOCUS.GAINED then
5+
_G.focus1_gained = true
6+
elseif message_id == monarch.FOCUS.LOST then
7+
_G.focus1_lost = true
8+
end
9+
end

test/data/screen1.gui

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ nodes {
9696
}
9797
type: TYPE_TEXT
9898
blend_mode: BLEND_MODE_ALPHA
99-
text: "1"
99+
text: "FOCUS 1"
100100
font: "example"
101101
id: "text"
102102
xanchor: XANCHOR_NONE

test/data/screens.collection

+63
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,66 @@ embedded_instances {
471471
z: 1.0
472472
}
473473
}
474+
embedded_instances {
475+
id: "focus1"
476+
data: "components {\n"
477+
" id: \"screen_proxy\"\n"
478+
" component: \"/monarch/screen_proxy.script\"\n"
479+
" position {\n"
480+
" x: 0.0\n"
481+
" y: 0.0\n"
482+
" z: 0.0\n"
483+
" }\n"
484+
" rotation {\n"
485+
" x: 0.0\n"
486+
" y: 0.0\n"
487+
" z: 0.0\n"
488+
" w: 1.0\n"
489+
" }\n"
490+
" properties {\n"
491+
" id: \"screen_id\"\n"
492+
" value: \"focus1\"\n"
493+
" type: PROPERTY_TYPE_HASH\n"
494+
" }\n"
495+
" properties {\n"
496+
" id: \"focus_url\"\n"
497+
" value: \"focus1:/go#focus1\"\n"
498+
" type: PROPERTY_TYPE_URL\n"
499+
" }\n"
500+
"}\n"
501+
"embedded_components {\n"
502+
" id: \"collectionproxy\"\n"
503+
" type: \"collectionproxy\"\n"
504+
" data: \"collection: \\\"/test/data/focus1.collection\\\"\\n"
505+
"exclude: false\\n"
506+
"\"\n"
507+
" position {\n"
508+
" x: 0.0\n"
509+
" y: 0.0\n"
510+
" z: 0.0\n"
511+
" }\n"
512+
" rotation {\n"
513+
" x: 0.0\n"
514+
" y: 0.0\n"
515+
" z: 0.0\n"
516+
" w: 1.0\n"
517+
" }\n"
518+
"}\n"
519+
""
520+
position {
521+
x: 0.0
522+
y: 0.0
523+
z: 0.0
524+
}
525+
rotation {
526+
x: 0.0
527+
y: 0.0
528+
z: 0.0
529+
w: 1.0
530+
}
531+
scale3 {
532+
x: 1.0
533+
y: 1.0
534+
z: 1.0
535+
}
536+
}

test/test_monarch.lua

+17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ local SCREEN1_STR = hash("screen1")
77
local SCREEN1 = hash(SCREEN1_STR)
88
local SCREEN2 = hash("screen2")
99
local SCREEN_PRELOAD = hash("screen_preload")
10+
local FOCUS1 = hash("focus1")
1011
local BACKGROUND = hash("background")
1112
local POPUP1 = hash("popup1")
1213
local POPUP2 = hash("popup2")
@@ -405,5 +406,21 @@ return function()
405406
-- second time the screen gets shown it will be reloaded and increment the count
406407
assert(monarch.data(SCREEN_PRELOAD).count == 2)
407408
end)
409+
410+
411+
it("should send focus messages", function()
412+
_G.focus1_gained = nil
413+
_G.focus1_lost = nil
414+
415+
monarch.show(SCREEN1)
416+
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
417+
monarch.show(FOCUS1)
418+
assert(wait_until_shown(FOCUS1), "Screen1 was never shown")
419+
assert(_G.focus1_gained)
420+
monarch.show(SCREEN1)
421+
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
422+
assert(wait_until_hidden(FOCUS1), "Focus1 was never hidden")
423+
assert(_G.focus1_lost)
424+
end)
408425
end)
409426
end

0 commit comments

Comments
 (0)