use the actual cursor for selection mode
This commit is contained in:
parent
c55ac0f5ae
commit
ad3f6b3144
41
termite.c
41
termite.c
|
@ -1,5 +1,6 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -32,7 +33,6 @@ typedef struct select_info {
|
||||||
AtkText *text;
|
AtkText *text;
|
||||||
select_mode mode;
|
select_mode mode;
|
||||||
int begin;
|
int begin;
|
||||||
int end;
|
|
||||||
} select_info;
|
} select_info;
|
||||||
|
|
||||||
typedef struct search_panel_info {
|
typedef struct search_panel_info {
|
||||||
|
@ -96,16 +96,25 @@ static void update_selection(VteTerminal *vte, select_info *select) {
|
||||||
|
|
||||||
remove_selection(select->text);
|
remove_selection(select->text);
|
||||||
|
|
||||||
|
int offset = atk_text_get_caret_offset(select->text);
|
||||||
|
|
||||||
atk_text_add_selection(select->text,
|
atk_text_add_selection(select->text,
|
||||||
MIN(select->begin, select->end),
|
MIN(select->begin, offset),
|
||||||
MAX(select->begin, select->end));
|
MAX(select->begin, offset));
|
||||||
|
|
||||||
vte_terminal_copy_primary(vte);
|
vte_terminal_copy_primary(vte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_selection(select_info *select) {
|
#define CSI "\x1b["
|
||||||
|
|
||||||
|
static void start_selection(VteTerminal *vte, select_info *select) {
|
||||||
|
vte_terminal_feed(vte, CSI "s", sizeof CSI "s"); // save cursor position
|
||||||
select->mode = SELECT_ON;
|
select->mode = SELECT_ON;
|
||||||
select->end = atk_text_get_caret_offset(select->text);
|
}
|
||||||
|
|
||||||
|
static void end_selection(VteTerminal *vte, select_info *select) {
|
||||||
|
vte_terminal_feed(vte, CSI "u", sizeof CSI "u"); // restore cursor position
|
||||||
|
select->mode = SELECT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void toggle_visual(select_info *select) {
|
static void toggle_visual(select_info *select) {
|
||||||
|
@ -114,7 +123,7 @@ static void toggle_visual(select_info *select) {
|
||||||
remove_selection(select->text);
|
remove_selection(select->text);
|
||||||
} else {
|
} else {
|
||||||
select->mode = SELECT_VISUAL;
|
select->mode = SELECT_VISUAL;
|
||||||
select->begin = select->end;
|
select->begin = atk_text_get_caret_offset(select->text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,19 +134,29 @@ gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *i
|
||||||
switch (event->keyval) {
|
switch (event->keyval) {
|
||||||
case GDK_KEY_Left:
|
case GDK_KEY_Left:
|
||||||
case GDK_KEY_h:
|
case GDK_KEY_h:
|
||||||
info->select.end--;
|
vte_terminal_feed(vte, CSI "1D", strlen(CSI "1D"));
|
||||||
|
update_selection(vte, &info->select);
|
||||||
|
break;
|
||||||
|
case GDK_KEY_Down:
|
||||||
|
case GDK_KEY_j:
|
||||||
|
vte_terminal_feed(vte, CSI "1B", strlen(CSI "1B"));
|
||||||
|
update_selection(vte, &info->select);
|
||||||
|
break;
|
||||||
|
case GDK_KEY_Up:
|
||||||
|
case GDK_KEY_k:
|
||||||
|
vte_terminal_feed(vte, CSI "1A", strlen(CSI "1A"));
|
||||||
update_selection(vte, &info->select);
|
update_selection(vte, &info->select);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_Right:
|
case GDK_KEY_Right:
|
||||||
case GDK_KEY_l:
|
case GDK_KEY_l:
|
||||||
info->select.end++;
|
vte_terminal_feed(vte, CSI "1C", strlen(CSI "1C"));
|
||||||
update_selection(vte, &info->select);
|
update_selection(vte, &info->select);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_v:
|
case GDK_KEY_v:
|
||||||
toggle_visual(&info->select);
|
toggle_visual(&info->select);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_Escape:
|
case GDK_KEY_Escape:
|
||||||
info->select.mode = SELECT_OFF;
|
end_selection(vte, &info->select);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -145,7 +164,7 @@ gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_info *i
|
||||||
if (modifiers == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) {
|
if (modifiers == (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) {
|
||||||
switch (gdk_keyval_to_lower(event->keyval)) {
|
switch (gdk_keyval_to_lower(event->keyval)) {
|
||||||
case GDK_KEY_space:
|
case GDK_KEY_space:
|
||||||
start_selection(&info->select);
|
start_selection(vte, &info->select);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case GDK_KEY_c:
|
case GDK_KEY_c:
|
||||||
vte_terminal_copy_clipboard(vte);
|
vte_terminal_copy_clipboard(vte);
|
||||||
|
@ -641,7 +660,7 @@ int main(int argc, char **argv) {
|
||||||
gtk_container_add(GTK_CONTAINER(overlay), vte);
|
gtk_container_add(GTK_CONTAINER(overlay), vte);
|
||||||
gtk_container_add(GTK_CONTAINER(window), overlay);
|
gtk_container_add(GTK_CONTAINER(window), overlay);
|
||||||
|
|
||||||
select_info select = {ATK_TEXT(vte_terminal_accessible_new(VTE_TERMINAL(vte))), SELECT_OFF, 0, 0};
|
select_info select = {ATK_TEXT(vte_terminal_accessible_new(VTE_TERMINAL(vte))), SELECT_OFF, 0};
|
||||||
search_panel_info info = {vte, entry, alignment, OVERLAY_HIDDEN, select};
|
search_panel_info info = {vte, entry, alignment, OVERLAY_HIDDEN, select};
|
||||||
|
|
||||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
|
Loading…
Reference in New Issue