Improve mouse selection for windows with padding
Moving the mouse into the padding area now acts as if the mouse is over the nearest cell. Fixes #430 Note that this only applies to padding defined via the window_padding_width option, not any leftover space from the window size not being an exact multiple of the cell size.
This commit is contained in:
parent
90a4b4f859
commit
325d2bc14e
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user