Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-06-25 13:29:53 +01:00
19 changed files with 2811 additions and 1733 deletions

170
window.c
View File

@@ -78,6 +78,14 @@ RB_GENERATE(windows, window, entry, window_cmp);
RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
RB_GENERATE(window_pane_tree, window_pane, tree_entry, window_pane_cmp);
struct window_pane_prompt {
u_int wp_id;
struct client *c;
status_prompt_input_cb inputcb;
prompt_free_cb freecb;
void *data;
};
int
window_cmp(struct window *w1, struct window *w2)
{
@@ -1155,6 +1163,8 @@ window_pane_destroy(struct window_pane *wp)
window_pane_wait_finish(wp);
spawn_editor_finish(wp);
window_pane_clear_prompt(wp);
window_pane_free_modes(wp);
free(wp->searchstr);
@@ -1371,6 +1381,7 @@ window_pane_reset_mode(struct window_pane *wp)
server_kill_pane(wp);
}
/* Reset all modes. */
void
window_pane_reset_mode_all(struct window_pane *wp)
{
@@ -1378,6 +1389,165 @@ window_pane_reset_mode_all(struct window_pane *wp)
window_pane_reset_mode(wp);
}
/* Prompt input callback. */
static enum prompt_result
window_pane_prompt_input_callback(void *data, const char *s,
enum prompt_key_result key)
{
struct window_pane_prompt *wpp = data;
if (wpp->inputcb != NULL)
return (wpp->inputcb(wpp->c, wpp->data, s, key));
return (PROMPT_CLOSE);
}
/* Prompt free callback. */
static void
window_pane_prompt_free_callback(void *data)
{
struct window_pane_prompt *wpp = data;
struct window_pane *wp;
wp = window_pane_find_by_id(wpp->wp_id);
if (wp != NULL && wp->prompt_data == wpp)
wp->prompt_data = NULL;
if (wpp->freecb != NULL)
wpp->freecb(wpp->data);
free(wpp);
}
/* Open a prompt owned by a pane, drawn over the pane instead of the status. */
void
window_pane_set_prompt(struct window_pane *wp, struct client *c,
struct cmd_find_state *fs, const char *msg, const char *input,
status_prompt_input_cb inputcb, prompt_free_cb freecb, void *data,
int flags, enum prompt_type type)
{
struct session *s = NULL;
struct prompt_create_data pd;
struct window_pane_prompt *wpp;
if (c != NULL)
s = c->session;
window_pane_clear_prompt(wp);
wpp = xcalloc(1, sizeof *wpp);
wpp->wp_id = wp->id;
wpp->c = c;
wpp->inputcb = inputcb;
wpp->freecb = freecb;
wpp->data = data;
memset(&pd, 0, sizeof pd);
prompt_set_options(&pd, s);
pd.fs = fs;
pd.prompt = msg;
pd.input = input;
pd.type = type;
pd.flags = flags;
pd.inputcb = window_pane_prompt_input_callback;
pd.freecb = window_pane_prompt_free_callback;
pd.data = wpp;
wp->prompt = prompt_create(&pd);
wp->prompt_data = wpp;
wp->flags |= PANE_REDRAW;
prompt_incremental_start(wp->prompt);
}
/* Close a pane prompt. */
void
window_pane_clear_prompt(struct window_pane *wp)
{
struct prompt *prompt = wp->prompt;
if (prompt == NULL)
return;
wp->prompt = NULL;
prompt_free(prompt);
wp->flags |= PANE_REDRAW;
}
/* Does this pane have an open prompt? */
int
window_pane_has_prompt(struct window_pane *wp)
{
return (wp->prompt != NULL);
}
/* Replace the message and input of an open pane prompt. */
void
window_pane_update_prompt(struct window_pane *wp, const char *msg,
const char *input)
{
if (wp->prompt != NULL) {
prompt_update(wp->prompt, msg, input);
wp->flags |= PANE_REDRAW;
}
}
/*
* Pass a key to a pane prompt. The client is set transiently for the duration
* of the key in case the prompt or pane is destroyed by the callback.
*/
enum prompt_key_result
window_pane_prompt_key(struct window_pane *wp, struct client *c, key_code key,
struct mouse_event *m)
{
struct prompt *prompt = wp->prompt;
struct window_pane_prompt *wpp = wp->prompt_data;
enum prompt_key_result result;
u_int wp_id = wp->id, x, y, py;
int redraw = 0;
if (prompt == NULL)
return (PROMPT_KEY_NOT_HANDLED);
if (wpp != NULL)
wpp->c = c;
if (KEYC_IS_MOUSE(key)) {
if (m == NULL ||
MOUSE_BUTTONS(m->b) != MOUSE_BUTTON_1 ||
MOUSE_DRAG(m->b) ||
MOUSE_RELEASE(m->b) ||
cmd_mouse_at(wp, m, &x, &y, 0) != 0)
result = PROMPT_KEY_NOT_HANDLED;
else {
if (c != NULL && status_at_line(c) == 0)
py = 0;
else
py = wp->sy - 1;
if (y == py) {
result = prompt_mouse(prompt, x, 0, wp->sx,
&redraw);
} else
result = PROMPT_KEY_NOT_HANDLED;
}
} else
result = prompt_key(prompt, key, &redraw);
wp = window_pane_find_by_id(wp_id);
if (wp == NULL)
return (result);
if (wpp != NULL && wp->prompt_data == wpp)
wpp->c = NULL;
/*
* Only an explicit close or the prompt marking itself closed ends it;
* cursor movement and editing keep it open.
*/
if (wp->prompt == prompt &&
(result == PROMPT_KEY_CLOSE || prompt_closed(prompt)))
window_pane_clear_prompt(wp);
if (redraw || wp->prompt != prompt)
wp->flags |= PANE_REDRAW;
return (result);
}
static void
window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len)
{