Added crosshair implementation.

This commit is contained in:
Raimund Sacherer 2023-10-08 21:20:48 +02:00
parent 0ef07d24a9
commit c742f640af
9 changed files with 206 additions and 14 deletions

View file

@ -101,6 +101,10 @@ static const char *const binding_action_map[] = {
[BIND_ACTION_CLIPBOARD_PASTE] = "clipboard-paste",
[BIND_ACTION_PRIMARY_PASTE] = "primary-paste",
[BIND_ACTION_SEARCH_START] = "search-start",
[BIND_ACTION_CROSSHAIR] = "crosshair",
[BIND_ACTION_CROSSHAIR_FIX_POSITION] = "crosshair-fix-position",
[BIND_ACTION_CROSSHAIR_PIXEL_POSITION] = "crosshair-use-pixel-position",
[BIND_ACTION_CROSSHAIR_MOUSE_POSITION] = "crosshair-use-mouse-position",
[BIND_ACTION_FONT_SIZE_UP] = "font-increase",
[BIND_ACTION_FONT_SIZE_DOWN] = "font-decrease",
[BIND_ACTION_FONT_SIZE_RESET] = "font-reset",
@ -1252,6 +1256,7 @@ parse_section_colors(struct context *ctx)
}
else if (strcmp(key, "flash") == 0) color = &conf->colors.flash;
else if (strcmp(key, "crosshair") == 0) color = &conf->colors.crosshair;
else if (strcmp(key, "foreground") == 0) color = &conf->colors.fg;
else if (strcmp(key, "background") == 0) color = &conf->colors.bg;
else if (strcmp(key, "selection-foreground") == 0) color = &conf->colors.selection_fg;
@ -1349,6 +1354,19 @@ parse_section_colors(struct context *ctx)
return true;
}
else if (strcmp(key, "crosshair-alpha") == 0) {
float alpha;
if (!value_to_float(ctx, &alpha))
return false;
if (alpha < 0. || alpha > 1.) {
LOG_CONTEXTUAL_ERR("not in range 0.0-1.0");
return false;
}
conf->colors.crosshair_alpha = alpha * 65535.;
return true;
}
else {
LOG_CONTEXTUAL_ERR("not valid option");
@ -2846,6 +2864,10 @@ add_default_key_bindings(struct config *conf)
{BIND_ACTION_CLIPBOARD_PASTE, m_none, {{XKB_KEY_XF86Paste}}},
{BIND_ACTION_PRIMARY_PASTE, m_shift, {{XKB_KEY_Insert}}},
{BIND_ACTION_SEARCH_START, m_ctrl_shift, {{XKB_KEY_r}}},
{BIND_ACTION_CROSSHAIR, m_ctrl_shift, {{XKB_KEY_i}}},
{BIND_ACTION_CROSSHAIR_FIX_POSITION, m_ctrl_shift, {{XKB_KEY_f}}},
{BIND_ACTION_CROSSHAIR_MOUSE_POSITION, m_ctrl_shift, {{XKB_KEY_m}}},
{BIND_ACTION_CROSSHAIR_PIXEL_POSITION, m_ctrl_shift, {{XKB_KEY_p}}},
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, {{XKB_KEY_plus}}},
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, {{XKB_KEY_equal}}},
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, {{XKB_KEY_KP_Add}}},
@ -3036,6 +3058,8 @@ config_load(struct config *conf, const char *conf_path,
.bg = default_background,
.flash = 0x7f7f00,
.flash_alpha = 0x7fff,
.crosshair = default_foreground,
.crosshair_alpha = 0xffff,
.alpha = 0xffff,
.selection_fg = 0x80000000, /* Use default bg */
.selection_bg = 0x80000000, /* Use default fg */
@ -3077,7 +3101,6 @@ config_load(struct config *conf, const char *conf_path,
.border_width_visible = 0,
.button_width = 26,
},
.render_worker_count = sysconf(_SC_NPROCESSORS_ONLN),
.server_socket_path = get_server_socket_path(),
.presentation_timings = false,

View file

@ -204,7 +204,9 @@ struct config {
uint32_t fg;
uint32_t bg;
uint32_t flash;
uint32_t flash_alpha;
uint16_t flash_alpha;
uint32_t crosshair;
uint16_t crosshair_alpha;
uint32_t table[256];
uint16_t alpha;
uint32_t selection_fg;

View file

@ -625,6 +625,13 @@ can configure the background transparency with the _alpha_ option.
Default: _0.5_.
*crosshair*
Color to use for the crosshair cursor.
*crosshair-alpha*
Crosshair translucency. A value in the range 0.0-1.0, where 0.0
means completely transparent, and 1.0 is opaque.
*alpha*
Background translucency. A value in the range 0.0-1.0, where 0.0
means completely transparent, and 1.0 is opaque. Default: _1.0_.
@ -906,6 +913,41 @@ e.g. *search-start=none*.
Default: _Control+Shift+u_.
*crosshair*
Activates a crosshair on the current cursor position. Helps to
line up horizontal and vertical lines.
Default: _Control+Shift+i_.
*crosshair-fix-position*
A toggle switch to freeze the crosshair to the current cursor
location. The location is remembered even if the crosshair is
deactivated. Press the keyboard combination again to unfreeze
the crosshair.
Default: _Control+Shift+f_.
*crosshair-use-mouse-position*
By default the crosshair uses the current text cursor position.
This keybinding activates the mouse cursor position instead. If
the mouse option *hide-when-typing* is active, once the mouse
cursor is hidden by starting to type, the crosshair falls back to
the text cursor. This can be used for example to quickly check an
alignment on another part of the screen. To have the crosshair
remain on the new position use the *crosshair-fix-position*
keybinding.
The crosshair will be drawn at the cursor row and column the mouse
cursor points to.
Default: _Control+Shift+m_.
*crosshair-use-pixel-position*
Activates pixel precision for the crosshair when
*crosshair-use-mouse-position* is used.
Default: _Control+Shift+p_.
# SECTION: search-bindings
This section lets you override the default key bindings used in

View file

@ -80,6 +80,8 @@
# foreground=ffffff
# flash=7f7f00
# flash-alpha=0.5
# crosshair=ffffff
# crosshair_alpha=1.0
## Normal/regular colors (color palette 0-7)
# regular0=242424 # black
@ -164,6 +166,10 @@
# prompt-prev=Control+Shift+z
# prompt-next=Control+Shift+x
# unicode-input=Control+Shift+u
# crosshair=Control+Shift+i
# crosshair-fix-position=Control+Shift+f
# crosshair-use-pixel-position=Control+Shift+p
# crosshair-use-mouse-position=Control+Shift+m
# noop=none
[search-bindings]

18
input.c
View file

@ -186,6 +186,22 @@ execute_binding(struct seat *seat, struct terminal *term,
search_begin(term);
return true;
case BIND_ACTION_CROSSHAIR:
term->crosshair.active = !term->crosshair.active;
return true;
case BIND_ACTION_CROSSHAIR_FIX_POSITION:
term->crosshair.position_fixed = !term->crosshair.position_fixed;
return true;
case BIND_ACTION_CROSSHAIR_MOUSE_POSITION:
term->crosshair.use_mouse_position = !term->crosshair.use_mouse_position;
return true;
case BIND_ACTION_CROSSHAIR_PIXEL_POSITION:
term->crosshair.use_mouse_pixel_coordinates = !term->crosshair.use_mouse_pixel_coordinates;
return true;
case BIND_ACTION_FONT_SIZE_UP:
term_font_size_increase(term);
return true;
@ -429,7 +445,7 @@ execute_binding(struct seat *seat, struct terminal *term,
term_damage_view(term);
render_refresh(term);
break;
break;
}
return true;

View file

@ -22,6 +22,10 @@ enum bind_action_normal {
BIND_ACTION_CLIPBOARD_PASTE,
BIND_ACTION_PRIMARY_PASTE,
BIND_ACTION_SEARCH_START,
BIND_ACTION_CROSSHAIR,
BIND_ACTION_CROSSHAIR_MOUSE_POSITION,
BIND_ACTION_CROSSHAIR_FIX_POSITION,
BIND_ACTION_CROSSHAIR_PIXEL_POSITION,
BIND_ACTION_FONT_SIZE_UP,
BIND_ACTION_FONT_SIZE_DOWN,
BIND_ACTION_FONT_SIZE_RESET,

View file

@ -362,6 +362,7 @@ draw_underline_cursor(const struct terminal *term, pixman_image_t *pix,
PIXMAN_OP_SRC, pix, color,
1, &(pixman_rectangle16_t){
x, y + y_ofs, cols * term->cell_width, thickness});
}
static void
@ -1565,6 +1566,7 @@ render_overlay(struct terminal *term)
term->is_searching ? OVERLAY_SEARCH :
term->flash.active ? OVERLAY_FLASH :
unicode_mode_active ? OVERLAY_UNICODE_MODE :
term->crosshair.active ? OVERLAY_CROSSHAIR :
OVERLAY_NONE;
if (likely(style == OVERLAY_NONE)) {
@ -1582,6 +1584,7 @@ render_overlay(struct terminal *term)
return;
}
struct buffer *buf = shm_get_buffer(
term->render.chains.overlay, term->width, term->height);
@ -1603,6 +1606,13 @@ render_overlay(struct terminal *term)
term->conf->colors.flash,
term->conf->colors.flash_alpha);
break;
case OVERLAY_CROSSHAIR:
color = color_hex_to_pixman_with_alpha(
term->conf->colors.crosshair,
term->conf->colors.crosshair_alpha);
break;
}
/* Bounding rectangle of damaged areas - for wl_surface_damage_buffer() */
@ -1725,7 +1735,8 @@ render_overlay(struct terminal *term)
}
else if (buf == term->render.last_overlay_buf &&
style == term->render.last_overlay_style)
style == term->render.last_overlay_style &&
style != OVERLAY_CROSSHAIR)
{
xassert(style == OVERLAY_FLASH || style == OVERLAY_UNICODE_MODE);
shm_did_not_use_buf(buf);
@ -1735,9 +1746,78 @@ render_overlay(struct terminal *term)
damage_bounds = (pixman_box32_t){0, 0, buf->width, buf->height};
}
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){0, 0, term->width, term->height});
if (style == OVERLAY_CROSSHAIR) {
int cursor_row = term->grid->cursor.point.row;
int cursor_col = term->grid->cursor.point.col;
int mouse_x = 0;
int mouse_y = 0;
tll_foreach(term->wl->seats, it) {
if (it->item.kbd_focus == term) {
if (it->item.pointer.hidden == 0 &&
term->crosshair.use_mouse_position == true) {
cursor_row = it->item.mouse.row > 0 ? it->item.mouse.row : 0;
cursor_col = it->item.mouse.col > 0 ? it->item.mouse.col : 0;
mouse_x = it->item.mouse.x;
mouse_y = it->item.mouse.y;
break;
}
}
}
if (term->crosshair.position_fixed == true) {
cursor_row = term->render.last_crosshair.row;
cursor_col = term->render.last_crosshair.col;
mouse_x = term->render.last_crosshair.mouse_x;
mouse_y = term->render.last_crosshair.mouse_y;
}
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &(pixman_color_t){0}, 1,
&(pixman_rectangle16_t){0, 0, term->width, term->height});
if (term->crosshair.use_mouse_pixel_coordinates == false) {
int y = term->margins.top + (cursor_row * term->cell_height) + term->cell_height;
int y2 = 1; // --FIXME-- maybe define crosshair thickness?
if (y + y2 > term->height)
y = term->height - 1;
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){term->margins.left, y, term->width, y2} );
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){term->margins.left + (cursor_col * term->cell_width),
term->margins.top, 1, term->height} );
} else {
if (mouse_x > 0 || mouse_y > 0) {
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){term->margins.left, mouse_y, term->width, 1} );
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){mouse_x, term->margins.top, 1, term->height} );
}
}
if (term->crosshair.position_fixed == false) {
term->render.last_crosshair.row = cursor_row;
term->render.last_crosshair.col = cursor_col;
term->render.last_crosshair.mouse_x = mouse_x;
term->render.last_crosshair.mouse_y = mouse_y;
}
} else {
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 1,
&(pixman_rectangle16_t){0, 0, term->width, term->height});
}
quirk_weston_subsurface_desync_on(overlay->sub);
wayl_surface_scale(
@ -2234,7 +2314,7 @@ render_csd_button_maximize_window(
pixman_image_fill_rectangles(
PIXMAN_OP_SRC, buf->pix[0], &color, 4,
(pixman_rectangle16_t[]) {
{x_margin, y_margin, width, thick},
{ x_margin, y_margin, width, thick },
{ x_margin, y_margin + thick, thick, width - 2 * thick },
{ x_margin + width - thick, y_margin + thick, thick, width - 2 * thick },
{ x_margin, y_margin + width - thick, width, thick }

View file

@ -1172,8 +1172,6 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.colors = {
.fg = conf->colors.fg,
.bg = conf->colors.bg,
.flash = conf->colors.flash,
.flash_alpha = conf->colors.flash_alpha,
.alpha = conf->colors.alpha,
.selection_fg = conf->colors.selection_fg,
.selection_bg = conf->colors.selection_bg,
@ -1215,6 +1213,10 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
},
.num_lock_modifier = true,
.bell_action_enabled = true,
.crosshair.active = false,
.crosshair.position_fixed = false,
.crosshair.use_mouse_position = false,
.crosshair.use_mouse_pixel_coordinates = false,
.tab_stops = tll_init(),
.wl = wayl,
.render = {
@ -1926,9 +1928,7 @@ term_reset(struct terminal *term, bool hard)
fdm_del(term->fdm, term->blink.fd); term->blink.fd = -1;
term->colors.fg = term->conf->colors.fg;
term->colors.bg = term->conf->colors.bg;
term->colors.flash = term->conf->colors.flash;
term->colors.alpha = term->conf->colors.alpha;
term->colors.flash_alpha = term->conf->colors.flash_alpha;
term->colors.selection_fg = term->conf->colors.selection_fg;
term->colors.selection_bg = term->conf->colors.selection_bg;
term->colors.use_custom_selection = term->conf->colors.use_custom.selection;
@ -1968,6 +1968,12 @@ term_reset(struct terminal *term, bool hard)
}
term->normal.cur_row = term->normal.rows[0];
term->alt.cur_row = term->alt.rows[0];
term->crosshair.active = false;
term->crosshair.position_fixed = false;
term->crosshair.use_mouse_position = false;
term->crosshair.use_mouse_pixel_coordinates = false;
tll_free(term->normal.scroll_damage);
tll_free(term->alt.scroll_damage);
term->render.last_cursor.row = NULL;

View file

@ -332,6 +332,7 @@ enum overlay_style {
OVERLAY_SEARCH,
OVERLAY_FLASH,
OVERLAY_UNICODE_MODE,
OVERLAY_CROSSHAIR,
};
typedef tll(struct ptmx_buffer) ptmx_buffer_list_t;
@ -509,8 +510,6 @@ struct terminal {
struct {
uint32_t fg;
uint32_t bg;
uint32_t flash;
uint32_t flash_alpha;
uint32_t table[256];
uint16_t alpha;
uint32_t selection_fg;
@ -564,6 +563,13 @@ struct terminal {
} last;
} search;
struct {
bool active;
bool position_fixed;
bool use_mouse_position;
bool use_mouse_pixel_coordinates;
} crosshair;
struct wayland *wl;
struct wl_window *window;
bool visual_focus;
@ -637,6 +643,13 @@ struct terminal {
struct buffer *last_overlay_buf;
pixman_region32_t last_overlay_clip;
struct {
int row;
int col;
int mouse_x;
int mouse_y;
} last_crosshair;
size_t search_glyph_offset;
struct timespec input_time;