Выделить текущую позицию мыши


18

Я запускаю настройку с двумя экранами и большую часть времени отключаю свой трекпад (включая скрытие указателя мыши). Когда я снова включаю трекпад (и снова отображаю указатель мыши), я теряю трек там, где раньше был указатель.

Я ищу инструмент для выделения текущей позиции мыши (например, по кругу). В идеале это будет одна команда, мигающая в течение короткого промежутка времени.

Я знаю, что xdotoolмогу найти текущую позицию, пока нет подсветки; Кроме того, key-monне предоставляет эту функциональность. Я также читал, что cairo composition managerобеспечивает такую ​​функциональность, но мне интересно, есть ли меньший инструмент для достижения этой цели.

Если такого инструмента нет: какой самый простой способ отобразить такой круг вокруг курсора, используя данные, предоставленные xdotool getmouselocation ?

В случае, если это уместно: я не использую рабочую среду, а только xmonadдиспетчер окон.

Ответы:


18

Хотя мне нравится ответ Mikeserv за сообразительность, у него есть и недостаток, заключающийся в том, что он создаст окно, которое «крадет» фокус и его нужно будет щелкнуть. Я также считаю , что нужно просто немного слишком долго , чтобы начать: около 0,2 до 0,3 секунды, что чуть - чуть слишком медленно для «гладкого» опыта.

Я наконец-то нашел время копаться в XLib и собрал вместе базовую C-программу для этого. Визуальный эффект примерно такой же, как у Windows (XP) (из памяти). Это не очень красиво, но работает ;-) Он не «крадет» фокус, запускается практически мгновенно, и вы можете нажать «через» его.

введите описание изображения здесь

Вы можете скомпилировать его cc find-cursor.c -o find-cursor -lX11 -lXext -lXfixes. Вверху есть некоторые переменные, которые можно настроить, чтобы изменить размер, скорость и т. Д.

Я выпустил это как программу на http://code.arp242.net/find-cursor . Я рекомендую вам использовать эту версию, так как в ней есть некоторые улучшения, которых нет в приведенном ниже сценарии (например, аргументы командной строки и возможность щелкнуть «через» окно). Я оставил ниже как есть из-за его простоты.

/*
 * http://code.arp242.net/find-cursor
 * Copyright © 2015 Martin Tournoij <martin@arp242.net>
 * 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.
 */

Насколько легко было бы превратить это в фасонное окно с отверстием посередине для прохождения событий мыши? Я попытался превратить ваш пример во что-то вроде того, что ищет ОП здесь , но, не имея опыта работы с xlib, я безнадежно проиграл ..
gandalf3

FTR: Как скомпилировать его под Ubuntu: askubuntu.com/q/801252/31300
Гжегож Вежовецкий,

@ gandalf3 Почти год спустя я наконец-то нашел способ реализовать это :-) Я не модифицировал приведенный выше фрагмент кода, чтобы он мог сохранить его простоту, я изменил только версию на github.com/Carpetsmoker/find-cursor .
Мартин Турной

@Carpetsmoker Работает как шарм, блестящий! Спасибо за это :) Теперь, чтобы он
обновил

1
Приложение показывает круг, а затем завершает работу @AquariusPower, так что это ожидаемое поведение. Способ использовать это, чтобы сопоставить комбинацию клавиш, чтобы запустить его. В -fозначает вариант будет следовать за курсором мыши вокруг во время работы , но на самом деле не изменить эту основную концепцию (это не совместимо со всеми оконными менеджерами, поэтому это вариант).
Мартин Турной

6

Следующее, вероятно, будет работать для вас:

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

Это зависит от трех коммунальных услуг xv, xwdи xdotool. Первые два - очень распространенные Xутилиты, а третье, я уверен, у вас уже есть.

Через sleepодну секунду xdotoolзаписывает текущие координаты мыши в стандартный вывод в удобном для ознакомления -shellформате, например:

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

evalсоответственно устанавливает переменные оболочки, и forцикл вычитает половину размера изображения, которое должно отображаться в ближайшее время, из каждого из значений $Xand $Yи, или, если любое из значений меньше 25, устанавливает их в 0.

xwdсоздает дамп корневого окна по каналу xv, который обрезает область расположения мыши до размера изображения 50x50 и отображает негатив изображения под текущим курсором мыши в небольшом окне без каких-либо украшений диспетчера окон.

Конечный результат примерно такой:

findmouse

... хотя я думаю, что мой курсор мыши не появляется на снимках экрана. Будьте уверены, однако, это было прямо над белой коробкой, когда я сделал снимок.

Вы можете видеть на изображении, как я также написал это как функцию оболочки и создал фон. Это в основном по той причине, что там вообще sleepесть - нажатие RETURNклавиши прокручивает терминал, если вы уже внизу, и xwdбыл достаточно быстрым, чтобы захватить его изображение экрана перед прокруткой терминала - что сместило бы мой негатива на изображении немного и мне это не понравилось.

Во всяком случае, так как xvвыполняется с обоими -viewonlyи -quitкоммутаторами, она исчезнет , как только кнопка мыши нажата или клавиша клавиатуры нажата - но будет оставаться до тех пор , пока сделать что- либо.

Несомненно, вы могли бы сделать намного более сложные вещи с помощью ImageMagickили даже в xvодиночку, но я просто сделал небольшой отрицательный блок под курсором мыши. Вы можете найти xvдокументы здесь и документы для xwdв man xwd.


1
Это выглядит хорошо, за исключением того факта, что мой дистрибутив (Debian) не предоставляет xv. Если возможно, я бы хотел избежать компиляции xvсамостоятельно и разрешить aptуправление пакетами.
Дештоп

1
@deshtop - вот репо, если хочешь. Вы также можете делать подобные вещи с помощью displayутилиты ImageMagick . И конечно всегда есть feh. Я не fehустановил в тот момент, когда писал это, и, хотя я пытался один или два раза, я не мог легко понять, как displayоткрыть без оконных рамок.
mikeserv

Спасибо за репо, но я немного осторожен с неофициальными репозиториями. Я посмотрю, смогу ли я использовать ImageMagick
deshtop

1
@deshtop - вы, вероятно, можете. По крайней мере, вы можете настроить, чтобы xmonad не украшать displayокно, которое это запустит - или вы могли бы запустить displayкак -iconicзатем использовать, xdotoolчтобы удалить его украшения и uniconify (или как там это называется) .
mikeserv

это звучит очень интересно, но xvкажется, что нет ubuntu 14.04 (он не компилировался, несмотря на то, что все deps были поставлены), и displayоткрывает большое окно, и я пока не знаю, как его использовать, fehпросто отсканировал все файлы у себя дома (текущий путь) ищу картинки, смешно .. хе-хе это каталогизатор.
Водолей Сила
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.