mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-02 22:29:25 +00:00
relative-mouse-mode
This commit is contained in:
parent
9ec4017910
commit
7dba4a9e98
2 changed files with 83 additions and 0 deletions
|
@ -156,6 +156,17 @@ get_initial_optimal_size(struct sc_size content_size, uint16_t req_width,
|
||||||
return window_size;
|
return window_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
screen_capture_mouse(struct screen *screen, bool capture) {
|
||||||
|
if (SDL_SetRelativeMouseMode(capture)) {
|
||||||
|
LOGE("Could not set relative mouse mode to %s: %s",
|
||||||
|
capture ? "true" : "false", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->mouse_captured = capture;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_update_content_rect(struct screen *screen) {
|
screen_update_content_rect(struct screen *screen) {
|
||||||
int dw;
|
int dw;
|
||||||
|
@ -354,6 +365,8 @@ screen_init(struct screen *screen, const struct screen_params *params) {
|
||||||
screen->fullscreen = false;
|
screen->fullscreen = false;
|
||||||
screen->maximized = false;
|
screen->maximized = false;
|
||||||
screen->event_failed = false;
|
screen->event_failed = false;
|
||||||
|
screen->mouse_captured = false;
|
||||||
|
screen->mouse_capture_key_pressed = 0;
|
||||||
|
|
||||||
static const struct sc_video_buffer_callbacks cbs = {
|
static const struct sc_video_buffer_callbacks cbs = {
|
||||||
.on_new_frame = sc_video_buffer_on_new_frame,
|
.on_new_frame = sc_video_buffer_on_new_frame,
|
||||||
|
@ -741,6 +754,11 @@ screen_resize_to_pixel_perfect(struct screen *screen) {
|
||||||
content_size.height);
|
content_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
screen_is_mouse_capture_key(SDL_Keycode key) {
|
||||||
|
return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
screen_handle_event(struct screen *screen, SDL_Event *event) {
|
screen_handle_event(struct screen *screen, SDL_Event *event) {
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
|
@ -783,8 +801,68 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
||||||
apply_pending_resize(screen);
|
apply_pending_resize(screen);
|
||||||
screen_render(screen, true);
|
screen_render(screen, true);
|
||||||
break;
|
break;
|
||||||
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||||
|
if (screen->im.mp->relative_mode) {
|
||||||
|
screen_capture_mouse(screen, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (screen->im.mp->relative_mode) {
|
||||||
|
SDL_Keycode key = event->key.keysym.sym;
|
||||||
|
if (screen_is_mouse_capture_key(key)) {
|
||||||
|
if (!screen->mouse_capture_key_pressed) {
|
||||||
|
screen->mouse_capture_key_pressed = key;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Another mouse capture key has been pressed, cancel
|
||||||
|
// mouse (un)capture
|
||||||
|
screen->mouse_capture_key_pressed = 0;
|
||||||
|
// Do not return, the event must be forwarded to the
|
||||||
|
// input manager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_KEYUP:
|
||||||
|
if (screen->im.mp->relative_mode) {
|
||||||
|
SDL_Keycode key = event->key.keysym.sym;
|
||||||
|
SDL_Keycode cap = screen->mouse_capture_key_pressed;
|
||||||
|
screen->mouse_capture_key_pressed = 0;
|
||||||
|
if (key == cap) {
|
||||||
|
// A mouse capture key has been pressed then released:
|
||||||
|
// toggle the capture mouse mode
|
||||||
|
screen_capture_mouse(screen, !screen->mouse_captured);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Do not return, the event must be forwarded to the input
|
||||||
|
// manager
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEWHEEL:
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
if (screen->im.mp->relative_mode && !screen->mouse_captured) {
|
||||||
|
// Do not forward to input manager, the mouse will be captured
|
||||||
|
// on SDL_MOUSEBUTTONUP
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_FINGERMOTION:
|
||||||
|
case SDL_FINGERDOWN:
|
||||||
|
case SDL_FINGERUP:
|
||||||
|
if (screen->im.mp->relative_mode) {
|
||||||
|
// Touch events are not compatible with relative mode
|
||||||
|
// (coordinates are not relative)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
if (screen->im.mp->relative_mode && !screen->mouse_captured) {
|
||||||
|
screen_capture_mouse(screen, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return input_manager_handle_event(&screen->im, event);
|
return input_manager_handle_event(&screen->im, event);
|
||||||
|
|
|
@ -51,6 +51,11 @@ struct screen {
|
||||||
|
|
||||||
bool event_failed; // in case SDL_PushEvent() returned an error
|
bool event_failed; // in case SDL_PushEvent() returned an error
|
||||||
|
|
||||||
|
bool mouse_captured; // only relevant in relative mouse mode
|
||||||
|
// To enable/disable mouse capture, a mouse capture key (LALT, LGUI or
|
||||||
|
// RGUI) must be pressed. This variable tracks the pressed capture key.
|
||||||
|
SDL_Keycode mouse_capture_key_pressed;
|
||||||
|
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue