@@ -3826,12 +3826,27 @@ NK_API void nk_contextual_end(struct nk_context*);
38263826 * TOOLTIP
38273827 *
38283828 * ============================================================================= */
3829+ enum nk_tooltip_flags {
3830+ /**!< tells where tooltip should appear relatively to the cursor, can be combined (e.g. BELOW|ON_RIGHT) */
3831+ NK_TOOLTIP_ABOVE = NK_FLAG(0),
3832+ NK_TOOLTIP_BELOW = NK_FLAG(1),
3833+ NK_TOOLTIP_ON_LEFT = NK_FLAG(2),
3834+ NK_TOOLTIP_ON_RIGHT = NK_FLAG(3),
3835+ /**!< if set, the offset will be absolute, instead of relative */
3836+ NK_TOOLTIP_ABS_OFFSET = NK_FLAG(4)
3837+ /* FIXME: https://github.com/Immediate-Mode-UI/Nuklear/issues/899 */
3838+ /*NK_TOOLTIP_CLAMP_IN_SCREEN = NK_FLAG(5),*/
3839+ };
38293840NK_API void nk_tooltip(struct nk_context*, const char*);
3841+ NK_API void nk_tooltip_offset(struct nk_context *ctx, const char *text, nk_flags tooltip, struct nk_vec2);
38303842#ifdef NK_INCLUDE_STANDARD_VARARGS
38313843NK_API void nk_tooltipf(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(2);
38323844NK_API void nk_tooltipfv(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(2);
3845+ NK_API void nk_tooltipf_offset(struct nk_context*, nk_flags tooltip, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(4);
3846+ NK_API void nk_tooltipfv_offset(struct nk_context*, nk_flags tooltip, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char*, va_list) NK_PRINTF_VALIST_FUNC(4);
38333847#endif
38343848NK_API nk_bool nk_tooltip_begin(struct nk_context*, float width);
3849+ NK_API nk_bool nk_tooltip_begin_offset(struct nk_context*, float width, nk_flags tooltip, struct nk_vec2);
38353850NK_API void nk_tooltip_end(struct nk_context*);
38363851/* =============================================================================
38373852 *
@@ -30603,8 +30618,38 @@ nk_combobox_callback(struct nk_context *ctx,
3060330618 * TOOLTIP
3060430619 *
3060530620 * ===============================================================*/
30621+ NK_LIB struct nk_vec2
30622+ nk_tooltip_get_default_offset(const struct nk_context *ctx)
30623+ {
30624+ struct nk_vec2 offset = {0};
30625+ NK_ASSERT(ctx);
30626+ if (!ctx) return offset;
30627+ if (ctx->style.cursor_active) {
30628+ /* nuklear is drawing its own cursor so we can reuse its size (best case!) */
30629+ offset.x = ctx->style.window.padding.x + ctx->style.cursor_active->size.x;
30630+ offset.x = ctx->style.window.padding.y + ctx->style.cursor_active->size.y;
30631+ } else if (ctx->style.font) {
30632+ /* assume that cursor size is similar to font height (flawed but reasonable)*/
30633+ offset.y = ctx->style.window.padding.x + ctx->style.font->height;
30634+ offset.x = ctx->style.window.padding.y + ctx->style.font->height;
30635+ }
30636+ return offset;
30637+ }
30638+ NK_LIB nk_flags
30639+ nk_tooltip_get_default_flags(const struct nk_context *ctx)
30640+ {
30641+ NK_UNUSED(ctx);
30642+ return NK_TOOLTIP_BELOW|NK_TOOLTIP_ON_RIGHT;
30643+ }
3060630644NK_API nk_bool
3060730645nk_tooltip_begin(struct nk_context *ctx, float width)
30646+ {
30647+ return nk_tooltip_begin_offset(ctx, width,
30648+ nk_tooltip_get_default_flags(ctx),
30649+ nk_tooltip_get_default_offset(ctx));
30650+ }
30651+ NK_API nk_bool
30652+ nk_tooltip_begin_offset(struct nk_context *ctx, float width, nk_flags tooltip, struct nk_vec2 offset)
3060830653{
3060930654 int x,y,w,h;
3061030655 struct nk_window *win;
@@ -30625,14 +30670,34 @@ nk_tooltip_begin(struct nk_context *ctx, float width)
3062530670 return 0;
3062630671
3062730672 w = nk_iceilf(width);
30628- h = nk_iceilf(nk_null_rect.h);
30629- x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
30630- y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
30673+ h = ctx->current->layout->row.min_height;
30674+
30675+ /* turn relative offset into absolute one, unless it's already absolute */
30676+ if ((tooltip & NK_TOOLTIP_ON_LEFT) && !(tooltip & NK_TOOLTIP_ABS_OFFSET))
30677+ offset.x *= -1;
30678+ if ((tooltip & NK_TOOLTIP_ABOVE) && !(tooltip & NK_TOOLTIP_ABS_OFFSET))
30679+ offset.y *= -1;
30680+
30681+ x = 0;
30682+ x -= !!(tooltip & NK_TOOLTIP_ON_LEFT );
30683+ x += !!(tooltip & NK_TOOLTIP_ON_RIGHT);
30684+ NK_ASSERT(x == -1 || x == 0 || x == 1);
30685+ x = -w/2 + (x * w/2);
30686+ x += nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
30687+ x += offset.x;
30688+
30689+ y = 0;
30690+ y -= !!(tooltip & NK_TOOLTIP_ABOVE);
30691+ y += !!(tooltip & NK_TOOLTIP_BELOW);
30692+ NK_ASSERT(y == -1 || y == 0 || y == 1);
30693+ y = -h/2 + (y * h/2);
30694+ y += nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
30695+ y += offset.y;
3063130696
3063230697 bounds.x = (float)x;
3063330698 bounds.y = (float)y;
3063430699 bounds.w = (float)w;
30635- bounds.h = (float)h ;
30700+ bounds.h = (float)nk_iceilf(nk_null_rect.h) ;
3063630701
3063730702 ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
3063830703 "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
@@ -30641,7 +30706,6 @@ nk_tooltip_begin(struct nk_context *ctx, float width)
3064130706 ctx->current->layout->type = NK_PANEL_TOOLTIP;
3064230707 return ret;
3064330708}
30644-
3064530709NK_API void
3064630710nk_tooltip_end(struct nk_context *ctx)
3064730711{
@@ -30653,7 +30717,7 @@ nk_tooltip_end(struct nk_context *ctx)
3065330717 nk_popup_end(ctx);
3065430718}
3065530719NK_API void
30656- nk_tooltip (struct nk_context *ctx, const char *text)
30720+ nk_tooltip_offset (struct nk_context *ctx, const char *text, nk_flags tooltip, struct nk_vec2 offset )
3065730721{
3065830722 const struct nk_style *style;
3065930723 struct nk_vec2 padding;
@@ -30681,14 +30745,29 @@ nk_tooltip(struct nk_context *ctx, const char *text)
3068130745 text_height = (style->font->height + 2 * padding.y);
3068230746
3068330747 /* execute tooltip and fill with text */
30684- if (nk_tooltip_begin (ctx, (float)text_width)) {
30748+ if (nk_tooltip_begin_offset (ctx, (float)text_width, tooltip, offset )) {
3068530749 nk_layout_row_dynamic(ctx, (float)text_height, 1);
3068630750 nk_text(ctx, text, text_len, NK_TEXT_LEFT);
3068730751 nk_tooltip_end(ctx);
3068830752 }
3068930753}
30754+ NK_API void
30755+ nk_tooltip(struct nk_context *ctx, const char *text)
30756+ {
30757+ nk_tooltip_offset(ctx, text,
30758+ nk_tooltip_get_default_flags(ctx),
30759+ nk_tooltip_get_default_offset(ctx));
30760+ }
3069030761#ifdef NK_INCLUDE_STANDARD_VARARGS
3069130762NK_API void
30763+ nk_tooltipf_offset(struct nk_context *ctx, nk_flags tooltip, struct nk_vec2 offset, const char *fmt, ...)
30764+ {
30765+ va_list args;
30766+ va_start(args, fmt);
30767+ nk_tooltipfv_offset(ctx, tooltip, offset, fmt, args);
30768+ va_end(args);
30769+ }
30770+ NK_API void
3069230771nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
3069330772{
3069430773 va_list args;
@@ -30697,6 +30776,13 @@ nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
3069730776 va_end(args);
3069830777}
3069930778NK_API void
30779+ nk_tooltipfv_offset(struct nk_context *ctx, nk_flags tooltip, struct nk_vec2 offset, const char *fmt, va_list args)
30780+ {
30781+ char buf[256];
30782+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
30783+ nk_tooltip_offset(ctx, buf, tooltip, offset);
30784+ }
30785+ NK_API void
3070030786nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
3070130787{
3070230788 char buf[256];
@@ -30762,6 +30848,8 @@ nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
3076230848/// - [y]: Minor version with non-breaking API and library changes
3076330849/// - [z]: Patch version with no direct changes to the API
3076430850///
30851+ /// - 2026/02/17 (4.13.3) - Fixed default tooltip from being covered by the cursor,
30852+ /// added new tooltip variation that allows to set the offset manually
3076530853/// - 2026/01/31 (4.13.2) - Fix: replace incorrect static asserts for size(nk_bool)
3076630854/// - 2026/01/26 (4.13.1) - Fix: nk_do_property now uses NK_STRTOD via macro
3076730855/// - Fix: failure to build from source, due to
0 commit comments