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))
|
||||
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:
|
||||
self.cached_values['window-size'] = viewport_width, viewport_height
|
||||
tm = self.os_window_map.pop(os_window_id, None)
|
||||
|
||||
@ -865,25 +865,42 @@ process_pending_resizes(monotonic_t now) {
|
||||
|
||||
static inline 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
|
||||
process_pending_closes(ChildMonitor *self) {
|
||||
global_state.has_pending_closes = false;
|
||||
bool has_open_windows = false;
|
||||
for (size_t w = global_state.num_os_windows; w > 0; w--) {
|
||||
OSWindow *os_window = global_state.os_windows + w - 1;
|
||||
if (should_os_window_close(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);
|
||||
} else has_open_windows = true;
|
||||
switch(os_window->close_request) {
|
||||
case NO_CLOSE_REQUESTED:
|
||||
has_open_windows = true;
|
||||
break;
|
||||
case CONFIRMABLE_CLOSE_REQUESTED:
|
||||
os_window->close_request = NO_CLOSE_REQUESTED;
|
||||
call_boss(confirm_os_window_close, "K", os_window->id);
|
||||
if (os_window->close_request == IMPERATIVE_CLOSE_REQUESTED) {
|
||||
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__
|
||||
if (!OPT(macos_quit_when_last_window_closed)) {
|
||||
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) {
|
||||
if (!set_callback_window(window)) return;
|
||||
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();
|
||||
global_state.callback_os_window = NULL;
|
||||
}
|
||||
@ -973,12 +977,6 @@ wakeup_main_loop() {
|
||||
glfwPostEmptyEvent();
|
||||
}
|
||||
|
||||
void
|
||||
mark_os_window_for_close(OSWindow* w, bool yes) {
|
||||
global_state.has_pending_closes = true;
|
||||
glfwSetWindowShouldClose(w->handle, yes);
|
||||
}
|
||||
|
||||
bool
|
||||
should_os_window_be_rendered(OSWindow* w) {
|
||||
return (
|
||||
@ -988,11 +986,6 @@ should_os_window_be_rendered(OSWindow* w) {
|
||||
) ? false : true;
|
||||
}
|
||||
|
||||
bool
|
||||
should_os_window_close(OSWindow* w) {
|
||||
return glfwWindowShouldClose(w->handle) ? true : false;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
primary_monitor_size(PYNOARG) {
|
||||
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 {{{
|
||||
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
||||
@ -784,10 +792,10 @@ PYWRAP1(os_window_has_background_image) {
|
||||
|
||||
PYWRAP1(mark_os_window_for_close) {
|
||||
id_type os_window_id;
|
||||
int yes = 1;
|
||||
PA("K|p", &os_window_id, &yes);
|
||||
CloseRequest cr = IMPERATIVE_CLOSE_REQUESTED;
|
||||
PA("K|i", &os_window_id, &cr);
|
||||
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;
|
||||
END_WITH_OS_WINDOW
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
@ -139,6 +139,7 @@ typedef struct {
|
||||
} OSWindowGeometry;
|
||||
|
||||
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 {
|
||||
monotonic_t last_resize_event_at;
|
||||
@ -183,6 +184,7 @@ typedef struct {
|
||||
uint64_t render_calls;
|
||||
id_type last_focused_counter;
|
||||
ssize_t gvao_idx;
|
||||
CloseRequest close_request;
|
||||
} OSWindow;
|
||||
|
||||
|
||||
@ -220,9 +222,8 @@ void remove_vao(ssize_t vao_idx);
|
||||
bool remove_os_window(id_type os_window_id);
|
||||
void make_os_window_context_current(OSWindow *w);
|
||||
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);
|
||||
bool should_os_window_close(OSWindow* w);
|
||||
bool should_os_window_be_rendered(OSWindow* w);
|
||||
void wakeup_main_loop(void);
|
||||
void swap_window_buffers(OSWindow *w);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user