Infrastructure for passing layer shell config from python to glfw
This commit is contained in:
parent
fe5ccc144b
commit
56978189e0
4 changed files with 50 additions and 11 deletions
|
|
@ -7,9 +7,19 @@ from kitty.fonts import FontFeature
|
|||
from kitty.fonts.render import FontObject
|
||||
from kitty.marks import MarkerFunc
|
||||
from kitty.options.types import Options
|
||||
from kitty.types import SignalInfo
|
||||
from kitty.types import LayerShellConfig, SignalInfo
|
||||
|
||||
# Constants {{{
|
||||
GLFW_LAYER_SHELL_NONE: int
|
||||
GLFW_LAYER_SHELL_PANEL: int
|
||||
GLFW_LAYER_SHELL_BACKGROUND: int
|
||||
GLFW_EDGE_TOP: int
|
||||
GLFW_EDGE_BOTTOM: int
|
||||
GLFW_EDGE_LEFT: int
|
||||
GLFW_EDGE_RIGHT: int
|
||||
GLFW_FOCUS_NOT_ALLOWED: int
|
||||
GLFW_FOCUS_EXCLUSIVE: int
|
||||
GLFW_FOCUS_ON_DEMAND: int
|
||||
IMAGE_PLACEHOLDER_CHAR: int
|
||||
GLFW_PRIMARY_SELECTION: int
|
||||
GLFW_CLIPBOARD: int
|
||||
|
|
@ -508,6 +518,7 @@ def create_os_window(
|
|||
x: Optional[int] = None,
|
||||
y: Optional[int] = None,
|
||||
disallow_override_title: bool = False,
|
||||
layer_shell_config: Optional[LayerShellConfig] = None,
|
||||
) -> int:
|
||||
pass
|
||||
|
||||
|
|
|
|||
36
kitty/glfw.c
36
kitty/glfw.c
|
|
@ -1047,18 +1047,35 @@ native_window_handle(GLFWwindow *w) {
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
static GLFWLayerShellConfig
|
||||
translate_layer_shell_config(PyObject *p) {
|
||||
GLFWLayerShellConfig ans = {0};
|
||||
#define A(attr, type_check, convert) RAII_PyObject(attr, PyObject_GetAttrString(p, #attr)); if (attr == NULL) return ans; if (!type_check(attr)) { PyErr_SetString(PyExc_TypeError, #attr " not of the correct type"); return ans; }; ans.attr = convert(attr);
|
||||
A(output_name, PyUnicode_Check, PyUnicode_AsUTF8);
|
||||
A(type, PyLong_Check, PyLong_AsLong);
|
||||
A(edge, PyLong_Check, PyLong_AsLong);
|
||||
A(focus_policy, PyLong_Check, PyLong_AsLong);
|
||||
#undef A
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
||||
int x = INT_MIN, y = INT_MIN, window_state = WINDOW_NORMAL, disallow_override_title = 0;
|
||||
char *title, *wm_class_class, *wm_class_name;
|
||||
PyObject *optional_window_state = NULL, *load_programs = NULL, *get_window_size, *pre_show_callback, *optional_x = NULL, *optional_y = NULL;
|
||||
static const char* kwlist[] = {"get_window_size", "pre_show_callback", "title", "wm_class_name", "wm_class_class", "window_state", "load_programs", "x", "y", "disallow_override_title", NULL};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "OOsss|OOOOp", (char**)kwlist,
|
||||
&get_window_size, &pre_show_callback, &title, &wm_class_name, &wm_class_class, &optional_window_state, &load_programs, &optional_x, &optional_y, &disallow_override_title)) return NULL;
|
||||
if (optional_window_state && optional_window_state != Py_None) { if (!PyLong_Check(optional_window_state)) { PyErr_SetString(PyExc_TypeError, "window_state must be an int"); return NULL; } window_state = (int) PyLong_AsLong(optional_window_state); }
|
||||
if (optional_x && optional_x != Py_None) { if (!PyLong_Check(optional_x)) { PyErr_SetString(PyExc_TypeError, "x must be an int"); return NULL;} x = (int)PyLong_AsLong(optional_x); }
|
||||
if (optional_y && optional_y != Py_None) { if (!PyLong_Check(optional_y)) { PyErr_SetString(PyExc_TypeError, "y must be an int"); return NULL;} y = (int)PyLong_AsLong(optional_y); }
|
||||
if (window_state < WINDOW_NORMAL || window_state > WINDOW_MINIMIZED) window_state = WINDOW_NORMAL;
|
||||
PyObject *optional_window_state = NULL, *load_programs = NULL, *get_window_size, *pre_show_callback, *optional_x = NULL, *optional_y = NULL, *layer_shell_config = NULL;
|
||||
static const char* kwlist[] = {"get_window_size", "pre_show_callback", "title", "wm_class_name", "wm_class_class", "window_state", "load_programs", "x", "y", "disallow_override_title", "layer_shell_config", NULL};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "OOsss|OOOOpO", (char**)kwlist,
|
||||
&get_window_size, &pre_show_callback, &title, &wm_class_name, &wm_class_class, &optional_window_state, &load_programs, &optional_x, &optional_y, &disallow_override_title, &layer_shell_config)) return NULL;
|
||||
if (layer_shell_config && global_state.is_wayland) {
|
||||
glfwWaylandSetupLayerShellForNextWindow(translate_layer_shell_config(layer_shell_config));
|
||||
} else {
|
||||
if (optional_window_state && optional_window_state != Py_None) { if (!PyLong_Check(optional_window_state)) { PyErr_SetString(PyExc_TypeError, "window_state must be an int"); return NULL; } window_state = (int) PyLong_AsLong(optional_window_state); }
|
||||
if (optional_x && optional_x != Py_None) { if (!PyLong_Check(optional_x)) { PyErr_SetString(PyExc_TypeError, "x must be an int"); return NULL;} x = (int)PyLong_AsLong(optional_x); }
|
||||
if (optional_y && optional_y != Py_None) { if (!PyLong_Check(optional_y)) { PyErr_SetString(PyExc_TypeError, "y must be an int"); return NULL;} y = (int)PyLong_AsLong(optional_y); }
|
||||
if (window_state < WINDOW_NORMAL || window_state > WINDOW_MINIMIZED) window_state = WINDOW_NORMAL;
|
||||
}
|
||||
if (PyErr_Occurred()) return NULL;
|
||||
|
||||
static bool is_first_window = true;
|
||||
if (is_first_window) {
|
||||
|
|
@ -2183,6 +2200,9 @@ init_glfw(PyObject *m) {
|
|||
ADDC(GLFW_REPEAT);
|
||||
ADDC(true); ADDC(false);
|
||||
ADDC(GLFW_PRIMARY_SELECTION); ADDC(GLFW_CLIPBOARD);
|
||||
ADDC(GLFW_LAYER_SHELL_NONE); ADDC(GLFW_LAYER_SHELL_PANEL); ADDC(GLFW_LAYER_SHELL_BACKGROUND);
|
||||
ADDC(GLFW_FOCUS_NOT_ALLOWED); ADDC(GLFW_FOCUS_EXCLUSIVE); ADDC(GLFW_FOCUS_ON_DEMAND);
|
||||
ADDC(GLFW_EDGE_TOP); ADDC(GLFW_EDGE_BOTTOM); ADDC(GLFW_EDGE_LEFT); ADDC(GLFW_EDGE_RIGHT);
|
||||
|
||||
/* start glfw functional keys (auto generated by gen-key-constants.py do not edit) */
|
||||
ADDC(GLFW_FKEY_ESCAPE);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
from .os_window_size import initial_window_size_func
|
||||
from .session import create_sessions, get_os_window_sizing_data
|
||||
from .shaders import CompileError, load_shader_programs
|
||||
from .types import SingleInstanceData
|
||||
from .types import LayerShellConfig, SingleInstanceData
|
||||
from .utils import (
|
||||
cleanup_ssh_control_masters,
|
||||
detach,
|
||||
|
|
@ -269,7 +269,7 @@ def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ())
|
|||
run_app.initial_window_size_func(get_os_window_sizing_data(opts, startup_sessions[0] if startup_sessions else None), cached_values),
|
||||
pre_show_callback,
|
||||
args.title or appname, args.name or args.cls or appname,
|
||||
wincls, wstate, load_all_shaders, disallow_override_title=bool(args.title))
|
||||
wincls, wstate, load_all_shaders, disallow_override_title=bool(args.title), layer_shell_config=run_app.layer_shell_config)
|
||||
boss = Boss(opts, args, cached_values, global_shortcuts)
|
||||
boss.start(window_id, startup_sessions)
|
||||
if bad_lines or boss.misc_config_errors:
|
||||
|
|
@ -286,6 +286,7 @@ class AppRunner:
|
|||
def __init__(self) -> None:
|
||||
self.cached_values_name = 'main'
|
||||
self.first_window_callback = lambda window_handle: None
|
||||
self.layer_shell_config: Optional[LayerShellConfig] = None
|
||||
self.initial_window_size_func = initial_window_size_func
|
||||
|
||||
def __call__(self, opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ class SignalInfo(NamedTuple):
|
|||
sival_ptr: int
|
||||
|
||||
|
||||
class LayerShellConfig(NamedTuple):
|
||||
type: int = 0
|
||||
edge: int = 0
|
||||
focus_policy: int = 0
|
||||
output_name: Optional[str] = None
|
||||
|
||||
|
||||
def mod_to_names(mods: int, has_kitty_mod: bool = False, kitty_mod: int = 0) -> Iterator[str]:
|
||||
if has_kitty_mod:
|
||||
mods &= ~kitty_mod
|
||||
|
|
|
|||
Loading…
Reference in a new issue