Commit: 4b076acf215453e2d87f7267abd7e792dac475eb
Parent: b59406740b24469e6752bf57827cdbb317361e34
Author: Randy Palamar
Date: Tue, 26 May 2026 10:31:47 -0600
platform: load input key modifiers in platform layer
Diffstat:
6 files changed, 58 insertions(+), 19 deletions(-)
diff --git a/beamformer.h b/beamformer.h
@@ -137,6 +137,25 @@ typedef enum {
BeamformerButtonID_Count,
} BeamformerButtonID;
+typedef enum {
+ BeamformerInputModifier_LeftAlt = (1 << 0),
+ BeamformerInputModifier_RightAlt = (1 << 1),
+
+ BeamformerInputModifier_LeftControl = (1 << 2),
+ BeamformerInputModifier_RightControl = (1 << 3),
+
+ BeamformerInputModifier_LeftShift = (1 << 4),
+ BeamformerInputModifier_RightShift = (1 << 5),
+
+ BeamformerInputModifier_LeftMeta = (1 << 6),
+ BeamformerInputModifier_RightMeta = (1 << 7),
+
+ BeamformerInputModifier_Alt = BeamformerInputModifier_LeftAlt|BeamformerInputModifier_RightAlt,
+ BeamformerInputModifier_Control = BeamformerInputModifier_LeftControl|BeamformerInputModifier_RightControl,
+ BeamformerInputModifier_Shift = BeamformerInputModifier_LeftShift|BeamformerInputModifier_RightShift,
+ BeamformerInputModifier_Meta = BeamformerInputModifier_LeftMeta|BeamformerInputModifier_RightMeta,
+} BeamformerInputModifiers;
+
typedef struct {
BeamformerInputEventKind kind;
union {
@@ -165,12 +184,11 @@ typedef struct {
float mouse_x;
float mouse_y;
- float last_mouse_x;
- float last_mouse_y;
uint32_t event_count;
- BeamformerInputEvent event_queue[256];
+ BeamformerInputModifiers input_modifiers;
+ BeamformerInputEvent event_queue[256];
/* NOTE(rnp): the beamformer is not allowed to dynamically load libraries
* itself. Besides Vulkan, which is required, libraries are optional and
diff --git a/beamformer_internal.h b/beamformer_internal.h
@@ -134,6 +134,7 @@ typedef struct {
} BeamformerShaderResourceInfo;
#include "threads.c"
+#include "util_os_ui.c"
#include "util_os.c"
///////////////////////////
diff --git a/main_linux.c b/main_linux.c
@@ -341,19 +341,16 @@ main(void)
fds[0].events = POLLIN;
while (!WindowShouldClose() && !beamformer_should_close(input)) {
+ os_build_frame_input(input);
+
poll(fds, countof(fds), 0);
if (fds[0].revents & POLLIN)
dispatch_file_watch_events(input);
- Vector2 new_mouse = GetMousePosition();
- input->last_mouse_x = input->mouse_x;
- input->last_mouse_y = input->mouse_y;
- input->mouse_x = new_mouse.x;
- input->mouse_y = new_mouse.y;
-
beamformer_frame_step(input);
- input->event_count = 0;
+ // NOTE(rnp): this must happen at the end of frame to allow the pre loop events through
+ input->event_count = 0;
}
beamformer_terminate(input);
diff --git a/main_w32.c b/main_w32.c
@@ -418,20 +418,17 @@ main(void)
beamformer_init(input);
while (!WindowShouldClose() && !beamformer_should_close(input)) {
+ os_build_frame_input(input);
+
DeferLoop(take_lock(&os_w32_context.arena_lock, -1), release_lock(&os_w32_context.arena_lock))
{
clear_io_queue(input, os_w32_context.arena);
}
- Vector2 new_mouse = GetMousePosition();
- input->last_mouse_x = input->mouse_x;
- input->last_mouse_y = input->mouse_y;
- input->mouse_x = new_mouse.x;
- input->mouse_y = new_mouse.y;
-
beamformer_frame_step(input);
- input->event_count = 0;
+ // NOTE(rnp): this must happen at the end of frame to allow the pre loop events through
+ input->event_count = 0;
}
beamformer_terminate(input);
diff --git a/ui.c b/ui.c
@@ -416,6 +416,8 @@ struct BeamformerUI {
Font font;
Font small_font;
+ v2 last_mouse;
+
Variable *regions;
Variable *variable_freelist;
@@ -3926,7 +3928,6 @@ function void
ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect)
{
v2 input_mouse = {{input->mouse_x, input->mouse_y}};
- v2 last_mouse = {{input->last_mouse_x, input->last_mouse_y}};
Interaction *it = &ui->interaction;
if (it->kind == InteractionKind_None || interaction_is_sticky(*it)) {
ui->hot_interaction = ui->next_interaction;
@@ -3959,7 +3960,7 @@ ui_interact(BeamformerUI *ui, BeamformerInput *input, Rect window_rect)
ui_end_interact(ui, input_mouse);
} else {
v2 ws = window_rect.size;
- v2 dMouse = v2_sub(input_mouse, last_mouse);
+ v2 dMouse = v2_sub(input_mouse, ui->last_mouse);
switch (it->var->type) {
case VT_BEAMFORMER_VARIABLE:{
@@ -4341,4 +4342,6 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input, BeamformerFrame *frame_to_dr
draw_ui_regions(ui, window_rect, mouse);
draw_floating_widgets(ui, window_rect, mouse);
EndDrawing();
+
+ ui->last_mouse = (v2){{input->mouse_x, input->mouse_y}};
}
diff --git a/util_os_ui.c b/util_os_ui.c
@@ -0,0 +1,23 @@
+/* See LICENSE for license details. */
+
+// NOTE(rnp): functions which require platform layer support but
+// otherwise share implementation
+
+function void
+os_build_frame_input(BeamformerInput *input)
+{
+ Vector2 new_mouse = {-1, -1};
+ if (IsWindowFocused()) new_mouse = GetMousePosition();
+ input->mouse_x = new_mouse.x;
+ input->mouse_y = new_mouse.y;
+
+ input->input_modifiers = 0;
+ input->input_modifiers |= BeamformerInputModifier_LeftAlt * IsKeyDown(KEY_LEFT_ALT);
+ input->input_modifiers |= BeamformerInputModifier_RightAlt * IsKeyDown(KEY_RIGHT_ALT);
+ input->input_modifiers |= BeamformerInputModifier_LeftControl * IsKeyDown(KEY_LEFT_CONTROL);
+ input->input_modifiers |= BeamformerInputModifier_RightControl * IsKeyDown(KEY_RIGHT_CONTROL);
+ input->input_modifiers |= BeamformerInputModifier_LeftShift * IsKeyDown(KEY_LEFT_SHIFT);
+ input->input_modifiers |= BeamformerInputModifier_RightShift * IsKeyDown(KEY_RIGHT_SHIFT);
+ input->input_modifiers |= BeamformerInputModifier_LeftMeta * IsKeyDown(KEY_LEFT_SUPER);
+ input->input_modifiers |= BeamformerInputModifier_RightMeta * IsKeyDown(KEY_RIGHT_SUPER);
+}