@@ -32,8 +32,6 @@ static constexpr int kBase64EncodedChunkSize = 4096; // Max allowed: 4096.
32
32
static constexpr int kByteChunk = kBase64EncodedChunkSize / 4 * 3 ;
33
33
34
34
namespace timg {
35
- static char *append_xy_msb (char *buffer, int x, int y, uint8_t msb);
36
-
37
35
// Create ID unique enough for our purposes.
38
36
static uint32_t CreateId () {
39
37
static const uint32_t kStart = (uint32_t )time (nullptr ) << 7 ;
@@ -44,6 +42,7 @@ static uint32_t CreateId() {
44
42
45
43
// Placehholder unicode characters to be used in tmux image output.
46
44
// https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
45
+ static char *append_xy_msb (char *buffer, int x, int y, uint8_t msb);
47
46
static char *AppendUnicodePicureTiles (char *pos, uint32_t id, int indent,
48
47
int rows, int cols) {
49
48
*pos++ = ' \r ' ;
@@ -69,14 +68,47 @@ static char *AppendEscaped(char *pos, char c, bool wrap_tmux) {
69
68
return pos;
70
69
};
71
70
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
+
72
100
KittyGraphicsCanvas::KittyGraphicsCanvas (BufferedWriteSequencer *ws,
73
101
ThreadPool *thread_pool,
74
- bool tmux_workaround_needed ,
102
+ bool tmux_passthrough_needed ,
75
103
const DisplayOptions &opts)
76
104
: TerminalCanvas(ws),
77
105
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
+ }
80
112
81
113
void KittyGraphicsCanvas::Send (int x, int dy, const Framebuffer &fb_orig,
82
114
SeqType seq_type, Duration end_of_frame) {
@@ -127,7 +159,7 @@ void KittyGraphicsCanvas::Send(int x, int dy, const Framebuffer &fb_orig,
127
159
const int cols = fb->width () / opts.cell_x_px ;
128
160
const int rows = -cell_height_for_pixels (-fb->height ());
129
161
const int indent = x / opts.cell_x_px ;
130
- bool wrap_tmux = tmux_workaround_needed_ ;
162
+ bool wrap_tmux = tmux_passthrough_needed_ ;
131
163
std::function<OutBuffer ()> encode_fun = [opts, fb, id, buffer, offset, rows,
132
164
cols, indent, wrap_tmux]() {
133
165
std::unique_ptr<const Framebuffer> auto_delete (fb);
0 commit comments