version 1.26, 2021/08/13 17:03:29 |
version 1.27, 2021/08/13 18:54:54 |
|
|
popup_close_cb cb; |
popup_close_cb cb; |
void *arg; |
void *arg; |
|
|
|
struct menu *menu; |
|
struct menu_data *md; |
|
int close; |
|
|
/* Current position and size. */ |
/* Current position and size. */ |
u_int px; |
u_int px; |
u_int py; |
u_int py; |
|
|
void *arg; |
void *arg; |
}; |
}; |
|
|
|
static const struct menu_item popup_menu_items[] = { |
|
{ "Close", 'q', NULL }, |
|
{ "#{?buffer_name,Paste #[underscore]#{buffer_name},}", 'p', NULL }, |
|
{ "", KEYC_NONE, NULL }, |
|
{ "Fill Space", 'F', NULL }, |
|
{ "Centre", 'C', NULL }, |
|
|
|
{ NULL, KEYC_NONE, NULL } |
|
}; |
|
|
static void |
static void |
popup_redraw_cb(const struct tty_ctx *ttyctx) |
popup_redraw_cb(const struct tty_ctx *ttyctx) |
{ |
{ |
|
|
} |
} |
|
|
static struct screen * |
static struct screen * |
popup_mode_cb(struct client *c, u_int *cx, u_int *cy) |
popup_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
|
|
|
if (pd->md != NULL) |
|
return (menu_mode_cb(c, pd->md, cx, cy)); |
|
|
if (pd->flags & POPUP_NOBORDER) { |
if (pd->flags & POPUP_NOBORDER) { |
*cx = pd->px + pd->s.cx; |
*cx = pd->px + pd->s.cx; |
*cy = pd->py + pd->s.cy; |
*cy = pd->py + pd->s.cy; |
|
|
} |
} |
|
|
static int |
static int |
popup_check_cb(struct client *c, u_int px, u_int py) |
popup_check_cb(struct client *c, void *data, u_int px, u_int py) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
|
|
if (px < pd->px || px > pd->px + pd->sx - 1) |
if (px < pd->px || px > pd->px + pd->sx - 1) |
return (1); |
return (1); |
if (py < pd->py || py > pd->py + pd->sy - 1) |
if (py < pd->py || py > pd->py + pd->sy - 1) |
return (1); |
return (1); |
|
if (pd->md != NULL) |
|
return (menu_check_cb(c, pd->md, px, py)); |
return (0); |
return (0); |
} |
} |
|
|
static void |
static void |
popup_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0) |
popup_draw_cb(struct client *c, void *data, struct screen_redraw_ctx *rctx) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
struct tty *tty = &c->tty; |
struct tty *tty = &c->tty; |
struct screen s; |
struct screen s; |
struct screen_write_ctx ctx; |
struct screen_write_ctx ctx; |
|
|
gc.fg = pd->palette.fg; |
gc.fg = pd->palette.fg; |
gc.bg = pd->palette.bg; |
gc.bg = pd->palette.bg; |
|
|
c->overlay_check = NULL; |
if (pd->md != NULL) { |
|
c->overlay_check = menu_check_cb; |
|
c->overlay_data = pd->md; |
|
} else { |
|
c->overlay_check = NULL; |
|
c->overlay_data = NULL; |
|
} |
for (i = 0; i < pd->sy; i++) |
for (i = 0; i < pd->sy; i++) |
tty_draw_line(tty, &s, 0, i, pd->sx, px, py + i, &gc, palette); |
tty_draw_line(tty, &s, 0, i, pd->sx, px, py + i, &gc, palette); |
|
if (pd->md != NULL) { |
|
c->overlay_check = NULL; |
|
c->overlay_data = NULL; |
|
menu_draw_cb(c, pd->md, rctx); |
|
} |
c->overlay_check = popup_check_cb; |
c->overlay_check = popup_check_cb; |
|
c->overlay_data = pd; |
} |
} |
|
|
static void |
static void |
popup_free_cb(struct client *c) |
popup_free_cb(struct client *c, void *data) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
struct cmdq_item *item = pd->item; |
struct cmdq_item *item = pd->item; |
|
|
|
if (pd->md != NULL) |
|
menu_free_cb(c, pd->md); |
|
|
if (pd->cb != NULL) |
if (pd->cb != NULL) |
pd->cb(pd->status, pd->arg); |
pd->cb(pd->status, pd->arg); |
|
|
|
|
|
|
screen_free(&pd->s); |
screen_free(&pd->s); |
colour_palette_free(&pd->palette); |
colour_palette_free(&pd->palette); |
|
|
free(pd); |
free(pd); |
} |
} |
|
|
static void |
static void |
popup_resize_cb(struct client *c) |
popup_resize_cb(__unused struct client *c, void *data) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
struct tty *tty = &c->tty; |
struct tty *tty = &c->tty; |
|
|
if (pd == NULL) |
if (pd == NULL) |
return; |
return; |
|
if (pd->md != NULL) |
|
menu_free_cb(c, pd->md); |
|
|
/* Adjust position and size. */ |
/* Adjust position and size. */ |
if (pd->psy > tty->sy) |
if (pd->psy > tty->sy) |
|
|
} |
} |
|
|
static void |
static void |
|
popup_menu_done(__unused struct menu *menu, __unused u_int choice, |
|
key_code key, void *data) |
|
{ |
|
struct popup_data *pd = data; |
|
struct client *c = pd->c; |
|
struct paste_buffer *pb; |
|
const char *buf; |
|
size_t len; |
|
|
|
pd->md = NULL; |
|
pd->menu = NULL; |
|
server_redraw_client(pd->c); |
|
|
|
switch (key) { |
|
case 'p': |
|
pb = paste_get_top(NULL); |
|
if (pb != NULL) { |
|
buf = paste_buffer_data(pb, &len); |
|
bufferevent_write(job_get_event(pd->job), buf, len); |
|
} |
|
break; |
|
case 'F': |
|
pd->sx = c->tty.sx; |
|
pd->sy = c->tty.sy; |
|
pd->px = 0; |
|
pd->py = 0; |
|
server_redraw_client(c); |
|
break; |
|
case 'C': |
|
pd->px = c->tty.sx / 2 - pd->sx / 2; |
|
pd->py = c->tty.sy / 2 - pd->sy / 2; |
|
server_redraw_client(c); |
|
break; |
|
case 'q': |
|
pd->close = 1; |
|
break; |
|
} |
|
} |
|
|
|
static void |
popup_handle_drag(struct client *c, struct popup_data *pd, |
popup_handle_drag(struct client *c, struct popup_data *pd, |
struct mouse_event *m) |
struct mouse_event *m) |
{ |
{ |
|
|
} |
} |
|
|
static int |
static int |
popup_key_cb(struct client *c, struct key_event *event) |
popup_key_cb(struct client *c, void *data, struct key_event *event) |
{ |
{ |
struct popup_data *pd = c->overlay_data; |
struct popup_data *pd = data; |
struct mouse_event *m = &event->m; |
struct mouse_event *m = &event->m; |
const char *buf; |
const char *buf; |
size_t len; |
size_t len; |
u_int px, py; |
u_int px, py, x; |
|
|
|
if (pd->md != NULL) { |
|
if (menu_key_cb(c, pd->md, event) == 1) { |
|
pd->md = NULL; |
|
pd->menu = NULL; |
|
if (pd->close) |
|
server_client_clear_overlay(c); |
|
else |
|
server_redraw_client(c); |
|
} |
|
return (0); |
|
} |
|
|
if (KEYC_IS_MOUSE(event->key)) { |
if (KEYC_IS_MOUSE(event->key)) { |
if (pd->dragging != OFF) { |
if (pd->dragging != OFF) { |
popup_handle_drag(c, pd, m); |
popup_handle_drag(c, pd, m); |
|
|
m->x > pd->px + pd->sx - 1 || |
m->x > pd->px + pd->sx - 1 || |
m->y < pd->py || |
m->y < pd->py || |
m->y > pd->py + pd->sy - 1) { |
m->y > pd->py + pd->sy - 1) { |
if (MOUSE_BUTTONS (m->b) == 1) |
if (MOUSE_BUTTONS(m->b) == 2) |
return (1); |
goto menu; |
return (0); |
return (0); |
} |
} |
|
if ((~pd->flags & POPUP_NOBORDER) && |
|
(~m->b & MOUSE_MASK_META) && |
|
MOUSE_BUTTONS(m->b) == 2 && |
|
(m->x == pd->px || |
|
m->x == pd->px + pd->sx - 1 || |
|
m->y == pd->py || |
|
m->y == pd->py + pd->sy - 1)) |
|
goto menu; |
if ((m->b & MOUSE_MASK_META) || |
if ((m->b & MOUSE_MASK_META) || |
((~pd->flags & POPUP_NOBORDER) && |
((~pd->flags & POPUP_NOBORDER) && |
(m->x == pd->px || |
(m->x == pd->px || |
|
|
goto out; |
goto out; |
} |
} |
} |
} |
|
|
if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) || |
if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) || |
pd->job == NULL) && |
pd->job == NULL) && |
(event->key == '\033' || event->key == '\003')) |
(event->key == '\033' || event->key == '\003')) |
|
|
input_key(&pd->s, job_get_event(pd->job), event->key); |
input_key(&pd->s, job_get_event(pd->job), event->key); |
} |
} |
return (0); |
return (0); |
|
|
|
menu: |
|
pd->menu = menu_create(""); |
|
menu_add_items(pd->menu, popup_menu_items, NULL, NULL, NULL); |
|
if (m->x >= (pd->menu->width + 4) / 2) |
|
x = m->x - (pd->menu->width + 4) / 2; |
|
else |
|
x = 0; |
|
pd->md = menu_prepare(pd->menu, 0, NULL, x, m->y, c, NULL, |
|
popup_menu_done, pd); |
|
c->flags |= CLIENT_REDRAWOVERLAY; |
|
|
out: |
out: |
pd->lx = m->x; |
pd->lx = m->x; |