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:
Kovid Goyal 2018-07-06 10:33:01 +05:30
parent e27ea3337a
commit 77c4f5fecc
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 41 additions and 2 deletions

View File

@ -12,6 +12,9 @@ Changelog
- Fix triple-click to select line not working when the entire line is filled - Fix triple-click to select line not working when the entire line is filled
(:iss:`703`) (: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] 0.11.2 [2018-07-01]
------------------------------ ------------------------------

View File

@ -202,6 +202,7 @@ push_focus_history(OSWindow *w) {
static void static void
window_focus_callback(GLFWwindow *w, int focused) { window_focus_callback(GLFWwindow *w, int focused) {
global_state.active_drag_in_window = 0;
if (!set_callback_window(w)) return; if (!set_callback_window(w)) return;
global_state.callback_os_window->is_focused = focused ? true : false; global_state.callback_os_window->is_focused = focused ? true : false;
if (focused) { if (focused) {

View File

@ -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)); 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 static inline bool
cell_for_pos(Window *w, unsigned int *x, unsigned int *y, OSWindow *os_window) { cell_for_pos(Window *w, unsigned int *x, unsigned int *y, OSWindow *os_window) {
WindowGeometry *g = &w->geometry; 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_x = global_state.callback_os_window->mouse_x;
double mouse_y = global_state.callback_os_window->mouse_y; 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); 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 < left || mouse_y < top || mouse_x > right || mouse_y > bottom) return false;
if (mouse_x >= g->right) qx = screen->columns - 1; 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); 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; Screen *screen = w->render_data.screen;
if (from_button) { if (from_button) {
if (is_release) { if (is_release) {
global_state.active_drag_in_window = 0;
if (screen->selection.in_progress) if (screen->selection.in_progress)
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, true); 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) { } else if (screen->selection.in_progress) {
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false); screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
} }
@ -372,6 +382,16 @@ mouse_in_region(Region *r) {
return true; 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* static inline Window*
window_for_event(unsigned int *window_idx, bool *in_tab_bar) { window_for_event(unsigned int *window_idx, bool *in_tab_bar) {
Region central, tab_bar; Region central, tab_bar;
@ -405,7 +425,21 @@ mouse_event(int button, int modifiers) {
MouseShape old_cursor = mouse_cursor_shape; MouseShape old_cursor = mouse_cursor_shape;
bool in_tab_bar; bool in_tab_bar;
unsigned int window_idx = 0; 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) { if (in_tab_bar) {
mouse_cursor_shape = HAND; mouse_cursor_shape = HAND;
handle_tab_bar_mouse(button, modifiers); handle_tab_bar_mouse(button, modifiers);

View File

@ -141,6 +141,7 @@ typedef struct {
bool in_sequence_mode; bool in_sequence_mode;
double font_sz_in_pts; double font_sz_in_pts;
struct { double x, y; } default_dpi; struct { double x, y; } default_dpi;
id_type active_drag_in_window;
} GlobalState; } GlobalState;
extern GlobalState global_state; extern GlobalState global_state;