Resalte posición actual del ratón

18

Estoy ejecutando una configuración de pantalla dual y tengo el trackpad desactivado la mayor parte del tiempo (lo que incluye ocultar el puntero del mouse). Cuando vuelvo a habilitar el panel táctil (y vuelvo a mostrar el puntero del mouse), he perdido la pista donde estaba el puntero antes.

Estoy buscando una herramienta para resaltar la posición actual del mouse (por ejemplo, mediante un círculo). Idealmente, este sería un comando único que parpadea el círculo durante un corto período de tiempo.

Soy consciente de que xdotoolpuede encontrar la posición actual, pero no hay resaltado; Además, key-monno proporciona esta funcionalidad. También he leído que cairo composition managerproporciona dicha funcionalidad, pero me pregunto si hay una herramienta más pequeña para lograrlo.

En caso de que no existe tal herramienta: ¿Cuál es la forma más sencilla de mostrar tal círculo alrededor del cursor utilizando los datos proporcionados por xdotool getmouselocation ?

En caso de que esto sea relevante: no uso un entorno de escritorio, solo el xmonadadministrador de ventanas.

deshtop
fuente

Respuestas:

18

Si bien me gusta la respuesta de Mikeserv para la inteligencia, tiene el inconveniente de que creará una ventana que "robará" el foco y tendrá que hacer clic. También encuentro que tarda un poco demasiado en comenzar: aproximadamente 0.2 a 0.3 segundos, lo cual es un poco demasiado lento para una experiencia "fluida".

Finalmente llegué a cavar en XLib, y creé un programa básico de C para hacer esto. El efecto visual es más o menos similar al que tiene Windows (XP) (de memoria). No es muy hermoso, pero funciona ;-) No "roba" el foco, comienza casi instantáneamente, y puede hacer clic en "a través de".

ingrese la descripción de la imagen aquí

Puedes compilarlo con cc find-cursor.c -o find-cursor -lX11 -lXext -lXfixes. Hay algunas variables en la parte superior que puede ajustar para cambiar el tamaño, la velocidad, etc.

Lancé esto como un programa en http://code.arp242.net/find-cursor . Le recomiendo que use esta versión, ya que tiene algunas mejoras que el siguiente script no tiene (como los argumentos de la línea de comandos y la capacidad de hacer clic "a través" de la ventana). Dejé el siguiente como es debido a su simplicidad.

/*
 * 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
fuente
¿Qué tan fácil sería convertir esto en una ventana con forma con un agujero en el medio para que pasen los eventos del mouse? Me trató de convertir su ejemplo en algo así como lo que el PO está buscando aquí , pero que no tengan experiencia con xlib, terminé irremediablemente perdido ..
gandalf3
FTR: Cómo compilar bajo Ubuntu: askubuntu.com/q/801252/31300
Grzegorz Wierzowiecki
@ gandalf3 Casi un año después finalmente pude implementar eso :-) No modifiqué el fragmento anterior para que pudiera mantener su simplicidad, solo modifiqué la versión en github.com/Carpetsmoker/find-cursor .
Martin Tournoij
@Carpetsmoker funciona de maravilla, genial! Gracias por esto :) Ahora para que actualice la posición para seguir el mouse ..
gandalf3
1
La aplicación muestra el círculo y luego sale de @AquariusPower, por lo que ese es el comportamiento esperado. La forma de usarlo es para asignar una combinación de teclas para iniciarlo. La -fopción significa que seguirá el cursor del mouse mientras se ejecuta , pero en realidad no cambia ese concepto básico (esto no es compatible con todos los administradores de ventanas, por eso es una opción).
Martin Tournoij
6

Lo siguiente probablemente funcionará para usted:

#!/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

Depende de las tres empresas de servicios públicos xv, xwdy xdotool. Los dos primeros son muy comunes Xlos servicios públicos, y el tercero Estoy razonablemente seguro de que ya tienen.

Después sleepde un segundo, xdotoolescribe las coordenadas actuales del mouse en su stdout en un -shellformato fácil de evaluar como:

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

evalestablece las variables de shell en consecuencia, y la forresta de bucle medio del tamaño de la imagen pronto-a-visualizado-ser de cada uno de $Xy $Ylos valores de s o, si cualquiera de los valores es inferior a 25, los conjuntos a 0.

xwdvoltea la ventana raíz sobre una tubería xv, que se recorta alrededor de la ubicación del mouse a un tamaño de imagen de 50x50 y muestra un negativo de la imagen debajo del cursor del mouse actual en una pequeña ventana sin decoraciones de administrador de ventanas.

El resultado final es algo como esto:

findmouse

... aunque supongo que el cursor de mi mouse no aparece en las capturas de pantalla. Sin embargo, tenga la seguridad de que estaba justo sobre la caja blanca allí cuando tomé la foto.

Puedes ver en la imagen cómo también lo escribí como una función de shell y lo hice en segundo plano. Es principalmente por esa razón que hay un elemento sleepallí: presionar la RETURNtecla desplazará el terminal si ya está en la parte inferior, y xwdfue lo suficientemente rápido como para tomar su imagen de la pantalla antes de que el terminal se desplazara, lo que compensaría mi negativa en la imagen un poco y no me gusta.

De todos modos, porque xvse ejecuta con las dos -viewonlyy -quitconmutadores, que desaparecerá tan pronto como se hace clic en un botón del ratón o se pulsa una tecla del teclado - sino que permanecerá hasta que lo haga bien.

Sin lugar a dudas, también podrías hacer cosas mucho más elaboradas ImageMagicko incluso xvsolo, pero acabo de hacer un pequeño cuadro negativo debajo del cursor del mouse. Puede encontrar los xvdocumentos aquí y los documentos de xwden man xwd.

mikeserv
fuente
1
Esto se ve bien, excepto por el hecho de que mi distro (debian) no proporciona xv. Si es posible me gustaría evitar la compilación xvpor mi cuenta y dejar que aptmanejar la gestión de paquetes.
Deshtop
1
@deshtop: aquí hay un repositorio, si lo desea. También puede probablemente hacer cosas similares con el ImageMagick displayutilidad. Y, por supuesto, siempre hay feh. No me he fehinstalado en el momento en que la escritura, y, aunque he intentado una o dos veces, no podría fácilmente figura sobre cómo hacer displayabierta y sin bordes de las ventanas manejadas.
mikeserv
Gracias por el repositorio, sin embargo, soy un poco cauteloso con los repositorios no oficiales.
Veré
1
@deshtop - probablemente puedas. Por lo menos se puede configurar xmonad no para decorar la displayventana que esto pondría en marcha - o de lo contrario se podría poner en marcha displaycomo -iconica continuación, utilizar xdotoolpara eliminar sus decoraciones y uniconify (o lo que se llama) es.
mikeserv
Esto suena muy interesante, pero xvparece un no ir en Ubuntu 14.04 (no fue recopilando a pesar de todas deps fueron suministrados), y displayse abre una ventana grande, y no tengo ni idea todavía cómo utilizar fehsimplemente escanea todos los archivos en mi casa (camino actual) buscando fotos, gracioso .. jeje es un catalogador.
Acuario Power