Puncte:1

Programare C: Detectează mișcarea indicatorului mouse-ului

drapel pt

Lucrez la un proiect în care trebuie să setez un steag numai când cursorul mouse-ului nu s-a mișcat pentru o perioadă de timp (de exemplu: 30 de secunde): dacă mouse-ul a fost inactiv timp de 30 de secunde, setați fără_mișcare (no_movement=true;).

Până acum, știu că serverul X window este backend pentru multe medii desktop și știu că există o documentație cuprinzătoare pentru el. x.org și tronche.com (Am înțeles de acolo că există un eveniment pentru pointer numit MotionNotify).

Folosind apt show xserver-xorg | Versiunea grep Am aflat că versiunea Xserver instalată pe sistemul meu este 1:7.7+22ubuntu1 (pe Ubuntu 21.04)

Care este modalitatea recomandată de a obține feedback despre mișcarea indicatorului mouse-ului?

Apreciez timpul acordat pentru a-mi răspunde.

HuHa avatar
drapel es
De ce simt un miros rău: lucrează lucrătorii mei de la biroul de acasă? software aici?
Shobeira avatar
drapel pt
Încerc să-mi cronometrez într-adevăr. Trebuie să știu cât de mult lucrez la un proiect, deoarece ne confruntăm cu cea de-a 5-a izolare și încă lucrăm de acasă.
Puncte:0
drapel in

X11 este destul de bine documentat pentru „măști de eveniment”

https://tronche.com/gui/x/xlib/events/mask.html

Sau există întotdeauna XQueryPointer)..

// Încercați acest program C ca bază pentru ceea ce doriți să faceți..

    #include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>

int main(int argc, char **argv)
{
    Display *afisaj;
    Fereastra root_window;

    /* Inițializare (FIXME: nicio verificare a erorilor). */
    display = XOpenDisplay(0);
    root_window = XRootWindow(afisare, 0);

    /* verifica XInput */
    int xi_opcode, eveniment, eroare;
    dacă (!XQueryExtension(afișare, „XInputExtension”, &xi_opcode, &eveniment, &eroare)) {
        fprintf(stderr, „Eroare: extensia XInput nu este acceptată!\n”);
        întoarcere 1;
    }

    /* Verificați XInput 2.0 */
    int major = 2;
    int minor = 0;
    int retval = XIQueryVersion(afișare, &major, &minor);
    if (retval != Succes) {
        fprintf(stderr, „Eroare: XInput 2.0 nu este acceptat (antic X11?)\n”);
        întoarcere 1;
    }

    /*
     * Setați masca pentru a primi evenimente XI_RawMotion. Pentru că este crudă,
     * Evenimentele XWarpPointer() nu sunt incluse, puteți utiliza XI_Motion
     * in schimb.
     */
    unsigned char mask_bytes[(XI_LASTEVENT + 7) / 8] = {0}; /* trebuie pus la zero! */
    XISetMask(mask_bytes, XI_RawMotion);

    /* Setați masca pentru a primi evenimente de pe toate dispozitivele principale */
    XIEventMask evmasks[1];
    /* Puteți folosi XIAllDevices pentru XWarpPointer() */
    evmasks[0].deviceid = XIAllMasterDevices;
    evmasks[0].mask_len = sizeof(mask_bytes);
    evmasks[0].mask = mask_bytes;
    XISelectEvents(afișare, fereastră_rădăcină, evmasks, 1);

    XEvent xevent;
    în timp ce (1) {
        XNextEvent(afișare, &xevent);

        if (xevent.xcookie.type != GenericEvent || xevent.xcookie.extension != xi_opcode) {
            /* nu este un eveniment XInput */
            continua;
        }
        XGetEventData(afișare, &xevent.xcookie);
        dacă (xevent.xcookie.evtype != XI_RawMotion) {
            /*
             * Nu este un eveniment XI_RawMotion (poate dori să detectați
             * XI_Motion, de asemenea, vezi comentariile de mai sus).
             */
            XFreeEventData(afișare, &xevent.xcookie);
            continua;
        }
        XFreeEventData(afișare, &xevent.xcookie);

        Fereastra root_return, child_return;
        int root_x_return, root_y_return;
        int win_x_return, win_y_return;
        unsigned int mask_return;
        /*
         * Avem nevoie:
         * child_return - fereastra activă sub cursor
         * win_{x,y}_return - coordona indicatorului în raport cu fereastra rădăcină
         */
        int retval = XQueryPointer(afișare, fereastră_rădăcină, &root_return, &child_return,
                                   &root_x_return, &root_y_return,
                                   &win_x_return, &win_y_return,
                                   &mask_return);
        dacă (!retval) {
            /* indicatorul nu este în același ecran, ignorați */
            continua;
        }

        /* Am folosit fereastra rădăcină ca referință, așa că ambele ar trebui să fie la fel */
        assert(root_x_return == win_x_return);
        assert(root_y_return == win_y_return);

        printf("rădăcină: x %d y %d\n", root_x_return, root_y_return);

        if (child_return) {
            int local_x, local_y;
            XTranslateCoordinates(display, root_window, child_return,
                                  root_x_return, root_y_return,
                                  &local_x, &local_y, &child_return);
            printf("local: x %d y %d\n\n", local_x, local_y);
        }
    }

    XCloseDisplay(afișare);

    întoarce 0;
}
Shobeira avatar
drapel pt
Apreciez răspunsul dvs. Deci, sunt pe drumul cel bun? Fereastra X este o abordare bună? În timp ce mă uitam la măștile de evenimente, am găsit MotionNotify cea mai potrivită mască, deoarece am nevoie de un return boolean pentru problemă. Ceea ce mă gândeam era să am o structură X relevantă, să o inițializez și apoi să o evaluez în raport cu masca de eveniment. Am nevoie de mișcare/fără_mișcare..
drapel in
Nicio problemă, cred că dacă vrei doar să detectezi mișcarea este destul de ușor... Doar monitorizează X\Y poziția mouse-ului și dacă se schimbă, atunci ai mișcare. Primul pas este obținerea evenimentelor pointer în primul rând..

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.