Markieren Sie die aktuelle Mausposition

18

Ich verwende ein Dual-Screen-Setup und habe mein Trackpad die meiste Zeit deaktiviert (dazu gehört auch das Ausblenden des Mauszeigers). Wenn ich das Trackpad wieder aktiviere (und den Mauszeiger erneut anzeige), habe ich den Track verloren, an dem sich der Zeiger zuvor befand.

Ich suche ein Werkzeug, um die aktuelle Mausposition hervorzuheben (zB durch einen Kreis). Im Idealfall ist dies ein einzelner Befehl, der den Kreis für kurze Zeit blinkt.

Mir ist bekannt, dass xdotooldie aktuelle Position gefunden werden kann, aber keine Hervorhebung vorhanden ist. auch, key-monverfügt nicht über diese Funktionalität. Ich habe auch gelesen, dass cairo composition managersolche Funktionen zur Verfügung stehen, aber ich frage mich, ob es ein kleineres Tool gibt, um dies zu erreichen.

Falls es kein solches Tool gibt: Wie lässt sich ein solcher Kreis mit den von bereitgestellten Daten am einfachsten um den Cursor anzeigen xdotool getmouselocation ?

Falls dies relevant ist: Ich verwende keine Desktop-Umgebung, sondern nur den xmonadFenstermanager.

Deshtop
quelle

Antworten:

18

Während ich Mikeservs Antwort für Cleverness mag , hat es den Nachteil, dass es ein Fenster erzeugt, das den Fokus "stiehlt" und weggeklickt werden muss. Ich finde auch , es dauert nur zu beginnen etwas zu lang: etwa 0,2 bis 0,3 Sekunden, was auch nur etwas langsam ist für eine „glatte“ Erfahrung.

Endlich bin ich dazu gekommen, mich in XLib zu vertiefen, und habe ein grundlegendes C-Programm zusammengestellt, um dies zu tun. Der visuelle Effekt ähnelt in etwa dem von Windows (XP) (aus dem Speicher). Es ist nicht sehr schön, aber es funktioniert ;-) Es "stiehlt" den Fokus nicht, beginnt fast augenblicklich und Sie können "durch" klicken.

Bildbeschreibung hier eingeben

Sie können es mit kompilieren cc find-cursor.c -o find-cursor -lX11 -lXext -lXfixes. Es gibt oben einige Variablen, die Sie anpassen können, um Größe, Geschwindigkeit usw. zu ändern.

Ich habe dies als Programm unter http://code.arp242.net/find-cursor veröffentlicht . Ich empfehle Ihnen, diese Version zu verwenden, da sie einige Verbesserungen aufweist, die das folgende Skript nicht bietet (z. B. Befehlszeilenargumente und die Möglichkeit, "durch" das Fenster zu klicken). Ich habe das Folgende so gelassen, wie es ist, aufgrund seiner Einfachheit.

/*
 * 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
quelle
Wie einfach wäre es, daraus ein geformtes Fenster mit einem Loch in der Mitte zu machen, durch das Mausereignisse passieren könnten? Ich habe versucht , Ihr Beispiel zu wie etwas zu machen , was die OP sucht hier , aber keine Erfahrung mit xlib hat, landete ich hoffnungslos verloren ..
gandalf3
FTR: So kompilieren Sie es unter Ubuntu: askubuntu.com/q/801252/31300
Grzegorz Wierzowiecki
@ gandalf3 Fast ein Jahr später habe ich mich endlich mit der Implementierung beschäftigt :-) Ich habe das obige Snippet nicht modifiziert, damit es seine Einfachheit beibehält. Ich habe nur die Version unter github.com/Carpetsmoker/find-cursor modifiziert .
Martin Tournoij
@Carpetsmoker Funktioniert wie ein Zauber, genial! Vielen Dank dafür :) Jetzt muss es die Position aktualisieren, um der Maus zu folgen ..
gandalf3
1
Die Anwendung zeigt den Kreis und beendet dann @AquariusPower. Das ist also das erwartete Verhalten. Sie können es verwenden, indem Sie eine Tastenkombination zuordnen, um es zu starten. Die -fOption bedeutet, dass sie beim Ausführen dem Mauszeiger folgt, dieses grundlegende Konzept jedoch nicht ändert (dies ist nicht mit allen Fenstermanagern kompatibel, weshalb dies eine Option ist).
Martin Tournoij
6

Folgendes wird wahrscheinlich für Sie funktionieren:

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

Es hängt von den drei Dienstprogramme xv, xwdund xdotool. Die ersten beiden sind sehr gebräuchliche XHilfsprogramme, und das dritte ist meines Erachtens bereits vorhanden.

Schreibt nach sleepeiner Sekunde xdotooldie aktuellen Koordinaten der Maus in einem auswertungsfreundlichen -shellFormat auf die Standardausgabe :

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

evalSetzt die Shell-Variablen entsprechend und die forSchleife subtrahiert die Hälfte der Größe des Bildes, das in Kürze angezeigt werden soll, von jedem der Werte von $Xund $Yoder setzt sie auf 0, wenn einer der Werte kleiner als 25 ist.

xwdBewegt das Stammfenster über eine Pipe zu xv, die auf eine Bildgröße von 50x50 um die Mausposition herum abschneidet und ein Negativ des Bildes unter dem aktuellen Mauszeiger in einem kleinen Fenster ohne Fenstermanagerdekorationen anzeigt.

Das Endergebnis ist ungefähr so:

findmouse

... obwohl ich vermute, dass mein Mauszeiger in Screenshots nicht angezeigt wird. Seien Sie versichert, es war direkt über der weißen Box, als ich das Foto machte.

Sie können im Bild sehen, wie ich es auch als Shell-Funktion geschrieben und hinterlegt habe. Dies ist vor allem deshalb so, weil es überhaupt eine sleepgibt - RETURNwenn Sie die Taste drücken, wird das Terminal gescrollt, wenn Sie bereits ganz unten sind, und sie xwdwar schnell genug, um das Bild des Bildschirms zu erfassen, bevor das Terminal gescrollt hat - was meinen Fehler ausgleichen würde Negativ im Bild ein wenig und es hat mir nicht gefallen.

Wie auch immer, da xvmit den Schaltern -viewonlyund ausgeführt wird -quit, wird es ausgeblendet, sobald eine Maustaste gedrückt oder eine Tastaturtaste gedrückt wird - es bleibt jedoch so lange, bis Sie dies tun.

Zweifellos könnte man mit ImageMagickoder auch xvallein viel aufwändiger vorgehen - aber ich habe nur ein kleines Negativfeld unter dem Mauszeiger angezeigt. Sie finden die xvDokumente hier und die Dokumente für xwdin man xwd.

mikeserv
quelle
1
Das sieht gut aus, bis auf die Tatsache, dass meine Distribution (Debian) dies nicht bietet xv. Wenn möglich, möchte ich vermeiden, selbstständig zu kompilieren xvund aptdie Paketverwaltung übernehmen.
Deshtop
1
@deshtop - hier ist ein Repo, wenn Sie es wollen. Sie können wahrscheinlich auch ähnliche Aufgaben mit dem ImageMagick- displayDienstprogramm ausführen . Und natürlich gibt es immer feh. Ich hatte es fehzum Zeitpunkt des Schreibens noch nicht installiert, und obwohl ich es ein oder zwei Mal versuchte, konnte ich nicht leicht herausfinden, wie man displayohne Fensterrahmen öffnet.
mikeserv
Danke für das Repo, aber ich bin ein bisschen vorsichtig mit inoffiziellen Repositories. Ich werde sehen, ob ich ImageMagick verwenden kann
deshtop
1
@deshtop - das können Sie wahrscheinlich. Zumindest können Sie konfigurieren , xmonad nicht das dekorieren displayFenster , dass dies starten - sonst könnten Sie starten displayals -iconicdann verwenden , xdotoolum seine Dekorationen zu entfernen und uniconify (oder was auch immer das heißt) es.
mikeserv
das hört sich wirklich interessant an, xvscheint aber ein no go auf ubuntu 14.04 zu sein (es wurde nicht kompiliert, obwohl alle deps mitgeliefert wurden), und displayöffnet ein großes Fenster, und ich habe noch keine Ahnung, wie es verwendet werden soll feh, scannte einfach alle Dateien in meinem Haus (aktueller Pfad) Bilder suchen, lustig .. hehe ist ein Katalogisierer.
Aquarius Power