From a5078afd1eb9e840b92bfe701fa3e38249cd8ae7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 20 Nov 2017 23:03:27 +0530 Subject: [PATCH] Move the bell implementation into glfw --- glfw/cocoa_window.m | 6 ++++++ glfw/glfw3.h | 27 +++++++++++++++++++++++++++ glfw/internal.h | 1 + glfw/null_window.c | 5 +++++ glfw/win32_window.c | 5 +++++ glfw/window.c | 10 ++++++++++ glfw/wl_window.c | 8 ++++++++ glfw/x11_window.c | 5 +++++ kitty/cocoa_window.m | 5 ----- kitty/glfw-wrapper.c | 3 +++ kitty/glfw-wrapper.h | 4 ++++ kitty/glfw.c | 43 ++----------------------------------------- 12 files changed, 76 insertions(+), 46 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index af1de09b9..faa22c255 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1350,6 +1350,12 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) [NSApp requestUserAttention:NSInformationalRequest]; } +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t param) +{ + NSBeep(); + return GLFW_TRUE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { // Make us the active application diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 67c2d495b..069aa794d 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -3086,6 +3086,33 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window); */ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window); +/*! @brief Sounds an audible bell associated with the window + * + * This function sounds an audible bell, on platforms where it is + * supported. Currently (macOS, Windows and X11). + * + * @param[in] window The window with which the bell is associated. + * @param[in] param The meaning of this parameter is platform dependent. On + * X11 it corresponds to the percentage controlling bell volume (see man + * XBell). On Windows it is the type of sound to make, see the MSDN docs for + * MessageBeep. On macOS, it is ignored. + * @return GLFW_TRUE if the bell succeeded otherwise GLFW_FALSE + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos Bell is associated to the application as a whole, not the + * specific window. + * + * @thread_safety This function must only be called from the main thread. + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI int glfwWindowBell(GLFWwindow* window, int64_t param); + + /*! @brief Returns the monitor that the window uses for full screen mode. * * This function returns the handle of the monitor that the specified window is diff --git a/glfw/internal.h b/glfw/internal.h index 463049252..488880279 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -680,6 +680,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window); void _glfwPlatformShowWindow(_GLFWwindow* window); void _glfwPlatformHideWindow(_GLFWwindow* window); void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t); void _glfwPlatformFocusWindow(_GLFWwindow* window); void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); int _glfwPlatformWindowFocused(_GLFWwindow* window); diff --git a/glfw/null_window.c b/glfw/null_window.c index 6eb4ac6e2..5ca1e1c5a 100644 --- a/glfw/null_window.c +++ b/glfw/null_window.c @@ -200,6 +200,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { } +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t param) +{ + return GLFW_FALSE; +} + void _glfwPlatformUnhideWindow(_GLFWwindow* window) { } diff --git a/glfw/win32_window.c b/glfw/win32_window.c index 1aa3213e7..810e83322 100644 --- a/glfw/win32_window.c +++ b/glfw/win32_window.c @@ -1456,6 +1456,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) FlashWindow(window->win32.handle, TRUE); } +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t param) +{ + return MessageBeep(0xFFFFFFFF & param) ? GLFW_TRUE : GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { BringWindowToTop(window->win32.handle); diff --git a/glfw/window.c b/glfw/window.c index f4468e169..7807717f3 100644 --- a/glfw/window.c +++ b/glfw/window.c @@ -731,6 +731,16 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) _glfwPlatformRequestWindowAttention(window); } +GLFWAPI int glfwWindowBell(GLFWwindow* handle, int64_t param) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + + return _glfwPlatformWindowBell(window, param); +} + GLFWAPI void glfwHideWindow(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index b2ae7aae2..af5793f28 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -618,6 +618,14 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) "Wayland: Window attention request not implemented yet"); } +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t param) +{ + // TODO + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Window bell request not implemented yet"); + return GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 0cc49d744..1e62b5658 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -2357,6 +2357,11 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) 0, 1, 0); } +int _glfwPlatformWindowBell(_GLFWwindow* window, int64_t param) +{ + return XkbBell(_glfw.x11.display, window->x11.handle, (int)param, (Atom)0) ? GLFW_TRUE : GLFW_FALSE; +} + void _glfwPlatformFocusWindow(_GLFWwindow* window) { if (_glfw.x11.NET_ACTIVE_WINDOW) diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 4e43acb8f..d24d6e2a0 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -152,11 +152,6 @@ cocoa_make_window_resizable(void *w) { return true; } -void -cocoa_audio_bell(void) { - NSBeep(); -} - PyObject* cocoa_get_lang(PyObject UNUSED *self) { NSString* locale = nil; diff --git a/kitty/glfw-wrapper.c b/kitty/glfw-wrapper.c index 93bd22111..1739cad02 100644 --- a/kitty/glfw-wrapper.c +++ b/kitty/glfw-wrapper.c @@ -152,6 +152,9 @@ load_glfw(const char* path) { *(void **) (&glfwRequestWindowAttention_impl) = dlsym(handle, "glfwRequestWindowAttention"); if (glfwRequestWindowAttention_impl == NULL) fail("Failed to load glfw function glfwRequestWindowAttention with error: %s", dlerror()); + *(void **) (&glfwWindowBell_impl) = dlsym(handle, "glfwWindowBell"); + if (glfwWindowBell_impl == NULL) fail("Failed to load glfw function glfwWindowBell with error: %s", dlerror()); + *(void **) (&glfwGetWindowMonitor_impl) = dlsym(handle, "glfwGetWindowMonitor"); if (glfwGetWindowMonitor_impl == NULL) fail("Failed to load glfw function glfwGetWindowMonitor with error: %s", dlerror()); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 52ae153b2..12e3e7b6b 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1531,6 +1531,10 @@ typedef void (*glfwRequestWindowAttention_func)(GLFWwindow*); glfwRequestWindowAttention_func glfwRequestWindowAttention_impl; #define glfwRequestWindowAttention glfwRequestWindowAttention_impl +typedef int (*glfwWindowBell_func)(GLFWwindow*, int64_t); +glfwWindowBell_func glfwWindowBell_impl; +#define glfwWindowBell glfwWindowBell_impl + typedef GLFWmonitor* (*glfwGetWindowMonitor_func)(GLFWwindow*); glfwGetWindowMonitor_func glfwGetWindowMonitor_impl; #define glfwGetWindowMonitor glfwGetWindowMonitor_impl diff --git a/kitty/glfw.c b/kitty/glfw.c index 21247daaa..8ec83cfa0 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -10,7 +10,6 @@ #include "glfw-wrapper.h" extern bool cocoa_make_window_resizable(void *w); extern void cocoa_create_global_menu(void); -extern void cocoa_audio_bell(void); #if GLFW_KEY_LAST >= MAX_KEY_COUNT #error "glfw has too many keys, you should increase MAX_KEY_COUNT" @@ -33,23 +32,6 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) { window->last_resize_at = monotonic(); } -static void* -load_libX11(bool unload) { - static void* ans = NULL; - static bool tried = false; - if (unload) { if (ans) { dlclose(ans); ans = NULL; }; return NULL; } - if (!tried) { - tried = true; - ans = dlopen("libX11.so", RTLD_LAZY); - if (ans == NULL) fprintf(stderr, "Failed to load libX11.so with error: %s\n", dlerror()); - } - return ans; -} - -typedef bool (*xkb_bell_func)(void*, int32_t, int, void*); -xkb_bell_func xkb_bell = NULL; - - // callbacks {{{ @@ -346,7 +328,6 @@ glfw_init(PyObject UNUSED *self, PyObject *args) { PyObject* glfw_terminate(PyObject UNUSED *self) { glfwTerminate(); - load_libX11(true); Py_RETURN_NONE; } @@ -494,29 +475,9 @@ ring_audio_bell(OSWindow *w) { double now = monotonic(); if (now - last_bell_at <= 0.1) return; last_bell_at = now; -#ifdef __APPLE__ - (void)w; - cocoa_audio_bell(); -#else - if (glfwGetX11Display) { - static bool tried = false; - if (!tried) { - tried = true; - void *lib = load_libX11(false); - if (lib) { - *(void **) (&xkb_bell) = dlsym(lib, "XkbBell"); - if (!xkb_bell) fprintf(stderr, "Failed to load the XkbBell function with error: %s\n", dlerror()); - } - } - if (xkb_bell) { - void* display = glfwGetX11Display(); - int32_t x11win = glfwGetX11Window(w->handle); - if (display) { - xkb_bell(display, x11win, OPT(x11_bell_volume), NULL); - } - } + if (w->handle) { + glfwWindowBell(w->handle, OPT(x11_bell_volume)); } -#endif } void