macOS: Fix option as alt not working for keys that act as dead keys in the current keyboard layout

This commit is contained in:
Kovid Goyal 2018-04-19 17:44:31 +05:30
parent e3795eb07e
commit 2504266806
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 34 additions and 23 deletions

View File

@ -37,6 +37,7 @@ typedef void* id;
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef int (* GLFWcocoatextinputfilterfun)(int,int,int);
typedef struct VkMacOSSurfaceCreateInfoMVK
{
@ -98,6 +99,8 @@ typedef struct _GLFWwindowNS
// This is kept to counteract Cocoa doing the same internally
double cursorWarpDeltaX, cursorWarpDeltaY;
// The text input filter callback
GLFWcocoatextinputfilterfun textInputFilterCallback;
} _GLFWwindowNS;
// Cocoa-specific global data

View File

@ -725,10 +725,12 @@ - (void)keyDown:(NSEvent *)event
const int key = translateKey(scancode, GLFW_TRUE);
const int mods = translateFlags([event modifierFlags]);
_glfw.ns.text[0] = 0;
// this will call insertText with the text for this event, if any
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
if ((1 <= _glfw.ns.text[0] && _glfw.ns.text[0] <= 31) || (unsigned)_glfw.ns.text[0] == 127) _glfw.ns.text[0] = 0; // dont send text for ascii control codes
debug_key(@"scancode: 0x%x (%s) mods: %stext: %s glfw_key: %s\n",
if (!window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, scancode) != 1) {
// this will call insertText with the text for this event, if any
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
if ((1 <= _glfw.ns.text[0] && _glfw.ns.text[0] <= 31) || (unsigned)_glfw.ns.text[0] == 127) _glfw.ns.text[0] = 0; // dont send text for ascii control codes
}
debug_key(@"scancode: 0x%x (%s)%stext: %s glfw_key: %s\n",
scancode, safe_name_for_scancode(scancode), format_mods(mods),
format_text(_glfw.ns.text), _glfwGetKeyName(key));
_glfwInputKeyboard(window, key, scancode, GLFW_PRESS, mods, _glfw.ns.text, 0);
@ -2000,3 +2002,11 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
return window->ns.object;
}
GLFWAPI GLFWcocoatextinputfilterfun glfwSetCocoaTextInputFilter(GLFWwindow *handle, GLFWcocoatextinputfilterfun callback) {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
GLFWcocoatextinputfilterfun previous = window->ns.textInputFilterCallback;
window->ns.textInputFilterCallback = callback;
return previous;
}

View File

@ -196,6 +196,7 @@ def generate_wrappers(glfw_header, glfw_native_header):
for line in '''\
void* glfwGetCocoaWindow(GLFWwindow* window)
uint32_t glfwGetCocoaMonitor(GLFWmonitor* monitor)
GLFWcocoatextinputfilterfun glfwSetCocoaTextInputFilter(GLFWwindow* window, GLFWcocoatextinputfilterfun callback)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
void glfwSetX11SelectionString(const char* string)
@ -212,6 +213,7 @@ def generate_wrappers(glfw_header, glfw_native_header):
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
{}
{}

2
kitty/glfw-wrapper.c generated
View File

@ -357,6 +357,8 @@ load_glfw(const char* path) {
*(void **) (&glfwGetCocoaMonitor_impl) = dlsym(handle, "glfwGetCocoaMonitor");
*(void **) (&glfwSetCocoaTextInputFilter_impl) = dlsym(handle, "glfwSetCocoaTextInputFilter");
*(void **) (&glfwGetX11Display_impl) = dlsym(handle, "glfwGetX11Display");
*(void **) (&glfwGetX11Window_impl) = dlsym(handle, "glfwGetX11Window");

5
kitty/glfw-wrapper.h generated
View File

@ -1,6 +1,7 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
/*! @name GLFW version macros
@ -1825,6 +1826,10 @@ typedef uint32_t (*glfwGetCocoaMonitor_func)(GLFWmonitor*);
glfwGetCocoaMonitor_func glfwGetCocoaMonitor_impl;
#define glfwGetCocoaMonitor glfwGetCocoaMonitor_impl
typedef GLFWcocoatextinputfilterfun (*glfwSetCocoaTextInputFilter_func)(GLFWwindow*, GLFWcocoatextinputfilterfun);
glfwSetCocoaTextInputFilter_func glfwSetCocoaTextInputFilter_impl;
#define glfwSetCocoaTextInputFilter glfwSetCocoaTextInputFilter_impl
typedef void* (*glfwGetX11Display_func)();
glfwGetX11Display_func glfwGetX11Display_impl;
#define glfwGetX11Display glfwGetX11Display_impl

View File

@ -309,6 +309,13 @@ set_dpi_from_os_window(OSWindow *w) {
static bool is_first_window = true;
#ifdef __APPLE__
static int
filter_option(int key UNUSED, int mods, unsigned int scancode UNUSED) {
return ((mods == GLFW_MOD_ALT) || (mods == (GLFW_MOD_ALT | GLFW_MOD_SHIFT))) ? 1 : 0;
}
#endif
static PyObject*
create_os_window(PyObject UNUSED *self, PyObject *args) {
int width, height, x = -1, y = -1;
@ -367,6 +374,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
Py_DECREF(ret);
#ifdef __APPLE__
cocoa_create_global_menu();
if (OPT(macos_option_as_alt)) glfwSetCocoaTextInputFilter(glfw_window, filter_option);
#endif
is_first_window = false;
}

View File

@ -43,22 +43,6 @@ active_window() {
return NULL;
}
void
on_text_input(unsigned int codepoint, int mods) {
Window *w = active_window();
static char buf[16];
unsigned int sz = 0;
if (w != NULL) {
bool is_text = mods <= GLFW_MOD_SHIFT;
if (is_text) sz = encode_utf8(codepoint, buf);
#ifdef __APPLE__
if (!OPT(macos_option_as_alt) && IS_ALT_MODS(mods)) sz = encode_utf8(codepoint, buf);
#endif
if (sz) schedule_write_to_child(w->id, buf, sz);
}
}
static inline bool
is_modifier_key(int key) {
switch(key) {
@ -107,9 +91,6 @@ on_key_input(int key, int scancode, int action, int mods, const char* text, int
}
Screen *screen = w->render_data.screen;
bool has_text = text && !is_ascii_control_char(text[0]);
#ifdef __APPLE__
if (has_text && IS_ALT_MODS(mods) && OPT(macos_option_as_alt)) has_text = false;
#endif
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
uint16_t qkey = (0 <= key && key < (ssize_t)arraysz(key_map)) ? key_map[key] : UINT8_MAX;
bool special = false;