summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/textarea.c31
-rw-r--r--desktop/textarea.h16
-rw-r--r--desktop/tree.c2
3 files changed, 39 insertions, 10 deletions
diff --git a/desktop/textarea.c b/desktop/textarea.c
index cef2c6c70..2c7b7484d 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -1173,6 +1173,7 @@ int textarea_get_caret(struct textarea *ta)
void textarea_redraw(struct textarea *ta, int x, int y, colour bg,
const struct rect *clip, const struct redraw_context *ctx)
{
+ struct textarea_msg msg;
const struct plotter_table *plot = ctx->plot;
int line0, line1, line, left, right;
int chars, text_y_offset, text_y_offset_baseline;
@@ -1383,13 +1384,33 @@ void textarea_redraw(struct textarea *ta, int x, int y, colour bg,
if ((ta->sel_end == -1 || ta->sel_start == ta->sel_end) &&
ta->caret_pos.char_off >= 0) {
- /* There is no selection, and caret visible: draw caret */
+ /* There is no selection, and caret visible: show caret */
int caret_y = y - ta->scroll_y + ta->caret_y + text_y_offset;
- int caret_height = caret_y + ta->line_height;
- plot->line(x - ta->scroll_x + ta->caret_x, caret_y,
- x - ta->scroll_x + ta->caret_x, caret_height,
- &pstyle_stroke_caret);
+ if (ta->flags & TEXTAREA_INTERNAL_CARET) {
+ /* Render our own caret */
+ plot->line(x - ta->scroll_x + ta->caret_x, caret_y,
+ x - ta->scroll_x + ta->caret_x,
+ caret_y + ta->line_height,
+ &pstyle_stroke_caret);
+ } else {
+ /* Tell client where caret should be placed */
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_MOVED_CARET;
+ msg.data.caret.hidden = false;
+ msg.data.caret.x = x - ta->scroll_x + ta->caret_x;
+ msg.data.caret.y = caret_y;
+ msg.data.caret.height = ta->line_height;
+
+ ta->callback(ta->data, &msg);
+ }
+ } else if (!(ta->flags & TEXTAREA_INTERNAL_CARET)) {
+ /* Caret hidden, and client is responsible: tell client */
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_MOVED_CARET;
+ msg.data.caret.hidden = true;
+
+ ta->callback(ta->data, &msg);
}
if (ta->bar_x != NULL)
diff --git a/desktop/textarea.h b/desktop/textarea.h
index fb8b13425..6a1a4714d 100644
--- a/desktop/textarea.h
+++ b/desktop/textarea.h
@@ -34,9 +34,10 @@ struct textarea;
/* Text area flags */
typedef enum {
- TEXTAREA_DEFAULT = (1 << 0),
- TEXTAREA_MULTILINE = (1 << 1),
- TEXTAREA_READONLY = (1 << 2)
+ TEXTAREA_DEFAULT = (1 << 0), /**< Standard input */
+ TEXTAREA_MULTILINE = (1 << 1), /**< Multiline area */
+ TEXTAREA_READONLY = (1 << 2), /**< Non-editable */
+ TEXTAREA_INTERNAL_CARET = (1 << 3) /**< Render own caret */
} textarea_flags;
typedef enum {
@@ -47,7 +48,8 @@ typedef enum {
typedef enum {
TEXTAREA_MSG_DRAG_REPORT, /**< Textarea drag start/end report */
- TEXTAREA_MSG_REDRAW_REQUEST /**< Textarea redraw request */
+ TEXTAREA_MSG_REDRAW_REQUEST, /**< Textarea redraw request */
+ TEXTAREA_MSG_MOVED_CARET /**< Textarea caret moved */
} textarea_msg_type;
struct textarea_msg {
@@ -57,6 +59,12 @@ struct textarea_msg {
union {
textarea_drag_type drag;
struct rect redraw;
+ struct {
+ bool hidden;
+ int x;
+ int y;
+ int height;
+ } caret;
} data;
};
diff --git a/desktop/tree.c b/desktop/tree.c
index 4f9170d06..959b9870a 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -2972,7 +2972,7 @@ void tree_start_edit(struct tree *tree, struct node_element *element)
tree->ta_height = height;
- ta_setup.flags = TEXTAREA_DEFAULT;
+ ta_setup.flags = TEXTAREA_INTERNAL_CARET;
ta_setup.width = width;
ta_setup.height = tree->ta_height;
ta_setup.pad_top = 0;