Mettez en surbrillance la position actuelle de la souris

18

J'utilise une configuration à double écran et mon trackpad est désactivé la plupart du temps (ce qui inclut le masquage du pointeur de la souris). Lorsque je réactive le trackpad (et que j'affiche à nouveau le pointeur de la souris), j'ai perdu la trace de l'emplacement du pointeur avant.

Je cherche un outil pour mettre en évidence la position actuelle de la souris (par exemple par un cercle). Idéalement, il s'agirait d'une seule commande faisant clignoter le cercle pendant une courte période de temps.

Je suis conscient que xdotoolpeut trouver la position actuelle, mais il n'y a pas de mise en évidence; aussi, key-monne fournit pas cette fonctionnalité. J'ai également lu qui cairo composition managerfournit de telles fonctionnalités, mais je me demande s'il existe un outil plus petit pour y parvenir.

Dans le cas où il n'y a pas un tel outil: Quelle est la façon la plus simple d'afficher un tel cercle autour du curseur en utilisant les données fournies par xdotool getmouselocation ?

Dans le cas où cela est pertinent: je n'utilise pas un environnement de bureau, juste le xmonadgestionnaire de fenêtres.

deshtop
la source

Réponses:

18

Bien que j'aime la réponse de Mikeserv pour son intelligence, elle a l'inconvénient de créer une fenêtre qui "vole" le focus et doit être cliquée. Je trouve également que le démarrage prend un peu trop de temps: environ 0,2 à 0,3 seconde, ce qui est juste un peu trop lent pour une expérience "fluide".

Je me suis finalement mis à creuser dans XLib et à assembler un programme C de base pour le faire. L'effet visuel est à peu près similaire à celui de Windows (XP) (de la mémoire). Ce n'est pas très beau, mais ça marche ;-) Il ne "vole" pas le focus, démarre presque instantanément, et vous pouvez cliquer "à travers".

entrez la description de l'image ici

Vous pouvez le compiler avec cc find-cursor.c -o find-cursor -lX11 -lXext -lXfixes. Il y a quelques variables en haut que vous pouvez modifier pour changer la taille, la vitesse, etc.

J'ai publié cela en tant que programme sur http://code.arp242.net/find-cursor . Je vous recommande d'utiliser cette version, car elle présente des améliorations que le script ci-dessous n'a pas (comme des arguments de ligne de commande et la possibilité de cliquer "à travers" la fenêtre). J'ai laissé le ci-dessous tel quel en raison de sa simplicité.

/*
 * http://code.arp242.net/find-cursor
 * Copyright © 2015 Martin Tournoij <[email protected]>
 * See below for full copyright
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>


// Some variables you can play with :-)
int size = 220;
int step = 40;
int speed = 400;
int line_width = 2;
char color_name[] = "black";


int main(int argc, char* argv[]) {
    // Setup display and such
    char *display_name = getenv("DISPLAY");
    if (!display_name) {
        fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name);
        exit(1);
    }

    Display *display = XOpenDisplay(display_name);
    int screen = DefaultScreen(display);

    // Get the mouse cursor position
    int win_x, win_y, root_x, root_y = 0;
    unsigned int mask = 0;
    Window child_win, root_win;
    XQueryPointer(display, XRootWindow(display, screen),
        &child_win, &root_win,
        &root_x, &root_y, &win_x, &win_y, &mask);

    // Create a window at the mouse position
    XSetWindowAttributes window_attr;
    window_attr.override_redirect = 1;
    Window window = XCreateWindow(display, XRootWindow(display, screen),
        root_x - size/2, root_y - size/2,   // x, y position
        size, size,                         // width, height
        0,                                  // border width
        DefaultDepth(display, screen),      // depth
        CopyFromParent,                     // class
        DefaultVisual(display, screen),     // visual
        CWOverrideRedirect,                 // valuemask
        &window_attr                        // attributes
    );
    XMapWindow(display, window);
    XStoreName(display, window, "find-cursor");

    XClassHint *class = XAllocClassHint();
    class->res_name = "find-cursor";
    class->res_class = "find-cursor";
    XSetClassHint(display, window, class);
    XFree(class);

    // Keep the window on top
    XEvent e;
    memset(&e, 0, sizeof(e));
    e.xclient.type = ClientMessage;
    e.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False);
    e.xclient.display = display;
    e.xclient.window = window;
    e.xclient.format = 32;
    e.xclient.data.l[0] = 1;
    e.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_STAYS_ON_TOP", False);
    XSendEvent(display, XRootWindow(display, screen), False, SubstructureRedirectMask, &e);

    XRaiseWindow(display, window);
    XFlush(display);

    // Prepare to draw on this window
    XGCValues values = { .graphics_exposures = False };
    unsigned long valuemask = 0;
    GC gc = XCreateGC(display, window, valuemask, &values);

    Colormap colormap = DefaultColormap(display, screen);
    XColor color;
    XAllocNamedColor(display, colormap, color_name, &color, &color);
    XSetForeground(display, gc, color.pixel);
    XSetLineAttributes(display, gc, line_width, LineSolid, CapButt, JoinBevel);

    // Draw the circles
    for (int i=1; i<=size; i+=step) { 
        XDrawArc(display, window, gc,
            size/2 - i/2, size/2 - i/2,   // x, y position
            i, i,                         // Size
            0, 360 * 64);                 // Make it a full circle

        XSync(display, False);
        usleep(speed * 100);
    }
    XFreeGC(display, gc);
    XCloseDisplay(display);
}


/*
 *  The MIT License (MIT)
 * 
 *  Copyright © 2015 Martin Tournoij
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to
 *  deal in the Software without restriction, including without limitation the
 *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 *  sell copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 * 
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 * 
 *  The software is provided "as is", without warranty of any kind, express or
 *  implied, including but not limited to the warranties of merchantability,
 *  fitness for a particular purpose and noninfringement. In no event shall the
 *  authors or copyright holders be liable for any claim, damages or other
 *  liability, whether in an action of contract, tort or otherwise, arising
 *  from, out of or in connection with the software or the use or other dealings
 *  in the software.
 */
Martin Tournoij
la source
Serait-il facile de transformer cela en une fenêtre en forme avec un trou au milieu pour que les événements de la souris passent? J'ai essayé de transformer votre exemple en quelque chose comme ce que l'OP recherche ici , mais n'ayant aucune expérience avec xlib, j'ai fini par perdre désespérément ..
gandalf3
FTR: Comment le compiler sous Ubuntu: askubuntu.com/q/801252/31300
Grzegorz Wierzowiecki
@ gandalf3 Presque un an plus tard, j'ai finalement réussi à implémenter cela :-) Je n'ai pas modifié l'extrait ci-dessus afin qu'il puisse conserver sa simplicité, j'ai seulement modifié la version sur github.com/Carpetsmoker/find-cursor .
Martin Tournoij
@Carpetsmoker Fonctionne comme un charme, génial! Merci pour cela :) Maintenant, pour avoir la position de mise à jour pour suivre la souris ..
gandalf3
1
L'application affiche le cercle puis quitte @AquariusPower, c'est donc le comportement attendu. La façon de l'utiliser est de mapper une combinaison de touches pour la démarrer. L' -foption signifie qu'elle suivra le curseur de la souris pendant l'exécution , mais ne change pas réellement ce concept de base (ce n'est pas compatible avec tous les gestionnaires de fenêtres, c'est pourquoi c'est une option).
Martin Tournoij
6

Les éléments suivants fonctionneront probablement pour vous:

#!/bin/sh
unset X Y; sleep 1
eval "$(xdotool getmouselocation -shell 2>/dev/null)"
for n in X Y; do  : "$(($n-=$n>25?25:$n))"; done
xwd -root -silent |
xv -    -crop "$X" "$Y" 50 50 \
        -geometry "50x50+$X+$Y" \
        -nodecor -viewonly -rv -quit

Cela dépend des trois services publics xv, xwdet xdotool. Les deux premiers sont des Xutilitaires très courants , et le troisième, je suis raisonnablement sûr que vous l'avez déjà.

Après sleepune seconde, xdotoolécrit les coordonnées actuelles de la souris dans sa sortie standard dans un -shellformat convivial comme:

X=[num]
Y=[num]
windowID=[num]

evaldéfinit les variables shell en conséquence, et la forsoustrait de la boucle de la moitié de la taille de l'image dès-à-être-affichée à partir de chacun des $Xet $Yles valeurs de » ou, si l'une ou l' autre valeur est inférieure à 25, les met à 0.

xwdvide la fenêtre racine sur un tuyau xv, qui recadre autour de l'emplacement de la souris à une taille d'image de 50x50 et affiche un négatif de l'image sous le curseur de souris actuel dans une petite fenêtre sans aucune décoration de gestionnaire de fenêtres.

Le résultat final est quelque chose comme ceci:

trouver une souris

... même si je suppose que le curseur de ma souris n'apparaît pas dans les captures d'écran. Rassurez-vous, cependant, c'était juste au-dessus de la boîte blanche lorsque j'ai pris la photo.

Vous pouvez voir dans l'image comment je l'ai également écrit en tant que fonction shell et mis en arrière-plan. C'est principalement pour cette raison qu'il y a un sleepdedans du tout - appuyer sur la RETURNtouche fera défiler le terminal si vous êtes déjà en bas, et xwdétait assez rapide pour saisir sa photo de l'écran avant que le terminal ne défile - ce qui compenserait ma négatif dans l'image un peu et je n'ai pas aimé.

Quoi qu'il en soit, parce qu'il xvest exécuté avec les commutateurs -viewonlyet -quit, il disparaîtra dès qu'un bouton de la souris est cliqué ou une touche du clavier est enfoncée - mais restera jusqu'à ce que vous fassiez l'un ou l'autre.

Sans aucun doute, vous pourriez faire des choses beaucoup plus élaborées avec ImageMagickou même xvseul - mais je viens de faire une petite case négative sous le curseur de la souris. Vous pouvez trouver les xvdocuments ici et les documents pour xwden man xwd.

mikeserv
la source
1
Cela semble bon, sauf pour le fait que ma distribution (debian) ne fournit pas xv. Si possible, je voudrais éviter de compiler xvmoi-même et laisser aptgérer la gestion des paquets.
deshtop
1
@deshtop - voici un repo, si vous le voulez. Vous pouvez également probablement faire des choses similaires avec l' displayutilitaire ImageMagick . Et bien sûr, il y en a toujours feh. Je n'avais pas fehinstallé au moment où j'écris cela, et, bien que j'aie essayé une ou deux fois, je ne pouvais pas facilement comprendre comment displayouvrir sans bordures de fenêtres.
mikeserv
Merci pour le dépôt, mais je suis un peu prudent avec les référentiels non officiels. Je vais voir si je peux utiliser ImageMagick
deshtop
1
@deshtop - vous le pouvez probablement. À tout le moins, vous pouvez configurer pour xmonad ne pas décorer la displayfenêtre que cela lancerait - ou bien vous pourriez lancer displaycomme -iconicensuite utiliser xdotoolpour supprimer ses décorations et la désiconifier (ou quel que soit son nom) .
mikeserv
cela semble vraiment intéressant, mais xvsemble un non sur ubuntu 14.04 (il ne compilait pas malgré tous les deps fournis), et displayouvre une grande fenêtre, et je n'ai encore aucune idée de comment l'utiliser fehjuste scanné tous les fichiers sur ma maison (chemin actuel) à la recherche d'images, drôle .. hehe est catalogueur.
Aquarius Power