Infrastructure for close confirmation

This commit is contained in:
Kovid Goyal 2020-05-02 18:19:08 +05:30
parent 2e63a4c83f
commit 3c8640f9ad
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 49 additions and 27 deletions

View File

@ -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)

View File

@ -865,16 +865,11 @@ 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 bool static inline void
process_pending_closes(ChildMonitor *self) { close_os_window(ChildMonitor *self, OSWindow *os_window) {
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); destroy_os_window(os_window);
call_boss(on_os_window_closed, "Kii", os_window->id, os_window->window_width, os_window->window_height); 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++) { for (size_t t=0; t < os_window->num_tabs; t++) {
@ -882,8 +877,30 @@ process_pending_closes(ChildMonitor *self) {
for (size_t w = 0; w < tab->num_windows; w++) mark_child_for_close(self, tab->windows[w].id); 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); remove_os_window(os_window->id);
} else has_open_windows = true;
} }
static inline bool
process_pending_closes(ChildMonitor *self) {
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;
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__ #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;

View File

@ -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();

View File

@ -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;

View File

@ -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);