Kivy: Sur Raspian Jessie, les clics de souris et de clavier sont passés à l'écran du bureau en arrière-plan

Créé le 14 janv. 2016  ·  23Commentaires  ·  Source: kivy/kivy

Sur Raspberry Pi 2 Raspian Jessie, la souris et le clavier fonctionnent, mais sur l'application plein écran (impossible de trouver un moyen de s'exécuter sous Windows), les clics de souris et de clavier sont transmis à l'écran du bureau. Aucun problème avec les touches de liaison sur le clavier ou le fonctionnement de la souris, par exemple / sur l'écran des paramètres, mais ces clics de souris entraînent l'exécution de certaines applications en arrière-plan.

RPi

Commentaire le plus utile

FYI: J'ai fait une solution de contournement.
L'application X11 saisissant le plein écran derrière l'application kivy sur le bureau peut capturer tous les événements passés de l'application kivy au bureau.

exemple de code :

// gcc -Wall -L/usr/X11R6/lib -lX11 kivyrun.c -o kivyrun
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long RGB(Display *disp,
        unsigned char r,
        unsigned char g,
        unsigned char b)
{
    XColor xc;
    Colormap cm = DefaultColormap(disp, DefaultScreen(disp));

    xc.red = 257 * r;
    xc.green = 257 * g;
    xc.blue = 257 * b;

    XAllocColor(disp, cm, &xc);
    return xc.pixel;
}

int main(int argc, char *argv[])
{
        char cmdStr[1024];
        Display *disp;
        XWindowAttributes attr;
        XSetWindowAttributes myAttr;
        Window myWin, rootWin;
        int screen;
        GC gc;

        if (argc != 2) {
                fprintf(stderr, "Usage: %s SCRIPT_FILE_NAME\n", argv[0]);
                exit(1);
        }

        disp = XOpenDisplay(":0.0");
        if (disp == NULL) {
                fprintf(stderr, "Cannot open display\n");
                exit(1);
        }

        rootWin = DefaultRootWindow(disp);
        screen = DefaultScreen(disp);

        XGetWindowAttributes(disp, rootWin, &attr);

        myAttr.override_redirect = True;

        myWin = XCreateWindow(disp, RootWindow(disp, screen),
                0, 0, attr.width, attr.height, 0,
                CopyFromParent, CopyFromParent, CopyFromParent,
                CWOverrideRedirect, &myAttr);
        XMapWindow(disp, myWin);

        gc = XCreateGC(disp, myWin, 0, 0);
        XSetForeground(disp, gc, RGB(disp, 0, 0, 0));

        XFillRectangle(disp, myWin, gc, 0, 0, attr.width, attr.height);
        XFlush(disp);

        snprintf(cmdStr, 1024, "python %s", argv[1]);

        printf("%s\n", cmdStr);
        system(cmdStr);

        XCloseDisplay(disp);
        return 0;
}

Veuillez saisir:

kivyrun SCRIPTNAME

à la place de

python SCRIPTNAME

Tous les 23 commentaires

Bravo pour ce problème !

Je travaille également avec Kivy sur Raspian Jessie depuis un certain temps maintenant et pour autant que je sache, cela ne fonctionne vraiment bien que lorsque vous êtes en cli et que vous démarrez l'application en plein écran.

Lorsque je démarre une application en x-session, je ne peux même pas fermer l'application (pas d'esc, pas de ctrl-c,...) - l'entrée dans les champs de texte fonctionne cependant.

Ce que j'ai découvert à propos de ce problème, c'est que Kivy est rendu au-dessus de votre x-session - et votre souris semble également être toujours active derrière votre application. Cela semble également être la raison pour laquelle vous ne voyez pas le curseur de votre souris lorsque vous n'activez pas la solution de contournement avec "touchring = show_cursor=true" dans votre config.ini. (Le truc ici, c'est que je ne vois la bague tactile que lorsque j'appuie sur le bouton de la souris - je devrais probablement examiner plus en détail la documentation du module touchring de kivy)

Par conséquent, la seule véritable façon d'exécuter kivy sur raspbian atm est de redémarrer en cli et de démarrer votre application là-bas.

Si je démarre l'application à partir d'une application terminale dans x-session, ctrl-c fonctionne. Mais si l'application est démarrée par autorun après la connexion, le modificateur ctrl ne fonctionne pas.

Le curseur de la souris est toujours visible et fonctionne bien (sauf que le clic est effectué dans le coin supérieur gauche de l'icône de l'anneau tactile).

La seule solution est de fonctionner en mode cli, comme vous l'avez mentionné.

Confirmation de ce problème également. J'ai ouvert une question StackOverflow à ce sujet.
Le démarrage en CLI atténue le problème tactile (évidemment), mais la saisie au clavier physique est toujours transmise.

Même problème ici. toujours pas de solution ? :/

Les applications RPi Kivy ne s'exécutent pas dans X. Afin d'utiliser l'accélération matérielle sur le RPi, nous devons écrire directement dans un framebuffer, qui restitue tout ce qui serait autrement à l'écran (X11 ou un VT). En tant que tel, nous ne faisons rien avec X Input, donc les événements d'entrée sont toujours transmis à X s'il est en cours d'exécution, et toutes les applications RPi Kivy sont en plein écran.

FYI: J'ai fait une solution de contournement.
L'application X11 saisissant le plein écran derrière l'application kivy sur le bureau peut capturer tous les événements passés de l'application kivy au bureau.

exemple de code :

// gcc -Wall -L/usr/X11R6/lib -lX11 kivyrun.c -o kivyrun
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long RGB(Display *disp,
        unsigned char r,
        unsigned char g,
        unsigned char b)
{
    XColor xc;
    Colormap cm = DefaultColormap(disp, DefaultScreen(disp));

    xc.red = 257 * r;
    xc.green = 257 * g;
    xc.blue = 257 * b;

    XAllocColor(disp, cm, &xc);
    return xc.pixel;
}

int main(int argc, char *argv[])
{
        char cmdStr[1024];
        Display *disp;
        XWindowAttributes attr;
        XSetWindowAttributes myAttr;
        Window myWin, rootWin;
        int screen;
        GC gc;

        if (argc != 2) {
                fprintf(stderr, "Usage: %s SCRIPT_FILE_NAME\n", argv[0]);
                exit(1);
        }

        disp = XOpenDisplay(":0.0");
        if (disp == NULL) {
                fprintf(stderr, "Cannot open display\n");
                exit(1);
        }

        rootWin = DefaultRootWindow(disp);
        screen = DefaultScreen(disp);

        XGetWindowAttributes(disp, rootWin, &attr);

        myAttr.override_redirect = True;

        myWin = XCreateWindow(disp, RootWindow(disp, screen),
                0, 0, attr.width, attr.height, 0,
                CopyFromParent, CopyFromParent, CopyFromParent,
                CWOverrideRedirect, &myAttr);
        XMapWindow(disp, myWin);

        gc = XCreateGC(disp, myWin, 0, 0);
        XSetForeground(disp, gc, RGB(disp, 0, 0, 0));

        XFillRectangle(disp, myWin, gc, 0, 0, attr.width, attr.height);
        XFlush(disp);

        snprintf(cmdStr, 1024, "python %s", argv[1]);

        printf("%s\n", cmdStr);
        system(cmdStr);

        XCloseDisplay(disp);
        return 0;
}

Veuillez saisir:

kivyrun SCRIPTNAME

à la place de

python SCRIPTNAME

Merci d'avoir posté cette solution de contournement !

Je l'ai essayé sur mon RPi mais il renvoie l'erreur "Impossible d'ouvrir l'affichage", donc je suppose que quelque chose ne va pas dans le XOpenDisplay.

Je suis nouveau sur Kivy et Python en général, et je n'ai aucune expérience avec C, donc je ne comprends pas ce que je fais mal.

Avez-vous des suggestions d'étapes de dépannage que je pourrais suivre pour aider à résoudre ce problème ?

Si cela peut aider, j'exécute Raspbian Jessie et Kivy 1.9.2.

Toute aide serait grandement appréciée!

dirkjan237,

Je pense que vous n'aviez pas d'autorisation de X-window à ce moment-là.
Par exemple, n'exécutez pas X11-desktop ou un autre utilisateur exécute X11-desktop.

Au début, vous devez vous connecter à X11-desktop.
Démarrez un LXTerminal par le menu de lancement sur le bureau puis exécutez cette commande.

Si vous retrouvez l'erreur, tapez 'echo $DISPLAY' sur LXTerminal et comparez avec le paramètre de XOpenDisplay(":0.0") dans le code source.
Si $DISPLAY était vide, vous n'exécutez pas le bureau X11.
S'il est différent du paramètre, remplacez le paramètre dans le code source par la valeur ou NULL.
Lorsque vous définissez le paramètre sur NULL, la variable d'environnement (DISPLAY) sera utilisée.

Exemple 1:

$ echo $DISPLAY
:0.1
$ 

Vous devez modifier le paramètre ci-dessous :

  • Option 1:

affichage = XOpenDisplay(":0.1");

  • Option 2:
    disp = XOpenDisplay(NULL);

exemple2 :

$ echo $DISPLAY

$ 

Vous devez d'abord exécuter le bureau X11.

Ce problème a été automatiquement marqué comme obsolète, car il n'a pas eu d'activité récente. Il sera fermé s'il n'y a plus d'activité. Merci pour vos contributions.

Voir la même chose sur Raspbian Stretch. Cela serait attendu du commentaire de kivyd ci-dessus, mais je voulais le rappeler aux développeurs afin que le bot obsolète ne ferme pas le problème.

Kivy et l'écran tactile officiel sont parfaits pour de nombreuses utilisations, donc un correctif serait bien.

Le fichier C de @ Hayatomon a aidé à exécuter l'application Kivy avec le X11 toujours ouvert à l'arrière. Merci @Hayatomon

J'ai trouvé une meilleure solution si vous utilisez Xorg (= écran de bureau, x-session) sur HDMI-1 et une application Kivy sur DSI-1. Comme l'explique @kived , une application Kivy dessine directement dans un framebuffer en contournant le serveur X. Mais l'écran tactile lui-même est répertorié comme une entrée X dans le serveur X :

$ xinput
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech MX Anywhere 2S                   id=6    [slave  pointer  (2)]
⎜   ↳ FT5406 memory based driver                id=9    [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ DELL DELL USB Keyboard                    id=7    [slave  keyboard (3)]
    ↳ DELL DELL USB Keyboard                    id=8    [slave  keyboard (3)]
    ↳ Logitech MX Anywhere 2S                   id=10   [slave  keyboard (3)]

Depuis Désactiver la souris (pas le pavé tactile !) dans Xorg pendant l'inactivité , je pouvais désactiver temporairement l'écran tactile dans Xorg mais pas dans l'application Kivy comme suit :

$ xinput list-props "FT5406 memory based driver"
Device 'FT5406 memory based driver':
    Device Enabled (114):   1
    Device Node (263):  "/dev/input/event2"
        [...]

$ xinput set-prop "FT5406 memory based driver" "Device Enabled" 0

Je vais vérifier s'il y a quelque chose de plus persistant comme Comment désactiver complètement le pavé tactile au démarrage ?

J'ai le même problème avec cette configuration :

  • Python : 3.6.0
  • Système d'exploitation : Raspbian GNU/Linux 9 (extensible)
  • Kivy : 1.10.1

Un correctif serait bien.

La solution de @ Hayatomon fonctionne toujours jusqu'à présent, en utilisant Raspbian 9 (stretch).
J'ai eu 3 problèmes :

  • en raison de modifications dans le dossier /usr , je pense que la nouvelle commande de compilation devrait être :
    gcc -Wall -L/usr/include/ -lX11 kivyrun.c -o kivyrun
  • utilisez ./ avant la commande kivyrun pour exécuter le fichier :
    ./kivyrun /path/to/my/file.py
  • lorsque l'application kivy a démarré, vous devez cliquer au moins une fois dans la fenêtre de votre programme (qui est en plein écran) pour la mettre au point. Tout ce que vous tapez avant de cliquer sera tapé dans X11 à la place.

Dans mon application, j'ouvre la fenêtre du terminal devant, mais la fenêtre apparaît mais en arrière-plan. J'ai essayé d'utiliser sdl2, c'est tellement lent. Si quelqu'un a trouvé une autre solution ?

Ou si quelqu'un a essayé la distribution kivypie ?

Ce n'est pas seulement un problème avec X. J'exécute une application Kivy en utilisant egl_rpi et No X windows, et en utilisant hidinput. Toutes les clés vont au shell en arrière-plan, ce qui peut causer des ravages lorsqu'elles exécutent des commandes dans ce shell. Les clés sont également vues par Kivy bien sûr. La solution X ci-dessus ne fonctionnera pas dans ce cas car il n'y a pas de X. Je suis en fait assez surpris que ce soit toujours un problème.

Pour info, ma solution actuelle à cela lors de l'exécution dans egl_rpi (pas de X) est d'exécuter mon application kivy dans le script shell suivant...

stty -echo
python3 main.py
while read -r -t 0; do read -r; done
stty echo

Cela arrête l'écho des caractères vers le shell d'arrière-plan, puis consomme les caractères avant que le shell ne puisse les obtenir.

Je suis en fait assez surpris que ce soit toujours un problème.

+1, bien que quelques années se soient écoulées - peut-être existe-t-il une solution appropriée ? J'utilise un lecteur de codes-barres qui agit comme un clavier USB HID ; chaque numérisation imprime le contenu du code-barres + CR sur la console même lorsque l'application Kivy est en cours d'exécution. Cela conduit à des échecs de connexion répétés sur le terminal :

Raspbian GNU/Linux 9 station tty1
station login: 82947682
Password: 
85404526
70198164

Login incorrect
station login: 72998502
Password: 
81799152
48270571
52904783

Login incorrect
...

ne pouvez-vous pas simplement configurer le tty par défaut pour qu'il n'y ait pas de console, tout comme celui pour X sur la plupart des distributions, de sorte que les événements tactiles/clavier ne soient reçus par rien ? (et vous pouvez toujours utiliser alt-fN pour passer à un autre tty), il s'agit de la configuration du système, pas de quelque chose que kivy peut vraiment résoudre dans un cas général.

ne pouvez-vous pas simplement configurer le tty par défaut pour qu'il n'y ait pas de console

Absolument, en fait j'allais le faire avant le déploiement de toute façon, pour obtenir un écran de démarrage complètement vide. Je pensais juste qu'il pourrait y avoir un moyen dans Python/Kivy de capturer un périphérique USB particulier et d'avaler tout ce qu'il produit.

faire
exporter AFFICHAGE=:0.0

faire
exporter AFFICHAGE=:0.0

Cela empêche l'application d'utiliser le pilote Broadcom OpenGL ES sur mon raspberry pi 3.
Il utilise à la place l'émulation logicielle Open GL, avec des performances très médiocres et un processeur utilisé à près de 100%.

La seule façon d'utiliser l'accélération matérielle est de définir la variable d'environnement DIPLAY sur rien.

Peut-être que je fais quelque chose de mal et qu'il existe un autre moyen de forcer SDL2 à utiliser la puce matérielle...

J'ai contourné mon problème en désactivant le périphérique xinput au lancement de mon application kivy et en le réactivant juste avant de quitter.

Pas une bonne solution cependant...

Cette page vous a été utile?
0 / 5 - 0 notes