macOS: Fix using shortcuts from the global menu bar as subsequent key presses in a multi key mapping not working

Fixes #4519
This commit is contained in:
Kovid Goyal 2022-01-15 13:56:18 +05:30
parent c473df4393
commit ca4840717b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
11 changed files with 59 additions and 17 deletions

View File

@ -114,6 +114,9 @@ Detailed list of changes
- macOS: Fix a few key-presses causing beeps from cocoa text input system - macOS: Fix a few key-presses causing beeps from cocoa text input system
(:iss:`4489`) (:iss:`4489`)
- macOS: Fix using shortcuts from the global menu bar as subsequent key presses
in a multi key mapping not working (:iss:`4519`)
0.24.1 [2022-01-06] 0.24.1 [2022-01-06]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -765,25 +765,27 @@ int _glfwPlatformInit(void)
{ {
debug_key("---------------- key down -------------------\n"); debug_key("---------------- key down -------------------\n");
debug_key("%s\n", [[event description] UTF8String]); debug_key("%s\n", [[event description] UTF8String]);
// first check if there is global menu bar shortcut if (!_glfw.ignoreOSKeyboardProcessing) {
if ([[NSApp mainMenu] performKeyEquivalent:event]) { // first check if there is a global menu bar shortcut
debug_key("keyDown triggerred global menu bar action ignoring\n"); if (_glfw.ignoreOSKeyboardProcessing && [[NSApp mainMenu] performKeyEquivalent:event]) {
last_keydown_shortcut_event.virtual_key_code = [event keyCode]; debug_key("keyDown triggerred global menu bar action ignoring\n");
last_keydown_shortcut_event.timestamp = [event timestamp]; last_keydown_shortcut_event.virtual_key_code = [event keyCode];
return nil; last_keydown_shortcut_event.timestamp = [event timestamp];
} return nil;
// now check if there is a useful apple shortcut }
int global_shortcut = is_active_apple_global_shortcut(event); // now check if there is a useful apple shortcut
if (is_useful_apple_global_shortcut(global_shortcut)) { int global_shortcut = is_active_apple_global_shortcut(event);
debug_key("keyDown triggerred global macOS shortcut ignoring\n"); if (is_useful_apple_global_shortcut(global_shortcut)) {
last_keydown_shortcut_event.virtual_key_code = [event keyCode]; debug_key("keyDown triggerred global macOS shortcut ignoring\n");
last_keydown_shortcut_event.timestamp = [event timestamp]; last_keydown_shortcut_event.virtual_key_code = [event keyCode];
return event; last_keydown_shortcut_event.timestamp = [event timestamp];
return event;
}
} }
last_keydown_shortcut_event.virtual_key_code = 0xffff; last_keydown_shortcut_event.virtual_key_code = 0xffff;
NSWindow *kw = [NSApp keyWindow]; NSWindow *kw = [NSApp keyWindow];
if (kw && kw.contentView) [kw.contentView keyDown:event]; if (kw && kw.contentView) [kw.contentView keyDown:event];
else debug_key("keyUp ignored as no keyWindow present\n"); else debug_key("keyDown ignored as no keyWindow present\n");
return nil; return nil;
}; };

View File

@ -1112,7 +1112,7 @@ is_ascii_control_char(char x) {
const NSUInteger flags = [event modifierFlags]; const NSUInteger flags = [event modifierFlags];
const int mods = translateFlags(flags); const int mods = translateFlags(flags);
const uint32_t key = translateKey(keycode, true); const uint32_t key = translateKey(keycode, true);
const bool process_text = !window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, keycode, flags) != 1; const bool process_text = !_glfw.ignoreOSKeyboardProcessing && (!window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, keycode, flags) != 1);
_glfw.ns.text[0] = 0; _glfw.ns.text[0] = 0;
if (keycode == 0x33 /* backspace */ || keycode == 0x35 /* escape */) [self unmarkText]; if (keycode == 0x33 /* backspace */ || keycode == 0x35 /* escape */) [self unmarkText];
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = GLFW_PRESS, .mods = mods}; GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = GLFW_PRESS, .mods = mods};

3
glfw/glfw3.h vendored
View File

@ -4119,6 +4119,9 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
*/ */
GLFWAPI void glfwPostEmptyEvent(void); GLFWAPI void glfwPostEmptyEvent(void);
GLFWAPI bool glfwGetIgnoreOSKeyboardProcessing(void);
GLFWAPI void glfwSetIgnoreOSKeyboardProcessing(bool enabled);
/*! @brief Returns the value of an input option for the specified window. /*! @brief Returns the value of an input option for the specified window.
* *
* This function returns the value of an input option for the specified window. * This function returns the value of an input option for the specified window.

8
glfw/input.c vendored
View File

@ -667,6 +667,14 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
////// GLFW public API ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWAPI bool glfwGetIgnoreOSKeyboardProcessing(void) {
return _glfw.ignoreOSKeyboardProcessing;
}
GLFWAPI void glfwSetIgnoreOSKeyboardProcessing(bool enabled) {
_glfw.ignoreOSKeyboardProcessing = enabled;
}
GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;

2
glfw/internal.h vendored
View File

@ -584,6 +584,8 @@ struct _GLFWlibrary
_GLFWtls contextSlot; _GLFWtls contextSlot;
_GLFWmutex errorLock; _GLFWmutex errorLock;
bool ignoreOSKeyboardProcessing;
struct { struct {
bool available; bool available;
void* handle; void* handle;

6
kitty/glfw-wrapper.c generated
View File

@ -249,6 +249,12 @@ load_glfw(const char* path) {
*(void **) (&glfwPostEmptyEvent_impl) = dlsym(handle, "glfwPostEmptyEvent"); *(void **) (&glfwPostEmptyEvent_impl) = dlsym(handle, "glfwPostEmptyEvent");
if (glfwPostEmptyEvent_impl == NULL) fail("Failed to load glfw function glfwPostEmptyEvent with error: %s", dlerror()); if (glfwPostEmptyEvent_impl == NULL) fail("Failed to load glfw function glfwPostEmptyEvent with error: %s", dlerror());
*(void **) (&glfwGetIgnoreOSKeyboardProcessing_impl) = dlsym(handle, "glfwGetIgnoreOSKeyboardProcessing");
if (glfwGetIgnoreOSKeyboardProcessing_impl == NULL) fail("Failed to load glfw function glfwGetIgnoreOSKeyboardProcessing with error: %s", dlerror());
*(void **) (&glfwSetIgnoreOSKeyboardProcessing_impl) = dlsym(handle, "glfwSetIgnoreOSKeyboardProcessing");
if (glfwSetIgnoreOSKeyboardProcessing_impl == NULL) fail("Failed to load glfw function glfwSetIgnoreOSKeyboardProcessing with error: %s", dlerror());
*(void **) (&glfwGetInputMode_impl) = dlsym(handle, "glfwGetInputMode"); *(void **) (&glfwGetInputMode_impl) = dlsym(handle, "glfwGetInputMode");
if (glfwGetInputMode_impl == NULL) fail("Failed to load glfw function glfwGetInputMode with error: %s", dlerror()); if (glfwGetInputMode_impl == NULL) fail("Failed to load glfw function glfwGetInputMode with error: %s", dlerror());

8
kitty/glfw-wrapper.h generated
View File

@ -1916,6 +1916,14 @@ typedef void (*glfwPostEmptyEvent_func)(void);
GFW_EXTERN glfwPostEmptyEvent_func glfwPostEmptyEvent_impl; GFW_EXTERN glfwPostEmptyEvent_func glfwPostEmptyEvent_impl;
#define glfwPostEmptyEvent glfwPostEmptyEvent_impl #define glfwPostEmptyEvent glfwPostEmptyEvent_impl
typedef bool (*glfwGetIgnoreOSKeyboardProcessing_func)(void);
GFW_EXTERN glfwGetIgnoreOSKeyboardProcessing_func glfwGetIgnoreOSKeyboardProcessing_impl;
#define glfwGetIgnoreOSKeyboardProcessing glfwGetIgnoreOSKeyboardProcessing_impl
typedef void (*glfwSetIgnoreOSKeyboardProcessing_func)(bool);
GFW_EXTERN glfwSetIgnoreOSKeyboardProcessing_func glfwSetIgnoreOSKeyboardProcessing_impl;
#define glfwSetIgnoreOSKeyboardProcessing glfwSetIgnoreOSKeyboardProcessing_impl
typedef int (*glfwGetInputMode_func)(GLFWwindow*, int); typedef int (*glfwGetInputMode_func)(GLFWwindow*, int);
GFW_EXTERN glfwGetInputMode_func glfwGetInputMode_impl; GFW_EXTERN glfwGetInputMode_func glfwGetInputMode_impl;
#define glfwGetInputMode glfwGetInputMode_impl #define glfwGetInputMode glfwGetInputMode_impl

View File

@ -1564,6 +1564,11 @@ strip_csi(PyObject *self UNUSED, PyObject *src) {
return PyUnicode_FromString(buf); return PyUnicode_FromString(buf);
} }
void
set_ignore_os_keyboard_processing(bool enabled) {
glfwSetIgnoreOSKeyboardProcessing(enabled);
}
// Boilerplate {{{ // Boilerplate {{{
static PyMethodDef module_methods[] = { static PyMethodDef module_methods[] = {

View File

@ -703,7 +703,11 @@ PYWRAP1(set_options) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
BOOL_SET(in_sequence_mode) PYWRAP1(set_in_sequence_mode) {
global_state.in_sequence_mode = PyObject_IsTrue(args);
set_ignore_os_keyboard_processing(global_state.in_sequence_mode);
Py_RETURN_NONE;
}
static void static void
init_screen_render_data(OSWindow *osw, const WindowGeometry *g, ScreenRenderData *d) { init_screen_render_data(OSWindow *osw, const WindowGeometry *g, ScreenRenderData *d) {

View File

@ -337,3 +337,4 @@ uint8_t* draw_single_ascii_char(const char ch, size_t *result_width, size_t *res
bool is_os_window_fullscreen(OSWindow *); bool is_os_window_fullscreen(OSWindow *);
void update_ime_position(Window* w, Screen *screen); void update_ime_position(Window* w, Screen *screen);
bool update_ime_position_for_window(id_type window_id, bool force); bool update_ime_position_for_window(id_type window_id, bool force);
void set_ignore_os_keyboard_processing(bool enabled);