From 44bf2da2be428281b6d96c9bacb8255caf8eede8 Mon Sep 17 00:00:00 2001 From: arakiken Date: Tue, 19 Sep 2023 21:41:46 +0900 Subject: [PATCH] * ui_screen.c: "exesel:" works in win32. * ui_main_config.c: --chsel/change_selection_immediately option is not available in xlib and wayland. * sdl2/ui_window.c: Fix for clipboard in SDL2. * sdl2/ui_display.c: - Shift+Control+xxx works in SDL2. - Process SDL_CLIPBOARDUPDATE event. * ui_window.h: Add SEL_NONE to ui_selection_flag_t. --- ChangeLog | 15 +++++++++++++++ doc/en/ReleaseNote | 5 ++++- doc/ja/README.ja | 4 ++-- man/mlterm.1 | 4 ++-- uitoolkit/fb/ui_window.c | 8 +++++++- uitoolkit/sdl2/ui_display.c | 10 ++++++++-- uitoolkit/ui_main_config.c | 4 ++++ uitoolkit/ui_screen.c | 32 ++++++++++++++++++++++++++------ uitoolkit/ui_selection.c | 26 +++++++++++++++++++++++--- uitoolkit/ui_selection.h | 18 ++++++++++++++++++ uitoolkit/ui_window.h | 5 +++-- 11 files changed, 112 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7eb6772..15eef5d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2023-09-18 Araki Ken + + * ui_screen.c: "exesel:" works in win32. + + * ui_main_config.c: --chsel/change_selection_immediately option is + not available in xlib and wayland. + + * sdl2/ui_window.c: Fix for clipboard in SDL2. + + * sdl2/ui_display.c: + - Shift+Control+xxx works in SDL2. + - Process SDL_CLIPBOARDUPDATE event. + + * ui_window.h: Add SEL_NONE to ui_selection_flag_t. + 2023-09-16 Araki Ken * README.ja, man/mlterm.1: Updated. diff --git a/doc/en/ReleaseNote b/doc/en/ReleaseNote index b8211e53..6a0e28b3 100644 --- a/doc/en/ReleaseNote +++ b/doc/en/ReleaseNote @@ -1,5 +1,6 @@ * Support Shift+Control+v and Shift+Control+c to copy&paste via clipboard by default. - Drop -P/--clip/use_clipboard option and add -P/--mouse/use_mouse_selection option. + Drop -P/--clip/use_clipboard option. + Add --chsel/change_selection_immediately option in anything except xlib and wayland. * Add COPY_CLIPBOARD shortcut key. * Pressing '?' in copy mode searches for a string backward. (https://github.com/arakiken/mlterm/issues/72) @@ -17,6 +18,8 @@ https://github.com/arakiken/mlterm/issues/73. https://github.com/arakiken/mlterm/issues/78. Fix an issue where mlconfig was not displayed. + Fix an issue where Control+Shift+xxx shortcut didn't work in SDL2. + Fix unexpected reset of inverted colors in selected area in SDL2. ver 3.9.3 * mlterm-wl supports xdg-decoration. diff --git a/doc/ja/README.ja b/doc/ja/README.ja index d6feb104..d44ea5df 100644 --- a/doc/ja/README.ja +++ b/doc/ja/README.ja @@ -895,7 +895,7 @@ comment -*- mode: text; tab-width:2; indent-tabs-mode:nil; coding:euc-jp -*- キー入力及びペーストされた文字列を、全ての pty (ignore_broadcasted_chars オプションの値が false なものに限る) に送信 - o change_selection_immediately (*true*/false) + o change_selection_immediately (*true*/false) (mlterm and mlterm-wl 以外用) マウスでテキストを選択した場合に、選択したテキストをすぐに Selection に反映 o cipher_list @@ -1621,7 +1621,7 @@ comment -*- mode: text; tab-width:2; indent-tabs-mode:nil; coding:euc-jp -*- --recvdir=value : receive_directory --fk(=bool) : format_other_keys --sdpr=value : simple_scrollbar_dpr - --chsel(=bool) : change_selection_immediately + --chsel(=bool) : change_selection_immediately (mlterm and mlterm-wl 以外用) --point=value : use_point_size --aafont(=bool) : use_aafont (mlterm-fb, mlterm-wl or mlterm-sdl2 用) --multivram(=bool) : separate_wall_picture (mlterm-fb on NetBSD/x68k 用) diff --git a/man/mlterm.1 b/man/mlterm.1 index 3068ce11..3095e40a 100644 --- a/man/mlterm.1 +++ b/man/mlterm.1 @@ -570,7 +570,7 @@ Use either unicode font or DEC Special font forcibly to draw box-drawing charact \fBunicode\fR for unicode font and \fBdecsp\fR for DEC special font. The default is \fBnoconv\fR which draw them as they are. .TP -\fB\-\-chsel\fR(=\fIbool\fR) +\fB\-\-chsel\fR(=\fIbool\fR) (Available for anything except mlterm and mlterm-wl) Whether to enable to change selection just after selecting text by mouse. The default is \fBtrue\fR. .TP @@ -1553,7 +1553,7 @@ Specify the amount of darkening or lightening the background image. Whether to broadcast input or pasted characters to all ptys whose value of "ignore_broadcasted_chars" option is false. .TP -\fBchange_selection_immediately=\fIbool\fR (\-\-chsel\fR) +\fBchange_selection_immediately=\fIbool\fR (\-\-chsel\fR) (Available for anything except mlterm and mlterm-wl) Whether to enable to change selection just after selecting text by mouse. .TP \fBcipher_list\fR=\fIvalue\fR (\fB\-\-ciphlist\fR) diff --git a/uitoolkit/fb/ui_window.c b/uitoolkit/fb/ui_window.c index 6b17012c..10ae1c8d 100644 --- a/uitoolkit/fb/ui_window.c +++ b/uitoolkit/fb/ui_window.c @@ -2376,7 +2376,13 @@ void ui_window_draw_rect_frame(ui_window_t *win, int x1, int y1, int x2, int y2) } int ui_window_set_selection_owner(ui_window_t *win, Time time, ui_selection_flag_t selection) { -#ifndef USE_SDL2 +#ifdef USE_SDL2 + /* + * Set selection_owner NULL for ui_display_own_selection() not to + * call ui_display_clear_selection(). + */ + win->disp->selection_owner = NULL; +#else if (ui_window_is_selection_owner(win, selection)) { /* Already owner */ } else diff --git a/uitoolkit/sdl2/ui_display.c b/uitoolkit/sdl2/ui_display.c index d5c7ab29..1c29a660 100644 --- a/uitoolkit/sdl2/ui_display.c +++ b/uitoolkit/sdl2/ui_display.c @@ -697,8 +697,8 @@ static void poll_event(void) { xev.xkey.state = get_mod_state(ev.key.keysym.mod); if (!cur_preedit_text && - (xev.xkey.ksym < 0x20 || xev.xkey.ksym >= 0x7f || xev.xkey.state == ControlMask || - xev.xkey.state == CommandMask)) { + (xev.xkey.ksym < 0x20 || xev.xkey.ksym >= 0x7f || (xev.xkey.state & ControlMask) || + (xev.xkey.state & CommandMask))) { ui_window_receive_event(get_display(ev.key.windowID)->roots[0], &xev); } @@ -881,6 +881,12 @@ static void poll_event(void) { break; } + case SDL_CLIPBOARDUPDATE: + disp = get_display(ev.window.windowID); + if (disp->selection_owner) { + ui_display_clear_selection(NULL, disp->selection_owner); + } + default: if (ev.type == pty_event_type) { #ifdef MONITOR_PTY diff --git a/uitoolkit/ui_main_config.c b/uitoolkit/ui_main_config.c index d1af318f..7915ae6e 100644 --- a/uitoolkit/ui_main_config.c +++ b/uitoolkit/ui_main_config.c @@ -333,8 +333,10 @@ void ui_prepare_for_main_config(bl_conf_t *conf) { "send modified keys as parameter for CSI u [false]"); bl_conf_add_opt(conf, '\0', "sdpr", 0, "simple_scrollbar_dpr", "device pixel ratio for simple scrollbar [1]"); +#ifdef SELECTION_STYLE_CHANGEABLE bl_conf_add_opt(conf, '\0', "chsel", 1, "change_selection_immediately", "change selection just after selecting text by mouse [true]"); +#endif #ifdef USE_IM_CURSOR_COLOR bl_conf_add_opt(conf, '\0', "imcolor", 0, "im_cursor_color", "cursor color when input method is activated. [false]"); @@ -1247,6 +1249,7 @@ void ui_main_config_init(ui_main_config_t *main_config, bl_conf_t *conf, int arg } } +#ifdef SELECTION_STYLE_CHANGEABLE if ((value = bl_conf_get_value(conf, "change_selection_immediately"))) { int flag = true_or_false(value); @@ -1254,6 +1257,7 @@ void ui_main_config_init(ui_main_config_t *main_config, bl_conf_t *conf, int arg ui_set_change_selection_immediately(flag); } } +#endif #ifndef __ANDROID__ if (!(value = bl_conf_get_value(conf, "auto_restart")) || strcmp(value, "false") != 0) { diff --git a/uitoolkit/ui_screen.c b/uitoolkit/ui_screen.c index 88def4fe..a259821e 100644 --- a/uitoolkit/ui_screen.c +++ b/uitoolkit/ui_screen.c @@ -1777,7 +1777,8 @@ static int copy_selection(ui_screen_t *screen, ui_selection_flag_t selection) { } #endif - if (!ui_window_set_selection_owner(&screen->window, CurrentTime, selection)) { + if (selection != SEL_NONE && + !ui_window_set_selection_owner(&screen->window, CurrentTime, selection)) { ui_selection_set_str(&screen->sel, NULL, 0); return 0; @@ -2070,8 +2071,10 @@ static int shortcut_match(ui_screen_t *screen, KeySym ksym, u_int state) { } else if (ui_shortcut_match(screen->shortcut, INSERT_CLIPBOARD, ksym, state)) { yank_event_received(screen, CurrentTime, SEL_CLIPBOARD); } else if (ui_shortcut_match(screen->shortcut, COPY_CLIPBOARD, ksym, state)) { - if (ui_sel_is_reversed(&screen->sel)) { + if (ui_selection_str_is_not_updated(&screen->sel)) { copy_selection(screen, SEL_CLIPBOARD); + } else if (!ui_window_is_selection_owner(&screen->window, SEL_CLIPBOARD)) { + ui_window_set_selection_owner(&screen->window, CurrentTime, SEL_CLIPBOARD); } } else if (ui_shortcut_match(screen->shortcut, RESET, ksym, state)) { vt_term_reset(screen->term, 1); @@ -2144,6 +2147,11 @@ static int shortcut_str(ui_screen_t *screen, KeySym ksym, u_int state, int x, in char *key; size_t key_len; + /* XXX In case change_selection_immediately is false. */ + if (ui_selection_str_is_not_updated(&screen->sel)) { + copy_selection(screen, SEL_NONE); + } + if (!ui_selection_has_str(&screen->sel)) { return 0; } @@ -2192,9 +2200,8 @@ static int shortcut_str(ui_screen_t *screen, KeySym ksym, u_int state, int x, in if (strncmp(key, "mlclient", 8) == 0) { ui_screen_exec_cmd(screen, key); - } + } else { #ifndef USE_WIN32API - else { char **argv; int argc; @@ -2205,8 +2212,19 @@ static int shortcut_str(ui_screen_t *screen, KeySym ksym, u_int state, int x, in exit(1); } } - } +#else + PROCESS_INFORMATION pi; + STARTUPINFO si; + + /* Set up the start up info struct. */ + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + + CreateProcess(NULL, key, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); #endif + } } else if (strncmp(str, "proto:", 6) == 0) { char *seq; size_t len; @@ -2478,7 +2496,9 @@ static void copymode_key(ui_screen_t *screen, int ksym, u_int state, u_char *str line->mark ^= 1; } } else if (ui_shortcut_match(screen->shortcut, COPY_CLIPBOARD, ksym, state)) { - if (ui_selection_has_str(&screen->sel)) { + if (ui_selection_str_is_not_updated(&screen->sel)) { + copy_selection(screen, SEL_CLIPBOARD); + } else if (!ui_window_is_selection_owner(&screen->window, SEL_CLIPBOARD)) { ui_window_set_selection_owner(&screen->window, CurrentTime, SEL_CLIPBOARD); } } else if (ksym == XK_Left || ksym == 'h') { diff --git a/uitoolkit/ui_selection.c b/uitoolkit/ui_selection.c index f576d098..53a466f8 100644 --- a/uitoolkit/ui_selection.c +++ b/uitoolkit/ui_selection.c @@ -13,7 +13,9 @@ /* --- static variables --- */ +#ifdef SELECTION_STYLE_CHANGEABLE static int change_selection_immediately = 1; +#endif /* --- static functions --- */ @@ -199,9 +201,11 @@ static int update_sel_region(ui_selection_t *sel, int col, int row) { /* --- global functions --- */ +#ifdef SELECTION_STYLE_CHANGEABLE void ui_set_change_selection_immediately(int flag) { change_selection_immediately = flag; } +#endif void ui_sel_init(ui_selection_t *sel, ui_sel_event_listener_t *sel_listener) { memset(sel, 0, sizeof(ui_selection_t)); @@ -269,7 +273,10 @@ int ui_stop_selecting(ui_selection_t *sel) { sel->is_selecting = 0; sel->is_locked = 0; - if (change_selection_immediately) { +#ifdef SELECTION_STYLE_CHANGEABLE + if (change_selection_immediately) +#endif + { if (!(*sel->sel_listener->select_in_window)(sel->sel_listener->self)) { #ifdef __DEBUG bl_debug_printf(BL_DEBUG_TAG " select_in_window() failed.\n"); @@ -278,6 +285,11 @@ int ui_stop_selecting(ui_selection_t *sel) { return 0; } } +#ifdef SELECTION_STYLE_CHANGEABLE + else { + sel->str_not_updated = 1; + } +#endif return 1; } @@ -289,6 +301,9 @@ void ui_selection_set_str(ui_selection_t *sel, vt_char_t *str, u_int len) { sel->sel_str = str; sel->sel_len = len; +#ifdef SELECTION_STYLE_CHANGEABLE + sel->str_not_updated = 0; +#endif } int ui_sel_clear(ui_selection_t *sel) { @@ -297,8 +312,13 @@ int ui_sel_clear(ui_selection_t *sel) { #endif if (sel->is_selecting) { - if (change_selection_immediately && sel->sel_str) { - ui_selection_set_str(sel, NULL, 0); +#ifdef SELECTION_STYLE_CHANGEABLE + if (change_selection_immediately) +#endif + { + if (sel->sel_str) { + ui_selection_set_str(sel, NULL, 0); + } } sel->is_selecting = 0; diff --git a/uitoolkit/ui_selection.h b/uitoolkit/ui_selection.h index dea850e3..92fb28e9 100644 --- a/uitoolkit/ui_selection.h +++ b/uitoolkit/ui_selection.h @@ -6,6 +6,12 @@ #include /* u_int */ #include +#include "ui.h" + +#if !defined(USE_XLIB) && !defined(USE_WAYLAND) +#define SELECTION_STYLE_CHANGEABLE +#endif + typedef enum { SEL_CHAR = 0x1, SEL_WORD = 0x2, @@ -52,10 +58,16 @@ typedef struct ui_selection { int8_t is_reversed; int8_t is_locked; int8_t is_rect; +#ifdef SELECTION_STYLE_CHANGEABLE + int8_t str_not_updated; +#endif } ui_selection_t; + +#ifdef SELECTION_STYLE_CHANGEABLE void ui_set_change_selection_immediately(int flag); +#endif void ui_sel_init(ui_selection_t *sel, ui_sel_event_listener_t *listener); @@ -80,6 +92,12 @@ void ui_selection_set_str(ui_selection_t *sel, vt_char_t *str, u_int len); #define ui_selection_has_str(sel) ((sel)->sel_str != NULL && (sel)->sel_len > 0) +#ifdef SELECTION_STYLE_CHANGEABLE +#define ui_selection_str_is_not_updated(sel) ((sel)->str_not_updated) +#else +#define ui_selection_str_is_not_updated(sel) (0) +#endif + int ui_sel_clear(ui_selection_t *sel); int ui_selected_region_is_changed(ui_selection_t *sel, int col, int row, u_int base); diff --git a/uitoolkit/ui_window.h b/uitoolkit/ui_window.h index 6219187f..31ffcba4 100644 --- a/uitoolkit/ui_window.h +++ b/uitoolkit/ui_window.h @@ -51,8 +51,9 @@ typedef enum ui_sizehint_flag { /* PRIMARY and CLIPBOARD are distinguished only in xlib/wayland. */ typedef enum ui_selection_flag { - SEL_PRIMARY = 0x0, - SEL_CLIPBOARD = 0x1, + SEL_NONE = 0x0, /* Not own selection */ + SEL_PRIMARY = 0x1, + SEL_CLIPBOARD = 0x2, } ui_selection_flag_t; typedef struct ui_xim_event_listener {