panel kitten: Do not depend on xprop

This commit is contained in:
Kovid Goyal 2022-09-24 15:44:54 +05:30
parent 2cef9abbd3
commit 98eacb2067
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
9 changed files with 41 additions and 33 deletions

View File

@ -172,6 +172,8 @@ class Arg:
while self.name.startswith('*'):
self.name = self.name[1:]
self.type = self.type + '*'
if '[' in self.name:
self.type += '[' + self.name.partition('[')[-1]
def __repr__(self) -> str:
return f'Arg({self.type}, {self.name})'
@ -253,6 +255,7 @@ const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callbac
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
void glfwSetX11WindowAsDock(int32_t x11_window_id)
void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12])
'''.splitlines():
if line:
functions.append(Function(line.strip(), check_fail=False))

2
glfw/x11_init.c vendored
View File

@ -149,6 +149,8 @@ static void detectEWMH(void)
getAtomIfSupported(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
_glfw.x11.NET_WM_STRUT_PARTIAL =
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STRUT_PARTIAL");
XFree(supportedAtoms);
}

1
glfw/x11_platform.h vendored
View File

@ -269,6 +269,7 @@ typedef struct _GLFWlibraryX11
Atom NET_ACTIVE_WINDOW;
Atom NET_FRAME_EXTENTS;
Atom NET_REQUEST_FRAME_EXTENTS;
Atom NET_WM_STRUT_PARTIAL;
Atom MOTIF_WM_HINTS;
// Xdnd (drag and drop) atoms

7
glfw/x11_window.c vendored
View File

@ -3205,3 +3205,10 @@ GLFWAPI void glfwSetX11WindowAsDock(int32_t x11_window_id) {
_glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &type, 1);
}
GLFWAPI void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12]) {
_GLFW_REQUIRE_INIT();
XChangeProperty(_glfw.x11.display, x11_window_id,
_glfw.x11.NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*) dimensions, 12);
}

View File

@ -2,8 +2,6 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import os
import shutil
import subprocess
import sys
from typing import Any, Callable, Dict, List, Tuple
@ -66,14 +64,7 @@ def parse_panel_args(args: List[str]) -> Tuple[PanelCLIOptions, List[str]]:
return parse_args(args, OPTIONS, usage, help_text, 'kitty +kitten panel', result_class=PanelCLIOptions)
def call_xprop(*cmd: str, silent: bool = False) -> None:
cmd_ = ['xprop'] + list(cmd)
try:
cp = subprocess.run(cmd_, stdout=subprocess.DEVNULL if silent else None)
except FileNotFoundError:
raise SystemExit('You must have the xprop program installed')
if cp.returncode != 0:
raise SystemExit(cp.returncode)
Strut = Tuple[int, int, int, int, int, int, int, int, int, int, int, int]
def create_strut(
@ -81,40 +72,33 @@ def create_strut(
left: int = 0, right: int = 0, top: int = 0, bottom: int = 0, left_start_y: int = 0, left_end_y: int = 0,
right_start_y: int = 0, right_end_y: int = 0, top_start_x: int = 0, top_end_x: int = 0,
bottom_start_x: int = 0, bottom_end_x: int = 0
) -> None:
call_xprop(
'-id',
str(int(win_id)), '-format', '_NET_WM_STRUT_PARTIAL', '32cccccccccccc',
'-set', '_NET_WM_STRUT_PARTIAL',
f'{left},{right},{top},{bottom},'
f'{left_start_y},{left_end_y},{right_start_y},{right_end_y},'
f'{top_start_x},{top_end_x},{bottom_start_x},{bottom_end_x}'
)
) -> Strut:
return left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x
def create_top_strut(win_id: int, width: int, height: int) -> None:
create_strut(win_id, top=height, top_end_x=width)
def create_top_strut(win_id: int, width: int, height: int) -> Strut:
return create_strut(win_id, top=height, top_end_x=width)
def create_bottom_strut(win_id: int, width: int, height: int) -> None:
create_strut(win_id, bottom=height, bottom_end_x=width)
def create_bottom_strut(win_id: int, width: int, height: int) -> Strut:
return create_strut(win_id, bottom=height, bottom_end_x=width)
def create_left_strut(win_id: int, width: int, height: int) -> None:
create_strut(win_id, left=width, left_end_y=height)
def create_left_strut(win_id: int, width: int, height: int) -> Strut:
return create_strut(win_id, left=width, left_end_y=height)
def create_right_strut(win_id: int, width: int, height: int) -> None:
create_strut(win_id, right=width, right_end_y=height)
def create_right_strut(win_id: int, width: int, height: int) -> Strut:
return create_strut(win_id, right=width, right_end_y=height)
window_width = window_height = 0
def setup_x11_window(win_id: int) -> None:
make_x11_window_a_dock_window(win_id)
func = globals()[f'create_{args.edge}_strut']
func(win_id, window_width, window_height)
strut = func(win_id, window_width, window_height)
make_x11_window_a_dock_window(win_id, strut)
def initial_window_size_func(opts: WindowSizeData, cached_values: Dict[str, Any]) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
@ -138,8 +122,6 @@ def main(sys_args: List[str]) -> None:
global args
if is_macos or not os.environ.get('DISPLAY'):
raise SystemExit('Currently the panel kitten is supported only on X11 desktops')
if not shutil.which('xprop'):
raise SystemExit('The xprop program is required for the panel kitten')
args, items = parse_panel_args(sys_args[1:])
if not items:
raise SystemExit('You must specify the program to run')

View File

@ -1475,4 +1475,4 @@ def clearenv() -> None: ...
def set_clipboard_data_types(ct: int, mime_types: Tuple[str, ...]) -> None: ...
def get_clipboard_mime(ct: int, mime: Optional[str], callback: Callable[[bytes], None]) -> None: ...
def run_with_activation_token(func: Callable[[str], None]) -> None: ...
def make_x11_window_a_dock_window(x11_window_id: int) -> None: ...
def make_x11_window_a_dock_window(x11_window_id: int, strut: Tuple[int, int, int, int, int, int, int, int, int, int, int, int]) -> None: ...

3
kitty/glfw-wrapper.c generated
View File

@ -470,6 +470,9 @@ load_glfw(const char* path) {
*(void **) (&glfwSetX11WindowAsDock_impl) = dlsym(handle, "glfwSetX11WindowAsDock");
if (glfwSetX11WindowAsDock_impl == NULL) dlerror(); // clear error indicator
*(void **) (&glfwSetX11WindowStrut_impl) = dlsym(handle, "glfwSetX11WindowStrut");
if (glfwSetX11WindowStrut_impl == NULL) dlerror(); // clear error indicator
return NULL;
}

4
kitty/glfw-wrapper.h generated
View File

@ -2234,4 +2234,8 @@ typedef void (*glfwSetX11WindowAsDock_func)(int32_t);
GFW_EXTERN glfwSetX11WindowAsDock_func glfwSetX11WindowAsDock_impl;
#define glfwSetX11WindowAsDock glfwSetX11WindowAsDock_impl
typedef void (*glfwSetX11WindowStrut_func)(int32_t, uint32_t[12]);
GFW_EXTERN glfwSetX11WindowStrut_func glfwSetX11WindowStrut_impl;
#define glfwSetX11WindowStrut glfwSetX11WindowStrut_impl
const char* load_glfw(const char* path);

View File

@ -1690,9 +1690,15 @@ get_clipboard_mime(PyObject *self UNUSED, PyObject *args) {
static PyObject*
make_x11_window_a_dock_window(PyObject *self UNUSED, PyObject *args UNUSED) {
int x11_window_id;
if (!PyArg_ParseTuple(args, "i", &x11_window_id)) return NULL;
PyObject *dims;
if (!PyArg_ParseTuple(args, "iO!", &x11_window_id, &PyTuple_Type, &dims)) return NULL;
if (PyTuple_GET_SIZE(dims) != 12 ) { PyErr_SetString(PyExc_TypeError, "dimesions must be a tuple of length 12"); return NULL; }
if (!glfwSetX11WindowAsDock) { PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwGetX11Window"); return NULL; }
uint32_t dimensions[12];
for (Py_ssize_t i = 0; i < 12; i++) dimensions[i] = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(dims, i));
if (PyErr_Occurred()) return NULL;
glfwSetX11WindowAsDock(x11_window_id);
glfwSetX11WindowStrut(x11_window_id, dimensions);
Py_RETURN_NONE;
}