Embora eu goste da resposta de Mikeserv por sua esperteza, ela tem a desvantagem de criar uma janela que "rouba" o foco e precisa ser clicada. Também acho que demora um pouco demais para iniciar: cerca de 0,2 a 0,3 segundos, o que é um pouco lento demais para uma experiência "suave".
Finalmente cheguei a explorar o XLib e juntei um programa C básico para fazer isso. O efeito visual é aproximadamente semelhante ao que o Windows (XP) possui (da memória). Não é muito bonito, mas funciona ;-) Não "rouba" o foco, começa quase instantaneamente e você pode clicar em "através" dele.
Você pode compilá-lo com cc find-cursor.c -o find-cursor -lX11 -lXext -lXfixes
. Existem algumas variáveis no topo que você pode ajustar para alterar o tamanho, velocidade, etc.
Lancei isso como um programa em http://code.arp242.net/find-cursor . Eu recomendo que você use esta versão, pois ela possui algumas melhorias que o script abaixo não possui (como argumentos da linha de comando e capacidade de clicar em "através" da janela). Deixei o abaixo como está devido à sua simplicidade.
/*
* 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.
*/
-f
opção significa que ele seguirá o cursor do mouse durante a execução , mas na verdade não altera esse conceito básico (isso não é compatível com todos os gerenciadores de janelas, e é por isso que é uma opção).Provavelmente, o seguinte funcionará para você:
Depende dos três utilitários
xv
,xwd
exdotool
. Os dois primeiros sãoX
utilitários muito comuns e o terceiro tenho quase certeza de que você já possui.Após
sleep
um segundo,xdotool
grava as coordenadas atuais do mouse no stdout em um-shell
formato compatível com a avaliação , como:eval
define as variáveis do shell Nesse sentido, e ofor
subtrai laço metade do tamanho da imagem logo-a-ser-exibido de cada uma$X
e$Y
valores 's ou, se qualquer valor for inferior a 25, define-los a 0.xwd
despeja a janela raiz sobre um tubo paraxv
, que corta ao redor da localização do mouse para um tamanho de imagem de 50x50 e exibe um negativo da imagem sob o cursor atual do mouse em uma pequena janela sem qualquer decoração do gerenciador de janelas.O resultado final é algo como isto:
... embora eu ache que o cursor do mouse não apareça nas capturas de tela. Tenha certeza, porém, estava logo acima da caixa branca quando tirei a foto.
Você pode ver na imagem como eu também escrevi como uma função shell e a coloquei em segundo plano. É principalmente por esse motivo que existe um
sleep
- pressione aRETURN
tecla para rolar o terminal se você já estiver na parte inferior exwd
foi rápido o suficiente para capturar a imagem da tela antes do terminal rolar - o que compensaria minha negativo na imagem um pouco e eu não gostei.De qualquer forma, como
xv
é executado com os botões-viewonly
e-quit
, ele desaparecerá assim que um botão do mouse for pressionado ou uma tecla do teclado for pressionada - mas permanecerá até que você o faça.Sem dúvida, você poderia fazer coisas muito mais elaboradas com
ImageMagick
ou mesmoxv
sozinho - mas eu apenas fiz uma pequena caixa negativa sob o cursor do mouse. Você pode encontrar osxv
documentos aqui e os documentosxwd
emman xwd
.fonte
xv
. Se possível, gostaria de evitar a compilaçãoxv
por conta própria e deixarapt
lidar com o gerenciamento de pacotes.display
utilitário ImageMagick . E é claro que sempre existefeh
. Eu não tinhafeh
instalado no momento em que escrevi isso e, apesar de ter tentado uma ou duas vezes, não conseguia descobrir com facilidade comodisplay
abrir sem bordas com janelas.xmonad
não para decorar adisplay
janela que isso iria lançar - ou então você pode lançardisplay
como-iconic
então usarxdotool
para remover as suas decorações e uniconify (ou seja lá o que é chamado) -lo.xv
parece que não existe no ubuntu 14.04 (não estava compilando apesar de todos os deps terem sido fornecidos) edisplay
está abrindo uma grande janela, e ainda não tenho idéia de como usá-feh
lo, apenas digitalizei todos os arquivos da minha casa (caminho atual) procurando imagens engraçadas .. hehe é um catalogador.