Skip to content

Commit 0b3432f

Browse files
committed
Provide slightly more helpful message on tmux set passthrough.
Issues #95
1 parent 5c5560d commit 0b3432f

File tree

3 files changed

+40
-19
lines changed

3 files changed

+40
-19
lines changed

src/kitty-canvas.cc

+38-6
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ static constexpr int kBase64EncodedChunkSize = 4096; // Max allowed: 4096.
3232
static constexpr int kByteChunk = kBase64EncodedChunkSize / 4 * 3;
3333

3434
namespace timg {
35-
static char *append_xy_msb(char *buffer, int x, int y, uint8_t msb);
36-
3735
// Create ID unique enough for our purposes.
3836
static uint32_t CreateId() {
3937
static const uint32_t kStart = (uint32_t)time(nullptr) << 7;
@@ -44,6 +42,7 @@ static uint32_t CreateId() {
4442

4543
// Placehholder unicode characters to be used in tmux image output.
4644
// https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
45+
static char *append_xy_msb(char *buffer, int x, int y, uint8_t msb);
4746
static char *AppendUnicodePicureTiles(char *pos, uint32_t id, int indent,
4847
int rows, int cols) {
4948
*pos++ = '\r';
@@ -69,14 +68,47 @@ static char *AppendEscaped(char *pos, char c, bool wrap_tmux) {
6968
return pos;
7069
};
7170

71+
static void EnableTmuxPassthrough() {
72+
bool set_passthrough_success = false;
73+
// We need to tell tmux to allow pass-through of the image data
74+
// that we send behind its back to kitty...
75+
const int ret = system("tmux set -p allow-passthrough on > /dev/null 2>&1");
76+
switch (ret) {
77+
case 0: set_passthrough_success = true; break;
78+
case 1:
79+
// Exit code 1: we were able to call tmux set, but option was unknown
80+
fprintf(stderr, "Can't set passthrough; need tmux >= 3.3.\n");
81+
break;
82+
default:
83+
// "command not found" is typically in upper region of exit codes
84+
if (getenv("TMUX")) { // crude way to determine if we run locally
85+
fprintf(stderr, "Can't set passthrough, tmux set exit-code=%d\n",
86+
ret);
87+
}
88+
else {
89+
// Probably remote, and no tmux installed there.
90+
}
91+
}
92+
if (!set_passthrough_success) {
93+
// Could not successfully set the passthrough mode, but we
94+
// actually don't know if it might work anyway.
95+
// TODO: Maybe send a kitty graphics query to determine if it would
96+
// work and only if not, provide a error message.
97+
}
98+
}
99+
72100
KittyGraphicsCanvas::KittyGraphicsCanvas(BufferedWriteSequencer *ws,
73101
ThreadPool *thread_pool,
74-
bool tmux_workaround_needed,
102+
bool tmux_passthrough_needed,
75103
const DisplayOptions &opts)
76104
: TerminalCanvas(ws),
77105
options_(opts),
78-
tmux_workaround_needed_(tmux_workaround_needed),
79-
executor_(thread_pool) {}
106+
tmux_passthrough_needed_(tmux_passthrough_needed),
107+
executor_(thread_pool) {
108+
if (tmux_passthrough_needed) {
109+
EnableTmuxPassthrough();
110+
}
111+
}
80112

81113
void KittyGraphicsCanvas::Send(int x, int dy, const Framebuffer &fb_orig,
82114
SeqType seq_type, Duration end_of_frame) {
@@ -127,7 +159,7 @@ void KittyGraphicsCanvas::Send(int x, int dy, const Framebuffer &fb_orig,
127159
const int cols = fb->width() / opts.cell_x_px;
128160
const int rows = -cell_height_for_pixels(-fb->height());
129161
const int indent = x / opts.cell_x_px;
130-
bool wrap_tmux = tmux_workaround_needed_;
162+
bool wrap_tmux = tmux_passthrough_needed_;
131163
std::function<OutBuffer()> encode_fun = [opts, fb, id, buffer, offset, rows,
132164
cols, indent, wrap_tmux]() {
133165
std::unique_ptr<const Framebuffer> auto_delete(fb);

src/kitty-canvas.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace timg {
2525
class KittyGraphicsCanvas final : public TerminalCanvas {
2626
public:
2727
KittyGraphicsCanvas(BufferedWriteSequencer *ws, ThreadPool *thread_pool,
28-
bool tmux_workaround_needed,
28+
bool tmux_passthrough_needed,
2929
const DisplayOptions &opts);
3030

3131
int cell_height_for_pixels(int pixels) const final;
@@ -35,7 +35,7 @@ class KittyGraphicsCanvas final : public TerminalCanvas {
3535

3636
private:
3737
const DisplayOptions &options_;
38-
const bool tmux_workaround_needed_;
38+
const bool tmux_passthrough_needed_;
3939
ThreadPool *const executor_;
4040

4141
char *RequestBuffer(int width, int height);

src/timg.cc

-11
Original file line numberDiff line numberDiff line change
@@ -780,17 +780,6 @@ int main(int argc, char *argv[]) {
780780
}
781781
#endif
782782

783-
// If we are in tmux and use the kitty protocol, we need to tell it to
784-
// allow pass-through.
785-
// Somewhat broken abstraction here, should move to some
786-
// TerminalCanvas::Prepare().
787-
if (present.pixelation == Pixelation::kKittyGraphics &&
788-
present.tmux_workaround) {
789-
if (system("tmux set -p allow-passthrough on") != 0) {
790-
fprintf(stderr, "Could not set tmux passthrough for graphics\n");
791-
}
792-
}
793-
794783
// The high-res image terminals provide alpha-blending, no need to
795784
// query the terminal color for 'auto'
796785
if (is_pixel_direct_with_alpha(present.pixelation) &&

0 commit comments

Comments
 (0)