Merge branch 'mouse-events-never-sent-to-client'

This commit is contained in:
Daniel Eklöf 2021-02-04 19:28:40 +01:00
commit 1d9cd8cc04
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 91 additions and 111 deletions

View file

@ -73,6 +73,13 @@
### Fixed ### Fixed
* Some mouse bindings (_primary paste_, for example) did not require
`shift` to be pressed while used in a mouse grabbing
application. This meant the mouse event was never seen by the
application.
### Security ### Security
### Contributors ### Contributors

172
input.c
View file

@ -82,8 +82,6 @@ execute_binding(struct seat *seat, struct terminal *term,
enum bind_action_normal action, char *const *pipe_argv, enum bind_action_normal action, char *const *pipe_argv,
uint32_t serial) uint32_t serial)
{ {
const bool cursor_is_on_grid = seat->mouse.col >= 0 && seat->mouse.row >= 0;
switch (action) { switch (action) {
case BIND_ACTION_NONE: case BIND_ACTION_NONE:
return true; return true;
@ -274,33 +272,22 @@ execute_binding(struct seat *seat, struct terminal *term,
} }
case BIND_ACTION_SELECT_BEGIN: case BIND_ACTION_SELECT_BEGIN:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_start(
selection_start( term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false); return true;
return true;
}
return false;
case BIND_ACTION_SELECT_BEGIN_BLOCK: case BIND_ACTION_SELECT_BEGIN_BLOCK:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_start(
selection_start( term, seat->mouse.col, seat->mouse.row, SELECTION_BLOCK, false);
term, seat->mouse.col, seat->mouse.row, SELECTION_BLOCK, false); return true;
return true;
}
return false;
case BIND_ACTION_SELECT_EXTEND: case BIND_ACTION_SELECT_EXTEND:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_extend(
selection_extend( seat, term, seat->mouse.col, seat->mouse.row, term->selection.kind);
seat, term, seat->mouse.col, seat->mouse.row, term->selection.kind); return true;
return true;
}
return false;
case BIND_ACTION_SELECT_EXTEND_CHAR_WISE: case BIND_ACTION_SELECT_EXTEND_CHAR_WISE:
if (selection_enabled(term, seat) && cursor_is_on_grid && if (term->selection.kind != SELECTION_BLOCK) {
term->selection.kind != SELECTION_BLOCK)
{
selection_extend( selection_extend(
seat, term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE); seat, term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE);
return true; return true;
@ -308,28 +295,19 @@ execute_binding(struct seat *seat, struct terminal *term,
return false; return false;
case BIND_ACTION_SELECT_WORD: case BIND_ACTION_SELECT_WORD:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_start(
selection_start( term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, false);
term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, false); return true;
return true;
}
return false;
case BIND_ACTION_SELECT_WORD_WS: case BIND_ACTION_SELECT_WORD_WS:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_start(
selection_start( term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, true);
term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, true); return true;
return true;
}
return false;
case BIND_ACTION_SELECT_ROW: case BIND_ACTION_SELECT_ROW:
if (selection_enabled(term, seat) && cursor_is_on_grid) { selection_start(
selection_start( term, seat->mouse.col, seat->mouse.row, SELECTION_LINE_WISE, false);
term, seat->mouse.col, seat->mouse.row, SELECTION_LINE_WISE, false); return true;
return true;
}
return false;
case BIND_ACTION_COUNT: case BIND_ACTION_COUNT:
xassert(false); xassert(false);
@ -1707,77 +1685,79 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
case WL_POINTER_BUTTON_STATE_PRESSED: { case WL_POINTER_BUTTON_STATE_PRESSED: {
bool consumed = false; bool consumed = false;
if (seat->wl_keyboard != NULL && seat->kbd.xkb_state != NULL) { if (cursor_is_on_grid && term_mouse_grabbed(term, seat)) {
/* Seat has keyboard - use mouse bindings *with* modifiers */ if (seat->wl_keyboard != NULL && seat->kbd.xkb_state != NULL) {
/* Seat has keyboard - use mouse bindings *with* modifiers */
xkb_mod_mask_t mods = xkb_state_serialize_mods( xkb_mod_mask_t mods = xkb_state_serialize_mods(
seat->kbd.xkb_state, XKB_STATE_MODS_DEPRESSED); seat->kbd.xkb_state, XKB_STATE_MODS_DEPRESSED);
/* Ignore Shift when matching modifiers, since it is /* Ignore Shift when matching modifiers, since it is
* used to enable selection in mouse grabbing client * used to enable selection in mouse grabbing client
* applications */ * applications */
mods &= ~(1 << seat->kbd.mod_shift); mods &= ~(1 << seat->kbd.mod_shift);
const struct mouse_binding *match = NULL; const struct mouse_binding *match = NULL;
tll_foreach(seat->mouse.bindings, it) { tll_foreach(seat->mouse.bindings, it) {
const struct mouse_binding *binding = &it->item; const struct mouse_binding *binding = &it->item;
if (binding->button != button) { if (binding->button != button) {
/* Wrong button */ /* Wrong button */
continue; continue;
}
if (binding->mods != mods) {
/* Modifier mismatch */
continue;
}
if (binding->count > seat->mouse.count) {
/* Not correct click count */
continue;
}
if (match == NULL || binding->count > match->count)
match = binding;
} }
if (binding->mods != mods) { if (match != NULL) {
/* Modifier mismatch */ consumed = execute_binding(
continue; seat, term, match->action, match->pipe_argv, serial);
} }
if (binding->count > seat->mouse.count) {
/* Not correct click count */
continue;
}
if (match == NULL || binding->count > match->count)
match = binding;
} }
if (match != NULL) { else {
consumed = execute_binding( /* Seat does NOT have a keyboard - use mouse bindings *without* modifiers */
seat, term, match->action, match->pipe_argv, serial); const struct config_mouse_binding *match = NULL;
}
}
else { tll_foreach(seat->wayl->conf->bindings.mouse, it) {
/* Seat does NOT have a keyboard - use mouse bindings *without* modifiers */ const struct config_mouse_binding *binding = &it->item;
const struct config_mouse_binding *match = NULL;
tll_foreach(seat->wayl->conf->bindings.mouse, it) { if (binding->button != button) {
const struct config_mouse_binding *binding = &it->item; /* Wrong button */
continue;
}
if (binding->button != button) { if (binding->count > seat->mouse.count) {
/* Wrong button */ /* Incorrect click count */
continue; continue;
}
const struct config_key_modifiers no_mods = {0};
if (memcmp(&binding->modifiers, &no_mods, sizeof(no_mods)) != 0) {
/* Binding has modifiers */
continue;
}
if (match == NULL || binding->count > match->count)
match = binding;
} }
if (binding->count > seat->mouse.count) { if (match != NULL) {
/* Incorrect click count */ consumed = execute_binding(
continue; seat, term, match->action, match->pipe.argv, serial);
} }
const struct config_key_modifiers no_mods = {0};
if (memcmp(&binding->modifiers, &no_mods, sizeof(no_mods)) != 0) {
/* Binding has modifiers */
continue;
}
if (match == NULL || binding->count > match->count)
match = binding;
}
if (match != NULL) {
consumed = execute_binding(
seat, term, match->action, match->pipe.argv, serial);
} }
} }

View file

@ -33,16 +33,6 @@ static const char *const mime_type_map[] = {
[DATA_OFFER_MIME_URI_LIST] = "text/uri-list", [DATA_OFFER_MIME_URI_LIST] = "text/uri-list",
}; };
bool
selection_enabled(const struct terminal *term, struct seat *seat)
{
return
seat->mouse.col >= 0 && seat->mouse.row >= 0 &&
(term->mouse_tracking == MOUSE_NONE ||
term_mouse_grabbed(term, seat) ||
term->is_searching);
}
bool bool
selection_on_rows(const struct terminal *term, int row_start, int row_end) selection_on_rows(const struct terminal *term, int row_start, int row_end)
{ {

View file

@ -8,7 +8,6 @@
extern const struct wl_data_device_listener data_device_listener; extern const struct wl_data_device_listener data_device_listener;
extern const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener; extern const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener;
bool selection_enabled(const struct terminal *term, struct seat *seat);
void selection_start( void selection_start(
struct terminal *term, int col, int row, struct terminal *term, int col, int row,
enum selection_kind new_kind, bool spaces_only); enum selection_kind new_kind, bool spaces_only);

View file

@ -2431,9 +2431,10 @@ term_mouse_grabbed(const struct terminal *term, struct seat *seat)
/* /*
* Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not. * Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not.
*/ */
return seat->kbd_focus == term && return term->mouse_tracking == MOUSE_NONE ||
seat->kbd.shift && (seat->kbd_focus == term &&
!seat->kbd.alt && /*!seat->kbd.ctrl &&*/ !seat->kbd.meta; seat->kbd.shift &&
!seat->kbd.alt && /*!seat->kbd.ctrl &&*/ !seat->kbd.meta);
} }
void void
@ -2569,7 +2570,10 @@ term_xcursor_update_for_seat(struct terminal *term, struct seat *seat)
const char *xcursor const char *xcursor
= seat->pointer.hidden ? XCURSOR_HIDDEN = seat->pointer.hidden ? XCURSOR_HIDDEN
: term->is_searching ? XCURSOR_LEFT_PTR : term->is_searching ? XCURSOR_LEFT_PTR
: selection_enabled(term, seat) ? XCURSOR_TEXT : (seat->mouse.col >= 0 &&
seat->mouse.row >= 0 &&
term_mouse_grabbed(term, seat)) ? XCURSOR_TEXT
: term->is_searching ? XCURSOR_TEXT
: XCURSOR_LEFT_PTR; : XCURSOR_LEFT_PTR;
render_xcursor_set(seat, term, xcursor); render_xcursor_set(seat, term, xcursor);