diff --git a/docs/custom-shaders.rst b/docs/custom-shaders.rst index 2d7e3f429..7b773d48d 100644 --- a/docs/custom-shaders.rst +++ b/docs/custom-shaders.rst @@ -321,6 +321,11 @@ be combined with ``|`` — any one of them will trigger the action. * - ``bell-in-window`` - A bell (BEL character) is received in any kitty window. + The geometry of the window in which the most recent bell occurred is + available in ``d.bell_window_geometry`` (UV co-ordinates, origin + bottom-left; ``.xy`` = lower-left corner, ``.zw`` = width and height). + If that window is not currently visible in the active tab or layout, + ``d.bell_window_geometry`` equals ``d.central_area``. * - ``user-activity`` - Any keyboard or mouse input is received. diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 960e4183e..bcfeb949e 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -907,8 +907,10 @@ prepare_to_render_os_window( } if (send_cell_data_to_gpu(WD.vao_idx, WD.screen, os_window)) needs_render = true; if (WD.screen->start_visual_bell_at | WD.screen->start_drag_overlay_at) needs_render = true; - if (WD.screen->start_visual_bell_at && WD.screen->start_visual_bell_at > os_window->last_rendered_at) + if (WD.screen->start_visual_bell_at && WD.screen->start_visual_bell_at > os_window->last_rendered_at) { os_window->shader_anim_event_registry |= (1u << SHADER_ANIM_EVENT_BELL_IN_WINDOW); + os_window->last_bell_window_id = w->id; + } // Prepare window title bar screen data for GPU WindowRenderData *trd = &w->window_title_render_data; if (trd->screen && trd->geometry.bottom > trd->geometry.top && trd->geometry.right > trd->geometry.left) { diff --git a/kitty/shaders.c b/kitty/shaders.c index ad57939ec..cceca119f 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -2359,6 +2359,7 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now) float mouse_pos[4]; float mouse_button_pressed[4]; float active_window_geometry[4]; + float bell_window_geometry[4]; float central_area[4]; float cursor_trail_corners_x[4]; float cursor_trail_corners_y[4]; @@ -2486,6 +2487,27 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now) d->central_area[2] = 1.f; d->central_area[3] = 1.f; } + if (os_window->last_bell_window_id && os_window->num_tabs > 0 && vpw > 0 && vph > 0) { + WindowGeometry bell_win_geom = {0}; + bool bell_win_found = false; + Tab *bt = os_window->tabs + os_window->active_tab; + for (unsigned i = 0; i < bt->num_windows; i++) { + Window *bw = bt->windows + i; + if (bw->id == os_window->last_bell_window_id && bw->visible) { + bell_win_geom = bw->render_data.geometry; + bell_win_found = true; + break; + } + } + if (bell_win_found && bell_win_geom.right > bell_win_geom.left) { + d->bell_window_geometry[0] = (float)bell_win_geom.left / vpw; + d->bell_window_geometry[1] = 1.f - (float)bell_win_geom.bottom / vph; + d->bell_window_geometry[2] = (float)(bell_win_geom.right - bell_win_geom.left) / vpw; + d->bell_window_geometry[3] = (float)(bell_win_geom.bottom - bell_win_geom.top) / vph; + } else { + memcpy(d->bell_window_geometry, d->central_area, sizeof(d->bell_window_geometry)); + } + } unmap_vao_buffer(custom_end_vao_idx, 0); bind_vao_uniform_buffer(custom_end_vao_idx, 0, CUSTOM_END_DATA_BINDING_POINT); diff --git a/kitty/shaders/custom/types.slang b/kitty/shaders/custom/types.slang index 9e0d079af..2ab0f61ca 100644 --- a/kitty/shaders/custom/types.slang +++ b/kitty/shaders/custom/types.slang @@ -22,6 +22,11 @@ public struct KittyCustomShaderData { // .xy = lower-left corner of the window, .zw = width and height. // All components are zero when no active window was rendered this frame. public float4 active_window_geometry; + // Geometry of the most recently belled window in UV co-ordinates (origin bottom-left). + // .xy = lower-left corner of the window, .zw = width and height. + // If the belled window is not currently visible in the active tab/layout, equals central_area. + // All components are zero until the first bell-in-window event occurs. + public float4 bell_window_geometry; // Geometry of the central content area of the OS window (the tab area, excluding any tab bar) // in UV co-ordinates (origin bottom-left). // .xy = lower-left corner, .zw = width and height. diff --git a/kitty/state.h b/kitty/state.h index a47eb0aa1..38aaf8196 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -563,6 +563,7 @@ typedef struct OSWindow { int last_v120_dir_x, last_v120_dir_y; } scroll; unsigned shader_anim_event_registry; + id_type last_bell_window_id; // ID of the most recent window that received a bell event struct { bool active; monotonic_t started_at;