| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 1 | (ns frq.cosmic |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 2 | "frq's own screens, painted by libcosmic. The desktop entry point. |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 3 | |
| 4 | The same trick as `frq.tui`: the components in `frq.app` do not know what is |
| 5 | under the reconciler, so requiring `glimmer-cosmic.core` after `frq.app` |
| 6 | makes it the backend glimmer renders with. Nothing in `frq.app` changes. |
| 7 | |
| 8 | glimmer-cosmic is a spike, and it shows. It paints a short list of tags and |
| 9 | treats every other one as a column, so most of frq comes out as stacked text |
| 10 | and buttons rather than its real layout. The jvui calls frq makes elsewhere |
| 11 | (a picture chooser, call frames) have no window of their own to act on and do |
| 12 | nothing, the same way they do in the terminal. |
| 13 | |
| 14 | The one real difference from the other two: libcosmic takes the main thread |
| 15 | and keeps it, so glimmer's loop runs on a worker. The timers handed to |
| 16 | `start!` are glimmer-cosmic's, which run on that worker. |
| 17 | |
| Call media-tick, and point the docstring at the recipe there is 8131fb6 nandi 7d ago | 18 | just run" |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 19 | (:require [frq.app :as app] |
| 20 | [frq.platform :as platform] |
| 21 | [frq.state :as s] |
| 22 | [glimmer.core :as ui] |
| 23 | [glimmer-cosmic.ffi :as cosmic-ffi] |
| 24 | ;; last, so its install! is the one that stands |
| 25 | [glimmer-cosmic.core :as cosmic])) |
| 26 | |
| 27 | (defn- dump-tree-to! |
| 28 | "Write the tree as the reconciler left it to `path` every few seconds. |
| 29 | |
| 30 | There is no REPL into a libcosmic window — it owns the main thread — so this |
| 31 | is how to tell a row that is not in the tree from a row that is in it and not |
| 32 | painted. Off unless FRQ_COSMIC_DUMP names a file." |
| 33 | [path] |
| 34 | (cosmic/every! 3000 #(spit path (cosmic/dump-str)))) |
| 35 | |
| Fold the list away, overview every other room, and open profiles in a dialog 39459ed nandi 7d ago | 36 | (defn- open-url! |
| 37 | "Hand a URL to the desktop's browser. |
| 38 | |
| 39 | libcosmic has none of its own, so this is xdg-open — which is what the |
| 40 | desktop's answer to \"show me this page\" has always been, and what |
| 41 | `frq.platform/open-url!` means by a backend that has a browser to hand it |
| 42 | to. Detached and its output thrown away: frq is not waiting on it, and a |
| 43 | child whose pipes nobody reads is a child that can block on a full one. |
| 44 | |
| 45 | http and https only. Every link in a conversation reaches this from |
| 46 | somewhere else's message, and xdg-open takes far more than a web page — a |
| 47 | `file:` URL is a file manager, and a bare path is whatever is registered for |
| 48 | it. A scheme this client did not mean to offer is not opened at all." |
| 49 | [url] |
| 50 | (boolean |
| 51 | (when (re-matches #"(?i)https?://[^\s]+" (str url)) |
| 52 | (try |
| 53 | (-> (ProcessBuilder. (into-array String ["xdg-open" url])) |
| 54 | (.redirectOutput java.lang.ProcessBuilder$Redirect/DISCARD) |
| 55 | (.redirectError java.lang.ProcessBuilder$Redirect/DISCARD) |
| 56 | (.start)) |
| 57 | true |
| 58 | (catch Exception _ false))))) |
| 59 | |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 60 | (defn -main [& _] |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 61 | ;; Everything this backend can do. What is missing is missing on purpose: |
| Fold the list away, overview every other room, and open profiles in a dialog 39459ed nandi 7d ago | 62 | ;; libcosmic has no texture to push call frames into, which is the same |
| 63 | ;; thing `:av? false` below says from the other end. It has no browser |
| 64 | ;; either, but the desktop it is running on does — `open-url!` above is |
| 65 | ;; that, and it is why the connect screen opens a browser here now rather |
| 66 | ;; than falling back to printing the URL for someone to copy. |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 67 | (platform/override! {:after! cosmic/after! |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 68 | :every! cosmic/every! |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 69 | :quit! cosmic/quit! |
| Fold the list away, overview every other room, and open profiles in a dialog 39459ed nandi 7d ago | 70 | :open-url! open-url! |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 71 | :screen-size cosmic/window-size |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 72 | :pick-image! cosmic/pick-image! |
| Read a pasted picture through the platform, so cosmic can lend its own 9dd480b nandi 8d ago | 73 | :picked-image! cosmic/picked-image! |
| 74 | :clipboard-image-png! cosmic/clipboard-image-png!}) |
| Paint frq with glimmer-cosmic, and give the tabs one shape 7b594b1 nandi 8d ago | 75 | (when-let [path (not-empty (System/getenv "FRQ_COSMIC_DUMP"))] |
| 76 | (dump-tree-to! path)) |
| 77 | (app/start! {:after! cosmic/after! |
| 78 | :every! cosmic/every! |
| 79 | :title! cosmic-ffi/set-title! |
| 80 | ;; The window's size, which frq lays its columns out against — |
| 81 | ;; the message list is told how much room the people panel |
| 82 | ;; leaves it. |
| 83 | :measure! (fn [] |
| 84 | (let [[w h] (cosmic/window-size)] |
| 85 | (when (and (pos? w) (not= w @s/window-width)) |
| 86 | (reset! s/window-width w)) |
| 87 | (when (and (pos? h) (not= h @s/window-height)) |
| 88 | (reset! s/window-height h)))) |
| 89 | ;; Call frames are painted into a jvui texture, which is not here. |
| 90 | :av? false}) |
| 91 | (ui/run app/app :title "frq" :width 520 :height 860)) |