Make passing layer shell config to glfw not use a global variable

This commit is contained in:
Kovid Goyal 2025-04-22 10:45:28 +05:30
parent 64ddd2cd04
commit 5e2d44ce15
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
10 changed files with 25 additions and 55 deletions

View file

@ -1819,11 +1819,8 @@ static bool createNativeWindow(_GLFWwindow* window,
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc) {
(void)lsc;
window->ns.deadKeyState = 0;
if (!_glfw.ns.finishedLaunching)
{

View file

@ -327,7 +327,6 @@ def generate_wrappers(glfw_header: str) -> None:
bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle)
bool glfwWaylandBeep(GLFWwindow *handle)
GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle)
void glfwWaylandSetupLayerShellForNextWindow(const GLFWLayerShellConfig *c)
pid_t glfwWaylandCompositorPID(void)
unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data)
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)

2
glfw/glfw3.h vendored
View file

@ -2869,7 +2869,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
*
* @ingroup window
*/
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share, const GLFWLayerShellConfig *lsc);
GLFWAPI bool glfwToggleFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwIsFullscreen(GLFWwindow *window, unsigned int flags);
GLFWAPI bool glfwAreSwapsAllowed(const GLFWwindow* window);

5
glfw/internal.h vendored
View file

@ -709,10 +709,7 @@ void _glfwPlatformTerminateJoysticks(void);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc);
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,

8
glfw/window.c vendored
View file

@ -187,11 +187,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
const char* title,
GLFWmonitor* monitor,
GLFWwindow* share)
{
GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share, const GLFWLayerShellConfig *lsc) {
_GLFWfbconfig fbconfig;
_GLFWctxconfig ctxconfig;
_GLFWwndconfig wndconfig;
@ -256,7 +252,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->heightincr = GLFW_DONT_CARE;
// Open the actual window and create its context
if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig, lsc))
{
glfwDestroyWindow((GLFWwindow*) window);
return NULL;

18
glfw/wl_window.c vendored
View file

@ -43,8 +43,6 @@
#define debug debug_rendering
static GLFWLayerShellConfig layer_shell_config_for_next_window = {0};
static bool
is_layer_shell(_GLFWwindow *window) { return window->wl.layer_shell.config.type != GLFW_LAYER_SHELL_NONE; }
@ -1361,13 +1359,11 @@ attach_opengl_context_to_window(_GLFWwindow *window, const _GLFWctxconfig *ctxco
return true;
}
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
window->wl.layer_shell.config = layer_shell_config_for_next_window;
memset(&layer_shell_config_for_next_window, 0, sizeof(layer_shell_config_for_next_window));
int _glfwPlatformCreateWindow(
_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig,
const GLFWLayerShellConfig *lsc
) {
window->wl.layer_shell.config = lsc ? *lsc : (GLFWLayerShellConfig){0};
csd_initialize_metrics(window);
window->wl.transparent = fbconfig->transparent;
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
@ -2838,10 +2834,6 @@ GLFWAPI void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle) {
if (csd_change_title(window)) commit_window_surface_if_safe(window);
}
GLFWAPI void glfwWaylandSetupLayerShellForNextWindow(const GLFWLayerShellConfig *c) {
layer_shell_config_for_next_window = *c;
}
GLFWAPI GLFWLayerShellConfig* glfwWaylandLayerShellConfig(GLFWwindow *handle) {
return &((_GLFWwindow*)handle)->wl.layer_shell.config;
}

6
glfw/x11_window.c vendored
View file

@ -1867,11 +1867,9 @@ void _glfwPushSelectionToManagerX11(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc)
{
(void)lsc;
Visual* visual = NULL;
int depth;

3
kitty/glfw-wrapper.c generated
View file

@ -497,9 +497,6 @@ load_glfw(const char* path) {
*(void **) (&glfwWaylandLayerShellConfig_impl) = dlsym(handle, "glfwWaylandLayerShellConfig");
if (glfwWaylandLayerShellConfig_impl == NULL) dlerror(); // clear error indicator
*(void **) (&glfwWaylandSetupLayerShellForNextWindow_impl) = dlsym(handle, "glfwWaylandSetupLayerShellForNextWindow");
if (glfwWaylandSetupLayerShellForNextWindow_impl == NULL) dlerror(); // clear error indicator
*(void **) (&glfwWaylandCompositorPID_impl) = dlsym(handle, "glfwWaylandCompositorPID");
if (glfwWaylandCompositorPID_impl == NULL) dlerror(); // clear error indicator

6
kitty/glfw-wrapper.h generated
View file

@ -1852,7 +1852,7 @@ typedef void (*glfwWindowHintString_func)(int, const char*);
GFW_EXTERN glfwWindowHintString_func glfwWindowHintString_impl;
#define glfwWindowHintString glfwWindowHintString_impl
typedef GLFWwindow* (*glfwCreateWindow_func)(int, int, const char*, GLFWmonitor*, GLFWwindow*);
typedef GLFWwindow* (*glfwCreateWindow_func)(int, int, const char*, GLFWmonitor*, GLFWwindow*, const GLFWLayerShellConfig*);
GFW_EXTERN glfwCreateWindow_func glfwCreateWindow_impl;
#define glfwCreateWindow glfwCreateWindow_impl
@ -2356,10 +2356,6 @@ typedef GLFWLayerShellConfig* (*glfwWaylandLayerShellConfig_func)(GLFWwindow*);
GFW_EXTERN glfwWaylandLayerShellConfig_func glfwWaylandLayerShellConfig_impl;
#define glfwWaylandLayerShellConfig glfwWaylandLayerShellConfig_impl
typedef void (*glfwWaylandSetupLayerShellForNextWindow_func)(const GLFWLayerShellConfig*);
GFW_EXTERN glfwWaylandSetupLayerShellForNextWindow_func glfwWaylandSetupLayerShellForNextWindow_impl;
#define glfwWaylandSetupLayerShellForNextWindow glfwWaylandSetupLayerShellForNextWindow_impl
typedef pid_t (*glfwWaylandCompositorPID_func)(void);
GFW_EXTERN glfwWaylandCompositorPID_func glfwWaylandCompositorPID_impl;
#define glfwWaylandCompositorPID glfwWaylandCompositorPID_impl

View file

@ -1237,13 +1237,13 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
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;
bool is_layer_shell = false;
GLFWLayerShellConfig *lsc = NULL, lsc_stack = {0};
if (layer_shell_config && layer_shell_config != Py_None && global_state.is_wayland) {
if (!glfwWaylandIsLayerShellSupported()) {
PyErr_SetString(PyExc_RuntimeError, "The Wayland compositor does not support the layer shell protocol.");
return NULL;
}
is_layer_shell = true;
lsc = &lsc_stack;
} 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); }
@ -1309,7 +1309,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
GLFWwindow *temp_window = NULL;
#ifdef __APPLE__
if (!apple_preserve_common_context) {
apple_preserve_common_context = glfwCreateWindow(640, 480, "kitty", NULL, common_context);
apple_preserve_common_context = glfwCreateWindow(640, 480, "kitty", NULL, common_context, NULL);
}
if (!common_context) common_context = apple_preserve_common_context;
#endif
@ -1326,7 +1326,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
}
}
} else {
temp_window = glfwCreateWindow(640, 480, "temp", NULL, common_context);
temp_window = glfwCreateWindow(640, 480, "temp", NULL, common_context, NULL);
if (temp_window == NULL) { fatal("Failed to create GLFW temp window! This usually happens because of old/broken OpenGL drivers. kitty requires working OpenGL %d.%d drivers.", OPENGL_REQUIRED_VERSION_MAJOR, OPENGL_REQUIRED_VERSION_MINOR); }
get_window_content_scale(temp_window, &xscale, &yscale, &xdpi, &ydpi);
}
@ -1335,13 +1335,11 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
if (ret == NULL) return NULL;
int width = PyLong_AsLong(PyTuple_GET_ITEM(ret, 0)), height = PyLong_AsLong(PyTuple_GET_ITEM(ret, 1));
Py_CLEAR(ret);
if (is_layer_shell) {
GLFWLayerShellConfig lsc = {0};
if (!layer_shell_config_from_python(layer_shell_config, &lsc)) return NULL;
lsc.expected.xdpi = xdpi; lsc.expected.ydpi = ydpi; lsc.expected.xscale = xscale; lsc.expected.yscale = yscale;
glfwWaylandSetupLayerShellForNextWindow(&lsc);
if (lsc) {
if (!layer_shell_config_from_python(layer_shell_config, lsc)) return NULL;
lsc->expected.xdpi = xdpi; lsc->expected.ydpi = ydpi; lsc->expected.xscale = xscale; lsc->expected.yscale = yscale;
}
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, temp_window ? temp_window : common_context);
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, temp_window ? temp_window : common_context, lsc);
if (temp_window) { glfwDestroyWindow(temp_window); temp_window = NULL; }
if (glfw_window == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; }
glfwMakeContextCurrent(glfw_window);
@ -1369,7 +1367,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
float n_xscale, n_yscale;
double n_xdpi, n_ydpi;
get_window_content_scale(glfw_window, &n_xscale, &n_yscale, &n_xdpi, &n_ydpi);
if (n_xdpi != xdpi || n_ydpi != ydpi || is_layer_shell) {
if (n_xdpi != xdpi || n_ydpi != ydpi || lsc) {
// this can happen if the window is moved by the OS to a different monitor when shown or with fractional scales on Wayland
// it can also happen with layer shell windows if the callback is
// called before the window is fully created
@ -1391,9 +1389,9 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
OSWindow *w = add_os_window();
w->handle = glfw_window;
w->disallow_title_changes = disallow_override_title;
w->is_layer_shell = is_layer_shell;
w->is_layer_shell = lsc != NULL;
update_os_window_references();
if (!is_layer_shell) {
if (!w->is_layer_shell) {
for (size_t i = 0; i < global_state.num_os_windows; i++) {
// On some platforms (macOS) newly created windows don't get the initial focus in event
OSWindow *q = global_state.os_windows + i;