Commit: 7b84d363f59f92a8c04278366957a77dc90d03e2
Parent: fb2a386b925dd7b30837831039ae6742e8e7c88a
Author: Randy Palamar
Date: Thu, 7 Nov 2024 22:04:22 -0700
move window title setting out of the terminal
Diffstat:
7 files changed, 47 insertions(+), 46 deletions(-)
diff --git a/platform_linux_x11.c b/platform_linux_x11.c
@@ -88,6 +88,8 @@ do_debug(TerminalMemory *t, Stream *err)
#endif /* _DEBUG */
+static GLFWwindow *g_window;
+
static void
button_action(ButtonState *button, b32 pressed)
{
@@ -326,14 +328,12 @@ update_input(GLFWwindow *win, TerminalInput *input, posix_platform_process child
input->data_available = os_child_data_available(child.handle);
}
-static PLATFORM_GET_CLIPBOARD_FN(x11_get_clipboard)
+static PLATFORM_CLIPBOARD_FN(x11_get_clipboard)
{
/* NOTE: this does a bunch of extra copying and other garbage. both GLFW and X11 are
* at fault. The API is designed to do what the terminal wants and not be constrained
* by GLFW and X11 garbage */
- b32 result = 0;
ASSERT(buffer);
-
char *text = 0;
switch (clipboard) {
case CLIPBOARD_0: text = (c8 *)glfwGetClipboardString(0); break;
@@ -342,13 +342,12 @@ static PLATFORM_GET_CLIPBOARD_FN(x11_get_clipboard)
if (text) {
/* TODO: we may need to replace '\n' with '\r\n' */
stream_push_s8(buffer, c_str_to_s8(text));
- result = !buffer->errors;
}
- return result;
+ return !buffer->errors;
}
-static PLATFORM_SET_CLIPBOARD_FN(x11_set_clipboard)
+static PLATFORM_CLIPBOARD_FN(x11_set_clipboard)
{
ASSERT(buffer);
stream_push_byte(buffer, 0);
@@ -359,6 +358,22 @@ static PLATFORM_SET_CLIPBOARD_FN(x11_set_clipboard)
case CLIPBOARD_1: glfwSetX11SelectionString((c8 *)buffer->buf); break;
}
}
+ return !buffer->errors;
+}
+
+static PLATFORM_WINDOW_TITLE_FN(x11_get_window_title)
+{
+ ASSERT(buffer);
+ char *title = (c8 *)glfwGetWindowTitle(g_window);
+ if (title) stream_push_s8(buffer, c_str_to_s8(title));
+}
+
+static PLATFORM_WINDOW_TITLE_FN(x11_set_window_title)
+{
+ ASSERT(buffer);
+ stream_push_byte(buffer, 0);
+ if (!buffer->errors)
+ glfwSetWindowTitle(g_window, (c8 *)buffer->buf);
}
static void
@@ -393,6 +408,8 @@ main(i32 argc, char *argv[], char *envp[])
term_memory.platform_api.allocate_ring_buffer = posix_allocate_ring_buffer;
term_memory.platform_api.get_clipboard = x11_get_clipboard;
term_memory.platform_api.set_clipboard = x11_set_clipboard;
+ term_memory.platform_api.get_window_title = x11_get_window_title;
+ term_memory.platform_api.set_window_title = x11_set_window_title;
Arena platform_arena = os_new_arena(2 * MEGABYTE);
Stream error_stream = stream_alloc(&platform_arena, MEGABYTE / 4);
@@ -465,6 +482,7 @@ main(i32 argc, char *argv[], char *envp[])
iv2 window_size = {.w = 1280, .h = 720};
GLFWwindow *window = init_window(&ctx, window_size);
+ g_window = window;
posix_platform_process child = os_fork_child("/bin/sh");
diff --git a/terminal.c b/terminal.c
@@ -34,12 +34,6 @@ get_word_around_cell(Term *t, iv2 cell)
return result;
}
-static void
-set_window_title(GLFWwindow *win, Arena a, s8 title)
-{
- glfwSetWindowTitle(win, s8_to_cstr(&a, title));
-}
-
static s8
consume(s8 raw, size count)
{
@@ -774,17 +768,9 @@ set_scrolling_region(Term *t, CSI *csi)
static void
window_manipulation(Term *t, CSI *csi)
{
- const char *s;
- u32 i;
-
switch (csi->argv[0]) {
- case 22:
- s = glfwGetWindowTitle(t->gl.window);
- for (i = 0; i < ARRAY_COUNT(t->saved_title) - 1 && s[i]; i++)
- t->saved_title[i] = s[i];
- t->saved_title[i] = 0;
- break;
- case 23: glfwSetWindowTitle(t->gl.window, t->saved_title); break;
+ case 22: t->platform->get_window_title(&t->saved_title); break;
+ case 23: t->platform->set_window_title(&t->saved_title); break;
default:
stream_push_s8(&t->error_stream, s8("unhandled xtwinops: "));
stream_push_i64(&t->error_stream, csi->argv[0]);
@@ -1009,10 +995,11 @@ handle_osc(Term *t, s8 *raw, Arena a)
i32 ret = parse_osc(raw, &osc);
ASSERT(ret != -1);
+ Stream buffer = arena_stream(a);
switch (osc.cmd) {
- case 0: set_window_title(t->gl.window, a, osc.arg); break;
- case 1: /* IGNORED: set icon name */ break;
- case 2: set_window_title(t->gl.window, a, osc.arg); break;
+ case 0: stream_push_s8(&buffer, osc.arg); t->platform->set_window_title(&buffer); break;
+ case 1: break; /* IGNORED: set icon name */
+ case 2: stream_push_s8(&buffer, osc.arg); t->platform->set_window_title(&buffer); break;
default:
stream_push_s8(&t->error_stream, s8("unhandled osc cmd: "));
dump_osc(&osc, &t->error_stream);
diff --git a/test.c b/test.c
@@ -18,9 +18,6 @@
#include "config.h"
/* NOTE: stubs for stuff we aren't testing */
-void glfwSetWindowTitle(GLFWwindow *w, const char *s) {}
-const char *glfwGetWindowTitle(GLFWwindow *w) { return "test"; }
-
static void get_gpu_glyph_index(Arena, void *, void *, u32, u32, u32, CachedGlyph **);
static GlyphCacheStats get_and_clear_glyph_cache_stats(void *p) { return (GlyphCacheStats){0}; }
static void init_font(void *a, void *b) {}
diff --git a/util.c b/util.c
@@ -187,16 +187,6 @@ c_str_to_s8(char *s)
return result;
}
-static char *
-s8_to_cstr(Arena *a, s8 s)
-{
- char *cstr = alloc(a, char, s.len + 1);
- for (size i = 0; i < s.len; i++)
- cstr[i] = s.data[i];
- cstr[s.len] = 0;
- return cstr;
-}
-
static struct conversion_result
i32_from_cstr(char *s, char delim)
{
diff --git a/util.h b/util.h
@@ -16,6 +16,7 @@
#endif
#define PI 3.1415926535897932384f
+#define KILOBYTE (1024ULL)
#define MEGABYTE (1024ULL * 1024ULL)
#define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
@@ -481,9 +482,10 @@ typedef struct Term {
* this would mean that cells are ~4px wide which is unreadable */
u32 tabs[32];
- char saved_title[1024];
-
+ Stream saved_title;
Stream error_stream;
+
+ PlatformAPI *platform;
} Term;
static f32 dt_for_frame;
diff --git a/vtgl.c b/vtgl.c
@@ -808,6 +808,8 @@ DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize)
Term *t = (Term *)memory->memory;
Arena a = {.beg = (u8 *)(t + 1), .end = memory->memory + memory->memory_size};
+ t->platform = &memory->platform_api;
+
t->cursor.state = CURSOR_NORMAL;
cursor_reset(t);
@@ -827,6 +829,7 @@ DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize)
t->size = (uv2){.x = 1, .y = 1};
t->error_stream = stream_alloc(&a, MEGABYTE / 4);
+ t->saved_title = stream_alloc(&a, 16 * KILOBYTE);
t->arena_for_frame = a;
t->child = child;
diff --git a/vtgl.h b/vtgl.h
@@ -11,18 +11,22 @@ typedef PLATFORM_WRITE_FN(platform_write_fn);
#define PLATFORM_READ_FN(name) size name(iptr file, s8 buffer, size offset)
typedef PLATFORM_READ_FN(platform_read_fn);
-#define PLATFORM_GET_CLIPBOARD_FN(name) b32 name(Stream *buffer, u32 clipboard)
-typedef PLATFORM_GET_CLIPBOARD_FN(platform_get_clipboard_fn);
-#define PLATFORM_SET_CLIPBOARD_FN(name) void name(Stream *buffer, u32 clipboard)
-typedef PLATFORM_SET_CLIPBOARD_FN(platform_set_clipboard_fn);
+#define PLATFORM_CLIPBOARD_FN(name) b32 name(Stream *buffer, u32 clipboard)
+typedef PLATFORM_CLIPBOARD_FN(platform_clipboard_fn);
+
+#define PLATFORM_WINDOW_TITLE_FN(name) void name(Stream *buffer)
+typedef PLATFORM_WINDOW_TITLE_FN(platform_window_title_fn);
typedef struct {
platform_allocate_ring_buffer_fn *allocate_ring_buffer;
platform_read_fn *read;
platform_write_fn *write;
- platform_get_clipboard_fn *get_clipboard;
- platform_set_clipboard_fn *set_clipboard;
+ platform_clipboard_fn *get_clipboard;
+ platform_clipboard_fn *set_clipboard;
+
+ platform_window_title_fn *get_window_title;
+ platform_window_title_fn *set_window_title;
} PlatformAPI;
/* NOTE: CLIPBOARD_1 need not be supported on all platforms */