Infrastructure for close confirmation
This commit is contained in:
parent
2e63a4c83f
commit
3c8640f9ad
@ -724,6 +724,9 @@ class Boss:
|
|||||||
text = '\n'.join(parse_uri_list(text))
|
text = '\n'.join(parse_uri_list(text))
|
||||||
w.paste(text)
|
w.paste(text)
|
||||||
|
|
||||||
|
def confirm_os_window_close(self, os_window_id: int) -> None:
|
||||||
|
mark_os_window_for_close(os_window_id)
|
||||||
|
|
||||||
def on_os_window_closed(self, os_window_id: int, viewport_width: int, viewport_height: int) -> None:
|
def on_os_window_closed(self, os_window_id: int, viewport_width: int, viewport_height: int) -> None:
|
||||||
self.cached_values['window-size'] = viewport_width, viewport_height
|
self.cached_values['window-size'] = viewport_width, viewport_height
|
||||||
tm = self.os_window_map.pop(os_window_id, None)
|
tm = self.os_window_map.pop(os_window_id, None)
|
||||||
|
|||||||
@ -865,25 +865,42 @@ process_pending_resizes(monotonic_t now) {
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
close_all_windows(void) {
|
close_all_windows(void) {
|
||||||
for (size_t w = 0; w < global_state.num_os_windows; w++) mark_os_window_for_close(&global_state.os_windows[w], true);
|
for (size_t w = 0; w < global_state.num_os_windows; w++) mark_os_window_for_close(&global_state.os_windows[w], IMPERATIVE_CLOSE_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
close_os_window(ChildMonitor *self, OSWindow *os_window) {
|
||||||
|
destroy_os_window(os_window);
|
||||||
|
call_boss(on_os_window_closed, "Kii", os_window->id, os_window->window_width, os_window->window_height);
|
||||||
|
for (size_t t=0; t < os_window->num_tabs; t++) {
|
||||||
|
Tab *tab = os_window->tabs + t;
|
||||||
|
for (size_t w = 0; w < tab->num_windows; w++) mark_child_for_close(self, tab->windows[w].id);
|
||||||
|
}
|
||||||
|
remove_os_window(os_window->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
process_pending_closes(ChildMonitor *self) {
|
process_pending_closes(ChildMonitor *self) {
|
||||||
global_state.has_pending_closes = false;
|
|
||||||
bool has_open_windows = false;
|
bool has_open_windows = false;
|
||||||
for (size_t w = global_state.num_os_windows; w > 0; w--) {
|
for (size_t w = global_state.num_os_windows; w > 0; w--) {
|
||||||
OSWindow *os_window = global_state.os_windows + w - 1;
|
OSWindow *os_window = global_state.os_windows + w - 1;
|
||||||
if (should_os_window_close(os_window)) {
|
switch(os_window->close_request) {
|
||||||
destroy_os_window(os_window);
|
case NO_CLOSE_REQUESTED:
|
||||||
call_boss(on_os_window_closed, "Kii", os_window->id, os_window->window_width, os_window->window_height);
|
has_open_windows = true;
|
||||||
for (size_t t=0; t < os_window->num_tabs; t++) {
|
break;
|
||||||
Tab *tab = os_window->tabs + t;
|
case CONFIRMABLE_CLOSE_REQUESTED:
|
||||||
for (size_t w = 0; w < tab->num_windows; w++) mark_child_for_close(self, tab->windows[w].id);
|
os_window->close_request = NO_CLOSE_REQUESTED;
|
||||||
}
|
call_boss(confirm_os_window_close, "K", os_window->id);
|
||||||
remove_os_window(os_window->id);
|
if (os_window->close_request == IMPERATIVE_CLOSE_REQUESTED) {
|
||||||
} else has_open_windows = true;
|
close_os_window(self, os_window);
|
||||||
|
} else has_open_windows = true;
|
||||||
|
break;
|
||||||
|
case IMPERATIVE_CLOSE_REQUESTED:
|
||||||
|
close_os_window(self, os_window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
global_state.has_pending_closes = false;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (!OPT(macos_quit_when_last_window_closed)) {
|
if (!OPT(macos_quit_when_last_window_closed)) {
|
||||||
if (!has_open_windows && !application_quit_requested()) has_open_windows = true;
|
if (!has_open_windows && !application_quit_requested()) has_open_windows = true;
|
||||||
|
|||||||
15
kitty/glfw.c
15
kitty/glfw.c
@ -153,6 +153,10 @@ static void
|
|||||||
window_close_callback(GLFWwindow* window) {
|
window_close_callback(GLFWwindow* window) {
|
||||||
if (!set_callback_window(window)) return;
|
if (!set_callback_window(window)) return;
|
||||||
global_state.has_pending_closes = true;
|
global_state.has_pending_closes = true;
|
||||||
|
if (global_state.callback_os_window->close_request < CONFIRMABLE_CLOSE_REQUESTED) {
|
||||||
|
global_state.callback_os_window->close_request = CONFIRMABLE_CLOSE_REQUESTED;
|
||||||
|
}
|
||||||
|
glfwSetWindowShouldClose(window, false);
|
||||||
request_tick_callback();
|
request_tick_callback();
|
||||||
global_state.callback_os_window = NULL;
|
global_state.callback_os_window = NULL;
|
||||||
}
|
}
|
||||||
@ -973,12 +977,6 @@ wakeup_main_loop() {
|
|||||||
glfwPostEmptyEvent();
|
glfwPostEmptyEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
mark_os_window_for_close(OSWindow* w, bool yes) {
|
|
||||||
global_state.has_pending_closes = true;
|
|
||||||
glfwSetWindowShouldClose(w->handle, yes);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
should_os_window_be_rendered(OSWindow* w) {
|
should_os_window_be_rendered(OSWindow* w) {
|
||||||
return (
|
return (
|
||||||
@ -988,11 +986,6 @@ should_os_window_be_rendered(OSWindow* w) {
|
|||||||
) ? false : true;
|
) ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
should_os_window_close(OSWindow* w) {
|
|
||||||
return glfwWindowShouldClose(w->handle) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
primary_monitor_size(PYNOARG) {
|
primary_monitor_size(PYNOARG) {
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
|
|||||||
@ -423,6 +423,14 @@ os_window_regions(OSWindow *os_window, Region *central, Region *tab_bar) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mark_os_window_for_close(OSWindow* w, CloseRequest cr) {
|
||||||
|
global_state.has_pending_closes = true;
|
||||||
|
w->close_request = cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Python API {{{
|
// Python API {{{
|
||||||
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
||||||
@ -784,10 +792,10 @@ PYWRAP1(os_window_has_background_image) {
|
|||||||
|
|
||||||
PYWRAP1(mark_os_window_for_close) {
|
PYWRAP1(mark_os_window_for_close) {
|
||||||
id_type os_window_id;
|
id_type os_window_id;
|
||||||
int yes = 1;
|
CloseRequest cr = IMPERATIVE_CLOSE_REQUESTED;
|
||||||
PA("K|p", &os_window_id, &yes);
|
PA("K|i", &os_window_id, &cr);
|
||||||
WITH_OS_WINDOW(os_window_id)
|
WITH_OS_WINDOW(os_window_id)
|
||||||
mark_os_window_for_close(os_window, yes ? true : false);
|
mark_os_window_for_close(os_window, cr);
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
END_WITH_OS_WINDOW
|
END_WITH_OS_WINDOW
|
||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
|
|||||||
@ -139,6 +139,7 @@ typedef struct {
|
|||||||
} OSWindowGeometry;
|
} OSWindowGeometry;
|
||||||
|
|
||||||
enum RENDER_STATE { RENDER_FRAME_NOT_REQUESTED, RENDER_FRAME_REQUESTED, RENDER_FRAME_READY };
|
enum RENDER_STATE { RENDER_FRAME_NOT_REQUESTED, RENDER_FRAME_REQUESTED, RENDER_FRAME_READY };
|
||||||
|
typedef enum { NO_CLOSE_REQUESTED, CONFIRMABLE_CLOSE_REQUESTED, IMPERATIVE_CLOSE_REQUESTED } CloseRequest;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
monotonic_t last_resize_event_at;
|
monotonic_t last_resize_event_at;
|
||||||
@ -183,6 +184,7 @@ typedef struct {
|
|||||||
uint64_t render_calls;
|
uint64_t render_calls;
|
||||||
id_type last_focused_counter;
|
id_type last_focused_counter;
|
||||||
ssize_t gvao_idx;
|
ssize_t gvao_idx;
|
||||||
|
CloseRequest close_request;
|
||||||
} OSWindow;
|
} OSWindow;
|
||||||
|
|
||||||
|
|
||||||
@ -220,9 +222,8 @@ void remove_vao(ssize_t vao_idx);
|
|||||||
bool remove_os_window(id_type os_window_id);
|
bool remove_os_window(id_type os_window_id);
|
||||||
void make_os_window_context_current(OSWindow *w);
|
void make_os_window_context_current(OSWindow *w);
|
||||||
void update_os_window_references(void);
|
void update_os_window_references(void);
|
||||||
void mark_os_window_for_close(OSWindow* w, bool yes);
|
void mark_os_window_for_close(OSWindow* w, CloseRequest cr);
|
||||||
void update_os_window_viewport(OSWindow *window, bool);
|
void update_os_window_viewport(OSWindow *window, bool);
|
||||||
bool should_os_window_close(OSWindow* w);
|
|
||||||
bool should_os_window_be_rendered(OSWindow* w);
|
bool should_os_window_be_rendered(OSWindow* w);
|
||||||
void wakeup_main_loop(void);
|
void wakeup_main_loop(void);
|
||||||
void swap_window_buffers(OSWindow *w);
|
void swap_window_buffers(OSWindow *w);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user