overall, this design should give no preference to any form of software or protocol. all dispatch should be handled within the WM, via a custom wayland protocol. some mechanism for informing the WM of protocol handlers, probably a registry on-disk. protocol handlers are servers that listen for an event on the wayland socket, that looks like request: URI: string isWrite: bool writer: fileDesc? metadata: dict isWrite indicates a write operation, may be folded into writer as optional. write operation translates 1:1 for file:// or sftp://, should indicate POST under http://. metadata is protocol-specific, possibly include an xmlns-alike. HTTP headers should be under one top-level key, not inlined. a request should return an error or a response. a request error is a fatal error, not a protocol-level error. a 404 is not a request error, a DNS lookup failure is. a response is a sum type with variants: tab: /* necessary wayland metadata */ data: mimeType: string filename: string? data: fileDesc writable: bool metadata: dict redirect: URI: string tab allows a protocol handler to directly display data to the user. for example, an ssh handler may route URIs like ssh://host to a host, but route URIs like ssh:///config to a settings menu that is rendered internally. data is delegated to a program defined per-mime-type. these renderers allow applications to delegate rendering work to the rest of the OS. there should be a standard function for sniffing MIME types, available to all applications. redirects instruct the OS to retry rendering the tab, with a new URI. the x-pipe mimetype namespace will be used for all bidirectional socket data, such as a shell session or IRC connection. x-pipe/shell is reserved for use as a UNIX shell. x-pipe/ansi is reserved for a pipe which expects a terminal emulator on on the other end. x-pipe/text is reserved for use as a pipe of text data. x-pipe/octet-stream is reserved for use as a generic pipe. x-pipe/tls is reserved for a pipe which expects the reciever to perform a TLS handshake immediately. x-pipe/scheme-* is reserved, and all values of * should correspond to a wire protocol named *. e.g. x-pipe/scheme-irc indicates that the pipe is an IRC socket. the flexible nature of this approach should also allow protocol handlers to delegate rendering to something else. an app may render its entire UI as a TUI by returning x-pipe/ansi. the default handler of x-pipe/ansi MUST ALWAYS be a full-featured terminal emulator. TODO: define "full-featured" the default handler of a mime type can be overriden with + in the scheme. a scheme of the form ssh://server?cmd=cat+/var/www/index.html would print to the default terminal handler, but html+ssh://server?cmd=cat+/var/www/index.html would render the file in the default HTML renderer. scheme handlers are servers. there should be a directory like /var/tabbde/schemes, where every file is an executable or a symlink to an executable. you may have a libcurl-based scheme handler, which is symlinked to http, https, ftp, ftps, etc. when the WM encounters an unknown scheme, it will start the corresponding server, and wait. when a server comes online, it will resume URL processing. renderers are also servers, with similar semantics, but mapped via /var/tabbde/mimes.kv, a file mapping MIME glob patterns to renderers to allow for in-memory lookups. a cold start for a web browser may look like the following: 1. WM is asked to go to https://example.com 2. WM checks for running https handlers, and finds nonw 3. WM launches /var/tabbde/schemes/https, with the sole argument https: 4. https connects to the WM, and advertises itself as an https handler 5. WM dispatches the pending https://example.com request 6. https makes the request, and returns data with mimeType text/html, data a pipe that transparently handles decryption, writable false, metadata { status: 200, headers: } 7. WM checks to see what handles text/html, and finds /path/to/renderer 8. WM executes it, with sole argument text/html 9. renderer connects to the WM, and advertises itself as a text/html renderer 10. WM dispatches the pending text/html response to the new renderer the WM will not care about what process or connection an advertisement comes from, and the most recent advertisement supercedes all others, meaning that, for example, if a renderer based on a browser engine like blink were to be used both as an HTML renderer and an XHTML renderer, and an instance were created for text/html, followed by one for application/xhtml+xml, the second instance would only need to inform the first that it should advertise a second mime type, instead of having two instances resident in memory. because scheme handlers are initialized with an argument ending in a colon, and renderers are initialized with an argument like x/y, a wrapper library's main() should match on either of these, and if neither are applicable, delegate to some user code. this may be useful for CLI configuration options.