Start work on adding a glfwGetKeyNameModifiers function

This commit is contained in:
Yukari Hafner 2026-06-16 11:49:20 +02:00
parent 92dcf4ce74
commit a27b7d32de
No known key found for this signature in database
GPG key ID: A65ADD33A582C0E2
14 changed files with 75 additions and 18 deletions

View file

@ -4852,6 +4852,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
*/
GLFWAPI const char* glfwGetKeyName(int key, int scancode);
GLFWAPI const char* glfwGetKeyNameModifiers(int key, int scancode, int modifiers);
/*! @brief Returns the platform-specific scancode of the specified key.
*
* This function returns the platform-specific scancode of the specified key.

View file

@ -259,7 +259,7 @@ void _glfwPostEmptyEventCocoa(void);
void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosCocoa(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameCocoa(int scancode);
const char* _glfwGetScancodeNameCocoa(int scancode, int modifiers);
int _glfwGetKeyScancodeCocoa(int key);
GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape);

View file

@ -159,6 +159,26 @@ static int translateFlags(NSUInteger flags)
return mods;
}
// Translates GLFW key modifiers into macOS ones
//
static int translateFlagsInverse(int mods)
{
NSUInteger flags = 0;
if (mods & GLFW_MOD_SHIFT)
flags |= NSEventModifierFlagShift;
if (mods & GLFW_MOD_CONTROL)
flags |= NSEventModifierFlagControl;
if (mods & GLFW_MOD_ALT)
flags |= NSEventModifierFlagOption;
if (mods & GLFW_MOD_SUPER)
flags |= NSEventModifierFlagCommand;
if (mods & GLFW_MOD_CAPS_LOCK)
flags |= NSEventModifierFlagCapsLock;
return flags;
}
// Translates a macOS keycode to a GLFW keycode
//
static int translateKey(unsigned int key)
@ -1682,7 +1702,7 @@ void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode)
} // autoreleasepool
}
const char* _glfwGetScancodeNameCocoa(int scancode)
const char* _glfwGetScancodeNameCocoa(int scancode, int modifiers)
{
@autoreleasepool {
@ -1703,7 +1723,7 @@ const char* _glfwGetScancodeNameCocoa(int scancode)
if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],
scancode,
kUCKeyActionDisplay,
0,
translateFlagsInverse(modifiers),
LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
&deadKeyState,

View file

@ -701,7 +701,7 @@ GLFWAPI int glfwRawMouseMotionSupported(void)
return _glfw.platform.rawMouseMotionSupported();
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)
GLFWAPI const char* glfwGetKeyNameModifiers(int key, int scancode, int modifiers)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -723,7 +723,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
scancode = _glfw.platform.getKeyScancode(key);
}
return _glfw.platform.getScancodeName(scancode);
return _glfw.platform.getScancodeName(scancode, modifiers);
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)
{
return glfwGetKeyNameModifiers(key, scancode, 0);
}
GLFWAPI int glfwGetKeyScancode(int key)

View file

@ -696,7 +696,7 @@ struct _GLFWplatform
GLFWbool (*createStandardCursor)(_GLFWcursor*,int);
void (*destroyCursor)(_GLFWcursor*);
void (*setCursor)(_GLFWwindow*,_GLFWcursor*);
const char* (*getScancodeName)(int);
const char* (*getScancodeName)(int, int);
int (*getKeyScancode)(int);
void (*setClipboardString)(const char*);
const char* (*getClipboardString)(void);

View file

@ -267,7 +267,7 @@ void _glfwDestroyCursorNull(_GLFWcursor* cursor);
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringNull(const char* string);
const char* _glfwGetClipboardStringNull(void);
const char* _glfwGetScancodeNameNull(int scancode);
const char* _glfwGetScancodeNameNull(int scancode, int modifiers);
int _glfwGetKeyScancodeNull(int key);
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);

View file

@ -569,7 +569,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
return 0;
}
const char* _glfwGetScancodeNameNull(int scancode)
const char* _glfwGetScancodeNameNull(int scancode, int modifiers)
{
if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST)
{

View file

@ -527,7 +527,7 @@ void _glfwPostEmptyEventWin32(void);
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWin32(int scancode);
const char* _glfwGetScancodeNameWin32(int scancode, int modifiers);
int _glfwGetKeyScancodeWin32(int key);
GLFWbool _glfwCreateCursorWin32(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWin32(_GLFWcursor* cursor, int shape);

View file

@ -2255,7 +2255,7 @@ void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode)
updateCursorImage(window);
}
const char* _glfwGetScancodeNameWin32(int scancode)
const char* _glfwGetScancodeNameWin32(int scancode, int modifiers)
{
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff))
{

View file

@ -700,7 +700,7 @@ void _glfwPostEmptyEventWayland(void);
void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWayland(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWayland(int scancode);
const char* _glfwGetScancodeNameWayland(int scancode, int modifiers);
int _glfwGetKeyScancodeWayland(int key);
GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape);

View file

@ -2978,7 +2978,7 @@ void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
_glfwSetCursorWayland(window, window->cursor);
}
const char* _glfwGetScancodeNameWayland(int scancode)
const char* _glfwGetScancodeNameWayland(int scancode, int modifiers)
{
if (scancode < 0 || scancode > 255)
{
@ -3002,11 +3002,14 @@ const char* _glfwGetScancodeNameWayland(int scancode)
return NULL;
}
// FIXME: can't seem to find any way in libxkbcommon to translate an xkb_mod_mask_t into
// a xkb_level_index_t . Sigh.
int level = (modifiers & GLFW_MOD_SHIFT)? 1 : 0;
const xkb_keysym_t* keysyms = NULL;
xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,
keycode,
layout,
0,
level,
&keysyms);
if (keysyms == NULL)
{

View file

@ -1498,6 +1498,8 @@ int _glfwInitX11(void)
_glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbGetState");
_glfw.x11.xkb.KeycodeToKeysym = (PFN_XkbKeycodeToKeysym)
_glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbKeycodeToKeysym");
_glfw.x11.xkb.LookupKeysym = (PFN_XkbLookupKeysym)
_glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbLookupKeysym");
_glfw.x11.xkb.QueryExtension = (PFN_XkbQueryExtension)
_glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XkbQueryExtension");
_glfw.x11.xkb.SelectEventDetails = (PFN_XkbSelectEventDetails)

View file

@ -188,6 +188,7 @@ typedef XkbDescPtr (* PFN_XkbGetMap)(Display*,unsigned int,unsigned int);
typedef Status (* PFN_XkbGetNames)(Display*,unsigned int,XkbDescPtr);
typedef Status (* PFN_XkbGetState)(Display*,unsigned int,XkbStatePtr);
typedef KeySym (* PFN_XkbKeycodeToKeysym)(Display*,KeyCode,int,int);
typedef Bool (* PFN_XkbLookupKeysym)(Display*,KeyCode,unsigned int,unsigned int*,KeySym*);
typedef Bool (* PFN_XkbQueryExtension)(Display*,int*,int*,int*,int*,int*);
typedef Bool (* PFN_XkbSelectEventDetails)(Display*,unsigned int,unsigned int,unsigned long,unsigned long);
typedef Bool (* PFN_XkbSetDetectableAutoRepeat)(Display*,Bool,Bool*);
@ -288,6 +289,7 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
#define XkbGetNames _glfw.x11.xkb.GetNames
#define XkbGetState _glfw.x11.xkb.GetState
#define XkbKeycodeToKeysym _glfw.x11.xkb.KeycodeToKeysym
#define XkbLookupKeysym _glfw.x11.xkb.LookupKeysym
#define XkbQueryExtension _glfw.x11.xkb.QueryExtension
#define XkbSelectEventDetails _glfw.x11.xkb.SelectEventDetails
#define XkbSetDetectableAutoRepeat _glfw.x11.xkb.SetDetectableAutoRepeat
@ -782,6 +784,7 @@ typedef struct _GLFWlibraryX11
PFN_XkbGetNames GetNames;
PFN_XkbGetState GetState;
PFN_XkbKeycodeToKeysym KeycodeToKeysym;
PFN_XkbLookupKeysym LookupKeysym;
PFN_XkbQueryExtension QueryExtension;
PFN_XkbSelectEventDetails SelectEventDetails;
PFN_XkbSetDetectableAutoRepeat SetDetectableAutoRepeat;
@ -945,7 +948,7 @@ void _glfwPostEmptyEventX11(void);
void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosX11(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeX11(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameX11(int scancode);
const char* _glfwGetScancodeNameX11(int scancode, int modifiers);
int _glfwGetKeyScancodeX11(int key);
GLFWbool _glfwCreateCursorX11(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorX11(_GLFWcursor* cursor, int shape);

View file

@ -233,6 +233,28 @@ static int translateState(int state)
return mods;
}
// Translates an X event modifier state mask
//
static int translateStateInverse(int mods)
{
int state = 0;
if (mods & GLFW_MOD_SHIFT)
state |= ShiftMask;
if (mods & GLFW_MOD_CONTROL)
state |= ControlMask;
if (mods & GLFW_MOD_ALT)
state |= Mod1Mask;
if (mods & GLFW_MOD_SUPER)
state |= Mod4Mask;
if (mods & GLFW_MOD_CAPS_LOCK)
state |= LockMask;
if (mods & GLFW_MOD_NUM_LOCK)
state |= Mod2Mask;
return state;
}
// Translates an X11 key code to a GLFW key token
//
static int translateKey(int scancode)
@ -2924,7 +2946,7 @@ void _glfwSetCursorModeX11(_GLFWwindow* window, int mode)
XFlush(_glfw.x11.display);
}
const char* _glfwGetScancodeNameX11(int scancode)
const char* _glfwGetScancodeNameX11(int scancode, int modifiers)
{
if (!_glfw.x11.xkb.available)
return NULL;
@ -2939,9 +2961,9 @@ const char* _glfwGetScancodeNameX11(int scancode)
if (key == GLFW_KEY_UNKNOWN)
return NULL;
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
scancode, _glfw.x11.xkb.group, 0);
if (keysym == NoSymbol)
unsigned int state = translateStateInverse(modifiers);
KeySym keysym;
if (XkbLookupKeysym(_glfw.x11.display, scancode, state, &state, &keysym) != True)
return NULL;
const uint32_t codepoint = _glfwKeySym2UnicodeX11(keysym);