When dragging to select with the mouse "grab" the mouse so that if it strays into neighboring windows, the selection is still updated
Fixes #624
This commit is contained in:
parent
e27ea3337a
commit
77c4f5fecc
@ -12,6 +12,9 @@ Changelog
|
||||
- Fix triple-click to select line not working when the entire line is filled
|
||||
(:iss:`703`)
|
||||
|
||||
- When dragging to select with the mouse "grab" the mouse so that if it strays
|
||||
into neighboring windows, the selection is still updated (:pull:`624`)
|
||||
|
||||
|
||||
0.11.2 [2018-07-01]
|
||||
------------------------------
|
||||
|
||||
@ -202,6 +202,7 @@ push_focus_history(OSWindow *w) {
|
||||
|
||||
static void
|
||||
window_focus_callback(GLFWwindow *w, int focused) {
|
||||
global_state.active_drag_in_window = 0;
|
||||
if (!set_callback_window(w)) return;
|
||||
global_state.callback_os_window->is_focused = focused ? true : false;
|
||||
if (focused) {
|
||||
|
||||
@ -119,6 +119,8 @@ contains_mouse(Window *w, OSWindow *os_window) {
|
||||
return (w->visible && window_left(w, os_window) <= x && x <= window_right(w, os_window) && window_top(w, os_window) <= y && y <= window_bottom(w, os_window));
|
||||
}
|
||||
|
||||
static bool clamp_to_window = false;
|
||||
|
||||
static inline bool
|
||||
cell_for_pos(Window *w, unsigned int *x, unsigned int *y, OSWindow *os_window) {
|
||||
WindowGeometry *g = &w->geometry;
|
||||
@ -128,6 +130,10 @@ cell_for_pos(Window *w, unsigned int *x, unsigned int *y, OSWindow *os_window) {
|
||||
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, os_window), top = window_top(w, os_window), right = window_right(w, os_window), bottom = window_bottom(w, os_window);
|
||||
if (clamp_to_window) {
|
||||
mouse_x = MIN(MAX(mouse_x, left), right);
|
||||
mouse_y = MIN(MAX(mouse_y, top), bottom);
|
||||
}
|
||||
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) / os_window->fonts_data->cell_width);
|
||||
@ -147,10 +153,14 @@ update_drag(bool from_button, Window *w, bool is_release, int modifiers) {
|
||||
Screen *screen = w->render_data.screen;
|
||||
if (from_button) {
|
||||
if (is_release) {
|
||||
global_state.active_drag_in_window = 0;
|
||||
if (screen->selection.in_progress)
|
||||
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, modifiers == (int)OPT(rectangle_select_modifiers) || modifiers == ((int)OPT(rectangle_select_modifiers) | GLFW_MOD_SHIFT), EXTEND_CELL);
|
||||
else {
|
||||
global_state.active_drag_in_window = w->id;
|
||||
screen_start_selection(screen, w->mouse_cell_x, w->mouse_cell_y, modifiers == (int)OPT(rectangle_select_modifiers) || modifiers == ((int)OPT(rectangle_select_modifiers) | GLFW_MOD_SHIFT), EXTEND_CELL);
|
||||
}
|
||||
} else if (screen->selection.in_progress) {
|
||||
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
|
||||
}
|
||||
@ -372,6 +382,16 @@ mouse_in_region(Region *r) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline Window*
|
||||
window_for_id(id_type window_id) {
|
||||
Tab *t = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab;
|
||||
for (unsigned int i = 0; i < t->num_windows; i++) {
|
||||
Window *w = t->windows + i;
|
||||
if (w->id == window_id) return w;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline Window*
|
||||
window_for_event(unsigned int *window_idx, bool *in_tab_bar) {
|
||||
Region central, tab_bar;
|
||||
@ -405,7 +425,21 @@ mouse_event(int button, int modifiers) {
|
||||
MouseShape old_cursor = mouse_cursor_shape;
|
||||
bool in_tab_bar;
|
||||
unsigned int window_idx = 0;
|
||||
Window *w = window_for_event(&window_idx, &in_tab_bar);
|
||||
Window *w = NULL;
|
||||
if (button == -1 && global_state.active_drag_in_window) { // drag move
|
||||
w = window_for_id(global_state.active_drag_in_window);
|
||||
if (w) {
|
||||
for (int i = 0; i < GLFW_MOUSE_BUTTON_5; i++) { if (global_state.callback_os_window->mouse_button_pressed[i]) { button = i; break; } }
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT) {
|
||||
clamp_to_window = true;
|
||||
handle_move_event(w, button, modifiers, window_idx);
|
||||
clamp_to_window = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
w = window_for_event(&window_idx, &in_tab_bar);
|
||||
if (in_tab_bar) {
|
||||
mouse_cursor_shape = HAND;
|
||||
handle_tab_bar_mouse(button, modifiers);
|
||||
|
||||
@ -141,6 +141,7 @@ typedef struct {
|
||||
bool in_sequence_mode;
|
||||
double font_sz_in_pts;
|
||||
struct { double x, y; } default_dpi;
|
||||
id_type active_drag_in_window;
|
||||
} GlobalState;
|
||||
|
||||
extern GlobalState global_state;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user