Merge branch 'mouse-events' of https://github.com/trygveaa/kitty
This commit is contained in:
commit
9fa97e6187
@ -142,12 +142,13 @@ those using::
|
||||
send_mouse_event(screen, x, y, button, action, mods)
|
||||
|
||||
``screen`` is the ``screen`` attribute of the window you want to send the event
|
||||
to. ``x`` and ``y`` are the 0-indexed coordinates. ``button`` is
|
||||
``GLFW_MOUSE_BUTTON_{button}`` where ``{button}`` is one of ``LEFT``,
|
||||
``RIGHT``, ``MIDDLE`` or a digit from ``1`` to ``8``. ``action`` is one of
|
||||
``PRESS``, ``RELEASE``, ``DRAG`` or ``MOVE``. ``mods`` is a bitmask of
|
||||
``GLFW_MOD_{mod}`` where ``{mod}`` is one of ``SHIFT``, ``CONTROL`` or ``ALT``.
|
||||
All the mentioned constants are imported from ``kitty.fast_data_types``.
|
||||
to. ``x`` and ``y`` are the 0-indexed coordinates. ``button`` is a number using
|
||||
the same numbering as X11 (left: ``1``, middle: ``2``, right: ``3``, scroll up:
|
||||
``4``, scroll down: ``5``, scroll left: ``6``, scroll right: ``7``, back:
|
||||
``8``, forward: ``9``). ``action`` is one of ``PRESS``, ``RELEASE``, ``DRAG``
|
||||
or ``MOVE``. ``mods`` is a bitmask of ``GLFW_MOD_{mod}`` where ``{mod}`` is one
|
||||
of ``SHIFT``, ``CONTROL`` or ``ALT``. All the mentioned constants are imported
|
||||
from ``kitty.fast_data_types``.
|
||||
|
||||
For example, to send a left click at position x: 2, y: 3 to the active window::
|
||||
|
||||
|
||||
28
kitty/glfw.c
28
kitty/glfw.c
@ -227,10 +227,38 @@ refresh_callback(GLFWwindow *w) {
|
||||
|
||||
static int mods_at_last_key_or_button_event = 0;
|
||||
|
||||
static inline int
|
||||
key_to_modifier(int key) {
|
||||
switch(key) {
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
return GLFW_MOD_SHIFT;
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
return GLFW_MOD_CONTROL;
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
case GLFW_KEY_RIGHT_ALT:
|
||||
return GLFW_MOD_ALT;
|
||||
case GLFW_KEY_LEFT_SUPER:
|
||||
case GLFW_KEY_RIGHT_SUPER:
|
||||
return GLFW_MOD_SUPER;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
key_callback(GLFWwindow *w, GLFWkeyevent *ev) {
|
||||
if (!set_callback_window(w)) return;
|
||||
mods_at_last_key_or_button_event = ev->mods;
|
||||
int key_modifier = key_to_modifier(ev->key);
|
||||
if (key_modifier != -1) {
|
||||
if (ev->action == GLFW_RELEASE) {
|
||||
mods_at_last_key_or_button_event &= ~key_modifier;
|
||||
} else {
|
||||
mods_at_last_key_or_button_event |= key_modifier;
|
||||
}
|
||||
}
|
||||
global_state.callback_os_window->cursor_blink_zero_time = monotonic();
|
||||
if (ev->key >= 0 && ev->key <= GLFW_KEY_LAST) {
|
||||
global_state.callback_os_window->is_key_pressed[ev->key] = ev->action == GLFW_RELEASE ? false : true;
|
||||
|
||||
@ -25,27 +25,43 @@ typedef enum MouseActions { PRESS, RELEASE, DRAG, MOVE } MouseAction;
|
||||
#define ALT_INDICATOR (1 << 3)
|
||||
#define CONTROL_INDICATOR (1 << 4)
|
||||
#define MOTION_INDICATOR (1 << 5)
|
||||
#define EXTRA_BUTTON_INDICATOR (1 << 6)
|
||||
#define SCROLL_BUTTON_INDICATOR (1 << 6)
|
||||
#define EXTRA_BUTTON_INDICATOR (1 << 7)
|
||||
|
||||
|
||||
static inline unsigned int
|
||||
button_map(int button) {
|
||||
switch(button) {
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
return 0;
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
return 2;
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
return 1;
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
return 3;
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
return 2;
|
||||
case GLFW_MOUSE_BUTTON_4:
|
||||
return EXTRA_BUTTON_INDICATOR;
|
||||
case GLFW_MOUSE_BUTTON_5:
|
||||
return EXTRA_BUTTON_INDICATOR | 1;
|
||||
case GLFW_MOUSE_BUTTON_6:
|
||||
case GLFW_MOUSE_BUTTON_7:
|
||||
case GLFW_MOUSE_BUTTON_8:
|
||||
return button + 5;
|
||||
default:
|
||||
return UINT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
encode_button(unsigned int button) {
|
||||
if (button >= 8 && button <= 11) {
|
||||
return (button - 8) | EXTRA_BUTTON_INDICATOR;
|
||||
} else if (button >= 4 && button <= 7) {
|
||||
return (button - 4) | SCROLL_BUTTON_INDICATOR;
|
||||
} else if (button >= 1 && button <= 3) {
|
||||
return button - 1;
|
||||
} else {
|
||||
return UINT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static char mouse_event_buf[64];
|
||||
|
||||
static inline int
|
||||
@ -54,7 +70,7 @@ encode_mouse_event_impl(unsigned int x, unsigned int y, int mouse_tracking_proto
|
||||
if (action == MOVE) {
|
||||
cb = 3;
|
||||
} else {
|
||||
cb = button_map(button);
|
||||
cb = encode_button(button);
|
||||
if (cb == UINT_MAX) return 0;
|
||||
}
|
||||
if (action == DRAG || action == MOVE) cb |= MOTION_INDICATOR;
|
||||
@ -92,7 +108,16 @@ encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
||||
unsigned int x = w->mouse_pos.cell_x + 1, y = w->mouse_pos.cell_y + 1; // 1 based indexing
|
||||
Screen *screen = w->render_data.screen;
|
||||
return encode_mouse_event_impl(x, y, screen->modes.mouse_tracking_protocol, button, action, mods);
|
||||
}
|
||||
|
||||
static int
|
||||
encode_mouse_button(Window *w, int button, MouseAction action, int mods) {
|
||||
return encode_mouse_event(w, button_map(button), action, mods);
|
||||
}
|
||||
|
||||
static int
|
||||
encode_mouse_scroll(Window *w, bool upwards, int mods) {
|
||||
return encode_mouse_event(w, upwards ? 4 : 5, PRESS, mods);
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -341,7 +366,7 @@ HANDLER(handle_move_event) {
|
||||
handle_mouse_movement_in_kitty(w, button, mouse_cell_changed | cell_half_changed);
|
||||
} else {
|
||||
if (!mouse_cell_changed) return;
|
||||
int sz = encode_mouse_event(w, MAX(0, button), button >=0 ? DRAG : MOVE, 0);
|
||||
int sz = encode_mouse_button(w, MAX(0, button), button >=0 ? DRAG : MOVE, modifiers);
|
||||
if (sz > 0) { mouse_event_buf[sz] = 0; write_escape_code_to_child(screen, CSI, mouse_event_buf); }
|
||||
}
|
||||
}
|
||||
@ -450,34 +475,25 @@ HANDLER(handle_button_event) {
|
||||
);
|
||||
if (handle_in_kitty) handle_button_event_in_kitty(w, button, modifiers, is_release);
|
||||
else {
|
||||
int sz = encode_mouse_event(w, button, is_release ? RELEASE : PRESS, modifiers);
|
||||
int sz = encode_mouse_button(w, button, is_release ? RELEASE : PRESS, modifiers);
|
||||
if (sz > 0) { mouse_event_buf[sz] = 0; write_escape_code_to_child(screen, CSI, mouse_event_buf); }
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
currently_pressed_button(void) {
|
||||
for (int i = 0; i < GLFW_MOUSE_BUTTON_5; i++) {
|
||||
for (int i = 0; i <= GLFW_MOUSE_BUTTON_8; i++) {
|
||||
if (global_state.callback_os_window->mouse_button_pressed[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
HANDLER(handle_event) {
|
||||
switch(button) {
|
||||
case -1:
|
||||
button = currently_pressed_button();
|
||||
handle_move_event(w, button, modifiers, window_idx);
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
case GLFW_MOUSE_BUTTON_4:
|
||||
case GLFW_MOUSE_BUTTON_5:
|
||||
handle_button_event(w, button, modifiers, window_idx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (button == -1) {
|
||||
button = currently_pressed_button();
|
||||
handle_move_event(w, button, modifiers, window_idx);
|
||||
} else {
|
||||
handle_button_event(w, button, modifiers, window_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,7 +706,7 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags, int modifiers) {
|
||||
screen_history_scroll(screen, abs(s), upwards);
|
||||
} else {
|
||||
if (screen->modes.mouse_tracking_mode) {
|
||||
int sz = encode_mouse_event(w, upwards ? GLFW_MOUSE_BUTTON_4 : GLFW_MOUSE_BUTTON_5, PRESS, modifiers);
|
||||
int sz = encode_mouse_scroll(w, upwards, modifiers);
|
||||
if (sz > 0) {
|
||||
mouse_event_buf[sz] = 0;
|
||||
for (s = abs(s); s > 0; s--) {
|
||||
|
||||
@ -81,7 +81,7 @@ class TestParser(BaseTest):
|
||||
|
||||
def test_encode_mouse_event(self):
|
||||
NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL = range(4)
|
||||
L, M, R = defines.GLFW_MOUSE_BUTTON_LEFT, defines.GLFW_MOUSE_BUTTON_MIDDLE, defines.GLFW_MOUSE_BUTTON_RIGHT
|
||||
L, M, R = 1, 2, 3
|
||||
protocol = SGR_PROTOCOL
|
||||
|
||||
def enc(button=L, action=defines.PRESS, mods=0, x=1, y=1):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user