diff --git a/kitty/mouse.c b/kitty/mouse.c index 0e12e0fa5..f01e9d44e 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -93,24 +93,51 @@ encode_mouse_event(Window *w, int button, MouseAction action, int mods) { // }}} +static inline double +window_left(Window *w) { + return w->geometry.left - OPT(window_padding_width) * (global_state.logical_dpi_x / 72.0); +} + +static inline double +window_right(Window *w) { + return w->geometry.right + OPT(window_padding_width) * (global_state.logical_dpi_x / 72.0); +} + +static inline double +window_top(Window *w) { + return w->geometry.top - OPT(window_padding_width) * (global_state.logical_dpi_y / 72.0); +} + +static inline double +window_bottom(Window *w) { + return w->geometry.bottom + OPT(window_padding_width) * (global_state.logical_dpi_y / 72.0); +} + static inline bool contains_mouse(Window *w) { - WindowGeometry *g = &w->geometry; double x = global_state.callback_os_window->mouse_x, y = global_state.callback_os_window->mouse_y; - return (w->visible && g->left <= x && x <= g->right && g->top <= y && y <= g->bottom); + return (w->visible && window_left(w) <= x && x <= window_right(w) && window_top(w) <= y && y <= window_bottom(w)); } static inline bool cell_for_pos(Window *w, unsigned int *x, unsigned int *y) { WindowGeometry *g = &w->geometry; - unsigned int qx = (unsigned int)((double)(global_state.callback_os_window->mouse_x - g->left) / global_state.cell_width); - unsigned int qy = (unsigned int)((double)(global_state.callback_os_window->mouse_y - g->top) / global_state.cell_height); - bool ret = false; Screen *screen = w->render_data.screen; - if (screen && qx <= screen->columns && qy <= screen->lines) { - *x = qx; *y = qy; ret = true; + if (!screen) return false; + unsigned int qx = 0, qy = 0; + double mouse_x = global_state.callback_os_window->mouse_x; + double mouse_y = global_state.callback_os_window->mouse_y; + double left = window_left(w), top = window_top(w), right = window_right(w), bottom = window_bottom(w); + if (mouse_x < left || mouse_y < top || mouse_x > right || mouse_y > bottom) return false; + if (mouse_x >= g->right) qx = screen->columns - 1; + else if (mouse_x >= g->left) qx = (unsigned int)((double)(mouse_x - g->left) / global_state.cell_width); + if (mouse_y >= g->bottom) qy = screen->lines - 1; + else if (mouse_y >= g->top) qy = (unsigned int)((double)(mouse_y - g->top) / global_state.cell_height); + if (qx < screen->columns && qy < screen->lines) { + *x = qx; *y = qy; + return true; } - return ret; + return false; } #define HANDLER(name) static inline void name(Window UNUSED *w, int UNUSED button, int UNUSED modifiers, unsigned int UNUSED window_idx) @@ -130,9 +157,10 @@ update_drag(bool from_button, Window *w, bool is_release, int modifiers) { bool drag_scroll(Window *w, OSWindow *frame) { unsigned int margin = global_state.cell_height / 2; + double left = window_left(w), top = window_top(w), right = window_right(w), bottom = window_bottom(w); double x = frame->mouse_x, y = frame->mouse_y; - if (y < w->geometry.top || y > w->geometry.bottom) return false; - if (x < w->geometry.left || x > w->geometry.right) return false; + if (y < top || y > bottom) return false; + if (x < left || x > right) return false; bool upwards = y <= (w->geometry.top + margin); if (upwards || y >= w->geometry.bottom - margin) { Screen *screen = w->render_data.screen; diff --git a/kitty/state.c b/kitty/state.c index d43d848c2..38fde1049 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -339,6 +339,7 @@ PYWRAP1(set_options) { S(cursor_stop_blinking_after, PyFloat_AsDouble); S(background_opacity, PyFloat_AsDouble); S(inactive_text_alpha, PyFloat_AsDouble); + S(window_padding_width, PyFloat_AsDouble); S(cursor_shape, PyLong_AsLong); S(url_style, PyLong_AsUnsignedLong); S(tab_bar_edge, PyLong_AsLong); diff --git a/kitty/state.h b/kitty/state.h index 6ac0d42a9..452ddf892 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -28,6 +28,7 @@ typedef struct { float adjust_line_height_frac, adjust_column_width_frac; float background_opacity; float inactive_text_alpha; + float window_padding_width; Edge tab_bar_edge; bool sync_to_monitor; bool close_on_child_death;