Skip to content

Commit

Permalink
Track mouse buttons state manually
Browse files Browse the repository at this point in the history
The buttons state was tracked by SDL_GetMouseState(), and scrcpy applied
a mask to ignore buttons used for shortcuts.

Instead, track the buttons actually pressed (ignoring shortcuts)
manually, to prepare the introduction of more dynamic mouse shortcuts.

PR #5076 <#5076>
  • Loading branch information
rom1v committed Jul 11, 2024
1 parent 86b8286 commit 6baea57
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 29 deletions.
20 changes: 3 additions & 17 deletions app/src/input_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,25 +437,11 @@ sc_mouse_button_from_sdl(uint8_t button) {
}

static inline uint8_t
sc_mouse_buttons_state_from_sdl(uint32_t buttons_state,
const struct sc_mouse_bindings *mb) {
sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
assert(buttons_state < 0x100); // fits in uint8_t

uint8_t mask = SC_MOUSE_BUTTON_LEFT;
if (!mb || mb->right_click == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_RIGHT;
}
if (!mb || mb->middle_click == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_MIDDLE;
}
if (!mb || mb->click4 == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_X1;
}
if (!mb || mb->click5 == SC_MOUSE_BINDING_CLICK) {
mask |= SC_MOUSE_BUTTON_X2;
}

return buttons_state & mask;
// SC_MOUSE_BUTTON_* constants are initialized from SDL_BUTTON(index)
return buttons_state;
}

#endif
24 changes: 17 additions & 7 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ sc_input_manager_init(struct sc_input_manager *im,
im->vfinger_invert_x = false;
im->vfinger_invert_y = false;

im->mouse_buttons_state = 0;

im->last_keycode = SDLK_UNKNOWN;
im->last_mod = 0;
im->key_repeat = 0;
Expand Down Expand Up @@ -654,8 +656,7 @@ sc_input_manager_process_mouse_motion(struct sc_input_manager *im,
: SC_POINTER_ID_MOUSE,
.xrel = event->xrel,
.yrel = event->yrel,
.buttons_state =
sc_mouse_buttons_state_from_sdl(event->state, &im->mouse_bindings),
.buttons_state = im->mouse_buttons_state,
};

assert(im->mp->ops->process_mouse_motion);
Expand Down Expand Up @@ -736,6 +737,13 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
bool control = im->controller;
bool paused = im->screen->paused;
bool down = event->type == SDL_MOUSEBUTTONDOWN;

enum sc_mouse_button button = sc_mouse_button_from_sdl(event->button);
if (!down) {
// Mark the button as released
im->mouse_buttons_state &= ~button;
}

if (control && !paused) {
enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP;

Expand Down Expand Up @@ -799,7 +807,10 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
return;
}

uint32_t sdl_buttons_state = SDL_GetMouseState(NULL, NULL);
if (down) {
// Mark the button as pressed
im->mouse_buttons_state |= button;
}

SDL_Keymod keymod = SDL_GetModState();
bool ctrl_pressed = keymod & KMOD_CTRL;
Expand All @@ -815,8 +826,7 @@ sc_input_manager_process_mouse_button(struct sc_input_manager *im,
.button = sc_mouse_button_from_sdl(event->button),
.pointer_id = use_finger ? SC_POINTER_ID_GENERIC_FINGER
: SC_POINTER_ID_MOUSE,
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state,
&im->mouse_bindings),
.buttons_state = im->mouse_buttons_state,
};

assert(im->mp->ops->process_mouse_click);
Expand Down Expand Up @@ -875,6 +885,7 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
int mouse_x;
int mouse_y;
uint32_t buttons = SDL_GetMouseState(&mouse_x, &mouse_y);
(void) buttons; // Actual buttons are tracked manually to ignore shortcuts

struct sc_mouse_scroll_event evt = {
.position = sc_input_manager_get_position(im, mouse_x, mouse_y),
Expand All @@ -885,8 +896,7 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
.hscroll = CLAMP(event->x, -1, 1),
.vscroll = CLAMP(event->y, -1, 1),
#endif
.buttons_state = sc_mouse_buttons_state_from_sdl(buttons,
&im->mouse_bindings),
.buttons_state = im->mouse_buttons_state,
};

im->mp->ops->process_mouse_scroll(im->mp, &evt);
Expand Down
2 changes: 2 additions & 0 deletions app/src/input_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ struct sc_input_manager {
bool vfinger_invert_x;
bool vfinger_invert_y;

uint8_t mouse_buttons_state; // OR of enum sc_mouse_button values

// Tracks the number of identical consecutive shortcut key down events.
// Not to be confused with event->repeat, which counts the number of
// system-generated repeated key presses.
Expand Down
8 changes: 3 additions & 5 deletions app/src/usb/screen_otg.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ sc_screen_otg_process_mouse_motion(struct sc_screen_otg *screen,
// .position not used for HID events
.xrel = event->xrel,
.yrel = event->yrel,
.buttons_state = sc_mouse_buttons_state_from_sdl(event->state, NULL),
.buttons_state = sc_mouse_buttons_state_from_sdl(event->state),
};

assert(mp->ops->process_mouse_motion);
Expand All @@ -188,8 +188,7 @@ sc_screen_otg_process_mouse_button(struct sc_screen_otg *screen,
// .position not used for HID events
.action = sc_action_from_sdl_mousebutton_type(event->type),
.button = sc_mouse_button_from_sdl(event->button),
.buttons_state =
sc_mouse_buttons_state_from_sdl(sdl_buttons_state, NULL),
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
};

assert(mp->ops->process_mouse_click);
Expand All @@ -208,8 +207,7 @@ sc_screen_otg_process_mouse_wheel(struct sc_screen_otg *screen,
// .position not used for HID events
.hscroll = event->x,
.vscroll = event->y,
.buttons_state =
sc_mouse_buttons_state_from_sdl(sdl_buttons_state, NULL),
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
};

assert(mp->ops->process_mouse_scroll);
Expand Down

0 comments on commit 6baea57

Please sign in to comment.