mirror of https://github.com/mpv-player/mpv
terminal-unix: support mouse escape codes
These 6-byte codes have the format of \e [ M <button> <xpos> <ypos>. Support the first 3 mouse bottons + scroll up/down for now as button numbers > 5 are pretty non-portable across terminals. Pixel-based mouse position values are calculated and sent to the input system.
This commit is contained in:
parent
805577c792
commit
9ae58ba186
|
@ -54,6 +54,12 @@ static struct termios tio_orig;
|
||||||
|
|
||||||
static int tty_in = -1, tty_out = -1;
|
static int tty_in = -1, tty_out = -1;
|
||||||
|
|
||||||
|
enum entry_type {
|
||||||
|
ENTRY_TYPE_KEY = 0,
|
||||||
|
ENTRY_TYPE_MOUSE_BUTTON,
|
||||||
|
ENTRY_TYPE_MOUSE_MOVE,
|
||||||
|
};
|
||||||
|
|
||||||
struct key_entry {
|
struct key_entry {
|
||||||
const char *seq;
|
const char *seq;
|
||||||
int mpkey;
|
int mpkey;
|
||||||
|
@ -61,6 +67,10 @@ struct key_entry {
|
||||||
// existing sequence is replaced by the following string. Matching
|
// existing sequence is replaced by the following string. Matching
|
||||||
// continues normally, and mpkey is or-ed into the final result.
|
// continues normally, and mpkey is or-ed into the final result.
|
||||||
const char *replace;
|
const char *replace;
|
||||||
|
// Extend the match length by a certain length, so the contents
|
||||||
|
// after the match can be processed with custom logic.
|
||||||
|
int skip;
|
||||||
|
enum entry_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct key_entry keys[] = {
|
static const struct key_entry keys[] = {
|
||||||
|
@ -160,6 +170,18 @@ static const struct key_entry keys[] = {
|
||||||
{"\033[29~", MP_KEY_MENU},
|
{"\033[29~", MP_KEY_MENU},
|
||||||
{"\033[Z", MP_KEY_TAB | MP_KEY_MODIFIER_SHIFT},
|
{"\033[Z", MP_KEY_TAB | MP_KEY_MODIFIER_SHIFT},
|
||||||
|
|
||||||
|
// Mouse button inputs. 2 bytes of position information requires special processing.
|
||||||
|
{"\033[M ", MP_MBTN_LEFT | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
{"\033[M!", MP_MBTN_MID | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
{"\033[M\"", MP_MBTN_RIGHT | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
{"\033[M#", MP_INPUT_RELEASE_ALL, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
{"\033[M`", MP_WHEEL_UP, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
{"\033[Ma", MP_WHEEL_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_BUTTON},
|
||||||
|
// Mouse move inputs. No key events should be generated for them.
|
||||||
|
{"\033[M@", MP_MBTN_LEFT | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_MOVE},
|
||||||
|
{"\033[MA", MP_MBTN_MID | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_MOVE},
|
||||||
|
{"\033[MB", MP_MBTN_RIGHT | MP_KEY_STATE_DOWN, .skip = 2, .type = ENTRY_TYPE_MOUSE_MOVE},
|
||||||
|
{"\033[MC", MP_INPUT_RELEASE_ALL, .skip = 2, .type = ENTRY_TYPE_MOUSE_MOVE},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -250,7 +272,7 @@ static void process_input(struct input_ctx *input_ctx, bool timeout)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int seq_len = strlen(match->seq);
|
int seq_len = strlen(match->seq) + match->skip;
|
||||||
if (seq_len > buf.len)
|
if (seq_len > buf.len)
|
||||||
goto read_more; /* partial match */
|
goto read_more; /* partial match */
|
||||||
|
|
||||||
|
@ -264,7 +286,23 @@ static void process_input(struct input_ctx *input_ctx, bool timeout)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_input_put_key(input_ctx, buf.mods | match->mpkey);
|
// Parse the initially skipped mouse position information.
|
||||||
|
// The positions are 1-based character cell positions plus 32.
|
||||||
|
// Treat mouse position as the pixel values at the center of the cell.
|
||||||
|
if ((match->type == ENTRY_TYPE_MOUSE_BUTTON ||
|
||||||
|
match->type == ENTRY_TYPE_MOUSE_MOVE) && seq_len >= 6)
|
||||||
|
{
|
||||||
|
int num_rows = 80;
|
||||||
|
int num_cols = 25;
|
||||||
|
int total_px_width = 0;
|
||||||
|
int total_px_height = 0;
|
||||||
|
terminal_get_size2(&num_rows, &num_cols, &total_px_width, &total_px_height);
|
||||||
|
mp_input_set_mouse_pos(input_ctx,
|
||||||
|
(buf.b[4] - 32.5) * (total_px_width / num_cols),
|
||||||
|
(buf.b[5] - 32.5) * (total_px_height / num_rows));
|
||||||
|
}
|
||||||
|
if (match->type != ENTRY_TYPE_MOUSE_MOVE)
|
||||||
|
mp_input_put_key(input_ctx, buf.mods | match->mpkey);
|
||||||
skip_buf(&buf, seq_len);
|
skip_buf(&buf, seq_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#define TERM_ESC_ALT_SCREEN "\033[?1049h"
|
#define TERM_ESC_ALT_SCREEN "\033[?1049h"
|
||||||
#define TERM_ESC_NORMAL_SCREEN "\033[?1049l"
|
#define TERM_ESC_NORMAL_SCREEN "\033[?1049l"
|
||||||
|
|
||||||
|
#define TERM_ESC_ENABLE_MOUSE "\033[?1003h"
|
||||||
|
#define TERM_ESC_DISABLE_MOUSE "\033[?1003l"
|
||||||
|
|
||||||
struct input_ctx;
|
struct input_ctx;
|
||||||
|
|
||||||
/* Global initialization for terminal output. */
|
/* Global initialization for terminal output. */
|
||||||
|
|
Loading…
Reference in New Issue