Fl4m3Ph03n1x

Fl4m3Ph03n1x

Desktop App does not close and always reopens

Background

I have a basic Desktop app with the following config:

application.ex

defmodule WebInterface.Application do
  use Application

  alias Desktop
  alias Manager
  alias WebInterface.{Endpoint, PubSub, Telemetry}

  @impl true
  def start(_type, _args) do
    children = [
      Telemetry,
      {Phoenix.PubSub, name: PubSub},
      Endpoint,
      Manager,
      {Desktop.Window,
       [
         app: :web_interface,
         id: WebInterface,
         title: "Market Manager",
         size: {900, 900},
         icon: "static/images/resized_logo_5_32x32.png",
         url: &WebInterface.Endpoint.url/0
       ]}
    ]

    opts = [strategy: :one_for_one, name: WebInterface.Supervisor]
    Supervisor.start_link(children, opts)
  end

  @impl true
  def config_change(changed, _new, removed) do
    WebInterface.Endpoint.config_change(changed, removed)
    :ok
  end
end

This is basically the default configuration. You will notice the desktop app does not have a MenuBar. This is on purpose, as I don’t want one.

Problem

The issue here is that no matter what, the application won’t close:

ezgif.com-gif-maker

It always reopens.
After checking the code of Desktop, I believe the issue could be in Desktop.Window:

def init(options) do
    window_title = options[:title] || Atom.to_string(options[:id])
    size = options[:size] || {600, 500}
    min_size = options[:min_size]
    app = options[:app]
    icon = options[:icon]
    taskbar_icon = options[:taskbar_icon]
    # not supported on mobile atm
    menubar = unless OS.mobile?(), do: options[:menubar]

Namely, I am lead to believe there is a difference for Mobile apps and normal apps.

Funnily enough, if add a MenuBar, then the application does eventually close, even though it takes forever for the process behind it to terminate:

{Desktop.Window,
       [
         app: :web_interface,
         id: WebInterface,
         title: "Market Manager",
         size: WindowUtils.calculate_window_size(0.4, 0.7),
         menubar: MenuBar,
         icon: "static/images/resized_logo_5_32x32.png",
         url: &WebInterface.Endpoint.url/0
       ]}

Cliking on the Menubar Quit option also closes the application.

Questions

Am I forced to have a Menubar, if my I have a Desktop app?
How can this be fixed?

First 3 of 3 Posts Switch mode

al2o3cr

al2o3cr

The “close window” icon and the “Quit” menu item do quite different things:

  • the “Quit” menu item ends up calling Window.quit/0, which ultimately kill -9s the BEAM from outside (!!).

  • the “close window” icon ends up calling Window.close_window/2 which returns {:stop, :normal, ui} - which will result in the parent Supervisor restarting the Window process.

    Setting the Desktop.Window process to restart: :transient would be prevent this restart.

Not sure how the menu bar ties into this, tho… :thinking:

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

I see that it spawns a process which eventually calls System.halt. This is curious to me, as it raises a couple of questions:

  1. Why do we need to spawn a new process for this? The new process will kill everything (including the parent) so why not have the parent just do it?

  2. Why not use System.stop instead? I know it eventually ends up calling System.halt, but it also does a lot of cleanup on the background before that.

Here I am confused. Both Window.quit and Window.close_window should eventually call OS.shutdown which would in theory kill the BEAM process, thus preventing a restart.

I am guessing the :wxFrame.isShown(frame) is preventing this from happening, but I am not sure if this is intended behavior or not.

Am I missing something in my interpretation of the code?
Also, huge thanks for helping !

al2o3cr

al2o3cr

I’m definitely at the edge of my understanding regarding what’s happening on shutdown, but the main conclusion I draw from the code + issues is that “application shutdown” is a complicated mess when the app is coordinating Erlang / C++ / native entities all at once.

More examples:

Researching about the other “close” event mentioned in that last ticket turns up this note in the wxWidgets docs:

The EVT_END_SESSION event is slightly different as it is sent by the system when the user session is ending (e.g. because of log out or shutdown) and so all windows are being forcefully closed. At least under MSW, after the handler for this event is executed the program is simply killed by the system. Because of this, the default handler for this event provided by wxWidgets calls all the usual cleanup code (including wxApp::OnExit()) so that it could still be executed and exit()s the process itself, without waiting for being killed. If this behaviour is for some reason undesirable, make sure that you define a handler for this event in your wxApp-derived class and do not call event.Skip() in it (but be aware that the system will still kill your application).

— All posts loaded —

Where Next?

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
silverdr
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated! To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead. Sta...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
michallepicki
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement