Mercurial > vim
comparison src/terminal.c @ 11711:dac96f8800be v8.0.0738
patch 8.0.0738: cannot use the mouse to resize a terminal window
commit https://github.com/vim/vim/commit/e825d8b0a4173871272b723f1c1f5b95ee981067
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jul 19 23:20:19 2017 +0200
patch 8.0.0738: cannot use the mouse to resize a terminal window
Problem: Cannot use the mouse to resize window while the focus is in a
terminal window.
Solution: Recognize nice mouse events in the terminal window. A few more
fixes for the terminal window.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 19 Jul 2017 23:30:03 +0200 |
parents | 8f5840a59b31 |
children | 2ec27561dd76 |
comparison
equal
deleted
inserted
replaced
11710:1a494055c8a1 | 11711:dac96f8800be |
---|---|
27 * terminal emulator invokes callbacks when its screen content changes. The | 27 * terminal emulator invokes callbacks when its screen content changes. The |
28 * line range is stored in tl_dirty_row_start and tl_dirty_row_end. Once in a | 28 * line range is stored in tl_dirty_row_start and tl_dirty_row_end. Once in a |
29 * while, if the terminal window is visible, the screen contents is drawn. | 29 * while, if the terminal window is visible, the screen contents is drawn. |
30 * | 30 * |
31 * TODO: | 31 * TODO: |
32 * - pressing Enter sends two CR and/or NL characters to "bash -i"? | |
33 * Passing Enter as NL seems to work. | |
34 * - set buffer options to be scratch, hidden, nomodifiable, etc. | 32 * - set buffer options to be scratch, hidden, nomodifiable, etc. |
35 * - set buffer name to command, add (1) to avoid duplicates. | 33 * - set buffer name to command, add (1) to avoid duplicates. |
36 * - If [command] is not given the 'shell' option is used. | 34 * - If [command] is not given the 'shell' option is used. |
37 * - Add a scrollback buffer (contains lines to scroll off the top). | 35 * - Add a scrollback buffer (contains lines to scroll off the top). |
38 * Can use the buf_T lines, store attributes somewhere else? | 36 * Can use the buf_T lines, store attributes somewhere else? |
249 out_flush(); | 247 out_flush(); |
250 } | 248 } |
251 | 249 |
252 /* | 250 /* |
253 * Wait for input and send it to the job. | 251 * Wait for input and send it to the job. |
254 * Return when a CTRL-W command is typed that moves to another window. | 252 * Return when the start of a CTRL-W command is typed or anything else that |
253 * should be handled as a Normal mode command. | |
255 */ | 254 */ |
256 void | 255 void |
257 terminal_loop(void) | 256 terminal_loop(void) |
258 { | 257 { |
259 char buf[KEY_BUF_LEN]; | 258 char buf[KEY_BUF_LEN]; |
260 int c; | 259 int c; |
261 size_t len; | 260 size_t len; |
261 static int mouse_was_outside = FALSE; | |
262 int dragging_outside = FALSE; | |
262 | 263 |
263 for (;;) | 264 for (;;) |
264 { | 265 { |
265 /* TODO: skip screen update when handling a sequence of keys. */ | 266 /* TODO: skip screen update when handling a sequence of keys. */ |
266 update_screen(0); | 267 update_screen(0); |
267 setcursor(); | 268 setcursor(); |
268 out_flush(); | 269 out_flush(); |
269 c = vgetc(); | 270 c = vgetc(); |
270 | 271 |
271 if (c == Ctrl_W) | 272 /* Catch keys that need to be handled as in Normal mode. */ |
273 switch (c) | |
272 { | 274 { |
273 stuffcharReadbuff(Ctrl_W); | 275 case Ctrl_W: |
274 return; | 276 case NUL: |
277 case K_ZERO: | |
278 stuffcharReadbuff(c); | |
279 return; | |
280 | |
281 case K_IGNORE: continue; | |
282 | |
283 case K_LEFTDRAG: | |
284 case K_MIDDLEDRAG: | |
285 case K_RIGHTDRAG: | |
286 case K_X1DRAG: | |
287 case K_X2DRAG: | |
288 dragging_outside = mouse_was_outside; | |
289 /* FALLTHROUGH */ | |
290 case K_LEFTMOUSE: | |
291 case K_LEFTMOUSE_NM: | |
292 case K_LEFTRELEASE: | |
293 case K_LEFTRELEASE_NM: | |
294 case K_MIDDLEMOUSE: | |
295 case K_MIDDLERELEASE: | |
296 case K_RIGHTMOUSE: | |
297 case K_RIGHTRELEASE: | |
298 case K_X1MOUSE: | |
299 case K_X1RELEASE: | |
300 case K_X2MOUSE: | |
301 case K_X2RELEASE: | |
302 if (mouse_row < W_WINROW(curwin) | |
303 || mouse_row >= (W_WINROW(curwin) + curwin->w_height) | |
304 || mouse_col < W_WINCOL(curwin) | |
305 || mouse_col >= W_ENDCOL(curwin) | |
306 || dragging_outside) | |
307 { | |
308 /* click outside the current window */ | |
309 stuffcharReadbuff(c); | |
310 mouse_was_outside = TRUE; | |
311 return; | |
312 } | |
275 } | 313 } |
314 mouse_was_outside = FALSE; | |
276 | 315 |
277 /* Convert the typed key to a sequence of bytes for the job. */ | 316 /* Convert the typed key to a sequence of bytes for the job. */ |
278 len = term_convert_key(c, buf); | 317 len = term_convert_key(c, buf); |
279 if (len > 0) | 318 if (len > 0) |
280 /* TODO: if FAIL is returned, stop? */ | 319 /* TODO: if FAIL is returned, stop? */ |
390 /* TODO: depends on 'encoding'. */ | 429 /* TODO: depends on 'encoding'. */ |
391 vterm_set_utf8(vterm, 1); | 430 vterm_set_utf8(vterm, 1); |
392 /* Required to initialize most things. */ | 431 /* Required to initialize most things. */ |
393 vterm_screen_reset(screen, 1 /* hard */); | 432 vterm_screen_reset(screen, 1 /* hard */); |
394 | 433 |
395 /* By default NL means CR-NL. */ | |
396 vterm_input_write(vterm, "\x1b[20h", 5); | |
397 | |
398 return OK; | 434 return OK; |
399 } | 435 } |
400 | 436 |
401 /* | 437 /* |
402 * Free the terminal emulator part of "term". | 438 * Free the terminal emulator part of "term". |
412 */ | 448 */ |
413 static void | 449 static void |
414 term_write_job_output(term_T *term, char_u *msg, size_t len) | 450 term_write_job_output(term_T *term, char_u *msg, size_t len) |
415 { | 451 { |
416 VTerm *vterm = term->tl_vterm; | 452 VTerm *vterm = term->tl_vterm; |
417 | 453 char_u *p; |
418 vterm_input_write(vterm, (char *)msg, len); | 454 size_t done; |
455 size_t len_now; | |
456 | |
457 for (done = 0; done < len; done += len_now) | |
458 { | |
459 for (p = msg + done; p < msg + len; ) | |
460 { | |
461 if (*p == NL) | |
462 break; | |
463 p += mb_ptr2len_len(p, len - (p - msg)); | |
464 } | |
465 len_now = p - msg - done; | |
466 vterm_input_write(vterm, (char *)msg + done, len_now); | |
467 if (p < msg + len && *p == NL) | |
468 { | |
469 /* Convert NL to CR-NL, that appears to work best. */ | |
470 vterm_input_write(vterm, "\r\n", 2); | |
471 ++len_now; | |
472 } | |
473 } | |
419 vterm_screen_flush_damage(vterm_obtain_screen(vterm)); | 474 vterm_screen_flush_damage(vterm_obtain_screen(vterm)); |
420 } | 475 } |
421 | 476 |
422 static int | 477 static int |
423 handle_damage(VTermRect rect, void *user) | 478 handle_damage(VTermRect rect, void *user) |
489 VTermKey key = VTERM_KEY_NONE; | 544 VTermKey key = VTERM_KEY_NONE; |
490 VTermModifier mod = VTERM_MOD_NONE; | 545 VTermModifier mod = VTERM_MOD_NONE; |
491 | 546 |
492 switch (c) | 547 switch (c) |
493 { | 548 { |
494 /* TODO: which of these two should be used? */ | |
495 #if 0 | |
496 case CAR: key = VTERM_KEY_ENTER; break; | 549 case CAR: key = VTERM_KEY_ENTER; break; |
497 #else | |
498 case CAR: c = NL; break; | |
499 #endif | |
500 case ESC: key = VTERM_KEY_ESCAPE; break; | 550 case ESC: key = VTERM_KEY_ESCAPE; break; |
501 case K_BS: key = VTERM_KEY_BACKSPACE; break; | 551 case K_BS: key = VTERM_KEY_BACKSPACE; break; |
502 case K_DEL: key = VTERM_KEY_DEL; break; | 552 case K_DEL: key = VTERM_KEY_DEL; break; |
503 case K_DOWN: key = VTERM_KEY_DOWN; break; | 553 case K_DOWN: key = VTERM_KEY_DOWN; break; |
504 case K_END: key = VTERM_KEY_END; break; | 554 case K_END: key = VTERM_KEY_END; break; |
542 case K_PAGEDOWN: key = VTERM_KEY_PAGEDOWN; break; | 592 case K_PAGEDOWN: key = VTERM_KEY_PAGEDOWN; break; |
543 case K_PAGEUP: key = VTERM_KEY_PAGEUP; break; | 593 case K_PAGEUP: key = VTERM_KEY_PAGEUP; break; |
544 case K_RIGHT: key = VTERM_KEY_RIGHT; break; | 594 case K_RIGHT: key = VTERM_KEY_RIGHT; break; |
545 case K_UP: key = VTERM_KEY_UP; break; | 595 case K_UP: key = VTERM_KEY_UP; break; |
546 case TAB: key = VTERM_KEY_TAB; break; | 596 case TAB: key = VTERM_KEY_TAB; break; |
597 | |
598 case K_MOUSEUP: /* TODO */ break; | |
599 case K_MOUSEDOWN: /* TODO */ break; | |
600 case K_MOUSELEFT: /* TODO */ break; | |
601 case K_MOUSERIGHT: /* TODO */ break; | |
602 | |
603 case K_LEFTMOUSE: /* TODO */ break; | |
604 case K_LEFTMOUSE_NM: /* TODO */ break; | |
605 case K_LEFTDRAG: /* TODO */ break; | |
606 case K_LEFTRELEASE: /* TODO */ break; | |
607 case K_LEFTRELEASE_NM: /* TODO */ break; | |
608 case K_MIDDLEMOUSE: /* TODO */ break; | |
609 case K_MIDDLEDRAG: /* TODO */ break; | |
610 case K_MIDDLERELEASE: /* TODO */ break; | |
611 case K_RIGHTMOUSE: /* TODO */ break; | |
612 case K_RIGHTDRAG: /* TODO */ break; | |
613 case K_RIGHTRELEASE: /* TODO */ break; | |
614 case K_X1MOUSE: /* TODO */ break; | |
615 case K_X1DRAG: /* TODO */ break; | |
616 case K_X1RELEASE: /* TODO */ break; | |
617 case K_X2MOUSE: /* TODO */ break; | |
618 case K_X2DRAG: /* TODO */ break; | |
619 case K_X2RELEASE: /* TODO */ break; | |
620 | |
621 /* TODO: handle all special keys and modifiers that terminal_loop() | |
622 * does not handle. */ | |
547 } | 623 } |
548 | 624 |
549 /* | 625 /* |
550 * Convert special keys to vterm keys: | 626 * Convert special keys to vterm keys: |
551 * - Write keys to vterm: vterm_keyboard_key() | 627 * - Write keys to vterm: vterm_keyboard_key() |
595 c = cell.chars[0]; | 671 c = cell.chars[0]; |
596 ScreenLines[off] = c == NUL ? ' ' : c; | 672 ScreenLines[off] = c == NUL ? ' ' : c; |
597 ScreenAttrs[off] = 0; | 673 ScreenAttrs[off] = 0; |
598 ++off; | 674 ++off; |
599 } | 675 } |
676 else | |
677 pos.col = 0; | |
600 | 678 |
601 screen_line(wp->w_winrow + pos.row, wp->w_wincol, pos.col, wp->w_width, | 679 screen_line(wp->w_winrow + pos.row, wp->w_wincol, pos.col, wp->w_width, |
602 FALSE); | 680 FALSE); |
603 } | 681 } |
604 } | 682 } |