Files
scrcpy/app/src/mouse_capture.c
Romain Vimont 4920cd4c3e Remove obsolete workaround for macOS
TODO refs 3031
TODO refs SDL 5340 5976
2025-12-30 22:27:16 +01:00

101 lines
3.4 KiB
C

#include "mouse_capture.h"
#include "shortcut_mod.h"
#include "util/log.h"
void
sc_mouse_capture_init(struct sc_mouse_capture *mc, SDL_Window *window,
uint8_t shortcut_mods) {
mc->window = window;
mc->sdl_mouse_capture_keys = sc_shortcut_mods_to_sdl(shortcut_mods);
mc->mouse_capture_key_pressed = SDLK_UNKNOWN;
}
static inline bool
sc_mouse_capture_is_capture_key(struct sc_mouse_capture *mc, SDL_Keycode key) {
return sc_shortcut_mods_is_shortcut_key(mc->sdl_mouse_capture_keys, key);
}
bool
sc_mouse_capture_handle_event(struct sc_mouse_capture *mc,
const SDL_Event *event) {
switch (event->type) {
case SDL_EVENT_WINDOW_FOCUS_LOST:
sc_mouse_capture_set_active(mc, false);
return true;
case SDL_EVENT_KEY_DOWN: {
SDL_Keycode key = event->key.key;
if (sc_mouse_capture_is_capture_key(mc, key)) {
if (!mc->mouse_capture_key_pressed) {
mc->mouse_capture_key_pressed = key;
} else {
// Another mouse capture key has been pressed, cancel
// mouse (un)capture
mc->mouse_capture_key_pressed = 0;
}
// Mouse capture keys are never forwarded to the device
return true;
}
break;
}
case SDL_EVENT_KEY_UP: {
SDL_Keycode key = event->key.key;
SDL_Keycode cap = mc->mouse_capture_key_pressed;
mc->mouse_capture_key_pressed = 0;
if (sc_mouse_capture_is_capture_key(mc, key)) {
if (key == cap) {
// A mouse capture key has been pressed then released:
// toggle the capture mouse mode
sc_mouse_capture_toggle(mc);
}
// Mouse capture keys are never forwarded to the device
return true;
}
break;
}
case SDL_EVENT_MOUSE_WHEEL:
case SDL_EVENT_MOUSE_MOTION:
case SDL_EVENT_MOUSE_BUTTON_DOWN:
if (!sc_mouse_capture_is_active(mc)) {
// The mouse will be captured on SDL_EVENT_MOUSE_BUTTON_UP, so
// consume the event
return true;
}
break;
case SDL_EVENT_MOUSE_BUTTON_UP:
if (!sc_mouse_capture_is_active(mc)) {
sc_mouse_capture_set_active(mc, true);
return true;
}
break;
case SDL_EVENT_FINGER_MOTION:
case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP:
// Touch events are not compatible with relative mode
// (coordinates are not relative), so consume the event
return true;
}
return false;
}
void
sc_mouse_capture_set_active(struct sc_mouse_capture *mc, bool capture) {
bool ok = SDL_SetWindowRelativeMouseMode(mc->window, capture);
if (!ok) {
LOGE("Could not set relative mouse mode to %s: %s",
capture ? "true" : "false", SDL_GetError());
}
}
bool
sc_mouse_capture_is_active(struct sc_mouse_capture *mc) {
return SDL_GetWindowRelativeMouseMode(mc->window);
}
void
sc_mouse_capture_toggle(struct sc_mouse_capture *mc) {
bool new_value = !sc_mouse_capture_is_active(mc);
sc_mouse_capture_set_active(mc, new_value);
}