/* Text Selection Mode for hterm - Add to x.c */
/* Add these variables near the top with other static variables (around line 250) */
static int text_selection_mode = 0;
static int selection_start_x = 0;
static int selection_start_y = 0;
static int selection_anchor_x = 0;
static int selection_anchor_y = 0;
static struct timespec last_click_time;
static int click_count = 0;
/* Modify the bpress function to handle text selection mode entry */
void
bpress(XEvent *e)
{
int btn = e->xbutton.button;
struct timespec now;
int snap;
if (1 <= btn && btn <= 11)
buttons |= 1 << (btn-1);
/* Handle text selection mode for left click (Button1) */
if (btn == Button1 && !IS_SET(MODE_MOUSE)) {
clock_gettime(CLOCK_MONOTONIC, &now);
/* Check if we're in text selection mode */
if (text_selection_mode) {
/* Exit text selection mode on second click */
text_selection_mode = 0;
/* Keep the selection */
setsel(getsel(), e->xbutton.time);
return;
} else {
/* Enter text selection mode on first click */
text_selection_mode = 1;
/* Clear any existing selection */
selclear();
/* Store the starting position */
selection_start_x = evcol(e);
selection_start_y = evrow(e);
selection_anchor_x = selection_start_x;
selection_anchor_y = selection_start_y;
/* Start selection at current position */
selstart(selection_start_x, selection_start_y, 0);
/* Store click time for potential double/triple click detection */
last_click_time = now;
return;
}
}
/* Original mouse handling code for other cases */
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e);
return;
}
if (mouseaction(e, 0))
return;
/* Original Button1 handling when not in text selection mode */
if (btn == Button1 && !text_selection_mode) {
clock_gettime(CLOCK_MONOTONIC, &now);
if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) {
snap = SNAP_LINE;
} else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) {
snap = SNAP_WORD;
} else {
snap = 0;
}
xsel.tclick2 = xsel.tclick1;
xsel.tclick1 = now;
selstart(evcol(e), evrow(e), snap);
}
}
/* Modify the bmotion function to handle text selection during movement */
void
bmotion(XEvent e)
{
/ Handle text selection mode */
if (text_selection_mode) {
int current_x = evcol(e);
int current_y = evrow(e);
/* Extend selection to current mouse position */
selextend(current_x, current_y, SEL_REGULAR, 0);
/* Trigger redraw to show selection */
draw();
return;
}
/* Original trackpad motion handling */
if (IS_SET(MODE_TRACKPAD)) {
trackpadmotion(e);
return;
}
/* Original mouse motion handling */
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e);
return;
}
mousesel(e, 0);
}
/* Add a helper function to check if we're in text selection mode */
int
is_text_selection_mode(void)
{
return text_selection_mode;
}
/* Modify the focus function to cancel text selection mode on focus loss */
void
focus(XEvent *ev)
{
XFocusChangeEvent *e = &ev->xfocus;
if (e->mode == NotifyGrab)
return;
if (ev->type == FocusIn) {
if (xw.ime.xic)
XSetICFocus(xw.ime.xic);
win.mode |= MODE_FOCUSED;
xseturgency(0);
if (IS_SET(MODE_FOCUS))
ttywrite("\033[I", 3, 0);
if (trackpadRemap) {
win.mode |= MODE_TRACKPAD;
trackpad_reset_pos = 1;
XGrabPointer(xw.dpy, xw.win, False, PointerMotionMask,
GrabModeAsync, GrabModeAsync, None, blank_cursor, CurrentTime);
}
} else {
if (xw.ime.xic)
XUnsetICFocus(xw.ime.xic);
win.mode &= ~MODE_FOCUSED;
if (IS_SET(MODE_FOCUS))
ttywrite("\033[O", 3, 0);
if (trackpadRemap) {
win.mode &= ~MODE_TRACKPAD;
trackpad_dx = 0;
trackpad_dy = 0;
XUngrabPointer(xw.dpy, CurrentTime);
XDefineCursor(xw.dpy, xw.win, normal_cursor);
}
/* Cancel text selection mode on focus loss */
text_selection_mode = 0;
}
}
/* Optional: Add keyboard shortcuts to cancel text selection mode */
void
kpress(XEvent *ev)
{
XKeyEvent *e = &ev->xkey;
KeySym ksym = NoSymbol;
char buf[64], *customkey;
int len;
Rune c;
Status status;
Shortcut *bp;
/* Cancel text selection mode on Escape key */
if (text_selection_mode) {
if (xw.ime.xic) {
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
if (status == XBufferOverflow)
return;
} else {
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
}
if (ksym == XK_Escape) {
text_selection_mode = 0;
selclear();
return;
}
}
/* Original kpress code continues... */
if (IS_SET(MODE_KBDLOCK))
return;
if (xw.ime.xic) {
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
if (status == XBufferOverflow)
return;
} else {
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
}
/* 1. shortcuts */
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
if (ksym == bp->keysym && match(bp->mod, e->state)) {
bp->func(&(bp->arg));
return;
}
}
/* 2. custom keys from config.h */
if ((customkey = kmap(ksym, e->state))) {
ttywrite(customkey, strlen(customkey), 1);
return;
}
/* 3. composed string from input method */
if (len == 0)
return;
if (len == 1 && e->state & Mod1Mask) {
if (IS_SET(MODE_8BIT)) {
if (*buf < 0177) {
c = *buf | 0x80;
len = utf8encode(c, buf);
}
} else {
buf[1] = buf[0];
buf[0] = '\033';
len = 2;
}
}
ttywrite(buf, len, 1);
}
/* Text Selection Mode for hterm - Add to x.c */
/* Add these variables near the top with other static variables (around line 250) */
static int text_selection_mode = 0;
static int selection_start_x = 0;
static int selection_start_y = 0;
static int selection_anchor_x = 0;
static int selection_anchor_y = 0;
static struct timespec last_click_time;
static int click_count = 0;
/* Modify the bpress function to handle text selection mode entry */
void
bpress(XEvent *e)
{
int btn = e->xbutton.button;
struct timespec now;
int snap;
}
/* Modify the bmotion function to handle text selection during movement */
void
bmotion(XEvent e)
{
/ Handle text selection mode */
if (text_selection_mode) {
int current_x = evcol(e);
int current_y = evrow(e);
}
/* Add a helper function to check if we're in text selection mode */
int
is_text_selection_mode(void)
{
return text_selection_mode;
}
/* Modify the focus function to cancel text selection mode on focus loss */
void
focus(XEvent *ev)
{
XFocusChangeEvent *e = &ev->xfocus;
}
/* Optional: Add keyboard shortcuts to cancel text selection mode */
void
kpress(XEvent *ev)
{
XKeyEvent *e = &ev->xkey;
KeySym ksym = NoSymbol;
char buf[64], *customkey;
int len;
Rune c;
Status status;
Shortcut *bp;
}