Skip to content

Commit 2f1a035

Browse files
authored
Hotkey blocking correction (libretro#14831)
1 parent 06c3cd8 commit 2f1a035

File tree

5 files changed

+207
-95
lines changed

5 files changed

+207
-95
lines changed

input/input_driver.c

Lines changed: 193 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4056,13 +4056,19 @@ static void input_keys_pressed(
40564056
rarch_joypad_info_t *joypad_info)
40574057
{
40584058
unsigned i;
4059-
bool libretro_input_pressed = false;
40604059
input_driver_state_t *input_st = &input_driver_st;
4060+
bool block_hotkey[RARCH_BIND_LIST_END];
4061+
bool libretro_hotkey_set =
4062+
binds[port][RARCH_ENABLE_HOTKEY].joykey != NO_BTN
4063+
|| binds[port][RARCH_ENABLE_HOTKEY].joyaxis != AXIS_NONE;
4064+
bool keyboard_hotkey_set =
4065+
binds[port][RARCH_ENABLE_HOTKEY].key != RETROK_UNKNOWN;
40614066

40624067
if (!binds)
40634068
return;
40644069

4065-
if (CHECK_INPUT_DRIVER_BLOCK_HOTKEY(binds_norm, binds_auto))
4070+
if ( binds[port][RARCH_ENABLE_HOTKEY].valid
4071+
&& CHECK_INPUT_DRIVER_BLOCK_HOTKEY(binds_norm, binds_auto))
40664072
{
40674073
if (input_state_wrap(
40684074
input_st->current_driver,
@@ -4090,14 +4096,13 @@ static void input_keys_pressed(
40904096
if (!is_menu && binds[port][RARCH_GAME_FOCUS_TOGGLE].valid)
40914097
{
40924098
const struct retro_keybind *focus_binds_auto =
4093-
&input_autoconf_binds[port][RARCH_GAME_FOCUS_TOGGLE];
4099+
&input_autoconf_binds[port][RARCH_GAME_FOCUS_TOGGLE];
40944100
const struct retro_keybind *focus_normal =
4095-
&binds[port][RARCH_GAME_FOCUS_TOGGLE];
4101+
&binds[port][RARCH_GAME_FOCUS_TOGGLE];
40964102

4097-
/* Allows rarch_focus_toggle hotkey to still work
4103+
/* Allows Game Focus toggle hotkey to still work
40984104
* even though every hotkey is blocked */
4099-
if (CHECK_INPUT_DRIVER_BLOCK_HOTKEY(
4100-
focus_normal, focus_binds_auto))
4105+
if (CHECK_INPUT_DRIVER_BLOCK_HOTKEY(focus_normal, focus_binds_auto))
41014106
{
41024107
if (input_state_wrap(
41034108
input_st->current_driver,
@@ -4107,106 +4112,236 @@ static void input_keys_pressed(
41074112
joypad_info,
41084113
&binds[port],
41094114
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4110-
port,
4111-
RETRO_DEVICE_JOYPAD, 0, RARCH_GAME_FOCUS_TOGGLE))
4115+
port, RETRO_DEVICE_JOYPAD, 0,
4116+
RARCH_GAME_FOCUS_TOGGLE))
41124117
input_st->flags &= ~INP_FLAG_BLOCK_HOTKEY;
41134118
}
41144119
}
41154120

41164121
{
4117-
int16_t ret = 0;
4122+
int16_t ret = 0;
4123+
bool libretro_input_pressed = false;
41184124

41194125
/* Check libretro input if emulated device type is active,
4120-
* except device type is always active in menu. */
4126+
* except device type must be always active in menu. */
41214127
if ( !(input_st->flags & INP_FLAG_BLOCK_LIBRETRO_INPUT)
41224128
&& !(!is_menu && !input_config_get_device(port)))
41234129
ret = input_state_wrap(
41244130
input_st->current_driver,
41254131
input_st->current_data,
41264132
input_st->primary_joypad,
41274133
sec_joypad,
4128-
joypad_info, &binds[port],
4134+
joypad_info,
4135+
&binds[port],
41294136
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
41304137
port, RETRO_DEVICE_JOYPAD, 0,
41314138
RETRO_DEVICE_ID_JOYPAD_MASK);
41324139

41334140
for (i = 0; i < RARCH_FIRST_META_KEY; i++)
41344141
{
4135-
if (
4136-
(ret & (UINT64_C(1) << i))
4137-
|| input_keys_pressed_other_sources(input_st,
4138-
i, p_new_state))
4142+
if ( (ret & (UINT64_C(1) << i))
4143+
|| input_keys_pressed_other_sources(input_st, i, p_new_state))
41394144
{
41404145
BIT256_SET_PTR(p_new_state, i);
41414146
libretro_input_pressed = true;
41424147
}
41434148
}
41444149

4145-
/* Check joypad menu toggle button, because
4146-
* Guide button is not part of the usual buttons. */
4147-
i = RARCH_MENU_TOGGLE;
4148-
if ( !libretro_input_pressed
4149-
&& !input_st->keyboard_menu_toggle_pressed)
4150+
if (!libretro_input_pressed)
41504151
{
4151-
bool bit_pressed = binds[port][i].valid
4152-
&& input_state_wrap(
4153-
input_st->current_driver,
4154-
input_st->current_data,
4155-
input_st->primary_joypad,
4156-
sec_joypad,
4157-
joypad_info,
4158-
&binds[port],
4159-
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4160-
port, RETRO_DEVICE_JOYPAD, 0, i);
4161-
4162-
if (
4163-
bit_pressed
4164-
|| BIT64_GET(lifecycle_state, i)
4165-
|| input_keys_pressed_other_sources(input_st,
4166-
i, p_new_state))
4152+
bool keyboard_menu_pressed = false;
4153+
4154+
/* Ignore keyboard menu toggle button and check
4155+
* joypad menu toggle button for pressing
4156+
* it without 'enable_hotkey', because Guide button
4157+
* is not part of the usual buttons. */
4158+
i = RARCH_MENU_TOGGLE;
4159+
4160+
keyboard_menu_pressed = binds[port][i].valid
4161+
&& input_state_wrap(
4162+
input_st->current_driver,
4163+
input_st->current_data,
4164+
input_st->primary_joypad,
4165+
sec_joypad,
4166+
joypad_info,
4167+
&binds[port],
4168+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4169+
port, RETRO_DEVICE_KEYBOARD, 0,
4170+
input_config_binds[port][i].key);
4171+
4172+
if (!keyboard_menu_pressed)
41674173
{
4168-
BIT256_SET_PTR(p_new_state, i);
4169-
libretro_input_pressed = true;
4174+
bool bit_pressed = binds[port][i].valid
4175+
&& input_state_wrap(
4176+
input_st->current_driver,
4177+
input_st->current_data,
4178+
input_st->primary_joypad,
4179+
sec_joypad,
4180+
joypad_info,
4181+
&binds[port],
4182+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4183+
port, RETRO_DEVICE_JOYPAD, 0, i);
4184+
4185+
if (
4186+
bit_pressed
4187+
|| BIT64_GET(lifecycle_state, i)
4188+
|| input_keys_pressed_other_sources(input_st, i, p_new_state))
4189+
{
4190+
BIT256_SET_PTR(p_new_state, i);
4191+
}
41704192
}
41714193
}
41724194
}
41734195

4174-
/* Check hotkeys, and block keyboard and joypad hotkeys separately. */
4196+
/* Hotkeys are only relevant for first port */
4197+
if (port > 0)
4198+
return;
4199+
4200+
/* Check hotkeys to block keyboard and joypad hotkeys separately.
4201+
* This looks complicated because hotkeys must be unblocked based
4202+
* on the device type depending if 'enable_hotkey' is set or not.. */
41754203
if ( input_st->flags & INP_FLAG_BLOCK_HOTKEY
4176-
&& !( binds[0][RARCH_ENABLE_HOTKEY].key == RETROK_UNKNOWN
4177-
&& !libretro_input_pressed))
4204+
&& (libretro_hotkey_set && keyboard_hotkey_set))
41784205
{
4206+
/* Block everything when hotkey bind exists for both device types */
4207+
for (i = RARCH_FIRST_META_KEY; i < RARCH_BIND_LIST_END; i++)
4208+
block_hotkey[i] = true;
4209+
}
4210+
else if (input_st->flags & INP_FLAG_BLOCK_HOTKEY
4211+
&& (!libretro_hotkey_set || !keyboard_hotkey_set))
4212+
{
4213+
/* Block selectively when hotkey bind exists for either device type */
41794214
for (i = RARCH_FIRST_META_KEY; i < RARCH_BIND_LIST_END; i++)
41804215
{
4181-
if (
4182-
BIT64_GET(lifecycle_state, i)
4183-
|| input_keys_pressed_other_sources(input_st,
4184-
i, p_new_state))
4216+
bool keyboard_hotkey_pressed = false;
4217+
bool libretro_hotkey_pressed = false;
4218+
4219+
/* Default */
4220+
block_hotkey[i] = true;
4221+
4222+
/* No 'enable_hotkey' in joypad */
4223+
if (!libretro_hotkey_set)
41854224
{
4186-
BIT256_SET_PTR(p_new_state, i);
4225+
if ( binds[port][i].joykey != NO_BTN
4226+
|| binds[port][i].joyaxis != AXIS_NONE)
4227+
{
4228+
/* Allow blocking if keyboard hotkey is pressed */
4229+
if (input_state_wrap(
4230+
input_st->current_driver,
4231+
input_st->current_data,
4232+
input_st->primary_joypad,
4233+
sec_joypad,
4234+
joypad_info,
4235+
&binds[port],
4236+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4237+
port, RETRO_DEVICE_KEYBOARD, 0,
4238+
input_config_binds[port][i].key))
4239+
{
4240+
keyboard_hotkey_pressed = true;
4241+
4242+
/* Always block */
4243+
block_hotkey[i] = true;
4244+
}
4245+
4246+
/* Deny blocking if joypad hotkey is pressed */
4247+
if (input_state_wrap(
4248+
input_st->current_driver,
4249+
input_st->current_data,
4250+
input_st->primary_joypad,
4251+
sec_joypad,
4252+
joypad_info,
4253+
&binds[port],
4254+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4255+
port, RETRO_DEVICE_JOYPAD, 0,
4256+
i))
4257+
{
4258+
libretro_hotkey_pressed = true;
4259+
4260+
/* Only deny block if keyboard is not pressed */
4261+
if (!keyboard_hotkey_pressed)
4262+
block_hotkey[i] = false;
4263+
}
4264+
}
4265+
}
4266+
4267+
/* No 'enable_hotkey' in keyboard */
4268+
if (!keyboard_hotkey_set)
4269+
{
4270+
if (binds[port][i].key != RETROK_UNKNOWN)
4271+
{
4272+
/* Deny blocking if keyboard hotkey is pressed */
4273+
if (input_state_wrap(
4274+
input_st->current_driver,
4275+
input_st->current_data,
4276+
input_st->primary_joypad,
4277+
sec_joypad,
4278+
joypad_info,
4279+
&binds[port],
4280+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4281+
port, RETRO_DEVICE_KEYBOARD, 0,
4282+
input_config_binds[port][i].key))
4283+
{
4284+
keyboard_hotkey_pressed = true;
4285+
4286+
/* Only deny block if joypad is not pressed */
4287+
if (!libretro_hotkey_pressed)
4288+
block_hotkey[i] = false;
4289+
}
4290+
4291+
/* Allow blocking if joypad hotkey is pressed */
4292+
if (input_state_wrap(
4293+
input_st->current_driver,
4294+
input_st->current_data,
4295+
input_st->primary_joypad,
4296+
sec_joypad,
4297+
joypad_info,
4298+
&binds[port],
4299+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4300+
port, RETRO_DEVICE_JOYPAD, 0,
4301+
i))
4302+
{
4303+
libretro_hotkey_pressed = true;
4304+
4305+
/* Only block if keyboard is not pressed */
4306+
if (!keyboard_hotkey_pressed)
4307+
block_hotkey[i] = true;
4308+
}
4309+
}
41874310
}
41884311
}
41894312
}
41904313
else
4314+
{
4315+
/* Clear everything */
4316+
for (i = RARCH_FIRST_META_KEY; i < RARCH_BIND_LIST_END; i++)
4317+
block_hotkey[i] = false;
4318+
}
4319+
41914320
{
41924321
for (i = RARCH_FIRST_META_KEY; i < RARCH_BIND_LIST_END; i++)
41934322
{
41944323
bool bit_pressed = binds[port][i].valid
4195-
&& input_state_wrap(
4196-
input_st->current_driver,
4197-
input_st->current_data,
4198-
input_st->primary_joypad,
4199-
sec_joypad,
4200-
joypad_info,
4201-
&binds[port],
4202-
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4203-
port, RETRO_DEVICE_JOYPAD, 0, i);
4324+
&& input_state_wrap(
4325+
input_st->current_driver,
4326+
input_st->current_data,
4327+
input_st->primary_joypad,
4328+
sec_joypad,
4329+
joypad_info,
4330+
&binds[port],
4331+
input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED,
4332+
port, RETRO_DEVICE_JOYPAD, 0,
4333+
i);
42044334

42054335
if ( bit_pressed
42064336
|| BIT64_GET(lifecycle_state, i)
4207-
|| input_keys_pressed_other_sources(input_st,
4208-
i, p_new_state))
4337+
|| input_keys_pressed_other_sources(input_st, i, p_new_state))
42094338
{
4339+
if (libretro_hotkey_set || keyboard_hotkey_set)
4340+
{
4341+
if (block_hotkey[i])
4342+
continue;
4343+
}
4344+
42104345
BIT256_SET_PTR(p_new_state, i);
42114346
}
42124347
}
@@ -6348,11 +6483,6 @@ void input_keyboard_event(bool down, unsigned code,
63486483
if (code == RETROK_UNKNOWN)
63496484
return;
63506485

6351-
/* Store keyboard menu toggle key for separating it from
6352-
* joypad menu toggle button when using 'enable_hotkey'. */
6353-
if (code == input_config_binds[0][RARCH_MENU_TOGGLE].key)
6354-
input_st->keyboard_menu_toggle_pressed = !!down;
6355-
63566486
/* Check if keyboard events should be blocked when
63576487
* pressing hotkeys and RetroPad binds, but
63586488
* - not with Game Focus

input/input_driver.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,6 @@ typedef struct
463463

464464
/* primitives */
465465
bool analog_requested[MAX_USERS];
466-
bool keyboard_menu_toggle_pressed;
467466
retro_bits_512_t keyboard_mapping_bits; /* bool alignment */
468467
input_game_focus_state_t game_focus_state; /* bool alignment */
469468
} input_driver_state_t;

intl/msg_hash_us.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3057,7 +3057,7 @@ MSG_HASH(
30573057
)
30583058
MSG_HASH(
30593059
MENU_ENUM_SUBLABEL_INPUT_META_ENABLE_HOTKEY,
3060-
"When assigned, the 'Hotkey Enable' key must be held before any other hotkeys are recognized. Allows controller buttons to be mapped to hotkey functions without affecting normal input. Assigning the modifier to controller only will not require it for keyboard hotkeys, but both modifiers work for both devices."
3060+
"When assigned, the 'Hotkey Enable' key must be held before any other hotkeys are recognized. Allows controller buttons to be mapped to hotkey functions without affecting normal input. Assigning the modifier to controller only will not require it for keyboard hotkeys, and vice versa, but both modifiers work for both devices."
30613061
)
30623062
MSG_HASH(
30633063
MENU_ENUM_LABEL_HELP_ENABLE_HOTKEY,

menu/menu_driver.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6883,8 +6883,8 @@ void retroarch_menu_running(void)
68836883
true);
68846884
}
68856885

6886-
/* Prevent stray input (for a single frame) */
6887-
menu_st->input_driver_flushing_input = 1;
6886+
/* Prevent stray input */
6887+
menu_st->input_driver_flushing_input = 2;
68886888

68896889
#ifdef HAVE_AUDIOMIXER
68906890
if (audio_enable_menu && audio_enable_menu_bgm)
@@ -6952,9 +6952,8 @@ void retroarch_menu_running_finished(bool quit)
69526952
false);
69536953
}
69546954

6955-
/* Prevent stray input
6956-
* (for a single frame) */
6957-
menu_st->input_driver_flushing_input = 1;
6955+
/* Prevent stray input */
6956+
menu_st->input_driver_flushing_input = 2;
69586957

69596958
if (!quit)
69606959
{

0 commit comments

Comments
 (0)