Port drag select to C
This commit is contained in:
parent
cf6894d74f
commit
a27004da35
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)) {
|
||||
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) {
|
||||
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:
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user