>> That would work. We could actually go all-pull on the protocol and
>> have a blocking "poll for new data" command that I send you, if that
>> makes life any easier. It's all the same from the client's end.
>
> Hmm. It all seems much the same to me, in both cases you will block in
> poll or select until tmux sends some message. Whether you explicitly
> request the message or whether it is just sent doesn't really make much
> difference.

I take it back, a block call wouldn't work if we decide we want to
send you a message while it's blocking. You should push output to us.
Needless to say, it has to be properly interleaved with command output
so that it can be parsed unambiguously.

>
>>
>> >> >> // Returns a single line of text from the nth line of scrollback for a
>> >> >> given window. A ScreenCell is a struct with a character, foreground
>> >> >> color, background color, etc., representing a single onscreen
>> >> >> character.
>> >> >> vector<ScreenCell> GetScrollbackHistoryInWindow(Window*, int 
>> >> >> lineNumber);
>> >> >
>> >> > What would be most likely is that you would request a line from the
>> >> > history and tmux will give you a sequence you can feed into your parser
>> >> > to draw it.
>> >>
>> >> Can you define "sequence"? VT100 escape codes are fine as long as any
>> >> existing state if taken into account. So if line 0 has a code to
>> >> change the foreground color and I request line 1, it must begin with
>> >> the foreground color escape code.
>> >
>> > Probably it will assume an empty terminal of the size of the line and
>> > draw the line into it using whatever terminal description you like (so
>> > long as its on the box running tmux). Then you can render it wherever
>> > you like.
>>
>> This is slightly scary because there's no guarantee at the protocol
>> level that the cursor will only stay on one line, but I understand why
>> it makes sense; not every emulator implements the same subset of the
>> terminal protocol.
>
> Well, we can tell you the length of the line and then send sequences
> limited within that size.

I'll have to refactor my vt100 parser, but it's certainly doable.

>>
>> >>
>> >> >> // Notify window of a size change
>> >> >> void ResizeWindow(Window*, int width, int height);
>> >> >
>> >> > You could actually sort of do this already with force-width and
>> >> > force-height options. Basically need to feed your data into the existing
>> >> > maximum window size calculations (resize.c).
>> >>
>> >> This is a little messy given the window/pane feature that tmux has and
>> >> iTerm2 doesn't. For now I'd probably prefer to do something really
>> >> simple like move each pane into its own window when iTerm2 connects
>> >> and then use the existing SIGWINCH functionality, so this API would be
>> >> unnecessary. If two clients are attached to the same server, tmux does
>> >> some presentation work (drawing a "no-man's land" of periods outside
>> >> of the window in the second client). I think tmux would have to change
>> >> its behavior in this mode to not draw those UI elements and just act
>> >> like a window that refuses to resize.
>> >
>> > If you are dealing at the level of panes not windows this won't
>> > matter. Panes are never larger or smaller than the window and contain
>> > nothing except the application, so you can draw whatever you like
>> > outside them.
>>
>> If a window has exactly one pane then the pane resizes along with the
>> window, does it not? Or have I got my terminology wrong?
>
> It does, yes, but in any case you will be limited to the same area as
> the application which is the size of the pane.

My original point was a client-initiated resize, resulting in a
SIGWINCH, will resize the window, and in turn resize the pane or panes
in that window. So we need to be able to tell you that a window
changed size. But is it possible to change the size of one window and
not another? The GUI will represent each tmux window as a separate
native window, and they can  of course be resized independently.

>>
>> >>
>> >> >>
>> >> >> // Close a window
>> >> >> void CloseWindow(Window*);
>> >> >>
>> >> >>
>> >> >> Does this help clear up what I had in mind?
>> >> >
>> >> > I'm thinking the right way to do this would be to decouple the display
>> >> > side of the client stuff a bit (where the client is the client object in
>> >> > the server not the client process). At the moment there are basically a
>> >> > few operations:
>> >> >
>> >> > - Exit (also detach).
>> >> > - Lock.
>> >> > - Here's an input command (draw line, etc etc).
>> >> > - Get the tty size.
>> >> > - Redraw everything including the status line.
>> >> > - Redraw just the status line.
>> >> > - Redraw a single pane.
>> >> > - Redraw just the pane borders.
>> >> > - Show pane identifiers for N time.
>> >> > - Show message (on the status line) for N time.
>> >> > - Clear message.
>> >> > - Start prompt (on the status line).
>> >> > - Clear prompt.
>> >> >
>> >> > So instead of this, we would start saying "the window has been split" or
>> >> > "a window has been closed" or "this window has been resized" and it
>> >> > could decide what it needed to redraw or whatever itself.
>> >> >
>> >>
>> >> Once iTerm2 is attached, it wouldn't receive instructions to "redraw
>> >> the screen" from tmux. You'd send us new output (whatever output you
>> >
>> > Which new output? The raw output from the application or tmux's
>> > translated output?
>>
>> I don't think there's ever a case where you'd perform any
>> transformations on a program's output in this system. It should just
>> pass it clean through, no?
>
> If we pass it through unchanged, you will have to write your parser to
> understand the tmux terminal description (that is, TERM=screen).

Oh, didn't know about TERM=screen. I'd strongly prefer not to write a
new terminal parser. Let's stick with re-encoding the output.

>> Or do you need to decode it, update your internal state, and re-encode it?
>
> We'll need to update the internal state so the decode step will not be
> optional.
>
> At the moment there are basically two outputs from this step:
>
> 1 A set of calls to screen-write.c which update the internal copy for
>  each pane (its "screen").
>
> 2 These pass through to call a set of functions tty_cmd_* which update
>  the real terminal for all attached clients using the appropriate
>  terminfo entry.
>
> There is no reason with a few tweaks the second output can't be
> redirected over the wire rather than sent directly to the tty.
>
> If this isn't necessary we can just tap directly into the read event and
> queue up the raw data from the application.
>
> Whichever we do you will need to provide key input in the same
> way.
>

Perfectly reasonable.

>>
>> >> > When you want to manipulate or query tmux state I think you could use
>> >> > existing tmux commands. It might be nicer to have a set of underlying
>> >> > primitives that the commands were based on and that you could invoke but
>> >> > that is probably quite a big job.
>> >>
>> >> The existing set of commands covers some nontrivial portion of what I
>> >> need, so it seems obvious to me that the protocol we develop should be
>> >> based on your existing commands and their syntax.
>> >>
>> >> I think it would be great if this became an established protocol that
>> >> other terminal emulators coded to. If this works like I think it will,
>> >> it could really change the way people interact with their terminals.
>> >
>> > So what I'm leaning to at the moment is you basically have an
>> > interaction like this, where => is stuff you send:
>> >
>> > $ ssh -e none host tmux -C
>> > => list-sessions
>> > 0: 19 windows (created Fri Oct 29 19:54:56 2010) [170x43]
>> > 1: 11 windows (created Fri Oct 29 19:54:56 2010) [80x23]
>> > 2: 11 windows (created Fri Oct 29 19:54:56 2010) [80x23]
>> > 3: 1 windows (created Thu Nov 11 21:35:22 2010) [170x43] (attached)
>> > ^D
>> > => list-windows -t 0
>> > 0: ksh [170x43]
>> >    layout: dfde,170x43,0,0
>> > ^D
>> > => list-panes -t 0:0
>> > 0: [170x43] [history 0/2000, 0 bytes] (active)
>> > ^D
>> > => monitor-pane -t 0:0.0 [new, start sending me events for this pane]
>> > ^D
>> > => send-keys -t 0:0.0 -p 12 [where "-p size" is new and means read from 
>> > stream]
>> > => xyz abc blah
>> > * 0:0.0 data 1000
>> > \033[Hblah blah whatever.......
>> > * 0:0.0 move 0:1.0
>> > * 0:1.0 resize 20 30
>> > * 0:1.0 close
>> >
>> > Not sure about the separator. A preannounced size would be better but
>> > that is harder to implement with the existing code.
>>
>> I agree that specifying the size first makes more sense. Once you have
>> to deal with separators, things get complicated with escaping and so
>> on. I would prefer to have tmux's output be formatted for easy
>> parsing. For instance, instead of:
>>
>> => list-sessions
>> 0: 19 windows (created Fri Oct 29 19:54:56 2010) [170x43]
>> 1: 11 windows (created Fri Oct 29 19:54:56 2010) [80x23]
>> 2: 11 windows (created Fri Oct 29 19:54:56 2010) [80x23]
>> 3: 1 windows (created Thu Nov 11 21:35:22 2010) [170x43] (attached)
>>
>> say:
>>
>> => list-sessions
>> 0 19 1288407296 170 43 u
>> 1 11 1288407296 80 23 u
>> 2 11 1288407296 80 23 u
>> 3 1 1289540122 170 43 a
>>
>> This is more to avoid bugs than anything else. Cross-platform date
>> parsing, for example, makes me feel a bit uneasy.
>
> I think two formats seems like an unnecessary maintenance burden but
> I'll think about it. May be possible to do it in a way that isn't a mess
> of conditionals everywhere there is output.
>
> We can tweak the output to make it easier to parse if necessary so long
> as it remains human readable.
>
> The asctime() format is mandated by POSIX, it isn't going to change. I'd
> prefer something more compact anyway so we can probably use a different
> format.

I can live with that.

>>
>> Also, I think we do need to do some escaping, at least in the
>> direction of client to server communication. In ssh, for instance, ~
>> has special meaning unless the user turns it off. Many users don't
>> know that this exists, and even fewer know they can change the escape
>> character.
>
> Typically you would get the user to tell your program the host and port
> and have it run the command, your default command can be something like
> "ssh -p $port -e none $host tmux -C".
>

It worries me that this will cause mysterious breakage and people will
regard the feature as unreliable. Or users may decide to start tmux on
a host that they're already connected to and don't want to reconnect
with -e none. Or more likely, they don't read the documentation and
are unaware of passing -e none. An example of where this could go
horribly wrong is where a user ssh's to a remote host from within a
tmux session and types ~., expecting it to disconnect the "inner"
session, but the ~. leaks into the iterm->tmux connection. Inband
signaling is evil.

------------------------------------------------------------------------------
Centralized Desktop Delivery: Dell and VMware Reference Architecture
Simplifying enterprise desktop deployment and management using
Dell EqualLogic storage and VMware View: A highly scalable, end-to-end
client virtualization framework. Read more!
http://p.sf.net/sfu/dell-eql-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to