HeinrichApfelmus / threepenny-gui

GUI framework that uses the web browser as a display.
https://heinrichapfelmus.github.io/threepenny-gui/
Other
439 stars 77 forks source link

Native shells and app deployment #52

Closed HeinrichApfelmus closed 7 years ago

HeinrichApfelmus commented 11 years ago

While connecting to GUIs via a web browser is nice, it would also be great if we could package Threepenny apps as native applications.

Technology-wise, the idea is to write a native app ("shell") which contains the Threepenny application as resource. When run, the native app forks the Threepenny app, embeds a browser (say WebKit) and connects to the Threepenny server. Further more, the shell injects some JavaScript plugins into the web browser, which can be called from driver.js.

For instance, this would allow us to better deal with file system operations like opening and saving files, and we can use the system menu bar.

Ideally, the whole thing would be integrated with cabala, similar to the cabal-macosx package. I'm thinking of a package named threepenny-wrapper that hooks into cabal and which depends on threepenny-wrapper-wine and so on depending on the platform.

Such a system subsumes issue #27 where the question was about packaging resources with the library.

snoyberg commented 11 years ago

For some prior art on this, you could look at http://hackage.haskell.org/package/wai-handler-webkit. The qtwebkit library is very easy to use to accomplish something like this,

HeinrichApfelmus commented 11 years ago

Thanks for the pointer, I'll take a look!

HeinrichApfelmus commented 10 years ago

A nice person on reddit mentioned that instead of targeting the HTML + browser combination, we could also target XULRunner, the cross-platform DOM+JS sauce on which Firefox and Thunderbird are built.

See also:

duplode commented 10 years ago

A nice person on reddit mentioned that instead of targeting the HTML + browser combination, we could also target XULRunner, the cross-platform DOM+JS sauce on which Firefox and Thunderbird are built.

As an optional target, this looks very interesting! From what I gather from this link (taken from the reddit thread), there is a small obstacle in that vanilla HTML elements need a namespace in a XUL document, and so a trivial wrapper would not be enough to run a regular, HTML-based Threepenny application (cf. the qtwebkit approach suggested above). An unobtrusive, if a little hacky, solution might be providing, in a threepenny-xul package, a variant of the elidToElement function in driver.js which would do any necessary tag name mangling when creating the elements. (It goes without saying that said hypothetical package would provide Graphics.UI.Threepenny.XUL.* modules with extra elements, attributes and whatever else is needed for taking advantage of relevant XUL goodies.)

mhitza commented 10 years ago

@duplode I was actually the one in that thread that suggested XUL. Now take the following point from the perspective of someone who hasn't yet actively used threepenny.

That suggestion came with the assumption, that it would be easy in the HTML generation stage to prefix the elements with the html namespace; more towards the idea of having an easy migration path.

However given your point, the alternative variant still stands where it's enough to bootstrap a XUL with a browser tag, and the applications written would still function the same way. But there may lie benefits in having a "deeper" integration with XUL, given the large amount of widgets already built in and it's cross platform nature.

duplode commented 10 years ago

@mhitza Indeed, I speak from the opposite perspective of a Threepenny user having no experience with XUL. In any case, it is reasonable to expect that an who user decides to deploy with XULRunner will likely want to go all the way and use the widgets and other features. That being so, I agree with you in that running HTML applications with XULRunner is, given the bigger picture, a secondary concern. I do think there is serious worth in preserving the possibility of cheap, zero-setup, browse-to-localhost deployment as an alternative to XUL.Thankfully, Threepenny as of now is, I believe, lean enough to allow building the XUL integration in a loosely coupled way atop the existing "core" modules, so that both approaches can coexist well.

P.S.: Lest the tone of my posts give the wrong impression, I find your suggestion excellent, and exciting! Given the other options XUL seems to be the easiest way to bridge the gap to native toolkits, and by some margin.

HeinrichApfelmus commented 10 years ago

At the moment, I have the following technical setup in mind: the main entrypoint in the XUL content package reads

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="driver-xul.js"/>
  <script src="http://localhost:10000/driver.js"/>
  <html:div id="body">
  </html:div>
</window>

The driver-xul.js sets up an environment variable that instructs driver.js to prefix all HTML elements with the html namespace, and to treat the tag with id="body" as the body element when it comes to appending new elements.

This is one way to support both localhost and XUL.

(Will take a while to implement this, as I want to focus on other things first.)


In the long run, I intend Threepenny to support two slightly diverging targets:

  1. Desktop apps with XULRunner. Haskell compiled to native code. localhost only for testing or deprecated altogether.
  2. Web apps in the browser. Haskell compiled to JavaScript. In other words, this target is a web app frontend.

But this is still a long way off.

HeinrichApfelmus commented 8 years ago

It appears to me that Electron is the most promising native shell at the moment. See also issue #111.