Optimize the services implementation
Dont construct the selection string when we are merely checking if a selection exists.
This commit is contained in:
parent
1c6bae636b
commit
682428fb54
@ -1585,8 +1585,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
(!sendType || [sendType isEqual:NSPasteboardTypeString] || [sendType isEqual:@"NSStringPboardType"]) &&
|
||||
(!returnType || [returnType isEqual:NSPasteboardTypeString] || [returnType isEqual:@"NSStringPboardType"])
|
||||
) {
|
||||
NSString *text = [self accessibilitySelectedText];
|
||||
if (text && text.length > 0) return self;
|
||||
if (_glfw.callbacks.has_current_selection && _glfw.callbacks.has_current_selection()) return self;
|
||||
}
|
||||
return [super validRequestorForSendType:sendType returnType:returnType];
|
||||
}
|
||||
@ -1594,17 +1593,21 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
// Selected text as input to be sent to Services
|
||||
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types
|
||||
{
|
||||
NSString *text = [self accessibilitySelectedText];
|
||||
if (text && [text length] > 0) {
|
||||
if (!_glfw.callbacks.get_current_selection) return NO;
|
||||
char *text = _glfw.callbacks.get_current_selection();
|
||||
if (!text) return NO;
|
||||
BOOL ans = NO;
|
||||
if (text[0]) {
|
||||
if ([types containsObject:NSPasteboardTypeString] == YES) {
|
||||
[pboard declareTypes:@[NSPasteboardTypeString] owner:self];
|
||||
return [pboard setString:text forType:NSPasteboardTypeString];
|
||||
ans = [pboard setString:@(text) forType:NSPasteboardTypeString];
|
||||
} else if ([types containsObject:@"NSStringPboardType"] == YES) {
|
||||
[pboard declareTypes:@[@"NSStringPboardType"] owner:self];
|
||||
return [pboard setString:text forType:NSPasteboardTypeString];
|
||||
ans = [pboard setString:@(text) forType:NSPasteboardTypeString];
|
||||
}
|
||||
free(text);
|
||||
}
|
||||
return NO;
|
||||
return ans;
|
||||
}
|
||||
|
||||
// Service output to be handled
|
||||
|
||||
2
glfw/glfw3.h
vendored
2
glfw/glfw3.h
vendored
@ -1719,6 +1719,7 @@ typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWactivationcallback)(GLFWwindow *window, const char *token, void *data);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
|
||||
typedef char* (* GLFWcurrentselectionfun)(void);
|
||||
typedef bool (* GLFWhascurrentselectionfun)(void);
|
||||
typedef void (* GLFWclipboarddatafreefun)(void* data);
|
||||
typedef struct GLFWDataChunk {
|
||||
const char *data;
|
||||
@ -1889,6 +1890,7 @@ GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, monotonic_t interval,
|
||||
GLFWAPI void glfwRemoveTimer(unsigned long long);
|
||||
GLFWAPI GLFWdrawtextfun glfwSetDrawTextFunction(GLFWdrawtextfun function);
|
||||
GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselectionfun callback);
|
||||
GLFWAPI GLFWhascurrentselectionfun glfwSetHasCurrentSelectionCallback(GLFWhascurrentselectionfun callback);
|
||||
|
||||
/*! @brief Terminates the GLFW library.
|
||||
*
|
||||
|
||||
7
glfw/init.c
vendored
7
glfw/init.c
vendored
@ -395,3 +395,10 @@ GLFWAPI GLFWcurrentselectionfun glfwSetCurrentSelectionCallback(GLFWcurrentselec
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.get_current_selection, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWhascurrentselectionfun glfwSetHasCurrentSelectionCallback(GLFWhascurrentselectionfun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.has_current_selection, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
1
glfw/internal.h
vendored
1
glfw/internal.h
vendored
@ -634,6 +634,7 @@ struct _GLFWlibrary
|
||||
GLFWapplicationclosefun application_close;
|
||||
GLFWdrawtextfun draw_text;
|
||||
GLFWcurrentselectionfun get_current_selection;
|
||||
GLFWhascurrentselectionfun has_current_selection;
|
||||
} callbacks;
|
||||
|
||||
|
||||
|
||||
@ -1985,6 +1985,12 @@ class Boss:
|
||||
return w.text_for_selection()
|
||||
return None
|
||||
|
||||
def has_active_selection(self) -> bool:
|
||||
w = self.active_window
|
||||
if w is not None and not w.destroyed:
|
||||
return w.has_selection()
|
||||
return False
|
||||
|
||||
@ac('cp', '''
|
||||
Copy the selection from the active window to the specified buffer
|
||||
|
||||
|
||||
3
kitty/glfw-wrapper.c
generated
3
kitty/glfw-wrapper.c
generated
@ -41,6 +41,9 @@ load_glfw(const char* path) {
|
||||
*(void **) (&glfwSetCurrentSelectionCallback_impl) = dlsym(handle, "glfwSetCurrentSelectionCallback");
|
||||
if (glfwSetCurrentSelectionCallback_impl == NULL) fail("Failed to load glfw function glfwSetCurrentSelectionCallback with error: %s", dlerror());
|
||||
|
||||
*(void **) (&glfwSetHasCurrentSelectionCallback_impl) = dlsym(handle, "glfwSetHasCurrentSelectionCallback");
|
||||
if (glfwSetHasCurrentSelectionCallback_impl == NULL) fail("Failed to load glfw function glfwSetHasCurrentSelectionCallback with error: %s", dlerror());
|
||||
|
||||
*(void **) (&glfwTerminate_impl) = dlsym(handle, "glfwTerminate");
|
||||
if (glfwTerminate_impl == NULL) fail("Failed to load glfw function glfwTerminate with error: %s", dlerror());
|
||||
|
||||
|
||||
5
kitty/glfw-wrapper.h
generated
5
kitty/glfw-wrapper.h
generated
@ -1457,6 +1457,7 @@ typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWactivationcallback)(GLFWwindow *window, const char *token, void *data);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
|
||||
typedef char* (* GLFWcurrentselectionfun)(void);
|
||||
typedef bool (* GLFWhascurrentselectionfun)(void);
|
||||
typedef void (* GLFWclipboarddatafreefun)(void* data);
|
||||
typedef struct GLFWDataChunk {
|
||||
const char *data;
|
||||
@ -1662,6 +1663,10 @@ typedef GLFWcurrentselectionfun (*glfwSetCurrentSelectionCallback_func)(GLFWcurr
|
||||
GFW_EXTERN glfwSetCurrentSelectionCallback_func glfwSetCurrentSelectionCallback_impl;
|
||||
#define glfwSetCurrentSelectionCallback glfwSetCurrentSelectionCallback_impl
|
||||
|
||||
typedef GLFWhascurrentselectionfun (*glfwSetHasCurrentSelectionCallback_func)(GLFWhascurrentselectionfun);
|
||||
GFW_EXTERN glfwSetHasCurrentSelectionCallback_func glfwSetHasCurrentSelectionCallback_impl;
|
||||
#define glfwSetHasCurrentSelectionCallback glfwSetHasCurrentSelectionCallback_impl
|
||||
|
||||
typedef void (*glfwTerminate_func)(void);
|
||||
GFW_EXTERN glfwTerminate_func glfwTerminate_impl;
|
||||
#define glfwTerminate glfwTerminate_impl
|
||||
|
||||
11
kitty/glfw.c
11
kitty/glfw.c
@ -496,6 +496,16 @@ get_current_selection(void) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_current_selection(void) {
|
||||
if (!global_state.boss) return false;
|
||||
PyObject *ret = PyObject_CallMethod(global_state.boss, "has_active_selection", NULL);
|
||||
if (!ret) { PyErr_Print(); return false; }
|
||||
bool ans = ret == Py_True;
|
||||
Py_DECREF(ret);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
static void get_window_dpi(GLFWwindow *w, double *x, double *y);
|
||||
|
||||
@ -800,6 +810,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
||||
if (OPT(hide_window_decorations) & 1) glfwWindowHint(GLFW_DECORATED, false);
|
||||
glfwSetApplicationCloseCallback(application_close_requested_callback);
|
||||
glfwSetCurrentSelectionCallback(get_current_selection);
|
||||
glfwSetHasCurrentSelectionCallback(has_current_selection);
|
||||
#ifdef __APPLE__
|
||||
cocoa_set_activation_policy(OPT(macos_hide_from_tasks));
|
||||
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, true);
|
||||
|
||||
@ -2785,7 +2785,12 @@ screen_detect_url(Screen *screen, unsigned int x, unsigned int y) {
|
||||
#define WRAP2B(name) static PyObject* name(Screen *self, PyObject *args) { unsigned int a, b; int p; if(!PyArg_ParseTuple(args, "IIp", &a, &b, &p)) return NULL; screen_##name(self, a, b, (bool)p); Py_RETURN_NONE; }
|
||||
|
||||
WRAP0(garbage_collect_hyperlink_pool)
|
||||
WRAP0x(has_selection)
|
||||
|
||||
static PyObject*
|
||||
has_selection(Screen *self, PyObject *a UNUSED) {
|
||||
if (screen_has_selection(self)) Py_RETURN_TRUE;
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
hyperlinks_as_list(Screen *self, PyObject *args UNUSED) {
|
||||
@ -4076,7 +4081,7 @@ static PyMethodDef methods[] = {
|
||||
MND(cursor_down1, METH_VARARGS)
|
||||
MND(cursor_forward, METH_VARARGS)
|
||||
{"index", (PyCFunction)xxx_index, METH_VARARGS, ""},
|
||||
{"has_selection", (PyCFunction)xxx_has_selection, METH_VARARGS, ""},
|
||||
{"has_selection", (PyCFunction)has_selection, METH_VARARGS, ""},
|
||||
MND(set_pending_timeout, METH_O)
|
||||
MND(as_text, METH_VARARGS)
|
||||
MND(as_text_non_visual, METH_VARARGS)
|
||||
|
||||
@ -1354,6 +1354,9 @@ class Window:
|
||||
lines = self.screen.text_for_selection(as_ansi, strip_trailing_spaces)
|
||||
return ''.join(lines)
|
||||
|
||||
def has_selection(self) -> bool:
|
||||
return self.screen.has_selection()
|
||||
|
||||
def call_watchers(self, which: Iterable[Watcher], data: Dict[str, Any]) -> None:
|
||||
boss = get_boss()
|
||||
for w in which:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user