On Wed, Nov 10, 2010 at 05:40:56PM -0800, George Nachman wrote:
> On Wed, Nov 10, 2010 at 4:33 PM, Nicholas Marriott
> <nicholas.marri...@gmail.com> wrote:
> > On Wed, Nov 10, 2010 at 01:41:36PM -0800, George Nachman wrote:
> >> >> Now that I understand your architecture better, it's pretty clear to
> >> >> me that we don't want to write our own client. I want to support the
> >> >> use case of ssh'ing to a remote host and running the tmux client
> >> >> there.
> >> >
> >> > In that case your only options from what I can see are:
> >> >
> >> > a) Open an ssh each time to run tmux commands.
> >>
> >> I think this is the right way to go as it would give users the most
> >> flexibility. I don't want them to have to install tmux on their Macs
> >> if they're just using iTerm2 to connect to a linux host, for example.
> >> The user would do:
> >>
> >> localhost% ssh foo
> >> foo% tmux --somenewflag
> >> <user selects a menu option in iTerm2>
> >>
> >> At this point iTerm2 would begin communicating with tmux over the
> >> existing ssh session, downloading relevant state (list of sessions the
> >> tmux server knows about, screen contents for each one, perhaps some of
> >> the scrollback for each, etc.). iTerm2 would open native GUI tabs with
> >> each corresponding to a separate session living in the tmux server,
> >> all multiplexed through the single connection.
> >
> > Hmmm. I'm not sure I'm really getting what you want to do.
> >
> > Do you really mean "session" here or do you mean "window"?
> 
> I don't normally use the word window to describe this concept because
> in my app a window can have many tabs, but in the context of a
> non-tabbed term like xterm it would be called a window. I gather that
> in tmux a session is a collection of windows, hence the confusion.

Its probably best to use the tmux terminology if you're talking getting
stuff out of tmux because that's what it'll use :-).

> 
> > If you mean session, then it may not be too difficult. tmux will still
> > manage everything within the session, all you want is a way for it to
> > pretend that multiple clients are attached on one stream (pair of file
> > descriptors, whatever). We can extend the existing command set enough
> > for you to get initial state and whatever else is missing.
> >
> > If you mean window, it sounds pretty much like writing a new UI for tmux
> > which seems awfully ambitious. tmux can be thought of as MVC in many
> > ways but there are some parts which fundamentally are not and decoupling
> > things far enough to replace the UI would be a fairly big job...
> 
> This is the core of the issue. I want tmux not to interact with the
> user directly and perform no presentation, and to serve as a backend
> server. My terminal emulator app would render content for the user.
> It's not so much replacing the UI as providing another interface to
> the model. If the UI component of tmux is not easily decoupled from
> its underlying state then this may turn out to be a difficult task
> indeed.
> 
> > What exactly do you see your program doing and not doing?
> 
> A very rough cut of the API in C++ish pseudocode would look like this:

Well, this stuff is actually fairly passive.

There are two big problems:

- Asynchronous events. What happens if the user closes a window, or
moves it to another session, or tmux resizes it? There are going to be a
lot of places where we need to trigger an event where at the moment we
just redraw our clients.

- UI side channels that are currently per client not per session. What
about the status line or if the user tries to enter the command prompt?
I always regret making this stuff per client but it is there now.

Also I guess you're content to let tmux manage panes.

> 
> // return windows tmux knows about
> vector<Window*> GetWindows();

This is the list-sessions/list-windows/list-panes commands.

> 
> // query a window for its size in rows x columns of text
> void GetWindowSize(Window*, int* width, int* height);

That's in the list-windows output.

> 
> // like select(2), but over Windows. Returns a vector of windows where
> ReadFromWindow() won't block.
> vector<Window*> GetWindowsWithNewInput();

Yeah but probably you'd be building the data yourself from stuff tmux
has fed on whatever event channel it has.

> 
> // read a block of input from a window.
> int ReadFromWindow(Window*, int maxBytes, string* buffer);
> 
> // write a string to a window.
> int WriteToWindow(Window*, string buffer);
> 
> // 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.

> 
> // Returns the total number of lines of scrollback history for a window.
> int GetLengthOfScrollbackHistoryInWindow(Window*);

Yeah.

> 
> // 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).

> 
> // 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.

If you look for server_redraw_* in the code it is an idea of where this
would have to be changed.

So what we would do for your idea would be then add a new client type
that instead of maintaining tty state and updating the tty, passed on
the event over some channel.

This would allow you to take over the display part of the UI and leave
tmux doing everything else (key bindings, options, yadda yadda).

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.

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