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

kitty with tmux passthrough only works if kitty +icat was invoked before #195

Closed
ronyclau opened this issue Mar 25, 2024 · 10 comments
Closed

Comments

@ronyclau
Copy link

Problem

No image is shown when chafa is called in a tmux pane in which kitty +icat has never been called.

Reproduction steps

Assuming that an image named red.png is in the current directory,

  1. Create a new pane in tmux. You can split an existing window, or create a new window.
  2. Call chafa --passthrough tmux -f kitty red.png. Black space of correct height is printed instead of the image.
  3. Call kitty +icat red.png. (Any image would do actually.)
  4. Call chafa --passthrough tmux -f kitty red.png again. The image would be displayed as expected.
Example image

red.png

Expected result

The image should be displayed regardless of whether kitty +icat has been invoked before.

Environment

chafa 1.14.0
tmux 3.4
kitty 0.32.2

@kovidgoyal
Copy link

This will be because you havent enabled tmux passthrough. icat does that for you if needed, automatically. I am guessing chafa doesnt.

@ronyclau
Copy link
Author

Greetings, Kovid. First of all, thank you for bringing kitty and calibre to us!

May I ask whether this is something I have to configure on kitty (generated a default kitty.conf just now, and didn't find anything related) or tmux side, or this is on chafa?

@kovidgoyal
Copy link

tmux

@ronyclau
Copy link
Author

TL;DR: add set -g allow-passthrough on to tmux.conf.

Thanks for the quick answer. Solved!

Related tmux doc here.

@hpjansson
Copy link
Owner

Chafa is supposed to set the tmux option automatically. The relevant code is here: https://github.com/hpjansson/chafa/blob/master/tools/chafa/chafa.c#L1818-L1904

It will only do so if it thinks it's not already set, and if it makes any changes, will restore the option to its original value afterwards.

There's likely something going wrong with this code; maybe we're being too conservative when detecting whether it's already set, you're running Chafa in a remote session where it's unable to set the option, or there's a bug. FWIW it works here, so I need some more info.

@ronyclau What's the output if you revert your configuration to the state where Chafa doesn't work, and run tmux show allow-passthrough and tmux set-option allow-passthrough on inside tmux? Does it work afterwards?

@hpjansson hpjansson reopened this Mar 25, 2024
@ronyclau
Copy link
Author

@hpjansson

Without the config, tmux show allow-passthrough prints nothing (or more precisely, just a new line, such that the next prompt is on the next line).

After tmux set-option allow-passthrough on is ran, it works, so allow-passthrough was indeed not enabled in tmux.


From the code block you linked, some observations:

  1. In my case where tmux show allow-passthrough prints just a new line, standard_output would be "\n", strings would be { "\n", "" }, and thus mode remains NULL. The part of the logic looks fine.

  2. When it does prints something, e.g. allow-passthrough on, due to the trailing new line, standard_output would be "allow-passthrough on\n", which in turn strings would be { "allow-passthrough", "on\n", "" }, and mode becomes "on\n".

    This line at

    if (!mode || (strcmp (mode, "on") && strcmp (mode, "all")))

    if (!mode || (strcmp (mode, "on") && strcmp (mode, "all")))

    would evaluate to true. Likely unintentional, but the result would just be that tmux set-option allow-passthrough on always got run. However, this doesn't match what I saw, as it's obvious from the test above that passthrough wasn't enabled when the image was printed, so the root cause likely isn't this.

  3. tmux show allow-passthrough would still print nothing or off even when the option is set globally, as this returns the session option value. From tmux's manpage (emphasis mine):

    Show the pane options (or a single option if option is provided) with -p, the window options with -w, the server options with -s, otherwise the session options.

    In other words, with set -g allow-passthrough on in config, item 1 still applies.
    Use tmux show -A allow-passthrough to get the effective value.


To dig a bit deeper, I enabled tmux's verbose mode with an empty config file (tmux -f /dev/null -v), and did some more tests:

Test 1

  1. Start a brand new tmux session by calling tmux -f /dev/null -v.
  2. Run tmux show allow-passthrough.
  3. Run tmux set allow-passthrough on.
  4. Quit tmux.
  5. Grep the log for tmux's command line parsing function cmd_unpack_argv.

Result

$ grep cmd_unpack_argv tmux-server-428170.log
1711392694.170651 cmd_unpack_argv: argv[0]=show
1711392694.170654 cmd_unpack_argv: argv[1]=allow-passthrough
1711392702.054822 cmd_unpack_argv: argv[0]=set
1711392702.054826 cmd_unpack_argv: argv[1]=allow-passthrough
1711392702.054829 cmd_unpack_argv: argv[2]=on

Test 2

  1. Start a brand new tmux session by calling tmux -f /dev/null -v.
  2. Run chafa --passthrough=tmux -f kitty red.png.
  3. Quit tmux.
  4. Grep the log for tmux's command line parsing function cmd_unpack_argv.

Result

$ grep cmd_unpack_argv tmux-server-426090.log

No matching line implies that the tmux server didn't receive any command from the tmux command line interface.

I would suggest checking whether apply_passthrough_workarounds_tmux really got called, and whether this call failed for some reason.

@hpjansson
Copy link
Owner

Thanks for the thorough analysis!

  • The reason it's getting the session value and not the effective one is so we can restore the old setting later (i.e. precisely unset or off). The effective value doesn't convey enough information to be able to restore the previous state. I think we can make this smarter by looking for the asterisk and assuming the session state is unset if present, or just using two exec calls, one for effective and another for specific state.
  • Trailing \n: Fair! It needs a g_strstrip().

To shed some light on what the exec calls are doing (if anything), could you please run:

strace -f -e trace=execve,read chafa red.png 2>&1 | grep 'allow-passthrough\|exited'

@ronyclau
Copy link
Author

Sure thing.

I am running this with the passthrough and format params as chafa couldn't detect kitty over ssh, and fallback to symbol mode.

$ strace -f -e trace=execve,read chafa --passthrough=tmux -f kitty red.png 2>&1 | grep 'allow-passthrough\|exited'
[pid 637726] +++ exited with 0 +++
[pid 637725] +++ exited with 0 +++
[pid 637724] +++ exited with 0 +++
[pid 637723] +++ exited with 0 +++
[pid 637722] +++ exited with 0 +++
[pid 637721] +++ exited with 0 +++
[pid 637720] +++ exited with 0 +++
[pid 637719] +++ exited with 0 +++
[pid 637718] +++ exited with 0 +++
[pid 637717] +++ exited with 0 +++
[pid 637716] +++ exited with 0 +++
[pid 637715] +++ exited with 0 +++
[pid 637714] +++ exited with 0 +++
[pid 637713] +++ exited with 0 +++
[pid 637712] +++ exited with 0 +++
[pid 637711] +++ exited with 0 +++
[pid 637710] +++ exited with 0 +++
[pid 637709] +++ exited with 0 +++
[pid 637708] +++ exited with 0 +++
[pid 637707] +++ exited with 0 +++
[pid 637706] +++ exited with 0 +++
[pid 637705] +++ exited with 0 +++
[pid 637704] +++ exited with 0 +++
[pid 637703] +++ exited with 0 +++
[pid 637702] +++ exited with 0 +++
[pid 637701] +++ exited with 0 +++
[pid 637700] +++ exited with 0 +++
[pid 637699] +++ exited with 0 +++
[pid 637698] +++ exited with 0 +++
[pid 637697] +++ exited with 0 +++
[pid 637696] +++ exited with 0 +++
[pid 637695] +++ exited with 0 +++
+++ exited with 0 +++

@hpjansson
Copy link
Owner

Are you running the remote ssh session inside tmux, or tmux inside the ssh session? If the former, there are two issues with it:

  • The TMUX environment variable won't be passed to the remote session unless it's in the remote sshd's AcceptEnv and specified in SendEnv to the local ssh, so Chafa won't detect tmux and will refuse to run the tmux workaround (but still emits the passthrough codes).
  • tmux show allow-passthrough etc. would fail anyway, because it can't see your local tmux session. AFAIK there's no way around this, except configuring the local tmux like you did above.

hpjansson added a commit that referenced this issue Mar 29, 2024
This prevents setting the passthrough option needlessly.

See #195 (GitHub).
@hpjansson
Copy link
Owner

I'll assume this issue resulted from running in an ssh session where tmux could not be detected nor manipulated. In that case there's no more to do in this issue, so I'm closing it. Please correct me if this is wrong.

Thanks for all the feedback!

hpjansson added a commit that referenced this issue Jun 11, 2024
This prevents setting the passthrough option needlessly.

See #195 (GitHub).
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