Skip to content
Merged
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
129 changes: 61 additions & 68 deletions lib/sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,51 +267,34 @@ void SdlWindow::mouseEventUp(SDL_MouseButtonEvent& eb)
}
}

void SdlWindow::keyEvent(SDL_Keysym& ks)
void SdlWindow::keyDownEvent(SDL_Keysym& ks)
{
bool handled = false;
if (ks.sym >= 128 || ks.sym < 32)
{
if (onKeyDown[ks.sym])
{
onKeyDown[ks.sym](ks.mod);
handled = true;
}
}
else if (ks.sym < 256 && std::isdigit(ks.sym))
{
if (!(SDL_GetModState() & KMOD_SHIFT))
{
// handle number key event here
onKeyDown[ks.sym](ks.mod);
handled = true;
}
}
else if (ctrlDown)
{
if (onKeyDown[ks.sym])
{
onKeyDown[ks.sym](ks.mod);
handled = true;
}
}
if (ks.sym == SDLK_RCTRL || ks.sym == SDLK_LCTRL)
{
ctrlDown = true;
// Some keyDown events will be followed by a textInput event which will
// handle key translation due to Shift or CapsLock, so we leave such events
// to be processed there.
// Note: the same condition has to be used in signalKeyDown().
if ((ks.sym >= 32 && ks.sym < 127) &&
(ks.mod & ~(KMOD_SHIFT | KMOD_CAPS)) == 0)
{
lastKeyDownProcessed = false;
return;
}
if (handled)
// If any 'mod' key other than KMOD_SHIFT or KMOD_CAPS is pressed, or the key
// is not in the range [32,127) then we processed the event here.
lastKeyDownProcessed = true;
if (onKeyDown[ks.sym])
{
onKeyDown[ks.sym](ks.mod);

// Record the key in 'saved_keys':
bool isAlt = ks.mod & (KMOD_ALT);
bool isCtrl = ks.mod & (KMOD_CTRL);
saved_keys += "[";
if (isCtrl) { saved_keys += "C-"; }
if (isAlt) { saved_keys += "Alt-"; }
if (ks.sym < 256 && std::isalpha(ks.sym))
if (ks.sym >= 32 && ks.sym < 127)
{
// key with corresponding text output
char c = ks.sym;
if (!(ks.mod & KMOD_SHIFT)) { c = std::tolower(c); }
saved_keys += c;
saved_keys += (char)(ks.sym);
}
else
{
Expand All @@ -321,25 +304,21 @@ void SdlWindow::keyEvent(SDL_Keysym& ks)
}
}

void SdlWindow::keyEvent(char c)
void SdlWindow::textInputEvent(const SDL_TextInputEvent &tie)
{
if (!std::isdigit(c) && onKeyDown[c])
{
SDL_Keymod mods = SDL_GetModState();
bool isAlt = mods & (KMOD_ALT);
bool isCtrl = mods & (KMOD_CTRL);
// This event follows a keyDown event where we've recorded if the event was
// processed in keyDownEvent(). If it was not processed, we do it here.
if (lastKeyDownProcessed) { return; }
const char c = tie.text[0];
if (onKeyDown[c])
{
// Keys with 'mods' (other than Shift and CapsLock) are processed in
// keyDownEvent().
const int mods = 0;
onKeyDown[c](mods);
if (isAlt || isCtrl)
{
saved_keys += "[";
if (isCtrl) { saved_keys += "C-"; }
if (isAlt) { saved_keys += "Alt-"; }
}

// Record the key in 'saved_keys':
saved_keys += c;
if (isAlt || isCtrl)
{
saved_keys += "]";
}
}
}

Expand Down Expand Up @@ -403,17 +382,30 @@ void SdlWindow::mainIter()
keep_going = true;
break;
case SDL_KEYDOWN:
keyEvent(e.key.keysym);
// For debugging: uncomment the next line to track key events.
// #define TRACK_KEY_EVENTS
#ifdef TRACK_KEY_EVENTS
cout << "Event: SDL_KEYDOWN sym=" << e.key.keysym.sym
<< " mod=" << e.key.keysym.mod << endl;
#endif
keyDownEvent(e.key.keysym);
break;
case SDL_KEYUP:
if (e.key.keysym.sym == SDLK_LCTRL
|| e.key.keysym.sym == SDLK_RCTRL)
{
ctrlDown = false;
}
#ifdef TRACK_KEY_EVENTS
cout << "Event: SDL_KEYUP sym=" << e.key.keysym.sym
<< " mod=" << e.key.keysym.mod << endl;
#endif
break;
case SDL_TEXTINPUT:
keyEvent(e.text.text[0]);
#ifdef TRACK_KEY_EVENTS
cout << "Event: SDL_TEXTINPUT text[0..3]="
<< (int)(unsigned char)(e.text.text[0])
<< ' ' << (int)(unsigned char)(e.text.text[1])
<< ' ' << (int)(unsigned char)(e.text.text[2])
<< ' ' << (int)(unsigned char)(e.text.text[3])
<< " (as codes 0-255)" << endl;
#endif
textInputEvent(e.text);
break;
case SDL_MOUSEMOTION:
motionEvent(e.motion);
Expand Down Expand Up @@ -630,20 +622,21 @@ void SdlWindow::setWindowPos(int x, int y)
void SdlWindow::signalKeyDown(SDL_Keycode k, SDL_Keymod m)
{
SDL_Event event;
if (k >= 32 && k < 128)

event.type = SDL_KEYDOWN;
event.key.windowID = window_id;
event.key.keysym.sym = k;
event.key.keysym.mod = m;
queueEvents({ event });

// The same condition as in keyDownEvent().
if ((k >= 32 && k < 127) && (m & ~(KMOD_SHIFT | KMOD_CAPS)) == 0)
{
event.type = SDL_TEXTINPUT;
event.text.windowID = window_id;
event.text.text[0] = k;
queueEvents({ event });
}
else
{
event.type = SDL_KEYDOWN;
event.key.windowID = window_id;
event.key.keysym.sym = k;
event.key.keysym.mod = m;
}
queueEvents({ event });
}

void SdlWindow::swapBuffer()
Expand Down
7 changes: 3 additions & 4 deletions lib/sdl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ class SdlWindow
TouchDelegate onTouchPinch{nullptr};
TouchDelegate onTouchRotate{nullptr};

bool ctrlDown{false};

#ifdef __EMSCRIPTEN__
std::string canvas_id_;
#endif
Expand All @@ -127,14 +125,15 @@ class SdlWindow
bool takeScreenshot{false};
std::string screenshot_file;
bool screenshot_convert;
bool lastKeyDownProcessed;

// internal event handlers
void windowEvent(SDL_WindowEvent& ew);
void motionEvent(SDL_MouseMotionEvent& em);
void mouseEventDown(SDL_MouseButtonEvent& eb);
void mouseEventUp(SDL_MouseButtonEvent& eb);
void keyEvent(SDL_Keysym& ks);
void keyEvent(char c);
void keyDownEvent(SDL_Keysym& ks);
void textInputEvent(const SDL_TextInputEvent &e);
void multiGestureEvent(SDL_MultiGestureEvent & e);

bool is_multithreaded{true};
Expand Down