mirror of
https://github.com/Genymobile/scrcpy
synced 2025-08-30 22:05:12 +00:00
Customize shortcut modifier
Add --shortcut-mod, and use Alt as default modifier. This paves the way to forward the Ctrl key to the device.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "input_manager.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <SDL2/SDL_keycode.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "event_converter.h"
|
||||
@@ -10,6 +11,64 @@
|
||||
static const int ACTION_DOWN = 1;
|
||||
static const int ACTION_UP = 1 << 1;
|
||||
|
||||
#define SC_SDL_SHORTCUT_MODS_MASK (KMOD_CTRL | KMOD_ALT | KMOD_GUI)
|
||||
|
||||
static inline uint16_t
|
||||
to_sdl_mod(unsigned mod) {
|
||||
uint16_t sdl_mod = 0;
|
||||
if (mod & SC_MOD_LCTRL) {
|
||||
sdl_mod |= KMOD_LCTRL;
|
||||
}
|
||||
if (mod & SC_MOD_RCTRL) {
|
||||
sdl_mod |= KMOD_RCTRL;
|
||||
}
|
||||
if (mod & SC_MOD_LALT) {
|
||||
sdl_mod |= KMOD_LALT;
|
||||
}
|
||||
if (mod & SC_MOD_RALT) {
|
||||
sdl_mod |= KMOD_RALT;
|
||||
}
|
||||
if (mod & SC_MOD_LSUPER) {
|
||||
sdl_mod |= KMOD_LGUI;
|
||||
}
|
||||
if (mod & SC_MOD_RSUPER) {
|
||||
sdl_mod |= KMOD_RGUI;
|
||||
}
|
||||
return sdl_mod;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_shortcut_mod(struct input_manager *im, uint16_t sdl_mod) {
|
||||
// keep only the relevant modifier keys
|
||||
sdl_mod &= SC_SDL_SHORTCUT_MODS_MASK;
|
||||
|
||||
assert(im->sdl_shortcut_mods.count);
|
||||
assert(im->sdl_shortcut_mods.count < SC_MAX_SHORTCUT_MODS);
|
||||
for (unsigned i = 0; i < im->sdl_shortcut_mods.count; ++i) {
|
||||
if (im->sdl_shortcut_mods.data[i] == sdl_mod) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
input_manager_init(struct input_manager *im, bool prefer_text,
|
||||
const struct sc_shortcut_mods *shortcut_mods)
|
||||
{
|
||||
im->prefer_text = prefer_text;
|
||||
|
||||
assert(shortcut_mods->count);
|
||||
assert(shortcut_mods->count < SC_MAX_SHORTCUT_MODS);
|
||||
for (unsigned i = 0; i < shortcut_mods->count; ++i) {
|
||||
uint16_t sdl_mod = to_sdl_mod(shortcut_mods->data[i]);
|
||||
assert(sdl_mod);
|
||||
im->sdl_shortcut_mods.data[i] = sdl_mod;
|
||||
}
|
||||
im->sdl_shortcut_mods.count = shortcut_mods->count;
|
||||
}
|
||||
|
||||
static void
|
||||
send_keycode(struct controller *controller, enum android_keycode keycode,
|
||||
int actions, const char *name) {
|
||||
@@ -258,22 +317,13 @@ input_manager_process_key(struct input_manager *im,
|
||||
const SDL_KeyboardEvent *event,
|
||||
bool control) {
|
||||
// control: indicates the state of the command-line option --no-control
|
||||
// ctrl: the Ctrl key
|
||||
|
||||
bool ctrl = event->keysym.mod & (KMOD_LCTRL | KMOD_RCTRL);
|
||||
bool alt = event->keysym.mod & (KMOD_LALT | KMOD_RALT);
|
||||
bool meta = event->keysym.mod & (KMOD_LGUI | KMOD_RGUI);
|
||||
|
||||
if (alt || meta) {
|
||||
// no shortcuts involve Alt or Meta, and they must not be forwarded to
|
||||
// the device
|
||||
return;
|
||||
}
|
||||
bool smod = is_shortcut_mod(im, event->keysym.mod);
|
||||
|
||||
struct controller *controller = im->controller;
|
||||
|
||||
// capture all Ctrl events
|
||||
if (ctrl) {
|
||||
// The shortcut modifier is pressed
|
||||
if (smod) {
|
||||
SDL_Keycode keycode = event->keysym.sym;
|
||||
bool down = event->type == SDL_KEYDOWN;
|
||||
int action = down ? ACTION_DOWN : ACTION_UP;
|
||||
@@ -281,33 +331,33 @@ input_manager_process_key(struct input_manager *im,
|
||||
bool shift = event->keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT);
|
||||
switch (keycode) {
|
||||
case SDLK_h:
|
||||
if (control && ctrl && !shift && !repeat) {
|
||||
if (control && !shift && !repeat) {
|
||||
action_home(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_b: // fall-through
|
||||
case SDLK_BACKSPACE:
|
||||
if (control && ctrl && !shift && !repeat) {
|
||||
if (control && !shift && !repeat) {
|
||||
action_back(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_s:
|
||||
if (control && ctrl && !shift && !repeat) {
|
||||
if (control && !shift && !repeat) {
|
||||
action_app_switch(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_m:
|
||||
if (control && ctrl && !shift && !repeat) {
|
||||
if (control && !shift && !repeat) {
|
||||
action_menu(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_p:
|
||||
if (control && ctrl && !shift && !repeat) {
|
||||
if (control && !shift && !repeat) {
|
||||
action_power(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_o:
|
||||
if (control && ctrl && !repeat && down) {
|
||||
if (control && !repeat && down) {
|
||||
enum screen_power_mode mode = shift
|
||||
? SCREEN_POWER_MODE_NORMAL
|
||||
: SCREEN_POWER_MODE_OFF;
|
||||
@@ -315,34 +365,34 @@ input_manager_process_key(struct input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_DOWN:
|
||||
if (control && ctrl && !shift) {
|
||||
if (control && !shift) {
|
||||
// forward repeated events
|
||||
action_volume_down(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_UP:
|
||||
if (control && ctrl && !shift) {
|
||||
if (control && !shift) {
|
||||
// forward repeated events
|
||||
action_volume_up(controller, action);
|
||||
}
|
||||
return;
|
||||
case SDLK_LEFT:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
rotate_client_left(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_RIGHT:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
rotate_client_right(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_c:
|
||||
if (control && ctrl && !shift && !repeat && down) {
|
||||
if (control && !shift && !repeat && down) {
|
||||
request_device_clipboard(controller);
|
||||
}
|
||||
return;
|
||||
case SDLK_v:
|
||||
if (control && ctrl && !repeat && down) {
|
||||
if (control && !repeat && down) {
|
||||
if (shift) {
|
||||
// store the text in the device clipboard and paste
|
||||
set_device_clipboard(controller, true);
|
||||
@@ -353,29 +403,29 @@ input_manager_process_key(struct input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_f:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
screen_switch_fullscreen(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_x:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
screen_resize_to_fit(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_g:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
screen_resize_to_pixel_perfect(im->screen);
|
||||
}
|
||||
return;
|
||||
case SDLK_i:
|
||||
if (ctrl && !shift && !repeat && down) {
|
||||
if (!shift && !repeat && down) {
|
||||
struct fps_counter *fps_counter =
|
||||
im->video_buffer->fps_counter;
|
||||
switch_fps_counter_state(fps_counter);
|
||||
}
|
||||
return;
|
||||
case SDLK_n:
|
||||
if (control && ctrl && !repeat && down) {
|
||||
if (control && !repeat && down) {
|
||||
if (shift) {
|
||||
collapse_notification_panel(controller);
|
||||
} else {
|
||||
@@ -384,7 +434,7 @@ input_manager_process_key(struct input_manager *im,
|
||||
}
|
||||
return;
|
||||
case SDLK_r:
|
||||
if (control && ctrl && !shift && !repeat && down) {
|
||||
if (control && !shift && !repeat && down) {
|
||||
rotate_device(controller);
|
||||
}
|
||||
return;
|
||||
|
Reference in New Issue
Block a user