Fix 24681: Proper filtering of modifiers when handling hotkeys
This adds proper handling for composition of input and also handles raw key up/down properly when there are modifiers applied to the keyboard that stops composition.
This commit is contained in:
parent
92ca7fdb5e
commit
daef8cd22c
4 changed files with 98 additions and 27 deletions
|
@ -20,18 +20,12 @@
|
|||
|
||||
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||
|
||||
#include "gettext.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
#include "sdl/surface.hpp"
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
#include "key.hpp"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <key.hpp>
|
||||
|
||||
|
||||
static lg::log_domain log_config("config");
|
||||
|
@ -152,17 +146,27 @@ void hotkey_base::save(config& item) const
|
|||
hotkey_ptr create_hotkey(const std::string &id, SDL_Event &event)
|
||||
{
|
||||
hotkey_ptr base = hotkey_ptr(new hotkey_void);
|
||||
unsigned mods = sdl_get_mods();
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
if (mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI || CKey::is_uncomposable(event.key)) {
|
||||
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
|
||||
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);
|
||||
SDL_Keycode code;
|
||||
code = event.key.keysym.sym;
|
||||
keyboard->set_keycode(code);
|
||||
keyboard->set_text(SDL_GetKeyName(event.key.keysym.sym));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTINPUT: {
|
||||
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
|
||||
base = std::dynamic_pointer_cast<hotkey_base>(keyboard);
|
||||
SDL_Keycode code;
|
||||
code = event.key.keysym.sym;
|
||||
keyboard->set_keycode(code);
|
||||
break;
|
||||
keyboard->set_text(std::string(event.text.text));
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP: {
|
||||
hotkey_mouse_ptr mouse(new hotkey_mouse());
|
||||
|
@ -279,32 +283,29 @@ void hotkey_mouse::save_helper(config &item) const
|
|||
|
||||
const std::string hotkey_keyboard::get_name_helper() const
|
||||
{
|
||||
std::string ret = text_;
|
||||
|
||||
if (ret.size() == 1) {
|
||||
boost::algorithm::to_lower(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return text_;
|
||||
}
|
||||
|
||||
bool hotkey_keyboard::matches_helper(const SDL_Event &event) const
|
||||
{
|
||||
unsigned int mods = sdl_get_mods();
|
||||
|
||||
if (event.type == SDL_TEXTINPUT && text_.length() == 1) {
|
||||
if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) &&
|
||||
(mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI ||
|
||||
CKey::is_uncomposable(event.key))) {
|
||||
return event.key.keysym.sym == keycode_ && mods == mod_;
|
||||
}
|
||||
|
||||
if (event.type == SDL_TEXTINPUT) {
|
||||
std::string text = std::string(event.text.text);
|
||||
boost::algorithm::to_lower(text);
|
||||
if (text == ":") {
|
||||
mods = mods & ~KMOD_SHIFT;
|
||||
}
|
||||
return text_ == text && mods == mod_;
|
||||
} else if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) &&
|
||||
(text_.length() > 1 || mods & (KMOD_CTRL|KMOD_ALT|KMOD_GUI)) ) {
|
||||
return event.key.keysym.sym == keycode_ && mods == mod_;
|
||||
} else {
|
||||
return false;
|
||||
return text_ == text && mods == mod_;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const
|
||||
|
@ -474,4 +475,22 @@ std::string get_names(std::string id)
|
|||
return boost::algorithm::join(names, ", ");
|
||||
}
|
||||
|
||||
bool is_hotkeyable_event(const SDL_Event &event) {
|
||||
|
||||
if (event.type == SDL_JOYBUTTONUP ||
|
||||
event.type == SDL_JOYHATMOTION ||
|
||||
event.type == SDL_MOUSEBUTTONUP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned mods = sdl_get_mods();
|
||||
|
||||
if (mods & KMOD_CTRL || mods & KMOD_ALT || mods & KMOD_GUI) {
|
||||
return event.type == SDL_KEYUP;
|
||||
} else {
|
||||
return event.type == SDL_TEXTINPUT ||
|
||||
(event.type == SDL_KEYUP && CKey::is_uncomposable(event.key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
class config;
|
||||
class CVideo;
|
||||
|
@ -256,6 +257,7 @@ public:
|
|||
void set_text(std::string text)
|
||||
{
|
||||
text_ = text;
|
||||
boost::algorithm::to_lower(text_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,6 +439,8 @@ void save_hotkeys(config& cfg);
|
|||
|
||||
hotkey_ptr show_binding_dialog(CVideo& video, const std::string& id);
|
||||
|
||||
bool is_hotkeyable_event(const SDL_Event &event);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
50
src/key.cpp
50
src/key.cpp
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "key.hpp"
|
||||
|
||||
#include <SDL_keyboard.h>
|
||||
|
||||
CKey::CKey() :
|
||||
key_list(SDL_GetKeyboardState(nullptr))
|
||||
{
|
||||
|
@ -25,3 +23,51 @@ bool CKey::operator[](int k) const
|
|||
{
|
||||
return key_list[SDL_GetScancodeFromKey(k)] > 0;
|
||||
}
|
||||
|
||||
bool CKey::is_uncomposable(const SDL_KeyboardEvent &event) {
|
||||
|
||||
switch (event.keysym.sym) {
|
||||
case SDLK_RETURN:
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_BACKSPACE:
|
||||
case SDLK_TAB:
|
||||
case SDLK_F1:
|
||||
case SDLK_F2:
|
||||
case SDLK_F3:
|
||||
case SDLK_F4:
|
||||
case SDLK_F5:
|
||||
case SDLK_F6:
|
||||
case SDLK_F7:
|
||||
case SDLK_F8:
|
||||
case SDLK_F9:
|
||||
case SDLK_F10:
|
||||
case SDLK_F11:
|
||||
case SDLK_F12:
|
||||
case SDLK_F13:
|
||||
case SDLK_F14:
|
||||
case SDLK_F15:
|
||||
case SDLK_F16:
|
||||
case SDLK_F17:
|
||||
case SDLK_F18:
|
||||
case SDLK_F19:
|
||||
case SDLK_F20:
|
||||
case SDLK_F21:
|
||||
case SDLK_F22:
|
||||
case SDLK_F23:
|
||||
case SDLK_F24:
|
||||
case SDLK_INSERT:
|
||||
case SDLK_HOME:
|
||||
case SDLK_PAGEUP:
|
||||
case SDLK_PAGEDOWN:
|
||||
case SDLK_DELETE:
|
||||
case SDLK_END:
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
case SDLK_LEFT:
|
||||
case SDLK_RIGHT:
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
#define KEY_HPP_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <SDL.h>
|
||||
|
||||
/**
|
||||
* Class that keeps track of all the keys on the keyboard.
|
||||
|
@ -31,6 +32,7 @@ class CKey
|
|||
public:
|
||||
CKey();
|
||||
bool operator[](int k) const;
|
||||
static bool is_uncomposable(const SDL_KeyboardEvent &event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue