Add auto-show/auto-hide feature for OSD
When osd_auto_show is enabled (default: true) and osd_start_visible is false, the OSD will automatically appear when keys are pressed and hide after the display_duration_ms timeout. Changes: - Added osd_auto_show config option - Added last_action_time_ms tracking in osd state - osd_record_action now shows OSD when hidden (if auto_show enabled) - osd_update now auto-hides after display_duration_ms of inactivity - Updated device.c to always call osd_update for auto-hide timer https://claude.ai/code/session_01H5sr8TkRyt6U1vdkVZRRvy
+40 −7 · 6 files changed
-
default.cfg+2 −0 -
src/config.c+9 −0 -
src/config.h+1 −0 -
src/device.c+3 −2 -
src/osd.c+23 −5 -
src/osd.h+2 −0
@@ -62,6 +62,7 @@ // OSD Settings: // osd_enabled: true/false - Enable/disable OSD feature // osd_start_visible: true/false - Show OSD when driver starts +// osd_auto_show: true/false - Auto-show OSD when keys are pressed (then auto-hide) // osd_position: x,y - Initial position on screen // osd_opacity: 0.0-1.0 - Background opacity (0.67 = 33% transparent) // osd_display_duration: milliseconds - How long actions stay visible @@ -72,6 +73,7 @@ // osd_enabled: true osd_start_visible: false +osd_auto_show: true osd_position: 50,50 osd_opacity: 0.67 osd_display_duration: 3000 @@ -90,6 +90,7 @@ config_t* config_create(void) { // Initialize OSD settings config->osd.enabled = 0; config->osd.start_visible = 0; + config->osd.auto_show = 1; // Auto-show on key press by default config->osd.pos_x = 50; config->osd.pos_y = 50; config->osd.opacity = 0.67f; // 33% transparent = 67% opaque @@ -294,6 +295,14 @@ int config_load(config_t* config, const char* filename, int debug) { continue; } + if (strncasecmp(line, "osd_auto_show:", 14) == 0) { + char* value = line + 14; + while (*value == ' ') value++; + config->osd.auto_show = (strncasecmp(value, "true", 4) == 0 || strcmp(value, "1") == 0); + if (debug) printf("Config: osd_auto_show = %s\n", config->osd.auto_show ? "true" : "false"); + continue; + } + if (strncasecmp(line, "osd_position:", 13) == 0) { char* value = line + 13; while (*value == ' ') value++; @@ -19,6 +19,7 @@ typedef struct { typedef struct { int enabled; // Is OSD enabled int start_visible; // Show OSD on startup + int auto_show; // Auto-show OSD when keys are pressed int pos_x; // Initial X position int pos_y; // Initial Y position float opacity; // Background opacity (0.0-1.0, default 0.67 = 33% transparent) @@ -61,6 +61,7 @@ void device_run(libusb_context* ctx, config_t* config, int debug, int accept, in osd->expanded_width = config->osd.expanded_width; osd->expanded_height = config->osd.expanded_height; osd->font_size = config->osd.font_size; + osd->auto_show = config->osd.auto_show; // Initialize X11 display if (osd_init_display(osd) == 0) { @@ -355,8 +356,8 @@ void device_run(libusb_context* ctx, config_t* config, int debug, int accept, in unsigned char data[40]; int keycode = 0; - // Update OSD (process X11 events) - if (osd && osd->mode != OSD_MODE_HIDDEN) { + // Update OSD (process X11 events and auto-hide timer) + if (osd) { osd_update(osd); } @@ -85,6 +85,8 @@ osd_state_t* osd_create(config_t* config) { osd->opacity = 0.67f; // 33% transparent = 67% opaque osd->display_duration_ms = 3000; // Show actions for 3 seconds osd->font_size = 13; // Default font size + osd->auto_show = 1; // Auto-show on key press by default + osd->last_action_time_ms = 0; osd->recent_count = 0; osd->recent_head = 0; osd->config = config; @@ -317,12 +319,16 @@ void osd_record_action(osd_state_t* osd, int button_index, const char* action) { if (osd->recent_actions[slot].action) free(osd->recent_actions[slot].action); // Store new action + long now = osd_get_time_ms(); osd->recent_actions[slot].key_name = strdup(BUTTON_NAMES[button_index]); osd->recent_actions[slot].action = action ? strdup(action) : strdup("(unknown)"); - osd->recent_actions[slot].timestamp_ms = osd_get_time_ms(); + osd->recent_actions[slot].timestamp_ms = now; + osd->last_action_time_ms = now; - // Trigger redraw if visible - if (osd->mode != OSD_MODE_HIDDEN) { + // Auto-show OSD if hidden and auto_show is enabled + if (osd->mode == OSD_MODE_HIDDEN && osd->auto_show && osd->display != NULL) { + osd_set_mode(osd, OSD_MODE_MINIMAL); + } else if (osd->mode != OSD_MODE_HIDDEN) { osd_redraw(osd); } } @@ -520,10 +526,23 @@ void osd_redraw(osd_state_t* osd) { // Process X11 events void osd_update(osd_state_t* osd) { - if (osd == NULL || osd->display == NULL || osd->mode == OSD_MODE_HIDDEN) return; + if (osd == NULL || osd->display == NULL) return; Display* dpy = (Display*)osd->display; Window win = (Window)osd->window; + long now = osd_get_time_ms(); + + // Auto-hide check: if auto_show is enabled, OSD is visible, and enough time passed + if (osd->auto_show && osd->mode != OSD_MODE_HIDDEN && osd->last_action_time_ms > 0) { + long time_since_action = now - osd->last_action_time_ms; + if (time_since_action > osd->display_duration_ms) { + osd_hide(osd); + return; + } + } + + // Only process X11 events if visible + if (osd->mode == OSD_MODE_HIDDEN) return; while (XPending(dpy)) { XEvent event; @@ -580,7 +599,6 @@ void osd_update(osd_state_t* osd) { // Check if we need to clear old actions and redraw static long last_cleanup = 0; - long now = osd_get_time_ms(); if (now - last_cleanup > 500) { // Check every 500ms last_cleanup = now; @@ -32,6 +32,8 @@ typedef struct { float opacity; // Background opacity (0.0-1.0) int display_duration_ms; // How long to show key actions int font_size; // Font size in pixels (default 13) + int auto_show; // Auto-show OSD on key press + long last_action_time_ms; // Time of last action (for auto-hide) // Recent actions buffer (circular) recent_action_t recent_actions[10];