mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-29 07:58:01 -04:00
commit
e391658d72
2 changed files with 84 additions and 32 deletions
|
|
@ -54,6 +54,9 @@
|
||||||
* Incorrect multi-column character spacer insertion when reflowing
|
* Incorrect multi-column character spacer insertion when reflowing
|
||||||
text.
|
text.
|
||||||
* Compilation errors in 32-bit builds.
|
* Compilation errors in 32-bit builds.
|
||||||
|
* Mouse cursor style in top and left margins.
|
||||||
|
* Selection is now **updated** when the cursor moves outside the grid
|
||||||
|
(https://codeberg.org/dnkl/foot/issues/70).
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
||||||
113
input.c
113
input.c
|
|
@ -1049,11 +1049,21 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
|
||||||
switch ((term->active_surface = term_surface_kind(term, surface))) {
|
switch ((term->active_surface = term_surface_kind(term, surface))) {
|
||||||
case TERM_SURF_GRID: {
|
case TERM_SURF_GRID: {
|
||||||
int col = (x - term->margins.left) / term->cell_width;
|
/*
|
||||||
int row = (y - term->margins.top) / term->cell_height;
|
* Translate x,y pixel coordinate to a cell coordinate, or -1
|
||||||
|
* if the cursor is outside the grid. I.e. if it is inside the
|
||||||
|
* margins.
|
||||||
|
*/
|
||||||
|
|
||||||
seat->mouse.col = col >= 0 && col < term->cols ? col : -1;
|
if (x < term->margins.left || x >= term->width - term->margins.right)
|
||||||
seat->mouse.row = row >= 0 && row < term->rows ? row : -1;
|
seat->mouse.col = -1;
|
||||||
|
else
|
||||||
|
seat->mouse.col = (x - term->margins.left) / term->cell_width;
|
||||||
|
|
||||||
|
if (y < term->margins.top || y >= term->height - term->margins.bottom)
|
||||||
|
seat->mouse.row = -1;
|
||||||
|
else
|
||||||
|
seat->mouse.row = (y - term->margins.top) / term->cell_height;
|
||||||
|
|
||||||
term_xcursor_update_for_seat(term, seat);
|
term_xcursor_update_for_seat(term, seat);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1200,33 +1210,65 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TERM_SURF_GRID: {
|
case TERM_SURF_GRID: {
|
||||||
term_xcursor_update_for_seat(term, seat);
|
|
||||||
|
|
||||||
int col = (x - term->margins.left) / term->cell_width;
|
|
||||||
int row = (y - term->margins.top) / term->cell_height;
|
|
||||||
|
|
||||||
int old_col = seat->mouse.col;
|
int old_col = seat->mouse.col;
|
||||||
int old_row = seat->mouse.row;
|
int old_row = seat->mouse.row;
|
||||||
|
|
||||||
seat->mouse.col = col >= 0 && col < term->cols ? col : -1;
|
/*
|
||||||
seat->mouse.row = row >= 0 && row < term->rows ? row : -1;
|
* While the seat's mouse coordinates must always be on the
|
||||||
|
* grid, or -1, we allow updating the selection even when the
|
||||||
|
* mouse is outside the grid (could also be outside the
|
||||||
|
* terminal window).
|
||||||
|
*/
|
||||||
|
int selection_col;
|
||||||
|
int selection_row;
|
||||||
|
|
||||||
if (seat->mouse.col < 0 || seat->mouse.row < 0)
|
if (x < term->margins.left) {
|
||||||
break;
|
seat->mouse.col = -1;
|
||||||
|
selection_col = 0;
|
||||||
|
} else if (x >= term->width - term->margins.right) {
|
||||||
|
seat->mouse.col = -1;
|
||||||
|
selection_col = term->cols - 1;
|
||||||
|
} else {
|
||||||
|
seat->mouse.col = (x - term->margins.left) / term->cell_width;
|
||||||
|
selection_col = seat->mouse.col;
|
||||||
|
}
|
||||||
|
|
||||||
bool update_selection = seat->mouse.button == BTN_LEFT || seat->mouse.button == BTN_RIGHT;
|
if (y < term->margins.top) {
|
||||||
bool update_selection_early = term->selection.end.row == -1;
|
seat->mouse.row = -1;
|
||||||
|
selection_row = 0;
|
||||||
|
} else if (y >= term->height - term->margins.bottom) {
|
||||||
|
seat->mouse.row = -1;
|
||||||
|
selection_row = term->rows - 1;
|
||||||
|
} else {
|
||||||
|
seat->mouse.row = (y - term->margins.top) / term->cell_height;
|
||||||
|
selection_row = seat->mouse.row;
|
||||||
|
}
|
||||||
|
|
||||||
if (update_selection && update_selection_early)
|
assert(seat->mouse.col == -1 || (seat->mouse.col >= 0 && seat->mouse.col < term->cols));
|
||||||
selection_update(term, seat->mouse.col, seat->mouse.row);
|
assert(seat->mouse.row == -1 || (seat->mouse.row >= 0 && seat->mouse.row < term->rows));
|
||||||
|
|
||||||
if (old_col == seat->mouse.col && old_row == seat->mouse.row)
|
term_xcursor_update_for_seat(term, seat);
|
||||||
break;
|
|
||||||
|
|
||||||
if (update_selection && !update_selection_early)
|
/* Cursor has moved to a different cell since last time */
|
||||||
selection_update(term, seat->mouse.col, seat->mouse.row);
|
bool cursor_is_on_new_cell
|
||||||
|
= old_col != seat->mouse.col || old_row != seat->mouse.row;
|
||||||
|
|
||||||
|
/* Cursor is inside the grid, i.e. *not* in the margins */
|
||||||
|
bool cursor_is_on_grid = seat->mouse.col >= 0 && seat->mouse.row >= 0;
|
||||||
|
|
||||||
|
/* Update selection */
|
||||||
|
if (seat->mouse.button == BTN_LEFT || seat->mouse.button == BTN_RIGHT) {
|
||||||
|
if (cursor_is_on_new_cell || term->selection.end.row < 0)
|
||||||
|
selection_update(term, selection_col, selection_row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send mouse event to client application */
|
||||||
|
if (!term_mouse_grabbed(term, seat) &&
|
||||||
|
cursor_is_on_new_cell && cursor_is_on_grid)
|
||||||
|
{
|
||||||
|
assert(seat->mouse.col < term->cols);
|
||||||
|
assert(seat->mouse.row < term->rows);
|
||||||
|
|
||||||
if (!term_mouse_grabbed(term, seat)) {
|
|
||||||
term_mouse_motion(
|
term_mouse_motion(
|
||||||
term, seat->mouse.button, seat->mouse.row, seat->mouse.col,
|
term, seat->mouse.button, seat->mouse.row, seat->mouse.col,
|
||||||
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
||||||
|
|
@ -1395,19 +1437,19 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
case TERM_SURF_GRID: {
|
case TERM_SURF_GRID: {
|
||||||
search_cancel(term);
|
search_cancel(term);
|
||||||
|
|
||||||
|
bool cursor_is_on_grid = seat->mouse.col >= 0 && seat->mouse.row >= 0;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case WL_POINTER_BUTTON_STATE_PRESSED: {
|
case WL_POINTER_BUTTON_STATE_PRESSED: {
|
||||||
if (button == BTN_LEFT && seat->mouse.count <= 3) {
|
if (button == BTN_LEFT && seat->mouse.count <= 3) {
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
|
|
||||||
if (selection_enabled(term, seat)) {
|
if (selection_enabled(term, seat) && cursor_is_on_grid) {
|
||||||
switch (seat->mouse.count) {
|
switch (seat->mouse.count) {
|
||||||
case 1:
|
case 1:
|
||||||
if (seat->mouse.col >= 0 && seat->mouse.row >= 0) {
|
selection_start(
|
||||||
selection_start(
|
term, seat->mouse.col, seat->mouse.row,
|
||||||
term, seat->mouse.col, seat->mouse.row,
|
seat->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL);
|
||||||
seat->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -1424,7 +1466,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (button == BTN_RIGHT && seat->mouse.count == 1) {
|
else if (button == BTN_RIGHT && seat->mouse.count == 1) {
|
||||||
if (selection_enabled(term, seat)) {
|
if (selection_enabled(term, seat) && cursor_is_on_grid) {
|
||||||
selection_extend(
|
selection_extend(
|
||||||
seat, term, seat->mouse.col, seat->mouse.row, serial);
|
seat, term, seat->mouse.col, seat->mouse.row, serial);
|
||||||
}
|
}
|
||||||
|
|
@ -1449,7 +1491,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!term_mouse_grabbed(term, seat)) {
|
if (!term_mouse_grabbed(term, seat) && cursor_is_on_grid) {
|
||||||
term_mouse_down(
|
term_mouse_down(
|
||||||
term, button, seat->mouse.row, seat->mouse.col,
|
term, button, seat->mouse.row, seat->mouse.col,
|
||||||
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
||||||
|
|
@ -1461,7 +1503,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
if (button == BTN_LEFT && term->selection.end.col != -1)
|
if (button == BTN_LEFT && term->selection.end.col != -1)
|
||||||
selection_finalize(seat, term, serial);
|
selection_finalize(seat, term, serial);
|
||||||
|
|
||||||
if (!term_mouse_grabbed(term, seat)) {
|
if (!term_mouse_grabbed(term, seat) && cursor_is_on_grid) {
|
||||||
term_mouse_up(
|
term_mouse_up(
|
||||||
term, button, seat->mouse.row, seat->mouse.col,
|
term, button, seat->mouse.row, seat->mouse.col,
|
||||||
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
||||||
|
|
@ -1513,16 +1555,23 @@ mouse_scroll(struct seat *seat, int amount)
|
||||||
keyboard_key(seat, NULL, seat->kbd.serial, 0, key - 8, XKB_KEY_DOWN);
|
keyboard_key(seat, NULL, seat->kbd.serial, 0, key - 8, XKB_KEY_DOWN);
|
||||||
keyboard_key(seat, NULL, seat->kbd.serial, 0, key - 8, XKB_KEY_UP);
|
keyboard_key(seat, NULL, seat->kbd.serial, 0, key - 8, XKB_KEY_UP);
|
||||||
} else {
|
} else {
|
||||||
if (!term_mouse_grabbed(term, seat)) {
|
if (!term_mouse_grabbed(term, seat) &&
|
||||||
|
seat->mouse.col >= 0 && seat->mouse.row >= 0)
|
||||||
|
{
|
||||||
|
assert(seat->mouse.col < term->cols);
|
||||||
|
assert(seat->mouse.row < term->rows);
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
term_mouse_down(
|
term_mouse_down(
|
||||||
term, button, seat->mouse.row, seat->mouse.col,
|
term, button, seat->mouse.row, seat->mouse.col,
|
||||||
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_mouse_up(
|
term_mouse_up(
|
||||||
term, button, seat->mouse.row, seat->mouse.col,
|
term, button, seat->mouse.row, seat->mouse.col,
|
||||||
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollback(term, amount);
|
scrollback(term, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue