mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-24 17:27:39 +02:00
Infrastructure for hiding OS Window on focus lost
This commit is contained in:
@@ -1736,6 +1736,7 @@ def set_redirect_keys_to_overlay(os_window_id: int, tab_id: int, window_id: int,
|
|||||||
def buffer_keys_in_window(os_window_id: int, tab_id: int, window_id: int, enabled: bool = True) -> bool: ...
|
def buffer_keys_in_window(os_window_id: int, tab_id: int, window_id: int, enabled: bool = True) -> bool: ...
|
||||||
def sprite_idx_to_pos(idx: int, xnum: int, ynum: int) -> tuple[int, int, int]: ...
|
def sprite_idx_to_pos(idx: int, xnum: int, ynum: int) -> tuple[int, int, int]: ...
|
||||||
def render_box_char(ch: int, width: int, height: int, scale: float = 1.0, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ...
|
def render_box_char(ch: int, width: int, height: int, scale: float = 1.0, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ...
|
||||||
|
def set_os_window_hide_on_focus_lost(os_window_id: int, hide: bool = True) -> bool: ...
|
||||||
def run_at_exit_cleanup_functions() -> None: ...
|
def run_at_exit_cleanup_functions() -> None: ...
|
||||||
DecorationTypes = Literal[
|
DecorationTypes = Literal[
|
||||||
'curl', 'dashed', 'dotted', 'double', 'straight', 'strikethrough', 'beam_cursor', 'underline_cursor', 'hollow_cursor', 'missing']
|
'curl', 'dashed', 'dotted', 'double', 'straight', 'strikethrough', 'beam_cursor', 'underline_cursor', 'hollow_cursor', 'missing']
|
||||||
|
|||||||
64
kitty/glfw.c
64
kitty/glfw.c
@@ -315,7 +315,7 @@ static void
|
|||||||
cocoa_out_of_sequence_render(OSWindow *window) {
|
cocoa_out_of_sequence_render(OSWindow *window) {
|
||||||
make_os_window_context_current(window);
|
make_os_window_context_current(window);
|
||||||
window->needs_render = true;
|
window->needs_render = true;
|
||||||
bool rendered = render_os_window(window, monotonic(), true, true);
|
bool rendered = render_os_window(window, monotonic(), true);
|
||||||
if (!rendered) {
|
if (!rendered) {
|
||||||
blank_os_window(window);
|
blank_os_window(window);
|
||||||
swap_window_buffers(window);
|
swap_window_buffers(window);
|
||||||
@@ -551,32 +551,51 @@ scroll_callback(GLFWwindow *w, double xoffset, double yoffset, int flags, int mo
|
|||||||
|
|
||||||
static id_type focus_counter = 0;
|
static id_type focus_counter = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_os_window_visibility(OSWindow *w, int set_visible) {
|
||||||
|
if (set_visible) {
|
||||||
|
glfwShowWindow(w->handle);
|
||||||
|
w->needs_render = true;
|
||||||
|
w->keep_rendering_till_swap = 256; // try this many times
|
||||||
|
request_tick_callback();
|
||||||
|
} else glfwHideWindow(w->handle);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_focus_callback(GLFWwindow *w, int focused) {
|
window_focus_callback(GLFWwindow *w, int focused) {
|
||||||
if (!set_callback_window(w)) return;
|
if (!set_callback_window(w)) return;
|
||||||
debug_input("\x1b[35mon_focus_change\x1b[m: window id: 0x%llu focused: %d\n", global_state.callback_os_window->id, focused);
|
#define osw global_state.callback_os_window
|
||||||
global_state.callback_os_window->is_focused = focused ? true : false;
|
debug_input("\x1b[35mon_focus_change\x1b[m: window id: 0x%llu focused: %d\n", osw->id, focused);
|
||||||
|
osw->is_focused = focused ? true : false;
|
||||||
monotonic_t now = monotonic();
|
monotonic_t now = monotonic();
|
||||||
|
id_type wid = osw->id;
|
||||||
if (focused) {
|
if (focused) {
|
||||||
cursor_active_callback(w, now);
|
cursor_active_callback(w, now);
|
||||||
focus_in_event();
|
focus_in_event();
|
||||||
global_state.callback_os_window->last_focused_counter = ++focus_counter;
|
osw->last_focused_counter = ++focus_counter;
|
||||||
global_state.check_for_active_animated_images = true;
|
global_state.check_for_active_animated_images = true;
|
||||||
}
|
}
|
||||||
global_state.callback_os_window->last_mouse_activity_at = now;
|
osw->last_mouse_activity_at = now;
|
||||||
global_state.callback_os_window->cursor_blink_zero_time = now;
|
osw->cursor_blink_zero_time = now;
|
||||||
if (is_window_ready_for_callbacks()) {
|
if (is_window_ready_for_callbacks()) {
|
||||||
WINDOW_CALLBACK(on_focus, "O", focused ? Py_True : Py_False);
|
WINDOW_CALLBACK(on_focus, "O", focused ? Py_True : Py_False);
|
||||||
GLFWIMEUpdateEvent ev = { .type = GLFW_IME_UPDATE_FOCUS, .focused = focused };
|
if (!osw || osw->id != wid) osw = os_window_for_id(wid);
|
||||||
glfwUpdateIMEState(global_state.callback_os_window->handle, &ev);
|
if (osw) {
|
||||||
if (focused) {
|
GLFWIMEUpdateEvent ev = { .type = GLFW_IME_UPDATE_FOCUS, .focused = focused };
|
||||||
Tab *tab = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab;
|
glfwUpdateIMEState(osw->handle, &ev);
|
||||||
Window *window = tab->windows + tab->active_window;
|
if (focused) {
|
||||||
if (window->render_data.screen) update_ime_position(window, window->render_data.screen);
|
Tab *tab = osw->tabs + osw->active_tab;
|
||||||
|
Window *window = tab->windows + tab->active_window;
|
||||||
|
if (window->render_data.screen) update_ime_position(window, window->render_data.screen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request_tick_callback();
|
request_tick_callback();
|
||||||
global_state.callback_os_window = NULL;
|
if (osw && osw->hide_on_focus_lost && osw->handle) {
|
||||||
|
if (glfwGetWindowAttrib(osw->handle, GLFW_VISIBLE)) set_os_window_visibility(osw, 0);
|
||||||
|
}
|
||||||
|
osw = NULL;
|
||||||
|
#undef osw
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2462,12 +2481,7 @@ toggle_os_window_visibility(PyObject *self UNUSED, PyObject *args) {
|
|||||||
bool is_visible = glfwGetWindowAttrib(w->handle, GLFW_VISIBLE) != 0;
|
bool is_visible = glfwGetWindowAttrib(w->handle, GLFW_VISIBLE) != 0;
|
||||||
if (set_visible == -1) set_visible = !is_visible;
|
if (set_visible == -1) set_visible = !is_visible;
|
||||||
else if (set_visible == is_visible) Py_RETURN_FALSE;
|
else if (set_visible == is_visible) Py_RETURN_FALSE;
|
||||||
if (set_visible) {
|
set_os_window_visibility(w, set_visible);
|
||||||
glfwShowWindow(w->handle);
|
|
||||||
w->needs_render = true;
|
|
||||||
w->keep_rendering_till_swap = 256; // try this many times
|
|
||||||
request_tick_callback();
|
|
||||||
} else glfwHideWindow(w->handle);
|
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2499,11 +2513,23 @@ set_layer_shell_config(PyObject *self UNUSED, PyObject *args) {
|
|||||||
return Py_NewRef(set_layer_shell_config_for(window, &lsc) ? Py_True : Py_False);
|
return Py_NewRef(set_layer_shell_config_for(window, &lsc) ? Py_True : Py_False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
set_os_window_hide_on_focus_lost(PyObject *self UNUSED, PyObject *args) {
|
||||||
|
unsigned long long wid; int val = 1;
|
||||||
|
if (!PyArg_ParseTuple(args, "K|p", &wid, &val)) return NULL;
|
||||||
|
OSWindow *window = os_window_for_id(wid);
|
||||||
|
if (!window) Py_RETURN_FALSE;
|
||||||
|
window->hide_on_focus_lost = val;
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Boilerplate {{{
|
// Boilerplate {{{
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
METHODB(set_custom_cursor, METH_VARARGS),
|
METHODB(set_custom_cursor, METH_VARARGS),
|
||||||
METHODB(is_css_pointer_name_valid, METH_O),
|
METHODB(is_css_pointer_name_valid, METH_O),
|
||||||
|
METHODB(set_os_window_hide_on_focus_lost, METH_O),
|
||||||
METHODB(toggle_os_window_visibility, METH_VARARGS),
|
METHODB(toggle_os_window_visibility, METH_VARARGS),
|
||||||
METHODB(layer_shell_config_for_os_window, METH_O),
|
METHODB(layer_shell_config_for_os_window, METH_O),
|
||||||
METHODB(set_layer_shell_config, METH_VARARGS),
|
METHODB(set_layer_shell_config, METH_VARARGS),
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ typedef struct {
|
|||||||
id_type last_focused_counter;
|
id_type last_focused_counter;
|
||||||
CloseRequest close_request;
|
CloseRequest close_request;
|
||||||
bool is_layer_shell;
|
bool is_layer_shell;
|
||||||
|
bool hide_on_focus_lost;
|
||||||
} OSWindow;
|
} OSWindow;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user