Move the scroll event handler to C
This commit is contained in:
14
kitty/glfw.c
14
kitty/glfw.c
@@ -36,7 +36,7 @@ typedef struct {
|
|||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
PyObject *framebuffer_size_callback, *char_mods_callback, *key_callback, *mouse_button_callback, *scroll_callback, *cursor_pos_callback, *window_focus_callback;
|
PyObject *framebuffer_size_callback, *char_mods_callback, *key_callback, *window_focus_callback;
|
||||||
GLFWcursor *standard_cursor, *click_cursor, *arrow_cursor;
|
GLFWcursor *standard_cursor, *click_cursor, *arrow_cursor;
|
||||||
} WindowWrapper;
|
} WindowWrapper;
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@ key_callback(GLFWwindow UNUSED *w, int key, int scancode, int action, int mods)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern void mouse_event(int, int);
|
extern void mouse_event(int, int);
|
||||||
|
extern void scroll_event(double, double);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mouse_button_callback(GLFWwindow *w, int button, int action, int mods) {
|
mouse_button_callback(GLFWwindow *w, int button, int action, int mods) {
|
||||||
@@ -78,7 +79,6 @@ mouse_button_callback(GLFWwindow *w, int button, int action, int mods) {
|
|||||||
global_state.mouse_button_pressed[button] = action == GLFW_PRESS ? true : false;
|
global_state.mouse_button_pressed[button] = action == GLFW_PRESS ? true : false;
|
||||||
mouse_event(button, mods);
|
mouse_event(button, mods);
|
||||||
}
|
}
|
||||||
/* WINDOW_CALLBACK(mouse_button_callback, "iii", button, action, mods); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -89,7 +89,6 @@ cursor_pos_callback(GLFWwindow *w, double x, double y) {
|
|||||||
global_state.cursor_blink_zero_time = now;
|
global_state.cursor_blink_zero_time = now;
|
||||||
global_state.mouse_x = x; global_state.mouse_y = y;
|
global_state.mouse_x = x; global_state.mouse_y = y;
|
||||||
mouse_event(-1, 0);
|
mouse_event(-1, 0);
|
||||||
/* WINDOW_CALLBACK(cursor_pos_callback, "dd", x, y); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -97,7 +96,7 @@ scroll_callback(GLFWwindow *w, double xoffset, double yoffset) {
|
|||||||
if (!global_state.mouse_visible) { glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL); global_state.mouse_visible = true; }
|
if (!global_state.mouse_visible) { glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL); global_state.mouse_visible = true; }
|
||||||
double now = monotonic();
|
double now = monotonic();
|
||||||
global_state.last_mouse_activity_at = now;
|
global_state.last_mouse_activity_at = now;
|
||||||
WINDOW_CALLBACK(scroll_callback, "dd", xoffset, yoffset);
|
scroll_event(xoffset, yoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -147,10 +146,10 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
|||||||
set_mouse_cursor(0);
|
set_mouse_cursor(0);
|
||||||
glfwSetFramebufferSizeCallback(self->window, framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(self->window, framebuffer_size_callback);
|
||||||
glfwSetCharModsCallback(self->window, char_mods_callback);
|
glfwSetCharModsCallback(self->window, char_mods_callback);
|
||||||
glfwSetKeyCallback(self->window, key_callback);
|
|
||||||
glfwSetMouseButtonCallback(self->window, mouse_button_callback);
|
glfwSetMouseButtonCallback(self->window, mouse_button_callback);
|
||||||
glfwSetScrollCallback(self->window, scroll_callback);
|
glfwSetScrollCallback(self->window, scroll_callback);
|
||||||
glfwSetCursorPosCallback(self->window, cursor_pos_callback);
|
glfwSetCursorPosCallback(self->window, cursor_pos_callback);
|
||||||
|
glfwSetKeyCallback(self->window, key_callback);
|
||||||
glfwSetWindowFocusCallback(self->window, window_focus_callback);
|
glfwSetWindowFocusCallback(self->window, window_focus_callback);
|
||||||
}
|
}
|
||||||
return (PyObject*)self;
|
return (PyObject*)self;
|
||||||
@@ -263,7 +262,7 @@ glfw_init_hint_string(PyObject UNUSED *self, PyObject *args) {
|
|||||||
static void
|
static void
|
||||||
dealloc(WindowWrapper* self) {
|
dealloc(WindowWrapper* self) {
|
||||||
the_window = NULL;
|
the_window = NULL;
|
||||||
Py_CLEAR(self->framebuffer_size_callback); Py_CLEAR(self->char_mods_callback); Py_CLEAR(self->key_callback); Py_CLEAR(self->mouse_button_callback); Py_CLEAR(self->scroll_callback); Py_CLEAR(self->cursor_pos_callback); Py_CLEAR(self->window_focus_callback);
|
Py_CLEAR(self->framebuffer_size_callback); Py_CLEAR(self->char_mods_callback); Py_CLEAR(self->key_callback); Py_CLEAR(self->window_focus_callback);
|
||||||
if (self->window != NULL) glfwDestroyWindow(self->window);
|
if (self->window != NULL) glfwDestroyWindow(self->window);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
@@ -452,9 +451,6 @@ static PyMemberDef members[] = {
|
|||||||
CBE(framebuffer_size_callback),
|
CBE(framebuffer_size_callback),
|
||||||
CBE(char_mods_callback),
|
CBE(char_mods_callback),
|
||||||
CBE(key_callback),
|
CBE(key_callback),
|
||||||
CBE(mouse_button_callback),
|
|
||||||
CBE(scroll_callback),
|
|
||||||
CBE(cursor_pos_callback),
|
|
||||||
CBE(window_focus_callback),
|
CBE(window_focus_callback),
|
||||||
{NULL}
|
{NULL}
|
||||||
#undef CBE
|
#undef CBE
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "lineops.h"
|
#include "lineops.h"
|
||||||
|
#include <math.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
extern void set_mouse_cursor(MouseShape);
|
extern void set_mouse_cursor(MouseShape);
|
||||||
@@ -203,23 +204,56 @@ handle_tab_bar_mouse(int button, int UNUSED modifiers) {
|
|||||||
call_boss(activate_tab_at, "d", global_state.mouse_x);
|
call_boss(activate_tab_at, "d", global_state.mouse_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static inline Window*
|
||||||
mouse_event(int button, int modifiers) {
|
window_for_event(unsigned int *window_idx, bool *in_tab_bar) {
|
||||||
MouseShape old_cursor = mouse_cursor_shape;
|
*in_tab_bar = global_state.num_tabs > 1 && global_state.mouse_y >= global_state.viewport_height - global_state.cell_height ? true : false;
|
||||||
bool in_tab_bar = global_state.num_tabs > 1 && global_state.mouse_y >= global_state.viewport_height - global_state.cell_height ? true : false;
|
if (!*in_tab_bar) {
|
||||||
if (in_tab_bar) {
|
|
||||||
mouse_cursor_shape = HAND;
|
|
||||||
handle_tab_bar_mouse(button, modifiers);
|
|
||||||
} else {
|
|
||||||
Tab *t = global_state.tabs + global_state.active_tab;
|
Tab *t = global_state.tabs + global_state.active_tab;
|
||||||
for (unsigned int i = 0; i < t->num_windows; i++) {
|
for (unsigned int i = 0; i < t->num_windows; i++) {
|
||||||
if (contains_mouse(t->windows + i) && t->windows[i].render_data.screen) {
|
if (contains_mouse(t->windows + i) && t->windows[i].render_data.screen) {
|
||||||
handle_event(t->windows + i, button, modifiers, i);
|
*window_idx = i; return t->windows + i;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mouse_event(int button, int modifiers) {
|
||||||
|
MouseShape old_cursor = mouse_cursor_shape;
|
||||||
|
bool in_tab_bar;
|
||||||
|
unsigned int window_idx;
|
||||||
|
Window *w = window_for_event(&window_idx, &in_tab_bar);
|
||||||
|
if (in_tab_bar) {
|
||||||
|
mouse_cursor_shape = HAND;
|
||||||
|
handle_tab_bar_mouse(button, modifiers);
|
||||||
|
} else if(w) {
|
||||||
|
handle_event(w, button, modifiers, window_idx);
|
||||||
|
}
|
||||||
if (mouse_cursor_shape != old_cursor) {
|
if (mouse_cursor_shape != old_cursor) {
|
||||||
set_mouse_cursor(mouse_cursor_shape);
|
set_mouse_cursor(mouse_cursor_shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scroll_event(double UNUSED xoffset, double yoffset) {
|
||||||
|
int s = (int) round(yoffset * OPT(wheel_scroll_multiplier));
|
||||||
|
if (s == 0) return;
|
||||||
|
bool upwards = s > 0 ? true : false;
|
||||||
|
bool in_tab_bar;
|
||||||
|
unsigned int window_idx;
|
||||||
|
Window *w = window_for_event(&window_idx, &in_tab_bar);
|
||||||
|
if (w) {
|
||||||
|
Screen *screen = w->render_data.screen;
|
||||||
|
if (screen->linebuf == screen->main_linebuf) {
|
||||||
|
screen_history_scroll(screen, abs(s), upwards);
|
||||||
|
} else {
|
||||||
|
if (screen->modes.mouse_tracking_mode) {
|
||||||
|
// TODO: Implement this
|
||||||
|
} else {
|
||||||
|
// TODO: Implement this, writing a up arrow or down arrow key event to the child
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ PYWRAP1(set_options) {
|
|||||||
S(cursor_shape, PyLong_AsLong);
|
S(cursor_shape, PyLong_AsLong);
|
||||||
S(cursor_opacity, PyFloat_AsDouble);
|
S(cursor_opacity, PyFloat_AsDouble);
|
||||||
S(mouse_hide_wait, PyFloat_AsDouble);
|
S(mouse_hide_wait, PyFloat_AsDouble);
|
||||||
|
S(wheel_scroll_multiplier, PyFloat_AsDouble);
|
||||||
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
||||||
S(click_interval, PyFloat_AsDouble);
|
S(click_interval, PyFloat_AsDouble);
|
||||||
PyObject *chars = PyObject_GetAttrString(args, "select_by_word_characters");
|
PyObject *chars = PyObject_GetAttrString(args, "select_by_word_characters");
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#define OPT(name) global_state.opts.name
|
#define OPT(name) global_state.opts.name
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double visual_bell_duration, cursor_blink_interval, cursor_stop_blinking_after, mouse_hide_wait, click_interval, cursor_opacity;
|
double visual_bell_duration, cursor_blink_interval, cursor_stop_blinking_after, mouse_hide_wait, click_interval, cursor_opacity, wheel_scroll_multiplier;
|
||||||
bool enable_audio_bell;
|
bool enable_audio_bell;
|
||||||
CursorShape cursor_shape;
|
CursorShape cursor_shape;
|
||||||
unsigned int open_url_modifiers;
|
unsigned int open_url_modifiers;
|
||||||
|
|||||||
Reference in New Issue
Block a user