Skip to content

Commit 1fbfde4

Browse files
committed
Added window activation event
1 parent 7b2c3d1 commit 1fbfde4

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

lib/desktop/env.ex

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ defmodule Desktop.Env do
99
1010
Also it has a global connect() method to allow binding of :wx event callbacks using
1111
this long lived process as reference.
12+
13+
Subscribers (see `subscribe/0`) also receive:
14+
15+
* `{:desktop, :window_activated, window_id}` — a `Desktop.Window` with registered
16+
`id` has become the active frame (user brought the app window to the foreground).
1217
"""
1318
alias Desktop.Env
1419
use GenServer
@@ -54,8 +59,15 @@ defmodule Desktop.Env do
5459
send(pid, e)
5560
end
5661

57-
Process.monitor(pid)
58-
{:reply, :ok, %Env{d | subs: [pid | subs], events: []}}
62+
subs =
63+
if pid in subs do
64+
subs
65+
else
66+
Process.monitor(pid)
67+
[pid | subs]
68+
end
69+
70+
{:reply, :ok, %Env{d | subs: subs, events: []}}
5971
end
6072

6173
def handle_call(:wx_env, _from, d = %Env{wx_env: env}) do
@@ -112,6 +124,14 @@ defmodule Desktop.Env do
112124
{:noreply, %Env{state | windows: [window | windows]}}
113125
end
114126

127+
def handle_cast({:notify_subscribers, message}, state = %Env{subs: subs}) do
128+
for sub <- subs do
129+
send(sub, message)
130+
end
131+
132+
{:noreply, state}
133+
end
134+
115135
@impl true
116136
def handle_info({:reopen_app, []}, state = %Env{windows: windows}) do
117137
# Handling MacOS event when the app icon is clicked again
@@ -259,11 +279,22 @@ defmodule Desktop.Env do
259279
* `{:open_file, [filename]}`
260280
* `{:open_url, [filename]}`
261281
* `{:new_file, []}`
282+
* `{:desktop, :window_activated, window_id}` — from `Desktop.Window` when the
283+
frame becomes active (see `Desktop.Env` module doc).
262284
"""
263285
def subscribe() do
264286
GenServer.call(__MODULE__, {:subscribe, self()})
265287
end
266288

289+
@doc """
290+
Delivers a message to all processes that called `subscribe/0`.
291+
292+
Used internally by `Desktop.Window` for lifecycle events (e.g. frame activation).
293+
"""
294+
def notify_subscribers(message) when is_tuple(message) do
295+
GenServer.cast(__MODULE__, {:notify_subscribers, message})
296+
end
297+
267298
defp init_sni() do
268299
# We're protecting the main application from any possible
269300
# side effects of the SNI startup using a monitored (not linked) process:

lib/desktop/window.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ defmodule Desktop.Window do
9595
:module,
9696
:taskbar,
9797
:frame,
98+
:id,
9899
:notifications,
99100
:webview,
100101
:home_url,
@@ -158,6 +159,13 @@ defmodule Desktop.Window do
158159
userData: self()
159160
)
160161

162+
unless OS.mobile?() do
163+
:wxFrame.connect(frame, :activate,
164+
callback: &frame_activate/2,
165+
userData: self()
166+
)
167+
end
168+
161169
if min_size do
162170
:wxFrame.setMinSize(frame, min_size)
163171
end
@@ -219,6 +227,7 @@ defmodule Desktop.Window do
219227

220228
ui = %Window{
221229
frame: frame,
230+
id: options[:id],
222231
webview: Fallback.webview_new(frame),
223232
notifications: %{},
224233
home_url: url,
@@ -579,6 +588,23 @@ defmodule Desktop.Window do
579588
:ok
580589
end
581590

591+
def frame_activate(wx(userData: pid), event) do
592+
if :wxActivateEvent.getActive(event) do
593+
GenServer.cast(pid, :frame_activated)
594+
end
595+
596+
:ok
597+
end
598+
599+
@doc false
600+
def handle_cast(:frame_activated, ui = %Window{id: id}) do
601+
if id != nil do
602+
Desktop.Env.notify_subscribers({:desktop, :window_activated, id})
603+
end
604+
605+
{:noreply, ui}
606+
end
607+
582608
@doc false
583609
def handle_cast(:close_window, ui = %Window{frame: frame, taskbar: taskbar, on_close: on_close}) do
584610
if on_close == :hide do

0 commit comments

Comments
 (0)