Commitda27f509Recorded20 Sep 2026Repositorysigil-app

Review fixes: GL 4.3 on non-Apple, size 0 defaults, no nested app-run

Message

From the adversarial review of the branch:

  • Request GL 4.3 core on Linux and Windows, 4.1 on macOS, which is what sokol_app asked for (sokol_app.h:3520-3527); sokol_gfx gates compute and texture views on the reported version, so a strict driver would have lost them silently under a 4.1 request. The comment said 4.1 was sokol's choice; it was not.
  • (app-run ... 0 0) opens the 640x480 default, as sokol_app did, instead of raising GLFW_INVALID_VALUE.
  • app-run refuses to nest: a second call from inside a callback used to free the outer loop's state under it.
  • A Scheme error in a frame sets quit-requested? too, so a cleanup callback sees #t as it did under sokol_app.
  • The frame clock restarts after the init callback; a long asset load is no longer frame 1's dt.
  • dl-search says so on stderr when there is no underlying dlopen (a static link), and the library record lists only the files every target compiles, with a comment on why.
Changed
 package.sgl          |  8 +++++---
 src/c/app.c          | 26 +++++++++++++++++++++-----
 src/c/dl-search.c    |  7 ++++++-
 src/c/sokol-compat.c |  3 +++
 4 files changed, 35 insertions(+), 9 deletions(-)
Diff
package.sglmodified
@@ -150,9 +150,11 @@
150
libraries: (list
151
(library
152
name: 'sigil-app
−153
;; The platform-independent files; the build task adds the GLFW
−154
;; backend files for the config's target OS.
−155
c-sources: '("src/c/app.c" "src/c/sokol-compat.c" "src/c/dl-search.c")
+153
;; sigil-build reads this list only as a "has native code" test and
+154
;; for the include dirs; the build task below compiles the real,
+155
;; target-dependent list (these two plus dl-search.c on Linux plus
+156
;; the GLFW backend files). Keep it to files every target compiles.
+157
c-sources: '("src/c/app.c" "src/c/sokol-compat.c")
158
c-include-dirs: '("vendor/glfw/include" "vendor/sokol" "src/c")
159
native-init: "sigil__init_sigil_app_module"
160
;; Platform linker flags.
src/c/app.cmodified
@@ -149,6 +149,7 @@ static void check_vm_error(const char *context)
149
if (err) {
150
fprintf(stderr, "Scheme error in %s: %s\n", context, err);
151
sigil_error_clear(g_app->vm);
+152
g_app->quit_requested = true;
153
if (g_app->window) glfwSetWindowShouldClose(g_app->window, GLFW_TRUE);
154
}
155
}
@@ -303,12 +304,18 @@ static bool run_main_loop(const char *title, int width, int height)
304
return false;
305
}
306
−306
/* GL 4.1 core, the profile sokol_app asked for (and the newest macOS
−307
* offers). Forward-compat is required by macOS for core profiles and
−308
* harmless elsewhere. Depth 24 / stencil 8 are GLFW's defaults and
−309
* match the sokol_app swapchain the graphics layer expects. */
+307
/* The GL core profile sokol_app asked for: 4.3 on Linux and Windows, 4.1
+308
* on macOS (the newest it offers); sokol_gfx gates a few features on the
+309
* reported version, and Mesa and NVIDIA hand back the highest core
+310
* version either way. Forward-compat as sokol_app set it too (required
+311
* on macOS). Depth 24 / stencil 8 are GLFW's defaults and match the
+312
* sokol_app swapchain the graphics layer expects. */
313
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+314
#if defined(__APPLE__)
315
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
+316
#else
+317
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+318
#endif
319
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
320
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
321
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
@@ -362,7 +369,9 @@ static bool run_main_loop(const char *title, int width, int height)
369
check_vm_error("init");
370
}
371
−365
/* frames */
+372
/* frames; the clock restarts after init so a long asset load is not
+373
* frame 1's dt (sokol_app handed the load time to the first frame). */
+374
g_app->last_time = glfwGetTime();
375
while (!glfwWindowShouldClose(window)) {
376
glfwPollEvents();
377
@@ -417,6 +426,10 @@ static Value native_app_run(SigilVM *vm, int argc, Value *args)
426
427
/* Initialize app state */
428
sigil_app_state_init(vm);
+429
if (g_app->window) {
+430
sigil__vm_error(vm, SIGIL_ERR_RUNTIME, "app-run: already running; app-run does not nest");
+431
return SIGIL_UNDEFINED;
+432
}
433
434
/* Store callbacks */
435
g_app->init_callback = args[0];
@@ -438,6 +451,9 @@ static Value native_app_run(SigilVM *vm, int argc, Value *args)
451
if (argc > 5 && sigil_is_fixnum(args[5])) {
452
height = (int)sigil_as_fixnum(args[5]);
453
}
+454
/* 0 (or less) means the default, as with sokol_app. */
+455
if (width <= 0) width = 640;
+456
if (height <= 0) height = 480;
457
458
bool ran = run_main_loop(title, width, height);
459
src/c/dl-search.cmodified
@@ -98,7 +98,12 @@ static void *try_under(sigil_dlopen_fn real, const char *base, const char *suffi
98
void *dlopen(const char *name, int flags)
99
{
100
sigil_dlopen_fn real = real_dlopen();
−101
if (!real) return NULL;
+101
if (!real) {
+102
/* No next dlopen: only a fully static link gets here; say so, since
+103
* GLFW then reports the library as missing. */
+104
fprintf(stderr, "sigil-app: dlopen(%s): no underlying dlopen (static link?)\n", name ? name : "(null)");
+105
return NULL;
+106
}
107
108
void *h = real(name, flags);
109
if (h || !name || strchr(name, '/')) return h;
src/c/sokol-compat.cmodified
@@ -18,6 +18,9 @@
18
#include "app-internal.h"
19
#include <string.h>
20
+21
/* Order is load-bearing: sokol_log.h with its IMPL defines SOKOL_API_IMPL,
+22
* which the sapp_* definitions below use; sokol_app.h then contributes
+23
* declarations only. */
24
#define SOKOL_LOG_IMPL
25
#include "sokol_log.h"
26