From ecee7086a8be320e8351f03e667ae2ccee05e0ae Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 4 Apr 2024 16:56:13 +0530 Subject: [PATCH] Report compositor missing capabilities in debug output --- glfw/glfw.py | 1 + glfw/wl_init.c | 26 +++++++++++++++++++------- kitty/debug_config.py | 6 ++++-- kitty/fast_data_types.pyi | 2 +- kitty/glfw-wrapper.c | 3 +++ kitty/glfw-wrapper.h | 4 ++++ kitty/glfw.c | 13 +++++++------ 7 files changed, 39 insertions(+), 16 deletions(-) diff --git a/glfw/glfw.py b/glfw/glfw.py index 96475ac9b..750ae339a 100755 --- a/glfw/glfw.py +++ b/glfw/glfw.py @@ -311,6 +311,7 @@ def generate_wrappers(glfw_header: str) -> None: int glfwGetNativeKeyForName(const char* key_name, int case_sensitive) void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback) void glfwWaylandActivateWindow(GLFWwindow *handle, const char *activation_token) + const char* glfwWaylandMissingCapabilities(void) void glfwWaylandRunWithActivationToken(GLFWwindow *handle, GLFWactivationcallback cb, void *cb_data) bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color) void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle) diff --git a/glfw/wl_init.c b/glfw/wl_init.c index cd6b75117..a75b89183 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -43,6 +43,7 @@ #include #include #include +#include // Needed for the BTN_* defines #ifdef __has_include #if __has_include() @@ -803,6 +804,22 @@ GLFWAPI pid_t glfwWaylandCompositorPID(void) { ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// +static const char* +get_compositor_missing_capabilities(void) { +#define C(title, x) if (!_glfw.wl.x) p += snprintf(buf, sizeof(buf) - (p - buf), "%s", #title); + static char buf[256]; + char *p = buf; + *p = 0; + C(viewporter, wp_viewporter); C(fractional_scale, wp_fractional_scale_manager_v1); + C(blur, org_kde_kwin_blur_manager); C(server_side_decorations, decorationManager); + C(cursor_shape, wp_cursor_shape_manager_v1); C(layer_shell, zwlr_layer_shell_v1); + C(single_pixel_buffer, wp_single_pixel_buffer_manager_v1); C(preferred_scale, has_preferred_buffer_scale); +#undef C + return buf; +} + +GLFWAPI const char* glfwWaylandMissingCapabilities(void) { return get_compositor_missing_capabilities(); } + int _glfwPlatformInit(void) { int i; @@ -890,13 +907,8 @@ int _glfwPlatformInit(void) return false; } if (_glfw.hints.init.debugRendering) { - debug("Compositor capabilities:"); -#define C(title, name) fprintf(stderr, " %s=%d", #title, _glfw.wl.name != NULL); - C(viewporter, wp_viewporter); C(fractional_scale, wp_fractional_scale_manager_v1); C(blur, org_kde_kwin_blur_manager); - C(SSD, decorationManager); C(cursor_shape, wp_cursor_shape_manager_v1); - fprintf(stderr, " preferred_buffer_scale: %d", _glfw.wl.has_preferred_buffer_scale); -#undef C - fprintf(stderr, "\n"); + const char *mc = get_compositor_missing_capabilities(); + if (mc && mc[0]) debug("Compositor missing capabilities: %s\n", mc); } return true; diff --git a/kitty/debug_config.py b/kitty/debug_config.py index 1238bf7d4..9de16ca06 100644 --- a/kitty/debug_config.py +++ b/kitty/debug_config.py @@ -17,7 +17,7 @@ from kittens.tui.operations import colored, styled from .child import cmdline_of_pid from .cli import version from .constants import extensions_dir, is_macos, is_wayland, kitty_base_dir, kitty_exe, shell_path -from .fast_data_types import Color, SingleKey, num_users, wayland_compositor_pid +from .fast_data_types import Color, SingleKey, num_users, wayland_compositor_data from .options.types import Options as KittyOpts from .options.types import defaults from .options.utils import KeyboardMode, KeyDefinition @@ -199,7 +199,7 @@ def compositor_name() -> str: if is_wayland(): ans = 'Wayland' with suppress(Exception): - pid = wayland_compositor_pid() + pid, missing_capabilities = wayland_compositor_data() if pid > -1: cmdline = cmdline_of_pid(pid) exe = cmdline[0] @@ -214,6 +214,8 @@ def compositor_name() -> str: exe = raw.splitlines()[0] exe = subprocess.check_output([exe, '--version']).decode().strip().splitlines()[0] ans += f' ({exe})' + if missing_capabilities: + ans += f' missing: {missing_capabilities}' return ans diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 5244772a4..3bd8de3e3 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1573,5 +1573,5 @@ def replace_c0_codes_except_nl_space_tab(text: str) -> str:... @overload def replace_c0_codes_except_nl_space_tab(text: Union[bytes, memoryview, bytearray]) -> bytes:... def terminfo_data() -> bytes:... -def wayland_compositor_pid() -> int:... +def wayland_compositor_data() -> Tuple[int, Optional[str]]:... def monotonic() -> float: ... diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index ceb1855b5..369e2cf53 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -470,6 +470,9 @@ load_glfw(const char* path) { *(void **) (&glfwWaylandActivateWindow_impl) = dlsym(handle, "glfwWaylandActivateWindow"); if (glfwWaylandActivateWindow_impl == NULL) dlerror(); // clear error indicator + *(void **) (&glfwWaylandMissingCapabilities_impl) = dlsym(handle, "glfwWaylandMissingCapabilities"); + if (glfwWaylandMissingCapabilities_impl == NULL) dlerror(); // clear error indicator + *(void **) (&glfwWaylandRunWithActivationToken_impl) = dlsym(handle, "glfwWaylandRunWithActivationToken"); if (glfwWaylandRunWithActivationToken_impl == NULL) dlerror(); // clear error indicator diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index ad09a7e63..eac44c312 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -2297,6 +2297,10 @@ typedef void (*glfwWaylandActivateWindow_func)(GLFWwindow*, const char*); GFW_EXTERN glfwWaylandActivateWindow_func glfwWaylandActivateWindow_impl; #define glfwWaylandActivateWindow glfwWaylandActivateWindow_impl +typedef const char* (*glfwWaylandMissingCapabilities_func)(void); +GFW_EXTERN glfwWaylandMissingCapabilities_func glfwWaylandMissingCapabilities_impl; +#define glfwWaylandMissingCapabilities glfwWaylandMissingCapabilities_impl + typedef void (*glfwWaylandRunWithActivationToken_func)(GLFWwindow*, GLFWactivationcallback, void*); GFW_EXTERN glfwWaylandRunWithActivationToken_func glfwWaylandRunWithActivationToken_impl; #define glfwWaylandRunWithActivationToken glfwWaylandRunWithActivationToken_impl diff --git a/kitty/glfw.c b/kitty/glfw.c index 48d039806..84a74c326 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1844,13 +1844,14 @@ x11_display(PYNOARG) { } static PyObject* -wayland_compositor_pid(PYNOARG) { - pid_t ans = -1; +wayland_compositor_data(PYNOARG) { + pid_t pid = -1; + const char *missing_capabilities = NULL; if (global_state.is_wayland && glfwWaylandCompositorPID) { - ans = glfwWaylandCompositorPID(); + pid = glfwWaylandCompositorPID(); + missing_capabilities = glfwWaylandMissingCapabilities(); } - long long x = ans; - return PyLong_FromLongLong(x); + return Py_BuildValue("Ls", (long long)pid, missing_capabilities); } static PyObject* @@ -2233,7 +2234,7 @@ static PyMethodDef module_methods[] = { METHODB(change_os_window_state, METH_VARARGS), METHODB(glfw_window_hint, METH_VARARGS), METHODB(x11_display, METH_NOARGS), - METHODB(wayland_compositor_pid, METH_NOARGS), + METHODB(wayland_compositor_data, METH_NOARGS), METHODB(get_click_interval, METH_NOARGS), METHODB(x11_window_id, METH_O), METHODB(make_x11_window_a_dock_window, METH_VARARGS),