Add an option to control the audio bell volume on X11
This commit is contained in:
@@ -34,6 +34,8 @@ version 0.5.1 [2017-12-01]
|
|||||||
|
|
||||||
- Drop the dependency on glfw (kitty now uses a modified, bundled copy of glfw)
|
- Drop the dependency on glfw (kitty now uses a modified, bundled copy of glfw)
|
||||||
|
|
||||||
|
- Add an option to control the audio bell volume on X11 systems
|
||||||
|
|
||||||
|
|
||||||
version 0.5.0 [2017-11-19]
|
version 0.5.0 [2017-11-19]
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|||||||
@@ -152,6 +152,10 @@ cocoa_make_window_resizable(void *w) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cocoa_audio_bell(void) {
|
||||||
|
NSBeep();
|
||||||
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
cocoa_get_lang(PyObject UNUSED *self) {
|
cocoa_get_lang(PyObject UNUSED *self) {
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ type_map = {
|
|||||||
'macos_hide_titlebar': to_bool,
|
'macos_hide_titlebar': to_bool,
|
||||||
'macos_option_as_alt': to_bool,
|
'macos_option_as_alt': to_bool,
|
||||||
'box_drawing_scale': box_drawing_scale,
|
'box_drawing_scale': box_drawing_scale,
|
||||||
|
'x11_bell_volume': int,
|
||||||
}
|
}
|
||||||
|
|
||||||
for name in (
|
for name in (
|
||||||
|
|||||||
@@ -272,4 +272,4 @@ void scroll_event(double, double);
|
|||||||
void set_special_key_combo(int glfw_key, int mods);
|
void set_special_key_combo(int glfw_key, int mods);
|
||||||
void on_text_input(unsigned int codepoint, int mods);
|
void on_text_input(unsigned int codepoint, int mods);
|
||||||
void on_key_input(int key, int scancode, int action, int mods);
|
void on_key_input(int key, int scancode, int action, int mods);
|
||||||
void request_window_attention(id_type);
|
void request_window_attention(id_type, bool);
|
||||||
|
|||||||
50
kitty/glfw.c
50
kitty/glfw.c
@@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include "glfw-wrapper.h"
|
#include "glfw-wrapper.h"
|
||||||
extern bool cocoa_make_window_resizable(void *w);
|
extern bool cocoa_make_window_resizable(void *w);
|
||||||
extern void cocoa_create_global_menu(void);
|
extern void cocoa_create_global_menu(void);
|
||||||
|
extern void cocoa_audio_bell(void);
|
||||||
|
|
||||||
#if GLFW_KEY_LAST >= MAX_KEY_COUNT
|
#if GLFW_KEY_LAST >= MAX_KEY_COUNT
|
||||||
#error "glfw has too many keys, you should increase MAX_KEY_COUNT"
|
#error "glfw has too many keys, you should increase MAX_KEY_COUNT"
|
||||||
@@ -31,6 +33,23 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) {
|
|||||||
window->last_resize_at = monotonic();
|
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 {{{
|
// callbacks {{{
|
||||||
|
|
||||||
@@ -327,6 +346,7 @@ glfw_init(PyObject UNUSED *self, PyObject *args) {
|
|||||||
PyObject*
|
PyObject*
|
||||||
glfw_terminate(PyObject UNUSED *self) {
|
glfw_terminate(PyObject UNUSED *self) {
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
load_libX11(true);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,10 +497,38 @@ toggle_fullscreen(PyObject UNUSED *self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ring_audio_bell(OSWindow *w) {
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
request_window_attention(id_type kitty_window_id) {
|
request_window_attention(id_type kitty_window_id, bool audio_bell) {
|
||||||
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
||||||
if (w) {
|
if (w) {
|
||||||
|
if (audio_bell) ring_audio_bell(w);
|
||||||
glfwRequestWindowAttention(w->handle);
|
glfwRequestWindowAttention(w->handle);
|
||||||
glfwPostEmptyEvent();
|
glfwPostEmptyEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,3 +331,7 @@ macos_hide_titlebar no
|
|||||||
# break any Alt+key keyboard shortcuts in your terminal programs, but you
|
# break any Alt+key keyboard shortcuts in your terminal programs, but you
|
||||||
# can use the macOS unicode input technique.
|
# can use the macOS unicode input technique.
|
||||||
macos_option_as_alt yes
|
macos_option_as_alt yes
|
||||||
|
|
||||||
|
# The number is a percentage of maximum volume.
|
||||||
|
# See man XBell for details.
|
||||||
|
x11_bell_volume 80
|
||||||
|
|||||||
@@ -1009,22 +1009,7 @@ screen_invert_colors(Screen *self) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
screen_bell(Screen *self) {
|
screen_bell(Screen *self) {
|
||||||
if (global_state.opts.enable_audio_bell) {
|
request_window_attention(self->window_id, OPT(enable_audio_bell));
|
||||||
int fd = open("/dev/tty", O_WRONLY | O_CLOEXEC | O_NOCTTY);
|
|
||||||
if (fd > 0) {
|
|
||||||
static const char bell[2] = {7, 0};
|
|
||||||
while(true) {
|
|
||||||
if (write(fd, &bell, sizeof(bell)) == sizeof(bell)) break;
|
|
||||||
if (errno == EINTR) continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (global_state.opts.visual_bell_duration > 0) {
|
|
||||||
self->start_visual_bell_at = monotonic();
|
|
||||||
}
|
|
||||||
request_window_attention(self->window_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -308,6 +308,7 @@ PYWRAP1(set_options) {
|
|||||||
S(cursor_blink_interval, PyFloat_AsDouble);
|
S(cursor_blink_interval, PyFloat_AsDouble);
|
||||||
S(cursor_stop_blinking_after, PyFloat_AsDouble);
|
S(cursor_stop_blinking_after, PyFloat_AsDouble);
|
||||||
S(cursor_shape, PyLong_AsLong);
|
S(cursor_shape, PyLong_AsLong);
|
||||||
|
S(x11_bell_volume, PyLong_AsLong);
|
||||||
S(mouse_hide_wait, PyFloat_AsDouble);
|
S(mouse_hide_wait, PyFloat_AsDouble);
|
||||||
S(wheel_scroll_multiplier, PyFloat_AsDouble);
|
S(wheel_scroll_multiplier, PyFloat_AsDouble);
|
||||||
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
S(open_url_modifiers, PyLong_AsUnsignedLong);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ typedef struct {
|
|||||||
bool focus_follows_mouse;
|
bool focus_follows_mouse;
|
||||||
bool macos_option_as_alt, macos_hide_titlebar;
|
bool macos_option_as_alt, macos_hide_titlebar;
|
||||||
int adjust_line_height_px;
|
int adjust_line_height_px;
|
||||||
|
int x11_bell_volume;
|
||||||
float adjust_line_height_frac;
|
float adjust_line_height_frac;
|
||||||
} Options;
|
} Options;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user