Port drag select to C

This commit is contained in:
Kovid Goyal 2017-09-14 13:53:24 +05:30
parent cf6894d74f
commit a27004da35
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
8 changed files with 49 additions and 46 deletions

View File

@ -197,13 +197,6 @@ PyInit_fast_data_types(void) {
PyModule_AddIntMacro(m, DECCOLM);
PyModule_AddIntMacro(m, DECOM);
PyModule_AddIntMacro(m, IRM);
PyModule_AddIntMacro(m, ANY_MODE);
PyModule_AddIntMacro(m, MOTION_MODE);
PyModule_AddIntMacro(m, BUTTON_MODE);
PyModule_AddIntMacro(m, SGR_PROTOCOL);
PyModule_AddIntMacro(m, NORMAL_PROTOCOL);
PyModule_AddIntMacro(m, URXVT_PROTOCOL);
PyModule_AddIntMacro(m, UTF8_PROTOCOL);
}
return m;

View File

@ -32,13 +32,8 @@ typedef uint16_t sprite_index;
typedef enum CursorShapes { NO_CURSOR_SHAPE, CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE, NUM_OF_CURSOR_SHAPES } CursorShape;
#define ERROR_PREFIX "[PARSE ERROR]"
#define ANY_MODE 3
#define MOTION_MODE 2
#define BUTTON_MODE 1
#define NORMAL_PROTOCOL 0
#define UTF8_PROTOCOL 1
#define SGR_PROTOCOL 2
#define URXVT_PROTOCOL 3
typedef enum MouseTrackingModes { NO_TRACKING, BUTTON_MODE, MOTION_MODE, ANY_MODE } MouseTrackingMode;
typedef enum MouseTrackingProtocols { NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL} MouseTrackingProtocol;
#define MAX_CHILDREN 256
#define BLANK_CHAR 0
@ -197,7 +192,8 @@ PyTypeObject ColorProfile_Type;
typedef struct {
bool mLNM, mIRM, mDECTCEM, mDECSCNM, mDECOM, mDECAWM, mDECCOLM, mDECARM, mDECCKM,
mBRACKETED_PASTE, mFOCUS_TRACKING, mEXTENDED_KEYBOARD;
unsigned long mouse_tracking_mode, mouse_tracking_protocol;
MouseTrackingMode mouse_tracking_mode;
MouseTrackingProtocol mouse_tracking_protocol;
} ScreenModes;
PyTypeObject ScreenModes_Type;

View File

@ -16,6 +16,10 @@
#error "glfw >= 3.2 required"
#endif
#if GLFW_KEY_LAST >= MAX_KEY_COUNT
#error "glfw has too many keys, you should increase MAX_KEY_COUNT"
#endif
#define MAX_WINDOWS 256
#define CALLBACK(name, fmt, ...) \
@ -59,6 +63,7 @@ char_mods_callback(GLFWwindow UNUSED *w, unsigned int codepoint, int mods) {
static void
key_callback(GLFWwindow UNUSED *w, int key, int scancode, int action, int mods) {
global_state.cursor_blink_zero_time = monotonic();
if (key >= 0 && key <= GLFW_KEY_LAST) global_state.is_key_pressed[key] = action == GLFW_RELEASE ? false : true;
WINDOW_CALLBACK(key_callback, "iiii", key, scancode, action, mods);
}

View File

@ -40,14 +40,37 @@ cell_for_pos(Window *w, unsigned int *x, unsigned int *y) {
#define HANDLER(name) static inline void name(Window UNUSED *w, int UNUSED button, int UNUSED modifiers, unsigned int UNUSED window_idx)
static inline void
update_drag(bool from_button, Window *w, bool is_release) {
Screen *screen = w->render_data.screen;
if (from_button) {
if (is_release) screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, true);
else screen_start_selection(screen, w->mouse_cell_x, w->mouse_cell_y);
} else if (screen->selection.in_progress) {
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
call_boss(set_primary_selection, NULL);
}
}
HANDLER(handle_move_event) {
unsigned int x, y;
if (cell_for_pos(w, &x, &y)) {
Line *line = screen_visual_line(w->render_data.screen, y);
has_click_cursor = (line && line_url_start_at(line, x) < line->xnum) ? true : false;
if (x != w->mouse_cell_x || y != w->mouse_cell_y) {
w->mouse_cell_x = x; w->mouse_cell_y = y;
if (!cell_for_pos(w, &x, &y)) return;
Line *line = screen_visual_line(w->render_data.screen, y);
has_click_cursor = (line && line_url_start_at(line, x) < line->xnum) ? true : false;
if (x == w->mouse_cell_x && y == w->mouse_cell_y) return;
w->mouse_cell_x = x; w->mouse_cell_y = y;
Screen *screen = w->render_data.screen;
bool handle_in_kitty = (
(screen->modes.mouse_tracking_mode == ANY_MODE ||
(screen->modes.mouse_tracking_mode == MOTION_MODE && button >= 0)) &&
!(global_state.is_key_pressed[GLFW_KEY_LEFT_SHIFT] || global_state.is_key_pressed[GLFW_KEY_RIGHT_SHIFT])
) ? false : true;
if (handle_in_kitty) {
if (screen->selection.in_progress && button == GLFW_MOUSE_BUTTON_LEFT) {
update_drag(false, w, false);
}
} else {
// TODO: Implement this
}
}
@ -107,7 +130,7 @@ HANDLER(handle_button_event) {
if (handle_in_kitty) {
switch(button) {
case GLFW_MOUSE_BUTTON_LEFT:
// TODO: update_drag
update_drag(true, w, is_release);
if (is_release) {
if (modifiers == (int)OPT(open_url_modifiers)) {
// TODO: click_url
@ -121,12 +144,14 @@ HANDLER(handle_button_event) {
break;
}
} else {
// TODO: Implement this
}
}
HANDLER(handle_event) {
switch(button) {
case -1:
for (int i = 0; i < GLFW_MOUSE_BUTTON_5; i++) { if (global_state.mouse_button_pressed[i]) { button = i; break; } }
handle_move_event(w, button, modifiers, window_idx);
break;
case GLFW_MOUSE_BUTTON_LEFT:

View File

@ -4,8 +4,8 @@
from .fast_data_types import (
GLFW_MOUSE_BUTTON_2, GLFW_MOUSE_BUTTON_3, GLFW_MOD_ALT, GLFW_MOD_CONTROL,
GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_4, GLFW_MOUSE_BUTTON_5, SGR_PROTOCOL,
GLFW_MOUSE_BUTTON_1, URXVT_PROTOCOL, UTF8_PROTOCOL
GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_4, GLFW_MOUSE_BUTTON_5,
GLFW_MOUSE_BUTTON_1,
)
PRESS, RELEASE, DRAG, MOVE = range(4)

View File

@ -1283,16 +1283,6 @@ MODE_GETSET(auto_repeat_enabled, DECARM)
MODE_GETSET(cursor_visible, DECTCEM)
MODE_GETSET(cursor_key_mode, DECCKM)
static PyObject*
mouse_tracking_mode(Screen *self) {
return PyLong_FromUnsignedLong(self->modes.mouse_tracking_mode);
}
static PyObject*
mouse_tracking_protocol(Screen *self) {
return PyLong_FromUnsignedLong(self->modes.mouse_tracking_protocol);
}
static PyObject*
cursor_up(Screen *self, PyObject *args) {
unsigned int count = 1;
@ -1417,13 +1407,6 @@ scroll(Screen *self, PyObject *args) {
Py_RETURN_FALSE;
}
static PyObject*
is_selection_in_progress(Screen *self) {
PyObject *ans = self->selection.in_progress ? Py_True : Py_False;
Py_INCREF(ans);
return ans;
}
bool
screen_is_selection_dirty(Screen *self) {
SelectionBoundary start, end;
@ -1507,8 +1490,6 @@ static PyMethodDef methods[] = {
MND(change_scrollback_size, METH_VARARGS)
MND(erase_characters, METH_VARARGS)
MND(cursor_up, METH_VARARGS)
MND(mouse_tracking_mode, METH_NOARGS)
MND(mouse_tracking_protocol, METH_NOARGS)
MND(cursor_up1, METH_VARARGS)
MND(cursor_down, METH_VARARGS)
MND(cursor_down1, METH_VARARGS)
@ -1526,7 +1507,6 @@ static PyMethodDef methods[] = {
MND(resize, METH_VARARGS)
MND(set_margins, METH_VARARGS)
MND(text_for_selection, METH_NOARGS)
MND(is_selection_in_progress, METH_NOARGS)
MND(scroll, METH_VARARGS)
MND(toggle_alt_screen, METH_NOARGS)
MND(reset_callbacks, METH_NOARGS)

View File

@ -53,6 +53,8 @@ typedef struct {
Window windows[MAX_CHILDREN];
} Tab;
#define MAX_KEY_COUNT 512
typedef struct {
Options opts;
@ -68,6 +70,7 @@ typedef struct {
unsigned int cell_width, cell_height;
PyObject *application_title;
PyObject *boss;
bool is_key_pressed[MAX_KEY_COUNT];
} GlobalState;
extern GlobalState global_state;

View File

@ -16,11 +16,11 @@ from .constants import (
is_key_pressed, mouse_button_pressed, viewport_size, wakeup
)
from .fast_data_types import (
ANY_MODE, BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_PROGRAM,
BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_PROGRAM,
CURSOR_PROGRAM, GLFW_KEY_DOWN, GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT,
GLFW_KEY_UP, GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_1, GLFW_MOUSE_BUTTON_4,
GLFW_MOUSE_BUTTON_5, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, GLFW_RELEASE,
MOTION_MODE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
compile_program, create_cell_vao, glfw_post_empty_event, init_cell_program,
init_cursor_program, remove_vao, set_window_render_data,
update_window_title, update_window_visibility
@ -350,14 +350,15 @@ class Window:
if mouse_button_pressed[b]:
button = b
break
action = MOVE if button is None else DRAG
mode = self.screen.mouse_tracking_mode()
ANY_MODE, MOTION_MODE = 3, 2
send_event = (mode == ANY_MODE or (mode == MOTION_MODE and button is not None)) and not (
is_key_pressed[GLFW_KEY_LEFT_SHIFT] or is_key_pressed[GLFW_KEY_RIGHT_SHIFT])
x, y = max(0, x - self.geometry.left), max(0, y - self.geometry.top)
self.last_mouse_cursor_pos = x, y
get_boss().change_mouse_cursor(self.has_url_at(x, y))
if send_event:
action = MOVE if button is None else DRAG
x, y = self.cell_for_pos(x, y)
if x is not None:
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),