Использование ncurses для захвата щелчков мыши в консольном приложении

Использование ncurses для захвата щелчков мыши в консольном приложении

03.07.2012 02:13:23 Просмотров 35 Источник

Я делаю консольное приложение для платформ unix, и я использую библиотеку curses (или ncurses) для обработки ввода с клавиатуры и мыши. Проблема в том, что я нашел очень мало документации о том , как именно использовать его для этого, например, на этой странице и на этой, где нет очень подробных примеров. Мне удалось захватить левый клик, но я не могу заставить его работать для правого клика, потому что меню опций для эмулятора терминала появляется в месте расположения курсора, но событие не обрабатывается приложением. Как этого избежать и зафиксировать событие в приложении?

У меня есть следующая строка для настройки событий мыши:

// Set up mouse event throwing
mousemask(BUTTON1_PRESSED | BUTTON2_PRESSED, NULL);

И в методе, который обрабатывает входные данные, у меня есть следующее:

int c = getch();
MEVENT event;
switch(c)
{
    case KEY_UP:
        ... do stuff
        break;
    case KEY_DOWN:
        ... do stuff
        break;
    case KEY_MOUSE:
        if(getmouse(&event) == OK)
        {
            if(event.bstate & BUTTON1_PRESSED) // This works for left-click
            {
                ... do stuff
            }
            else if(event.bstate & BUTTON2_PRESSED) // This doesn't capture right-click
            {
                ... do other stuff
            }
            else
                fprintf(stderr, "Event: %i", event.bstate); // Doesn't print anything on right-click
        }
        break;
    default:
        return;
}

Я также пытался настроить mousemask()с ALL_MOUSE_EVENTSмаски ALL_MOUSE_EVENTS, но она по-прежнему не печатает никаких событий в последнем предложении else, поэтому я считаю, что событие просто не запускается. Любая помощь в этом будет очень признательна.

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application#comment14870656_11301883
Похоже, что эмулятор вашего терминала не передает событие правого клика в окно терминала. Большинство эмуляторов имеют опции, которые отключают специальную обработку устройств ввода и позволяют передавать события непосредственно на терминал.
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application#comment14870761_11301883
Ну, я попробовал запустить его на нескольких терминалах: терминал по умолчанию для Ubuntu 11.10, Guake, внутренний терминал IDE NetBeans, и ни один из них не работает. Вы знаете, как я мог бы настроить один из них для передачи событий в приложение?
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application#comment14870925_11301883
askubuntu.com/questions/21330/... для аналогичного вопроса, имеет частичный ответ, т. е. использовать xterm.
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application#comment68605660_11301883
Фактически, страницы руководства уже находятся на вашем компьютере, если у вас есть библиотеки разработки (нет необходимости ссылаться на копию страниц руководства ncurses с конца 1990-х годов).

Ответы - Использование ncurses для захвата щелчков мыши в консольном приложении / Using ncurses to capture mouse clicks on a console application

LeoNerd

04.07.2012 02:24:48

Правая кнопка мыши-это кнопка 3, а не кнопка 2. Кнопка 2-Средняя.

https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/11327205#comment14950321_11327205
Да, я заметил это, но событие все еще не было передано в приложение. Я поставил событие правой кнопки на последний комментарий вопроса.
user1455085

09.11.2012 06:33:42

Я использовал ваш код, но не могу получить никакой реакции. Даже левый мышелов не работает.

Это у вас полный код?

#include <ncurses.h> 

int main(int argc, char **argv){ 

while(1) 
{ 

    mousemask( ALL_MOUSE_EVENTS, NULL); 
        int c = getch(); 
        MEVENT event; 
        switch(c) 
        { 
            case KEY_UP: 
                printf("keyup"); 
                break; 
            case KEY_DOWN: 
                printf("keydown"); 
                break; 
            case KEY_MOUSE: 
                if(getmouse(&event) == OK) 
                { 
                    if(event.bstate & BUTTON1_PRESSED) // This works for left-click 
                    { 
                        printf("button1"); 
                    } 
                    else if(event.bstate & BUTTON2_PRESSED) // This doesn't capture right-click 
                    { 
                        printf("button2"); 
                    } 
                    else 
                        printf("Event: %i", event.bstate); // Doesn't print anything on right-click 
                } 
                break; 
        } 
} 
return 0; 
}
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/13309974#comment18154266_13309974
Вы видели последний комментарий по этому вопросу? Вы используете Xterm и события BUTTON0_CLICKEDи BUTTON3_CLICKEDдля левой и правой кнопок? Те, что были нажаты, на меня не действовали.
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/13309974#comment18160519_13309974
Проблема в том, что у меня нет окна терминала. Я работаю с безголовым Ubuntu без какого-либо управления окнами...
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/13309974#comment18240067_13309974
Я думаю, тогда у вас не было бы проблемы с контекстным меню (в headless их нет). Он должен работать с оболочкой по умолчанию,хотя я не могу подтвердить это. Вы пробовали это с исправленным кодом? Вы уверены, что драйвер мыши работает (возможно, ваш безголовый запуск не загружает его по умолчанию, потому что он обычно не нужен).
Является ответом!
Designation

15.12.2012 02:18:34

Для тех, кто еще приходит сюда, пытаясь выяснить, почему он/она не может захватить события мыши вообще с Ncurses, скорее всего, это линия, которая вам нужна:

keypad(window, TRUE);      

Без этого я не получал никаких событий мыши с getch().

Он отсутствует во всех учебниках/примерах, которые я видел, поэтому мне потребовалось много времени, чтобы понять, что было не так с моим кодом - возможно, этот ответ поможет другим найти решение быстрее, чем я.

https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/13887057#comment44093019_13887057
Это, кажется, устраняет проблему в моей среде Debian / terminator. Без него, кажется, не происходит никаких событий. Я считаю, что этот ответ должен быть отмечен как правильный.
https://stackoverflow.com/questions/11301883/using-ncurses-to-capture-mouse-clicks-on-a-console-application/13887057#comment53908922_13887057
Это исправляет его и на OS X тоже.
Thomas Dickey

19.01.2020 03:00:38

Первоначально речь шла об эмуляторах терминалов (и активации меню, мешающей передаче щелчков мыши приложению). Это можно было бы решить с помощью какой-нибудь специфичной для терминала документации (или даже какого-нибудь учебника). Другие ответы упустили этот момент и сосредоточились на проблемах в приложении ncurses, получающем (и имеющем смысл) события мыши протокола xterm.

Последний вопрос задокументирован на странице руководства:

События мыши в xtermне будут правильно обнаружены в окне с его keypadоткусил, так как они интерпретируются как различные функциональная клавиша. Ваше описание terminfo должно иметь kmous(начало ответа от xterm для щелчков мыши). Другие значения для "\E[M"допускаются, но при том же допущении, то есть, это начало реакции.

не новый, впервые упоминается в 1995 году:

События мыши под xterm не будут правильно обнаружены в окне с его клавиатура была откушена.

Закрыть X