Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/common/KeyIdentification.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ namespace Scancode {

class Key
{
public:
public:
enum class Kind {
INVALID, // No key.
Expand Down
20 changes: 17 additions & 3 deletions src/engine/client/key_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,16 +274,18 @@ void SetBinding(Key key, int team, std::string binding)
bindingsModified = true;
}

const std::vector<Key>& GetConsoleKeys()
{
static std::vector<Keyboard::Key> consoleKeys;
static std::vector<Keyboard::Key> consoleKeys;
static std::string consoleKeysString;

void UpdateConsoleKeyCache() {
// Only parse the variable when it changes
Util::optional<std::string> modifiedString = cl_consoleKeys.GetModifiedValue();
if ( modifiedString )
{
const char* text_p = modifiedString.value().c_str();
consoleKeys.clear();
consoleKeysString.clear();

while ( true )
{
const char* token = COM_Parse( &text_p );
Expand All @@ -294,13 +296,25 @@ const std::vector<Key>& GetConsoleKeys()
Keyboard::Key k = Keyboard::StringToKey(token);
if (k.IsBindable()) {
consoleKeys.push_back(k);
consoleKeysString += KeyToStringUnprefixed( k );
}
}
}
}

const std::vector<Key>& GetConsoleKeys()
{
UpdateConsoleKeyCache();

return consoleKeys;
}

const std::string& GetConsoleKeysString() {
UpdateConsoleKeyCache();

return consoleKeysString;
}

void SetConsoleKeys(const std::vector<Key>& keys)
{
std::string text;
Expand Down
26 changes: 26 additions & 0 deletions src/engine/client/key_identification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,32 @@ Key StringToKey(Str::StringRef str)
return Key::NONE;
}

std::string KeyToStringUnprefixed( Key key ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, what is the point of forming a string with words like ESCAPE, 0x63 etc.?

if ( key.kind() == Key::Kind::KEYNUM ) {
return KeynumToString( key.AsKeynum() );
}

if ( key.kind() == Key::Kind::UNICODE_CHAR ) {
return CharToString( key.AsCharacter() );
}

if ( key.kind() == Key::Kind::SCANCODE ) {
int sc = key.AsScancode();
if ( char c = ScancodeToAscii( sc ) ) {
return CharToString( c );
}
for ( auto& functionKey : leftRightFunctionKeys ) {
if ( sc == functionKey.scancode ) {
return functionKey.name;
}
}
// make a hex string
return Str::Format( "0x%02x", key.AsScancode() );
}

return "<INVALID KEY>";
}

std::string KeyToString(Key key)
{
if (key.kind() == Key::Kind::KEYNUM) {
Expand Down
1 change: 1 addition & 0 deletions src/engine/client/key_identification.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace Keyboard {

Key StringToKey(Str::StringRef name);
std::string KeyToString(Key key);
std::string KeyToStringUnprefixed(Key key);

// Returns the code point of a character typed by the given key, or 0 if none is found.
int GetCharForScancode(int scancode);
Expand Down
1 change: 1 addition & 0 deletions src/engine/client/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Util::optional<std::string> GetBinding(Key key, BindTeam team, bool useDefault);
// Get/set the keys which toggle (both open and close) the console.
// The source of truth is cl_consoleKeys, but these provide an interface with Key objects.
const std::vector<Key>& GetConsoleKeys();
const std::string& GetConsoleKeysString();
void SetConsoleKeys(const std::vector<Key>& keys);

// Gets all keys that, if pressed, would execute the given command, based on the current team.
Expand Down
2 changes: 1 addition & 1 deletion src/engine/framework/ConsoleField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace Console {
Cmd::Args args(std::string(commandStart, commandEnd));
int argNum = args.Argc() - 1;
std::string prefix;
if (!args.Argc() || Str::cisspace(GetText()[GetCursorPos() - 1])) {
if (!args.Argc() || !GetCursorPos() || Str::cisspace(GetText()[GetCursorPos() - 1])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way things initially go wrong is with the subtraction underflow in std::string commandText = Str::UTF32To8(GetText().substr(1, GetCursorPos() - 1));. Would be nicer to return before that

argNum++;
} else {
prefix = args.Argv(argNum);
Expand Down
18 changes: 18 additions & 0 deletions src/engine/sys/sdl_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,24 @@ static void IN_ProcessEvents( bool dropInput )
{
std::string text = e.text.text;

/* We can get a console key as a text event after we've opened the console from a key up/down event,
* in a separate execution of IN_ProcessEvents()
* The key character can also be anywhere in the text
* This might be an SDL bug */
text.erase(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would break the feature where you can hold ALT to type a character that would otherwise be a console key (works on some Linux environments)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that handled in SDL_EVENT_KEY_DOWN()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is where the ALT exemption is initially applied. But IIUC this new third level of console key filtering has no condition to check that, so such characters would be filtered out.

std::remove_if( text.begin(), text.end(),
[]( unsigned char c ) {
for( const unsigned char key : Keyboard::GetConsoleKeysString() ) {
if ( c == key ) {
return true;
}
}

return false;
}
), text.end()
);

const char* c = text.c_str();
while ( *c ) {
int width = Q_UTF8_Width( c );
Expand Down
Loading