diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index 457f3a24e0b..84dcd294a3f 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -84,6 +84,7 @@ const UserDef U_default = { .menuthreshold1 = 5, .menuthreshold2 = 2, .app_template = "", + .text_cursor_blink = true, /** Initialized by #UI_theme_init_default. */ .themes = {NULL}, diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index de44d09d96c..db515307201 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -282,6 +282,7 @@ class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): col.prop(view, "color_picker_type") col.row().prop(view, "header_align") col.prop(view, "factor_display_type") + col.prop(system, "text_cursor_blink") class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, Panel): diff --git a/source/blender/blenkernel/BKE_screen.hh b/source/blender/blenkernel/BKE_screen.hh index 0200155d580..934a0a0382e 100644 --- a/source/blender/blenkernel/BKE_screen.hh +++ b/source/blender/blenkernel/BKE_screen.hh @@ -89,8 +89,10 @@ struct SpaceType { /* Listeners can react to bContext changes */ void (*listener)(const wmSpaceTypeListenerParams *params); + /* Called when the mouse moves into the area. */ + void (*activate)(bContext *C, ScrArea *sa); /* called when the mouse moves out of the area */ - void (*deactivate)(ScrArea *area); + void (*deactivate)(bContext *C, ScrArea *area); /** Refresh context, called after file-reads, #ED_area_tag_refresh(). */ void (*refresh)(const bContext *C, ScrArea *area); diff --git a/source/blender/blenloader/intern/versioning_userdef.cc b/source/blender/blenloader/intern/versioning_userdef.cc index 389d1a6a70c..f38b4831570 100644 --- a/source/blender/blenloader/intern/versioning_userdef.cc +++ b/source/blender/blenloader/intern/versioning_userdef.cc @@ -950,6 +950,10 @@ void blo_do_versions_userdef(UserDef *userdef) } } + if (!USER_VERSION_ATLEAST(402, 23)) { + userdef->text_cursor_blink = true; + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a USER_VERSION_ATLEAST check. diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh index a6a67f563bc..b74ff017d51 100644 --- a/source/blender/editors/include/UI_interface.hh +++ b/source/blender/editors/include/UI_interface.hh @@ -42,6 +42,11 @@ class AbstractViewItem; void UI_but_func_set(uiBut *but, std::function func); void UI_but_func_pushed_state_set(uiBut *but, std::function func); +/* Blink value of 530ms is default Windows rate. */ +#define TEXT_CURSOR_BLINK_RATE 0.53f +/* Off position of cursor is dimmer, not really off. */ +#define TEXT_CURSOR_BLINK_OFF_OPACITY 0.35f + namespace blender::ui { class AbstractGridView; diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 423675f43dd..f3efb711977 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -3069,6 +3069,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con /* XXX pass on as arg. */ uiFontStyle fstyle = UI_style_get()->widget; const float aspect = but->block->aspect; + but->is_cursor_bright = true; float startx = but->rect.xmin; float starty_dummy = 0.0f; @@ -3201,6 +3202,7 @@ static void ui_textedit_move(uiBut *but, const int len = strlen(str); const int pos_prev = but->pos; const bool has_sel = (but->selend - but->selsta) > 0; + but->is_cursor_bright = true; ui_but_update(but); @@ -3413,6 +3415,15 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) MEM_SAFE_FREE(data->str); + if (data->wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(data->wm, win, data->wm->cursor_blink_timer); + } + if (U.text_cursor_blink) { + but->is_cursor_bright = true; + data->wm->cursor_blink_timer = WM_event_timer_add( + data->wm, win, TIMER, TEXT_CURSOR_BLINK_RATE); + } + #ifdef USE_DRAG_MULTINUM /* this can happen from multi-drag */ if (data->applied_interactive) { @@ -3527,6 +3538,11 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) { wmWindow *win = data->window; + if (data->wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(data->wm, win, data->wm->cursor_blink_timer); + data->wm->cursor_blink_timer = nullptr; + } + if (but) { if (UI_but_is_utf8(but)) { const int strip = BLI_str_utf8_invalid_strip(but->editstr, strlen(but->editstr)); @@ -11553,7 +11569,13 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void * /*userdat if (retval == WM_UI_HANDLER_CONTINUE) { if (but) { - retval = ui_handle_button_event(C, event, but); + if (event->type == TIMER) { + but->is_cursor_bright = !but->is_cursor_bright; + ED_region_tag_redraw(region); + } + else { + retval = ui_handle_button_event(C, event, but); + } } else { retval = ui_handle_button_over(C, event, region); diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index e2d260e7dae..05de5e84e64 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -185,6 +185,7 @@ struct uiBut { std::string drawstr; + bool is_cursor_bright = true; char *placeholder = nullptr; rctf rect = {}; /* block relative coords */ diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index b9cbaaf502a..c5b47de8b12 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -1998,13 +1998,14 @@ static void widget_draw_text(const uiFontStyle *fstyle, /* We are drawing on top of widget bases. Flush cache. */ GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_WIDGET_TEXT_CURSOR); + immUniformThemeColorAlpha( + TH_WIDGET_TEXT_CURSOR, + (but->is_cursor_bright || !U.text_cursor_blink) ? 1.0f : TEXT_CURSOR_BLINK_OFF_OPACITY); /* draw cursor */ immRecti(pos, @@ -2014,6 +2015,7 @@ static void widget_draw_text(const uiFontStyle *fstyle, rect->ymax - U.pixelsize); immUnbindProgram(); + GPU_blend(GPU_BLEND_NONE); #ifdef WITH_INPUT_IME /* IME candidate window uses cursor position. */ diff --git a/source/blender/editors/screen/screen_edit.cc b/source/blender/editors/screen/screen_edit.cc index 4c1b8af99df..97930124947 100644 --- a/source/blender/editors/screen/screen_edit.cc +++ b/source/blender/editors/screen/screen_edit.cc @@ -982,7 +982,14 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) { /* Call old area's deactivate if assigned. */ if (region == region_prev && area_iter->type && area_iter->type->deactivate) { - area_iter->type->deactivate(area_iter); + area_iter->type->deactivate(C, area_iter); + } + + /* Call new area's activate handler if defined. */ + if (region == screen->active_region && region != region_prev && area_iter->type && + area_iter->type->activate) + { + area_iter->type->activate(C, area_iter); } if (region == region_prev && region != screen->active_region) { diff --git a/source/blender/editors/space_console/console_draw.cc b/source/blender/editors/space_console/console_draw.cc index f08e0c9ed5a..180669a6e66 100644 --- a/source/blender/editors/space_console/console_draw.cc +++ b/source/blender/editors/space_console/console_draw.cc @@ -18,6 +18,7 @@ #include "GPU_immediate.hh" +#include "UI_interface.hh" #include "UI_resources.hh" #include "UI_view2d.hh" @@ -133,8 +134,8 @@ static void console_cursor_wrap_offset( static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int columns) { int pen[2]; + const SpaceConsole *sc = (SpaceConsole *)tvc->arg1; { - const SpaceConsole *sc = (SpaceConsole *)tvc->arg1; const ConsoleLine *cl = (ConsoleLine *)sc->history.last; int offl = 0, offc = 0; @@ -151,13 +152,25 @@ static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int c } /* cursor */ + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_CONSOLE_CURSOR); + + float color[4]; + if (sc->is_area_active) { + UI_GetThemeColor4fv(TH_CONSOLE_CURSOR, color); + color[3] = (sc->is_cursor_bright || !U.text_cursor_blink) ? 1.0f : + TEXT_CURSOR_BLINK_OFF_OPACITY; + } + else { + UI_GetThemeColorBlend4f(TH_BACK, TH_CONSOLE_INPUT, 0.3f, color); + } + immUniformColor4fv(color); immRectf(pos, pen[0] - U.pixelsize, pen[1], pen[0] + U.pixelsize, pen[1] + tvc->lheight); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/space_console/console_ops.cc b/source/blender/editors/space_console/console_ops.cc index 752d0966299..47db7e3f321 100644 --- a/source/blender/editors/space_console/console_ops.cc +++ b/source/blender/editors/space_console/console_ops.cc @@ -386,6 +386,7 @@ static int console_move_exec(bContext *C, wmOperator *op) ConsoleLine *ci = console_history_verify(C); ScrArea *area = CTX_wm_area(C); ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); + sc->is_cursor_bright = true; int type = RNA_enum_get(op->ptr, "type"); bool select = RNA_boolean_get(op->ptr, "select"); @@ -1286,6 +1287,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven /* only redraw if the selection changed */ if (sel_prev[0] != sc->sel_start || sel_prev[1] != sc->sel_end) { + sc->is_cursor_bright = true; ED_area_tag_redraw(area); } } diff --git a/source/blender/editors/space_console/space_console.cc b/source/blender/editors/space_console/space_console.cc index 4d54b364288..e493b355c60 100644 --- a/source/blender/editors/space_console/space_console.cc +++ b/source/blender/editors/space_console/space_console.cc @@ -26,6 +26,7 @@ #include "WM_api.hh" #include "WM_types.hh" +#include "UI_interface.hh" #include "UI_resources.hh" #include "UI_view2d.hh" @@ -298,6 +299,11 @@ static void console_main_region_listener(const wmRegionListenerParams *params) ED_region_tag_redraw(region); } } + else if (wmn->action == NA_CURSOR_BLINK) { + SpaceConsole *sconsole = static_cast(area->spacedata.first); + sconsole->is_cursor_bright = !bool(sconsole->is_cursor_bright); + ED_region_tag_redraw(region); + } else { /* generic redraw request */ ED_region_tag_redraw(region); @@ -343,6 +349,46 @@ static void console_space_blend_write(BlendWriter *writer, SpaceLink *sl) BLO_write_struct(writer, SpaceConsole, sl); } +static void console_activate(bContext *C, struct ScrArea *area) +{ + SpaceConsole *sc = static_cast(area->spacedata.first); + sc->is_area_active = true; + sc->is_cursor_bright = true; + + if (C) { + wmWindow *win = CTX_wm_window(C); + wmWindowManager *wm = CTX_wm_manager(C); + if (wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(wm, win, wm->cursor_blink_timer); + } + if (U.text_cursor_blink) { + wm->cursor_blink_timer = WM_event_timer_add_notifier( + wm, win, NC_SPACE | ND_SPACE_CONSOLE | NA_CURSOR_BLINK, TEXT_CURSOR_BLINK_RATE); + } + } + + /* Redraw to show active caret. */ + ED_region_tag_redraw(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); +} + +static void console_deactivate(bContext *C, struct ScrArea *area) +{ + SpaceConsole *sc = static_cast(area->spacedata.first); + sc->is_area_active = false; + sc->is_cursor_bright = false; + + if (C && area == CTX_wm_area(C)) { + wmWindowManager *wm = CTX_wm_manager(C); + if (wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(wm, CTX_wm_window(C), wm->cursor_blink_timer); + wm->cursor_blink_timer = nullptr; + } + } + + /* Redraw to remove active caret. */ + ED_region_tag_redraw(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); +} + void ED_spacetype_console() { std::unique_ptr st = std::make_unique(); @@ -360,6 +406,8 @@ void ED_spacetype_console() st->dropboxes = console_dropboxes; st->blend_read_data = console_blend_read_data; st->blend_write = console_space_blend_write; + st->activate = console_activate; + st->deactivate = console_deactivate; /* regions: main window */ art = static_cast(MEM_callocN(sizeof(ARegionType), "spacetype console region")); diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc index a1852392386..f0add1ec005 100644 --- a/source/blender/editors/space_outliner/space_outliner.cc +++ b/source/blender/editors/space_outliner/space_outliner.cc @@ -488,7 +488,7 @@ static void outliner_foreach_id(SpaceLink *space_link, LibraryForeachIDData *dat } } -static void outliner_deactivate(ScrArea *area) +static void outliner_deactivate(bContext * /*C*/, ScrArea *area) { /* Remove hover highlights */ SpaceOutliner *space_outliner = static_cast(area->spacedata.first); diff --git a/source/blender/editors/space_text/space_text.cc b/source/blender/editors/space_text/space_text.cc index d957e34e6e0..c7203bc3db5 100644 --- a/source/blender/editors/space_text/space_text.cc +++ b/source/blender/editors/space_text/space_text.cc @@ -131,6 +131,10 @@ static void text_listener(const wmSpaceTypeListenerParams *params) } switch (wmn->action) { + case NA_CURSOR_BLINK: + st->runtime->is_cursor_bright = !st->runtime->is_cursor_bright; + ED_region_tag_redraw_editor_overlays(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); + break; case NA_EDITED: if (st->text) { space_text_drawcache_tag_update(st, true); @@ -284,6 +288,11 @@ static void text_main_region_draw(const bContext *C, ARegion *region) /* scrollers? */ } +static void text_main_region_draw_overlay(const bContext *C, ARegion *region) +{ + draw_text_cursor(CTX_wm_space_text(C), region); +} + static void text_cursor(wmWindow *win, ScrArea *area, ARegion *region) { SpaceText *st = static_cast(area->spacedata.first); @@ -414,6 +423,46 @@ static void text_space_blend_write(BlendWriter *writer, SpaceLink *sl) BLO_write_struct(writer, SpaceText, sl); } +static void text_activate(bContext *C, struct ScrArea *area) +{ + SpaceText *st = static_cast(area->spacedata.first); + st->runtime->is_area_active = true; + st->runtime->is_cursor_bright = true; + + if (C) { + wmWindow *win = CTX_wm_window(C); + wmWindowManager *wm = CTX_wm_manager(C); + if (wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(wm, win, wm->cursor_blink_timer); + } + if (U.text_cursor_blink) { + wm->cursor_blink_timer = WM_event_timer_add_notifier( + wm, win, NC_TEXT | NA_CURSOR_BLINK, TEXT_CURSOR_BLINK_RATE); + } + + /* Redraw to show active text caret. */ + ED_region_tag_redraw(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); + } +} + +static void text_deactivate(bContext *C, struct ScrArea *area) +{ + SpaceText *st = static_cast(area->spacedata.first); + st->runtime->is_area_active = false; + st->runtime->is_cursor_bright = false; + + if (C) { + wmWindowManager *wm = CTX_wm_manager(C); + if (wm->cursor_blink_timer) { + WM_event_timer_remove_notifier(wm, CTX_wm_window(C), wm->cursor_blink_timer); + wm->cursor_blink_timer = nullptr; + } + } + + /* Redraw to remove active text caret. */ + ED_region_tag_redraw(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); +} + /********************* registration ********************/ void ED_spacetype_text() @@ -438,12 +487,15 @@ void ED_spacetype_text() st->blend_read_data = text_space_blend_read_data; st->blend_read_after_liblink = nullptr; st->blend_write = text_space_blend_write; + st->activate = text_activate; + st->deactivate = text_deactivate; /* regions: main window */ art = static_cast(MEM_callocN(sizeof(ARegionType), "spacetype text region")); art->regionid = RGN_TYPE_WINDOW; art->init = text_main_region_init; art->draw = text_main_region_draw; + art->draw_overlay = text_main_region_draw_overlay; art->cursor = text_cursor; art->event_cursor = true; diff --git a/source/blender/editors/space_text/text_draw.cc b/source/blender/editors/space_text/text_draw.cc index 72ee4fa6f82..84fb61ba0a8 100644 --- a/source/blender/editors/space_text/text_draw.cc +++ b/source/blender/editors/space_text/text_draw.cc @@ -1165,12 +1165,87 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc /** \name Draw Cursor * \{ */ +void draw_text_cursor(SpaceText *st, ARegion *region) +{ + if (st == nullptr || st->text == nullptr) { + return; + } + + bool hidden = false; + Text *text = st->text; + int vsell, vselc; + int x, y, w; + int offl, offc; + const int lheight = TXT_LINE_HEIGHT(st); + + /* Convert to view space character coordinates to determine if cursor is hidden */ + space_text_wrap_offset(st, region, text->sell, text->selc, &offl, &offc); + vsell = txt_get_span(static_cast(text->lines.first), text->sell) - st->top + offl; + vselc = space_text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc; + + if (vselc < 0) { + vselc = 0; + hidden = true; + } + + if (text->curl == text->sell && text->curc == text->selc && !st->line_hlight && hidden) { + /* Nothing to draw here */ + return; + } + + uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + + if (!hidden) { + /* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */ + x = TXT_BODY_LEFT(st) + (vselc * st->runtime->cwidth_px); + y = region->winy - vsell * lheight; + if (st->flags & ST_SCROLL_SELECT) { + y += st->runtime->scroll_ofs_px[1]; + } + + float color[4]; + if (st->runtime->is_area_active) { + UI_GetThemeColor4fv(TH_HILITE, color); + color[3] = (st->runtime->is_cursor_bright || !U.text_cursor_blink) ? + 1.0f : + TEXT_CURSOR_BLINK_OFF_OPACITY; + } + else { + UI_GetThemeColorBlend4f(TH_BACK, TH_TEXT, 0.3f, color); + } + immUniformColor4fv(color); + + GPU_blend(GPU_BLEND_ALPHA); + + if (st->overwrite) { + char ch = text->sell->line[text->selc]; + + y += TXT_LINE_SPACING(st); + w = st->runtime->cwidth_px; + if (ch == '\t') { + w *= st->tabnumber - (vselc + st->left) % st->tabnumber; + } + + immRecti( + pos, x, y - lheight - U.pixelsize, x + w + U.pixelsize, y - lheight - (3 * U.pixelsize)); + } + else { + immRecti(pos, x - U.pixelsize, y, x + U.pixelsize, y - lheight); + } + GPU_blend(GPU_BLEND_NONE); + } + + immUnbindProgram(); +} + static void draw_text_decoration(SpaceText *st, ARegion *region) { Text *text = st->text; int vcurl, vcurc, vsell, vselc; bool hidden = false; - int x, y, w, i; + int x, y, i; int offl, offc; const int lheight = TXT_LINE_HEIGHT(st); @@ -1297,33 +1372,6 @@ static void draw_text_decoration(SpaceText *st, ARegion *region) } } - if (!hidden) { - /* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */ - x = TXT_BODY_LEFT(st) + (vselc * st->runtime->cwidth_px); - y = region->winy - vsell * lheight; - if (st->flags & ST_SCROLL_SELECT) { - y += st->runtime->scroll_ofs_px[1]; - } - - immUniformThemeColor(TH_HILITE); - - if (st->overwrite) { - char ch = text->sell->line[text->selc]; - - y += TXT_LINE_SPACING(st); - w = st->runtime->cwidth_px; - if (ch == '\t') { - w *= st->tabnumber - (vselc + st->left) % st->tabnumber; - } - - immRecti( - pos, x, y - lheight - U.pixelsize, x + w + U.pixelsize, y - lheight - (3 * U.pixelsize)); - } - else { - immRecti(pos, x - U.pixelsize, y, x + U.pixelsize, y - lheight); - } - } - immUnbindProgram(); } @@ -1782,6 +1830,7 @@ void space_text_update_cursor_moved(bContext *C) ScrArea *area = CTX_wm_area(C); SpaceText *st = CTX_wm_space_text(C); + st->runtime->is_cursor_bright = true; space_text_scroll_to_cursor_with_area(st, area, true); } diff --git a/source/blender/editors/space_text/text_intern.hh b/source/blender/editors/space_text/text_intern.hh index bfbc6a9141a..c056a83403b 100644 --- a/source/blender/editors/space_text/text_intern.hh +++ b/source/blender/editors/space_text/text_intern.hh @@ -24,6 +24,8 @@ struct wmOperatorType; void draw_text_main(SpaceText *st, ARegion *region); +void draw_text_cursor(SpaceText *st, ARegion *region); + void text_update_line_edited(TextLine *line); void text_update_edited(Text *text); @@ -208,6 +210,9 @@ struct SpaceText_Runtime { */ int scroll_ofs_px[2]{0, 0}; + bool is_area_active; + bool is_cursor_bright; + /** Cache for faster drawing. */ void *drawcache = nullptr; }; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 27c96628330..1392b2a090a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1712,6 +1712,10 @@ typedef struct SpaceConsole { int lheight; + char is_area_active; + char is_cursor_bright; + char _pad[6]; + /** Index into history of most recent up/down arrow keys. */ int history_index; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 09f69db825e..d210a554383 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -1060,7 +1060,9 @@ typedef struct UserDef { float collection_instance_empty_size; char text_flag; - char _pad10[1]; + + /* Blinking text cursor (caret) in various text inputs and editors. */ + char text_cursor_blink; char file_preview_type; /* eUserpref_File_Preview_Type */ char statusbar_flag; /* eUserpref_StatusBar_Flag */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index c89a858285c..94fbaaf029b 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -208,6 +208,8 @@ typedef struct wmWindowManager { /** Active timers. */ ListBase timers; + /** Timer for text cursor blinking. */ + struct wmTimer *cursor_blink_timer; /** Timer for auto save. */ struct wmTimer *autosavetimer; /** Auto-save timer was up, but it wasn't possible to auto-save in the current mode. */ diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index cd8787da1a9..573cd361c35 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -5945,6 +5945,11 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_sdna(prop, nullptr, "pixelsize"); + prop = RNA_def_property(srna, "text_cursor_blink", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Text Cursor Blink", "Blinking cursor when the area is active"); + RNA_def_property_update(prop, 0, "rna_userdef_gpu_update"); + /* Memory */ prop = RNA_def_property(srna, "memory_cache_limit", PROP_INT, PROP_NONE); diff --git a/source/blender/windowmanager/WM_types.hh b/source/blender/windowmanager/WM_types.hh index 3ee68207f9d..9943e099c0f 100644 --- a/source/blender/windowmanager/WM_types.hh +++ b/source/blender/windowmanager/WM_types.hh @@ -553,6 +553,7 @@ struct wmNotifier { #define NA_ACTIVATED 7 #define NA_PAINTING 8 #define NA_JOB_FINISHED 9 +#define NA_CURSOR_BLINK 10 /* ************** Gesture Manager data ************** */