Skip to content

Commit 97c99c2

Browse files
committed
FIX: macosx key-press key-release events
Handle the key-press and release events on macosx.
1 parent 0f7a7fc commit 97c99c2

File tree

1 file changed

+92
-24
lines changed

1 file changed

+92
-24
lines changed

src/_macosx.m

Lines changed: 92 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@
6262
Needed to know when to stop the NSApp */
6363
static long FigureWindowCount = 0;
6464

65+
/* Keep track of modifier key states for flagsChanged
66+
to keep track of press vs release */
67+
static bool lastCommand = false;
68+
static bool lastControl = false;
69+
static bool lastShift = false;
70+
static bool lastOption = false;
71+
static bool lastCapsLock = false;
72+
/* Keep track of whether this specific key modifier was pressed or not */
73+
static bool keyChangeCommand = false;
74+
static bool keyChangeControl = false;
75+
static bool keyChangeShift = false;
76+
static bool keyChangeOption = false;
77+
static bool keyChangeCapsLock = false;
78+
6579
/* -------------------------- Helper function ---------------------------- */
6680

6781
static void
@@ -1641,8 +1655,6 @@ - (const char*)convertKeyEvent:(NSEvent*)event
16411655
}
16421656
[returnkey appendString:specialchar];
16431657
}
1644-
else
1645-
[returnkey appendString:[event charactersIgnoringModifiers]];
16461658

16471659
return [returnkey UTF8String];
16481660
}
@@ -1711,30 +1723,86 @@ - (BOOL)acceptsFirstResponder
17111723
return YES;
17121724
}
17131725

1714-
// flagsChanged gets called on single modifier keypresses
1715-
// The modifier + second key gets handled in convertKeyEvent in KeyUp/KeyDown
1726+
// flagsChanged gets called whenever a modifier key is pressed OR released
1727+
// so we need to handle both cases here
17161728
- (void)flagsChanged:(NSEvent *)event
17171729
{
1718-
const char *s = NULL;
1719-
if ([event modifierFlags] & NSEventModifierFlagControl)
1720-
s = "control";
1721-
else if ([event modifierFlags] & NSEventModifierFlagShift)
1722-
s = "shift";
1723-
else if ([event modifierFlags] & NSEventModifierFlagOption)
1724-
s = "alt";
1725-
else if ([event modifierFlags] & NSEventModifierFlagCommand)
1726-
s = "cmd";
1727-
else if ([event modifierFlags] & NSEventModifierFlagCapsLock)
1728-
s = "caps_lock";
1729-
else return;
1730-
PyGILState_STATE gstate = PyGILState_Ensure();
1731-
PyObject* result = PyObject_CallMethod(canvas, "key_press_event", "s", s);
1732-
if (result)
1733-
Py_DECREF(result);
1734-
else
1735-
PyErr_Print();
1736-
1737-
PyGILState_Release(gstate);
1730+
bool keypress = false;
1731+
bool keyrelease = false;
1732+
if (([event modifierFlags] & NSEventModifierFlagCommand) && !lastCommand) {
1733+
// Command pressed
1734+
lastCommand = true;
1735+
keyChangeCommand = true;
1736+
keypress = true;
1737+
}
1738+
else if (!([event modifierFlags] & NSEventModifierFlagCommand) && lastCommand) {
1739+
// Command released
1740+
lastCommand = false;
1741+
keyChangeCommand = true;
1742+
keyrelease = true;
1743+
}
1744+
else if (([event modifierFlags] & NSEventModifierFlagControl) && !lastControl) {
1745+
// Control pressed
1746+
lastControl = true;
1747+
keyChangeControl = true;
1748+
keypress = true;
1749+
}
1750+
else if (!([event modifierFlags] & NSEventModifierFlagControl) && lastControl) {
1751+
// Control released
1752+
lastControl = false;
1753+
keyChangeControl = true;
1754+
keyrelease = true;
1755+
}
1756+
else if (([event modifierFlags] & NSEventModifierFlagShift) && !lastShift) {
1757+
// Shift pressed
1758+
lastShift = true;
1759+
keyChangeShift = true;
1760+
keypress = true;
1761+
}
1762+
else if (!([event modifierFlags] & NSEventModifierFlagShift) && lastShift) {
1763+
// Shift released
1764+
lastShift = false;
1765+
keyChangeShift = true;
1766+
keyrelease = true;
1767+
}
1768+
else if (([event modifierFlags] & NSEventModifierFlagOption) && !lastOption) {
1769+
// Option pressed
1770+
lastOption = true;
1771+
keyChangeOption = true;
1772+
keypress = true;
1773+
}
1774+
else if (!([event modifierFlags] & NSEventModifierFlagOption) && lastOption) {
1775+
// Option released
1776+
lastOption = false;
1777+
keyChangeOption = true;
1778+
keyrelease = true;
1779+
}
1780+
else if (([event modifierFlags] & NSEventModifierFlagCapsLock) && !lastCapsLock) {
1781+
// Capslock pressed
1782+
lastCapsLock = true;
1783+
keyChangeCapsLock = true;
1784+
keypress = true;
1785+
}
1786+
else if (!([event modifierFlags] & NSEventModifierFlagCapsLock) && lastCapsLock) {
1787+
// Capslock released
1788+
lastCapsLock = false;
1789+
keyChangeCapsLock = true;
1790+
keyrelease = true;
1791+
}
1792+
1793+
if (keypress) {
1794+
[self keyDown: event];
1795+
}
1796+
else if (keyrelease) {
1797+
[self keyUp: event];
1798+
}
1799+
1800+
// Reset the state for the key changes after handling the event
1801+
keyChangeCommand = false;
1802+
keyChangeControl = false;
1803+
keyChangeShift = false;
1804+
keyChangeOption = false;
1805+
keyChangeCapsLock = false;
17381806
}
17391807
@end
17401808

0 commit comments

Comments
 (0)