~aleteoryx/TabbDE

ref: 333a8e9c84f31d1b8765441c33dc5cac67d46868 TabbDE/design/notes -rw-r--r-- 7.5 KiB
333a8e9caleteoryx fallback handling 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
overall, this design should give no preference to any form of software
or protocol.

tabs == surfaces outside of debug schemes. the WM should not reap
surfaces when a tab is advanced or closed. this is so that a history
buffer can reuse surfaces, in the same way that chromium keeps some
tab data resident in ram after advancing tabs. perhaps a mechanism for
a client to set a limit on how far back in the history it should be
before being reaped?

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<string, string>

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<string, string>
  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: <key-value pairs as string> }
 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.

the system: scheme is reserved for things baked into the WM. it's
probably best if this *is* handled by an external program. it should be
immutable at runtime. we want WM consumers to be able to change the
look, but the user to not be able to disable the fuckin settings app.
maybe set it in config?

the wayland: scheme is reserved for any wayland windows that aren't
registered with the custom extensions. this will only work for windows
that allow compositor decorations, because a launcher app should just-
work. this should be entirely internal to the compositor, because duh.

wayland://xdg/toplevel/... will reference an xdg_shell toplevel
surface. it should use an internaly-assigned ID. these should be opened
by default for any surface which requests server-side decorations, or
doesn't seem to provide client-side decorations. detecting this is
gonna suck. the WM should treat closing all wayland: tabs that
reference a surface as closing that window. multiple tabs should be
handled transparently to the application, and only the most recently
focused tab will be rendered. changing tabs should send a configure
event and wait for ack to actually render the new tab.

wayland://surface/... will reference an arbitrary surface. this is
intended as a debugging facility. clients should in no way be informed
that this path is in use. the contents of the surface, if any, should
be rendered scaled within the tab.

wayland://launch/...?args=... will execute the target executable with
the given args. it will map to the first window created by the launched
application. this is intended to allow non-tabbde integrated apps to be
resumed on reboot. further windows created by the application are given
by-id URIs. there should be a UI in place to cycle which window maps to
this path.

the xorg: scheme is reserved for any xorg windows. specific handling of
this should mirror the wayland: scheme, but this is pending on the
author's understanding of xorg.

xorg://launch/...?args=... is functionally the same as the wayland
equivalent.

i need to read up on xorg more before i decide how other interfaces
should work.