Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development log #1

Open
okapia opened this issue Nov 11, 2016 · 15 comments
Open

Development log #1

okapia opened this issue Nov 11, 2016 · 15 comments

Comments

@okapia
Copy link

okapia commented Nov 11, 2016

Firstly thanks for sharing this (it was me that replied in the hacker news comment).

So having built this, I wanted to try it out and see how much is working. After digging in the code it looks like you have to pass it a command to run and it seems to wrap that command to look for the tmux control sequences. Passing sh seems to work, zsh didn't and basic commands like ls seem to result in a strange error. I'm not quite sure why zsh doesn't work. Are you using a pseudo-tty to wrap the command? Anyway, with sh, I get a new "tmux" desktop" in i3 that's empty. Unfortunately, I have no idea how to open a terminal. Is that implemented yet? What terminal emulator are you using and how do you plan to link it in. Is the idea to have a client so you can run urxvt -e i3-tmux-integration-client, perhaps passing a token for it to talk back to the controlling process? Or have you got something else in mind?

@roblabla
Copy link
Owner

Lots of stuff is unimplemented, including opening terminals (though I do have a semi-working stuff locally).

You can see the tmux events I'm handling there : https://github.com/roblabla/i3-tmux-integration/blob/in-progress/src/main.rs#L63

That is to say, I don't really handle much right now, and some things are broken (window-add shouldn't open a terminal for instance).

The idea is that i3-tmux-integration will wrap your shell (I only tried with sh for now, zsh might be doing some Fun Stuff™) to detect the tmux DEC sequence. I should probably find the default shell if no arg is provided, but that'll come when I can at least open a terminal and read/write to it ^^.

The idea is that when I get a new pane (need to find the correct way to detect that still), I'll run urxvt -e "i3-tmux-client" /tmp/path_to_some_unix_socket paneid. That client will connect to the unix socket and send those file descriptors over it :

  • stdin
  • stdout
  • signalfd (to get sigwinch)

It will then sleep until it dies. This way, everything happens in the main program.

I'm still trying different ideas though, nothing is set in stone.

@roblabla
Copy link
Owner

Yesterday night I did some stuff to parse tmux layouts. You can find the parser in here.

Note that for the app to work, we'll need a terminal that supports startup-notifications. For urxvt, this means making sure it was compiled with --enable-startup-notification. Otherwise, it's impossible to tell urxvt to start in another workspace than the active one.

@roblabla
Copy link
Owner

roblabla commented Nov 13, 2016

I have implemented almost all I need to handle reads and writes to an urxvt terminal today. It's 4AM so I need sleep. I just have one small problem for tomorrow morning: for some reason I only receive 1 FD in the controlmessage here even though I send two there. A bug in the nix crate ?

Anyway, once this is resolved, I'll be able to print the output of tmux to their respective terminal, and send the keys from the terminal to tmux. Yay \o/

EDIT: And I totally hijacked that issue into a personal log of what I'm doing. I hope you don't mind ^^.

@roblabla
Copy link
Owner

roblabla commented Nov 13, 2016

So yeah, looks like there's a bug in the nix crate. nix-rust/nix#464 .

Being no expert in unix domain socket (and given how lacking the tooling seems to be for debugging those problems), I'm going to have to work around this problem. One potential solution is sending multiple control message with nix. Another is to just send multiple datagram packets. Both annoyingly complexify the code, but oh well ¯_(ツ)_/¯

@okapia
Copy link
Author

okapia commented Nov 17, 2016

Thanks for the updates. Sending file descriptors over sockets is a good idea. I've known you can do that for a long time but never come across a need for it before.

@roblabla
Copy link
Owner

This week-end, I'll try fixing the nix crate's bug. I'll start by translating the simple rust program into a C program, then toy with it until I bend it into succeeding.

@roblabla roblabla changed the title Basic usage unclear Development log Nov 18, 2016
@roblabla
Copy link
Owner

Well that was easier than I thought. Fixed the bug in nix-rust/nix#473. This means I should have most of the week-end to implement the console redirects properly.

Yay \o/

@roblabla
Copy link
Owner

roblabla commented Nov 20, 2016

A lot has been done. We are now able to properly redirect tmux output to a terminal window, and send that window's stdin back to tmux ! Vim also seems to be working pretty ok !

You can test it (probably). Just start i3-tmux-integration (without parameters), it should drop you in your default shell. Right now, the size will be stuck at 80x60 (I need to properly handle SIGWINCH events and set the terminal size). Apart from that, it should work properly. When you do tmux -CC, it should create a terminal in a tmp workspace, and create a shell in it, with similar properties.

The next steps are going to be fun. I now need to be able to get the size of the window, and the corresponding amount of character, to synchronize the tmux and i3 sizes. The good news is, it appears tty_ioctl TIOCSWINSZ gives a struct defined as such :

struct winsize {
    unsigned short ws_row;
    unsigned short ws_col;
    unsigned short ws_xpixel;
    unsigned short ws_ypixel;
};

Meaning I get both the row/col count (obviously) but also the pixel density ! For xterm and urxvt, this works (apparently, I haven't tested yet). But setting those values correctly isn't mandatory, and as such... Well it appears a lot of "modern" terminals don't support it.

So my approach for now is going to be to ignore all those terminals. I only test i3-tmux-integration with urxvt anyway (I should probably test some others, like xterm).

For future reference though: Another software that has to fight similar problems is w3mimgdisplay. This software prints images inside terminal programs: http://blog.z3bra.org/2014/01/images-in-terminal.html. To do this, it must know the terminal size/pos in pixel, etc... I might be able to steal a few tricks from them.

@roblabla
Copy link
Owner

roblabla commented Dec 3, 2016

Been 2 weeks since I've had time to work on this. Unfortunately, life decided to get in the way, as usual.

This week-end's goal is to refactor the code to pull all the in/out forwarding logic back into the main loop, and handle resizing the main window or subwindows.

Main window being the window in which i3-tmux-integration is started, subwindows being the windows i3-tmux-integration starts when it detects tmux created a window.

@roblabla
Copy link
Owner

More than a month happened since I last worked on this, and a lot of stuff happened in rust-lang. Most importantly, tokio got a 0.1 release. i3-tmux-integration would certainly love async a whole lot (spawning threads everywhere isn't great, async would make stuff prettier).

It's possible to use tokio with stdin/out through the use of EventedFd and PollEvented. This should hopefully simplify the code a whole lot (going back to being a single async thread) and make it more performant (threads suck).

I hope to get some time to work on this during the week.

@20after4
Copy link

This is really cool work

@roblabla
Copy link
Owner

Thanks. Sadly, I haven't had much time to work on this at all lately. And tokio doesn't handle stdin yet (I started doing what I hinted at above, but never got around to finish it). So the async is pretty much canned until either someone does the hard work for me or I end up with a whole lot of free time :).

I need to find myself a weekend where I can put two solid days dedicated to this to get it in shape. I have almost all the puzzle pieces done (tmux layout parsing, control mode parsing, output piping, etc...). I just need to write a few more features (catching SIGWINCH, resize the terminal, and figure a way to get the terminal pixel size) and then stitch everything together to get something usable.

@roblabla
Copy link
Owner

My interest in this project has been reignited yesterday. Did some work to update the dependencies, short-term I'll work on getting terminal resizing to work.

More mid-term, I'm going to try refactoring the code to use either mio or tokio. A lot of the code is just boilerplate for making threads everywhere, when it could be a lot simpler to understand if I just registered Fds to a Poll.

@roblabla
Copy link
Owner

Working on moving off to mio before terminal resizing because threads annoy me. Turns out to be fairly easy, and it removes a lot of Arc<Mutex<>> that would complexify the code needlessly. And it moves all the logic back into one place, which is nice.

I'm also trying to comment the code, because it's kind of messy and I've got no idea what half of the code is doing now.

@roblabla
Copy link
Owner

Alright, mio port is done, we're now mono-threaded. Terminal resizing (for both the main window and the subwindows) now work. I sprinkled some comments here and there to make the flow a bit easier to understand.

Going to start work on putting the panes in the right layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants