diff --git a/include/webui.h b/include/webui.h index 8d239ac74..40755dac6 100644 --- a/include/webui.h +++ b/include/webui.h @@ -519,6 +519,19 @@ WEBUI_EXPORT void webui_set_browser_folder(const char* path); */ WEBUI_EXPORT bool webui_set_default_root_folder(const char* path); +/** + * @brief Set a callback to catch the close event of the WebView window. + * Must return `false` to prevent the close event, `true` otherwise. + * + * @example + * bool myCloseEvent(size_t window) { + * // Prevent WebView window close event + * return false; + * } + * webui_set_close_handler(myWindow, myCloseEvent); + */ +WEBUI_EXPORT void webui_set_close_handler_wv(size_t window, bool (*close_handler)(size_t window)); + /** * @brief Set a custom handler to serve files. This custom handler should * return full HTTP header and body. diff --git a/src/webui.c b/src/webui.c index d656c31b6..e35e80877 100644 --- a/src/webui.c +++ b/src/webui.c @@ -373,6 +373,7 @@ typedef struct _webui_window_t { int x; int y; bool position_set; + bool (*close_handler_wv)(size_t window); const void*(*files_handler)(const char* filename, int* length); const void*(*files_handler_window)(size_t window, const char* filename, int* length); const void* file_handler_async_response; @@ -641,6 +642,7 @@ static bool _webui_wv_set_position(_webui_wv_linux_t* webView, int x, int y); static bool _webui_wv_set_size(_webui_wv_linux_t* webView, int windowWidth, int windowHeight); static bool _webui_wv_show(_webui_window_t* win, char* url); static void _webui_wv_event_closed(void *widget, void *arg); +static bool _webui_wv_event_on_close(void *widget, void *event, void *arg); static int _webui_wv_exit_schedule(void* arg); static bool _webui_wv_maximize(_webui_wv_linux_t* webView); static bool _webui_wv_minimize(_webui_wv_linux_t* webView); @@ -775,6 +777,25 @@ void webui_run(size_t window, const char* script) { _webui_send_all(win, 0, WEBUI_CMD_JS_QUICK, script, js_len); } +void webui_set_close_handler_wv(size_t window, bool(*close_handler)(size_t window)) { + + // Initialization + _webui_init(); + + // Dereference + if (_webui_mutex_app_is_exit_now(WEBUI_MUTEX_GET_STATUS) || _webui.wins[window] == NULL) + return; + + _webui_window_t* win = _webui.wins[window]; + + #ifdef WEBUI_LOG + printf("[User]webui_set_close_handler(%zu, %p)", window, close_handler); + #endif + + // Set the close handler + win->close_handler_wv = close_handler; +} + void webui_set_file_handler(size_t window, const void*(*handler)(const char* filename, int* length)) { if (handler == NULL) @@ -11531,13 +11552,25 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { } case WM_CLOSE: { if (win) { - // Stop the WebView thread, close the window - // and free resources. - if (win->webView) { - win->webView->stop = true; - _webui_webview_update(win); - } - _webui_wv_event_closed(win); + bool can_close = true; + if (win->close_handler_wv != NULL) { + can_close = win->close_handler_wv(win->num); + #ifdef WEBUI_LOG + webui_log_debug("[Core]\t\tClose handler installed for %zu, result = %d\n", win->num, can_close); + #endif + } + if (can_close) { + // Stop the WebView thread, close the window + // and free resources. + if (win->webView) { + win->webView->stop = true; + _webui_webview_update(win); + } + _webui_wv_event_closed(win); + } else { + // Do not close the window, no default processing + return 0; + } } break; } @@ -11972,6 +12005,24 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { } } + // Delete Event (implement on close handling) + static bool _webui_wv_event_on_close(void *widget, void *evt, void *arg) { + #ifdef WEBUI_LOG + printf("[Core]\t\t_webui_wv_event_on_close()\n"); + #endif + _webui_window_t* win = _webui_dereference_win_ptr(arg); + if (win) { + if (win->close_handler_wv) { + bool can_close = win->close_handler_wv(win->num); + #ifdef WEBUI_LOG + printf("[Core]\t\t_webui_wv_event_on_close() -> can_close = %d\n", can_close); + #endif + return !can_close; + } + } + return false; + } + static bool _webui_wv_set_size(_webui_wv_linux_t* webView, int windowWidth, int windowHeight) { #ifdef WEBUI_LOG printf("[Core]\t\t_webui_wv_set_size(%d. %d)\n", windowWidth, windowHeight); @@ -12110,6 +12161,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { // Events g_signal_connect_data(win->webView->gtk_wv, "notify::title", G_CALLBACK( _webui_wv_event_title), (void *)win, NULL, 0); + g_signal_connect_data(win->webView->gtk_win, "delete-event", G_CALLBACK( + _webui_wv_event_on_close), (void *)win, NULL, 0); g_signal_connect_data(win->webView->gtk_win, "destroy", G_CALLBACK( _webui_wv_event_closed), (void *)win, NULL, 0);