From 3e4d73542bf7b279c9e0853981b97781f1f05e94 Mon Sep 17 00:00:00 2001 From: mitchell <70453897+orbitalquark@users.noreply.github.com> Date: Wed, 23 Feb 2022 10:58:04 -0500 Subject: Fixed `ui.update()` on macOS when monitoring output of spawned processes. Also removed unnecessary #if tests. --- src/lua.patch | 19 ++++++++++++++----- src/textadept.c | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/lua.patch b/src/lua.patch index 7f8de368..54c15b04 100644 --- a/src/lua.patch +++ b/src/lua.patch @@ -50,8 +50,8 @@ diff -r 8a23edc91533 src/luaconf.h #endif /* } */ ---- a/src/loslib.c 2017-04-19 13:29:57.000000000 -0400 -+++ b/src/loslib.c 2020-08-04 16:32:00.029294802 -0400 +--- a/src/loslib.c 2020-11-13 10:32:01.000000000 -0500 ++++ b/src/loslib.c 2022-02-18 16:17:50.639380353 -0500 @@ -4,6 +4,15 @@ ** See Copyright Notice in lua.h */ @@ -68,7 +68,7 @@ diff -r 8a23edc91533 src/luaconf.h #define loslib_c #define LUA_LIB -@@ -382,6 +391,11 @@ +@@ -403,6 +412,11 @@ return 0; } @@ -80,7 +80,7 @@ diff -r 8a23edc91533 src/luaconf.h static const luaL_Reg syslib[] = { {"clock", os_clock}, -@@ -393,6 +407,7 @@ +@@ -414,6 +428,7 @@ {"remove", os_remove}, {"rename", os_rename}, {"setlocale", os_setlocale}, @@ -88,7 +88,7 @@ diff -r 8a23edc91533 src/luaconf.h {"time", os_time}, {"tmpname", os_tmpname}, {NULL, NULL} -@@ -404,6 +419,629 @@ +@@ -425,6 +440,638 @@ LUAMOD_API int luaopen_os (lua_State *L) { luaL_newlib(L, syslib); @@ -446,6 +446,13 @@ diff -r 8a23edc91533 src/luaconf.h + * Monitors spawned fds when GTK is idle. + * This is necessary because at the moment, using GLib on macOS to spawn and + * monitor file descriptors mostly blocks when attempting to poll those fds. ++ * Note that this idle event is considered a pending event, so the construct ++ * `while (gtk_events_pending()) gtk_main_iteration();` will cycle for as long ++ * as the monitor is active. To help get around this, this function sets a ++ * "spawn_procs_polled" boolean in the registry after poll. An application can ++ * set this boolean to `false` prior to calling `gtk_main_iteration()`. If there ++ * are still pending events and this boolean is `true`, then there are no ++ * non-idle pending events left. + */ +static int monitor_fds(void *L) { + struct timeval timeout = {0, 1e5}; // 0.1s @@ -454,6 +461,8 @@ diff -r 8a23edc91533 src/luaconf.h + os_spawn_readfds(L); + lua_pop(L, 1); // fds + if (nfds == 1) monitoring_fds = 0; ++ lua_pushboolean(L, 1); ++ lua_setfield(L, LUA_REGISTRYINDEX, "spawn_procs_polled"); + return nfds > 1; +} +#endif diff --git a/src/textadept.c b/src/textadept.c index 794acd3f..d78dbf34 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -810,7 +810,19 @@ static int menu(lua_State *L) { /** `ui.update()` Lua function. */ static int update_ui(lua_State *L) { #if GTK +#if !__APPLE__ while (gtk_events_pending()) gtk_main_iteration(); +#else + // The idle event monitor created by os.spawn() on macOS is considered to be a pending event, + // so use its provided registry key to help determine when there are no longer any non-idle + // events pending. + lua_pushboolean(L, false), lua_setfield(L, LUA_REGISTRYINDEX, "spawn_procs_polled"); + while (gtk_events_pending()) { + bool polled = (lua_getfield(L, LUA_REGISTRYINDEX, "spawn_procs_polled"), lua_toboolean(L, -1)); + if (lua_pop(L, 1), polled) break; + gtk_main_iteration(); + } +#endif #elif (CURSES && !_WIN32) struct timeval timeout = {0, 1e5}; // 0.1s int nfds = os_spawn_pushfds(L); @@ -1795,7 +1807,7 @@ static bool exiting(GtkWidget *_, GdkEventAny *__, void *L) { return (gtk_main_quit(), false); } -#if (__APPLE__ && !CURSES) +#if __APPLE__ /** * Signal for opening files from macOS. * Generates an 'appleevent_odoc' event for each document sent. @@ -1996,7 +2008,7 @@ static void split_view(Scintilla *view, bool vertical) { gtk_widget_show_all(pane); g_object_unref(view); - while (gtk_events_pending()) gtk_main_iteration(); // ensure view2 is painted + update_ui(lua); // ensure view2 is painted #elif CURSES Scintilla *view2 = new_view(curdoc); split_pane(pane, vertical, view, view2); @@ -2254,7 +2266,7 @@ static void new_window() { gtdialog_set_parent(GTK_WINDOW(window)); accel = gtk_accel_group_new(); -#if (__APPLE__ && !CURSES) +#if __APPLE__ gtkosx_application_set_use_quartz_accelerators(osxapp, false); g_signal_connect(osxapp, "NSApplicationOpenFile", G_CALLBACK(open_file), lua); g_signal_connect(osxapp, "NSApplicationBlockTermination", G_CALLBACK(terminating), lua); -- cgit v1.2.3