On 10/03/2019 23.02, Bill Allombert wrote: > Could you write a simple test program ? > The problem with vttest is that it does not inhibit the normal copy > paste mechanism. So while it correctly detects the button press, the > result seems useless (try press- move-releas). > This might explain why gpm use another solution.
I don't think this is the reason. When I try to select something in a curses application which uses mouse tracking, gpm doesn't select what I want it to, but it does copy what I select. GPM also seams to disables pasting in that case. Other graphical terminal emulators seam to disable selecting, copying and pasting while an application uses mouse tracking. The linux console (fbcon) also clears any selection if anything is written to the tty, even if the screen content doesn't change because of it. I don't know if the curses library would do that automatically, but some curses applications may do that. For some reason, a button release mouse event also seams to clear the selection. In any case, unless how the linux console handles selections in such situations is changed, there is no way to use mouse reporting and text selection simultaneously, regardless of how the mouse reporting is archived. I'm not sure what the best course of action is. Some possibilities are: * If it isn't too much of a problem, we could just leave it how it is. * We could disable selections while mouse tracking is active * I could add an option to consolation which allows the user to enable this feature, in addition to one of the above options I've attached 2 test programs, one uses curses, the other one doesn't need any libraries. I've also attached a patch to reorder the button constants. Regards, Daniel Abrecht
diff --git a/src/consolation.h b/src/consolation.h index c8278e0..ee9fd4e 100644 --- a/src/consolation.h +++ b/src/consolation.h @@ -20,10 +20,10 @@ extern int nodaemon; enum current_button { - BUTTON_RELEASED, BUTTON_LEFT, BUTTON_MIDDLE, - BUTTON_RIGHT + BUTTON_RIGHT, + BUTTON_RELEASED }; /* global state */ diff --git a/src/selection.c b/src/selection.c index 4f65863..0d4c1e9 100644 --- a/src/selection.c +++ b/src/selection.c @@ -78,7 +78,7 @@ linux_selection(int xs, int ys, int xe, int ye, int sel_mode) void report_pointer(int x, int y, enum current_button button) { - linux_selection(x, y, x, y, TIOCL_SELMOUSEREPORT + ((button+3) % 4) ); + linux_selection(x, y, x, y, TIOCL_SELMOUSEREPORT + button ); } void
#include <curses.h> #include <stdbool.h> bool mousereporting = true; bool show_release = true; bool show_press = true; unsigned long i = 0; void printinfo(void){ clear(); move(0,0); addstr("q) quit"); move(1,0); addstr(mousereporting?".) mouse reporting: on":".) mouse reporting: off"); move(2,0); addstr(show_release?",) show button release: on":",) show button release: off"); move(3,0); addstr(show_press?"-) show button presses: on":"-) show button presses: off"); move(5,0); addch('>'); addch(' '); if(mousereporting){ mousemask( BUTTON1_PRESSED | BUTTON1_RELEASED | BUTTON2_PRESSED | BUTTON2_RELEASED | BUTTON3_PRESSED | BUTTON3_RELEASED, 0); }else{ mousemask(0,0); } mouseinterval(0); } int main(){ if(!initscr()){ fprintf(stderr,"initscr failed\n"); return 1; } clear(); noecho(); cbreak(); keypad(stdscr, true); printinfo(); bool running = true; while(running){ int ch = getch(); switch(ch){ case 'q': running = false; break; case '.': { mousereporting = !mousereporting; printinfo(); } break; case ',': { show_release = !show_release; printinfo(); } break; case '-': { show_press = !show_press; printinfo(); } break; case '\n': { i = 0; move(5,0); clrtoeol(); addch('>'); addch(' '); } break; default: { if(ch > 0xFF || ch <= 0) break; move(5,i+++2); addch(ch); } break; case KEY_MOUSE: { MEVENT event; if(getmouse(&event) != OK) break; if(show_release) if( event.bstate & (BUTTON1_RELEASED | BUTTON2_RELEASED | BUTTON3_RELEASED) ){ move(event.y, event.x); addch('*'); } int button = 0; if( event.bstate & BUTTON1_PRESSED ) button = 1; if( event.bstate & BUTTON2_PRESSED ) button = 2; if( event.bstate & BUTTON3_PRESSED ) button = 3; if(button && show_press){ move(event.y, event.x); addch('0'+button); } } break; } } endwin(); return 0; }
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdbool.h> bool mousereporting = true; bool show_release = true; bool show_press = true; unsigned long j = 0; void altscr(void){ printf("\033[?1047h\033c\033[?25l"); } void stdscr(void){ printf("\033[?1047l\033[?25h\033c"); } void clear(void){ printf("\033[3J\033[H\033[2J"); } void noecho(){ printf("\033[12h"); } void move(int y, int x){ printf("\033[%d;%dH",y,x); } void clrtoeol(void){printf("\033[2K");} void printinfo(void){ clear(); move(1,1); puts("q) quit"); move(2,1); puts(mousereporting?".) mouse reporting: on":".) mouse reporting: off"); move(3,1); puts(show_release?",) show button release: on":",) show button release: off"); move(4,1); puts(show_press?"-) show button press: on":"-) show button press: off"); move(6,1); putchar('>'); putchar(' '); if(mousereporting){ printf("\033[?1000h"); // mouse reporting on }else{ printf("\033[?1000l"); // mouse reporting off } } enum { BUTTON1_PRESSED, BUTTON2_PRESSED, BUTTON3_PRESSED, BUTTON_RELEASED }; int main(){ altscr(); clear(); noecho(); system("stty cbreak -echo"); printinfo(); bool running = true; int mss = 0; int seq[7]; while(running){ int ch = getchar(); // Parse mouse escape sequences seq[mss] = ch; if(mss >= 3){ if(++mss >= 6){ mss = 0; int button = seq[3] & 0x3; unsigned char x = seq[4] - ' '; unsigned char y = seq[5] - ' '; if(show_release) if( button == BUTTON_RELEASED ){ move(y, x); putchar('*'); } if(button != BUTTON_RELEASED && show_press){ move(y, x); putchar('0'+button); } } continue; }else{ if("\033[M"[mss] == ch){ mss++; continue; } } mss++; for(int i=0; i<mss; i++){ ch=seq[i]; switch(ch){ case EOF: case 'q': running = false; break; case '.': { mousereporting = !mousereporting; printinfo(); } break; case ',': { show_release = !show_release; printinfo(); } break; case '-': { show_press = !show_press; printinfo(); } break; case '\n': { j = 0; move(6,1); clrtoeol(); putchar('>'); putchar(' '); } break; default: { if(ch > 0xFF || ch <= 0) break; move(6,++j+2); putchar(ch); } break; } } mss = 0; } system("stty sane"); stdscr(); return 0; }
signature.asc
Description: OpenPGP digital signature