Load glfw primary selection functions dynamically
Allows kitty to run on wayland. Also dont try to set the window icon on wayland.
This commit is contained in:
parent
d4e5bc4141
commit
e558880e8f
5 changed files with 72 additions and 76 deletions
|
|
@ -75,3 +75,47 @@ def wakeup():
|
|||
raise RuntimeError('float size is not 4')
|
||||
if ctypes.sizeof(GLint) != 4:
|
||||
raise RuntimeError('int size is not 4')
|
||||
|
||||
|
||||
def get_glfw_lib_name():
|
||||
try:
|
||||
for line in open('/proc/{}/maps'.format(os.getpid())):
|
||||
lib = line.split()[-1]
|
||||
if '/libglfw.so' in lib:
|
||||
return lib
|
||||
except Exception as err:
|
||||
try:
|
||||
print(str(err), file=sys.stderr)
|
||||
except Exception:
|
||||
pass
|
||||
return 'libglfw.so.3'
|
||||
|
||||
|
||||
def glfw_lib():
|
||||
ans = getattr(glfw_lib, 'ans', None)
|
||||
if ans is None:
|
||||
ans = glfw_lib.ans = ctypes.CDLL('libglfw.3.dylib' if isosx else get_glfw_lib_name())
|
||||
return ans
|
||||
|
||||
|
||||
def selection_clipboard_funcs():
|
||||
ans = getattr(selection_clipboard_funcs, 'ans', None)
|
||||
if ans is None:
|
||||
lib = glfw_lib()
|
||||
if hasattr(lib, 'glfwGetX11SelectionString'):
|
||||
g = lib.glfwGetX11SelectionString
|
||||
g.restype = ctypes.c_char_p
|
||||
g.argtypes = []
|
||||
s = lib.glfwSetX11SelectionString
|
||||
s.restype = None
|
||||
s.argtypes = [ctypes.c_char_p]
|
||||
ans = g, s
|
||||
else:
|
||||
ans = None, None
|
||||
selection_clipboard_funcs.ans = ans
|
||||
return ans
|
||||
|
||||
|
||||
iswayland = False
|
||||
if not isosx:
|
||||
iswayland = selection_clipboard_funcs()[0] is None
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ extern bool init_keys(PyObject *module);
|
|||
extern bool init_graphics(PyObject *module);
|
||||
extern bool init_shaders(PyObject *module);
|
||||
extern bool init_shaders_debug(PyObject *module);
|
||||
extern bool init_x11_funcs(PyObject *module);
|
||||
#ifdef __APPLE__
|
||||
extern int init_CoreText(PyObject *);
|
||||
extern bool init_cocoa(PyObject *module);
|
||||
|
|
@ -181,7 +180,6 @@ PyInit_fast_data_types(void) {
|
|||
if (!init_Face(m)) return NULL;
|
||||
if (!init_freetype_library(m)) return NULL;
|
||||
if (!init_fontconfig_library(m)) return NULL;
|
||||
if (!init_x11_funcs(m)) return NULL;
|
||||
#endif
|
||||
|
||||
#define OOF(n) #n, offsetof(Cell, n)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
cached_values, load_cached_values, load_config, save_cached_values
|
||||
)
|
||||
from .constants import (
|
||||
appname, config_dir, isosx, logo_data_file, str_version, viewport_size
|
||||
appname, config_dir, isosx, iswayland, logo_data_file, str_version,
|
||||
viewport_size
|
||||
)
|
||||
from .fast_data_types import (
|
||||
GL_VERSION_REQUIRED, GLFW_CONTEXT_VERSION_MAJOR,
|
||||
|
|
@ -183,7 +184,7 @@ def run_app(opts, args):
|
|||
cocoa_create_global_menu()
|
||||
if opts.macos_hide_titlebar:
|
||||
cocoa_make_window_resizable(window.cocoa_window_id())
|
||||
else:
|
||||
elif not iswayland: # no window icons on wayland
|
||||
with open(logo_data_file, 'rb') as f:
|
||||
window.set_icon(f.read(), 256, 256)
|
||||
set_logical_dpi(*get_logical_dpi())
|
||||
|
|
|
|||
|
|
@ -12,8 +12,11 @@
|
|||
from functools import lru_cache
|
||||
from time import monotonic
|
||||
|
||||
from .constants import isosx
|
||||
from .fast_data_types import glfw_get_physical_dpi, wcwidth as wcwidth_impl, redirect_std_streams, GLSL_VERSION
|
||||
from .constants import isosx, iswayland, selection_clipboard_funcs
|
||||
from .fast_data_types import (
|
||||
GLSL_VERSION, glfw_get_physical_dpi, redirect_std_streams,
|
||||
wcwidth as wcwidth_impl
|
||||
)
|
||||
from .rgb import Color, to_color
|
||||
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
|
@ -118,8 +121,8 @@ def x11_dpi():
|
|||
|
||||
def get_logical_dpi():
|
||||
if not hasattr(get_logical_dpi, 'ans'):
|
||||
if isosx:
|
||||
# TODO: Investigate if this needs a different implementation on OS X
|
||||
if isosx or iswayland:
|
||||
# TODO: Investigate if this needs a different implementation on OS X or Wayland
|
||||
get_logical_dpi.ans = glfw_get_physical_dpi()
|
||||
else:
|
||||
# See https://github.com/glfw/glfw/issues/1019 for why we cant use
|
||||
|
|
@ -160,17 +163,31 @@ def parse_color_set(raw):
|
|||
continue
|
||||
|
||||
|
||||
def set_primary_selection(text):
|
||||
if isosx:
|
||||
return # There is no primary selection on OS X
|
||||
if isinstance(text, str):
|
||||
text = text.encode('utf-8')
|
||||
s = selection_clipboard_funcs()[1]
|
||||
if s is None:
|
||||
p = subprocess.Popen(['xsel', '-i', '-p'], stdin=subprocess.PIPE, stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)
|
||||
p.stdin.write(text), p.stdin.close()
|
||||
p.wait()
|
||||
else:
|
||||
s(text)
|
||||
|
||||
|
||||
def get_primary_selection():
|
||||
if isosx:
|
||||
return '' # There is no primary selection on OS X
|
||||
try:
|
||||
from .fast_data_types import get_selection_x11
|
||||
ans = (get_selection_x11() or b'').decode('utf-8', 'replace')
|
||||
except ImportError:
|
||||
g = selection_clipboard_funcs()[0]
|
||||
if g is None:
|
||||
ans = subprocess.check_output(['xsel', '-p'], stderr=open(os.devnull, 'wb'), stdin=open(os.devnull, 'rb')).decode('utf-8')
|
||||
if ans:
|
||||
# Without this for some reason repeated pastes dont work
|
||||
set_primary_selection(ans)
|
||||
else:
|
||||
ans = (g() or b'').decode('utf-8', 'replace')
|
||||
return ans
|
||||
|
||||
|
||||
|
|
@ -188,20 +205,6 @@ def base64_encode(
|
|||
return ans
|
||||
|
||||
|
||||
def set_primary_selection(text):
|
||||
if isosx:
|
||||
return # There is no primary selection on OS X
|
||||
if isinstance(text, str):
|
||||
text = text.encode('utf-8')
|
||||
try:
|
||||
from .fast_data_types import set_selection_x11
|
||||
set_selection_x11(text)
|
||||
except ImportError:
|
||||
p = subprocess.Popen(['xsel', '-i', '-p'], stdin=subprocess.PIPE, stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)
|
||||
p.stdin.write(text), p.stdin.close()
|
||||
p.wait()
|
||||
|
||||
|
||||
def open_url(url, program='default'):
|
||||
if program == 'default':
|
||||
cmd = ['open'] if isosx else ['xdg-open']
|
||||
|
|
|
|||
50
kitty/x11.c
50
kitty/x11.c
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* x11.c
|
||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <stdbool.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR > 2)
|
||||
#define HAS_X11_SELECTION
|
||||
#endif
|
||||
|
||||
#ifdef HAS_X11_SELECTION
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
static PyObject*
|
||||
get_selection_x11(PyObject *self) {
|
||||
(void)(self);
|
||||
return Py_BuildValue("y", glfwGetX11SelectionString());
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
set_selection_x11(PyObject *self, PyObject *args) {
|
||||
(void)(self);
|
||||
const char *data;
|
||||
if (!PyArg_ParseTuple(args, "y", &data)) return NULL;
|
||||
glfwSetX11SelectionString(data);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef sel_methods[] = {
|
||||
{"get_selection_x11", (PyCFunction)get_selection_x11, METH_NOARGS, ""},
|
||||
{"set_selection_x11", (PyCFunction)set_selection_x11, METH_VARARGS, ""},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
bool
|
||||
init_x11_funcs(PyObject *module) {
|
||||
(void)(module);
|
||||
#ifdef HAS_X11_SELECTION
|
||||
if (PyModule_AddFunctions(module, sel_methods) != 0) return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
Loading…
Reference in a new issue