{"record":{"id":"4fc21c805683ea4a","repo":"kovidgoyal/kitty","slug":"wayland-did-not-get-activation-token-from-composi","errorCode":null,"errorMessage":"Wayland: Did not get activation token from compositor. Use a better compositor.","messagePattern":"Wayland: Did not get activation token from compositor\\. Use a better compositor\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/glfw.c","lineNumber":2805,"sourceCode":"    OSWindow *w = os_window_for_id(os_window_id);\n    if (w && w->handle) glfwRequestWindowAttention(w->handle);\n    Py_RETURN_NONE;\n}\n\n\nstatic PyObject *\nget_content_scale_for_window(PYNOARG) {\n    OSWindow *w = global_state.callback_os_window ? global_state.callback_os_window : global_state.os_windows;\n    float xscale, yscale;\n    glfwGetWindowContentScale(w->handle, &xscale, &yscale);\n    return Py_BuildValue(\"ff\", xscale, yscale);\n}\n\nstatic void\nactivation_token_callback(GLFWwindow *window UNUSED, const char *token, void *data) {\n    if (!token || !token[0]) {\n        token = \"\";\n        log_error(\"Wayland: Did not get activation token from compositor. Use a better compositor.\");\n    }\n    PyObject *ret = PyObject_CallFunction(data, \"s\", token);\n    if (ret == NULL) PyErr_Print();\n    else Py_DECREF(ret);\n    Py_CLEAR(data);\n}\n\nvoid\nrun_with_activation_token_in_os_window(OSWindow *w, PyObject *callback) {\n    if (global_state.is_wayland) {\n        Py_INCREF(callback);\n        glfwWaylandRunWithActivationToken(w->handle, activation_token_callback, callback);\n    }\n}\n\nstatic PyObject *\ntoggle_fullscreen(PyObject UNUSED *self, PyObject *args) {\n    id_type os_window_id = 0;","sourceCodeStart":2787,"sourceCodeEnd":2823,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/glfw.c#L2787-L2823","documentation":"When kitty asks the Wayland compositor for an xdg-activation token (needed to focus a window without focus-stealing prevention blocking it), the compositor returned an empty or missing token. The callback still fires with an empty string, so the activation request is simply ineffective rather than fatal.","triggerScenarios":"Calling a kitty remote-control or focus API that requests window activation (e.g. kitty @ focus-window, set-window-title focus, or dbus activation) on a Wayland compositor that does not implement xdg_activation_v1 (wlroots-older versions, some minimal compositors).","commonSituations":"Using kitty @ focus-window under older sway/weston versions or compositors lacking the xdg-activation protocol; scripting kitty remote control on Wayland; version upgrades where the protocol support regressed or is absent.","solutions":["Upgrade to a compositor implementing xdg_activation_v1 (recent sway, labwc, KDE, GNOME)","Use the compositor's own focusing mechanism (swaymsg focus, wmctrl equivalent) instead of relying on kitty's activation","Check protocol support: wayland-info | grep xdg_activation","If you control the flow, ignore the error — the token is empty and activation is skipped"],"exampleFix":"# before\nkitty @ focus-window\n# after (sway)\nswaymsg '[app_id=\"kitty\"] focus'","handlingStrategy":"fallback","validationCode":"wayland-info | grep -q xdg_activation_v1 || echo 'focus-window may be a no-op; use swaymsg/wmctrl-style focusing'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the compositor's native focus command when scripting on Wayland","Treat an empty token as 'activation skipped' rather than an error in caller code","Test remote-control scripts on each compositor you support"],"tags":["kitty","wayland","activation-token","compositor","focus","remote-control"],"backgroundTag":"wayland-activation-token-missing","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}