Soy de los que configuran el Caps Lock para cambiar el idioma porque me da pereza presionar 2 teclas cuando puedo presionar una. Incluso desearía tener 2 teclas innecesarias: usaría una para activar el idioma inglés y la otra para el ruso. Pero la segunda tecla innecesaria es la que llama al menú contextual, que es tan innecesaria que muchos fabricantes de laptops la eliminan. Así que tengo que conformarme con lo que hay.
Además, no quiero estar buscando los iconos de las ventanas en la barra de tareas al cambiar entre ellas, intentando captar los nombres al desplazarse a través de Alt+Tab, desplazándome entre escritorios, etc. Quiero presionar una combinación de teclas (idealmente solo una, pero ya no hay teclas innecesarias disponibles) y entrar directamente a la ventana que necesito. Por ejemplo:
- Alt+F: Firefox
- Alt+D: Firefox (Navegación Privada)
- Alt+T: Terminal
- Alt+M: Calculadora
- Alt+E: IntelliJ Idea
- etc.
Y además, al presionar, por ejemplo, el Alt+M , quiero ver la calculadora sin importar si ese programa está abierto en ese momento. Si está abierto, el foco debe trasladarse a su ventana, y si no, se debe iniciar el programa necesario y transferir el foco cuando se cargue.
Para los casos que no cubre el escenario anterior, quiero tener combinaciones de teclas universales a las que se les pueda asignar fácilmente cualquier ventana abierta. Por ejemplo, tengo 10 combinaciones asignadas desde Alt+1 hasta Alt+0, que no están vinculadas a ningún programa. Solo puedo presionar Alt+1 y la ventana que está en foco obtendrá el foco al presionar Alt+1.
A continuación hay una descripción de un par de características adicionales y una respuesta sobre cómo se puede hacer esto. Pero advierto que este tipo de personalización «a medida» puede causar una fuerte dependencia e incluso malestar al tener que usar Windows, Mac OS o incluso otra computadora con Linux.
En realidad, si lo piensas, no usamos tantas aplicaciones en nuestro día a día. Un navegador, terminal, IDE, algún mensajero, un gestor de archivos, una calculadora y, quizás, eso es casi todo. No se necesitan muchas combinaciones de teclas para cubrir el 95% de las tareas cotidianas.
Para programas que tienen varias ventanas abiertas, se puede designar una de ellas como principal. Por ejemplo, si hay varias ventanas de IntelliJ Idea abiertas, se designan a la combinación Alt+E. En condiciones normales, al presionar Alt+E se abrirá alguna ventana de este programa, probablemente aquella que se abrió primero. Sin embargo, si haces clic en Alt+E cuando una de las ventanas de este programa ya está en el foco, esta ventana se convertirá en la principal y es a ella a la que se transferirá el foco en pulsaciones posteriores de la combinación.
La ventana principal se puede reasignar. Para ello, primero hay que desactivar la combinación y luego asignar otra ventana como principal. Para desactivar la combinación, hay que pulsar la propia combinación y luego una combinación especial de reinicio, que yo tengo asignada a Alt+Backspace. Esto ejecutará un script que cancelará la asignación de la ventana principal para la combinación anterior. Luego, puedes asignar una nueva ventana principal como se describió en el párrafo anterior. Reiniciar la ventana vinculada a las combinaciones universales ocurre de manera similar.
La introducción fue larga, pero quería contar primero qué haremos y luego explicar cómo hacerlo.
Para aquellos que están cansados de leer
En resumen, el enlace a los scripts está al final del artículo.
Pero no se podrá instalar y usar de inmediato. Primero tendrás que entender cómo el script encuentra la ventana deseada. Sin esto, no podrás indicar al script a dónde transferir el foco. Y hay que entender qué hacer si de repente no se encontró la ventana adecuada.
Además, no me detendré en cómo configurar la ejecución de scripts mediante combinaciones de teclas. Por ejemplo, en KDE esto se hace en Configuración del Sistema → Atajos → Atajos Personalizados. En otros gestores de ventanas también debería estar disponible.
Conociendo wmctrl
Wmctrl es una utilidad de consola para interactuar con el Gestor de Ventanas X. Es el programa clave para el script. Veamos rápidamente cómo se puede usar.
Primero, imprimamos una lista de ventanas abiertas:
$ wmctrl -lx
0x01e0000e -1 plasmashell.plasmashell N/A Escritorio — Plasma
0x01e0001e -1 plasmashell.plasmashell N/A Plasma
0x03a00001 0 skype.Skype N/A Skype
0x04400003 0 Navigator.Firefox N/A Google Translator - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Publicaciones más destacadas del día / Habr - Mozilla Firefox (Navegación Privada)
...La opción -l muestra una lista de todas las ventanas abiertas, y -x agrega a la salida el nombre de la clase (skype.Skype, Navigator.Firefox etc.). Aquí necesitaremos el id de la ventana (columna 1), el nombre de la clase (columna 3) y el nombre de la ventana (última columna).
Puedes intentar activar alguna ventana usando la opción -a:
$ wmctrl -a skype.Skype -xSi todo ha ido según lo planeado, debería aparecer una ventana de Skype en la pantalla. Si en lugar de la opción -x utilizar la opción , el intervalo entre el envío de paquetes., se puede usar id para especificar el id de la ventana en lugar del nombre de clase. El problema con el id es que cambia con cada inicio de la aplicación y no podemos conocerlo de antemano. Por otro lado, este atributo señala de manera inequívoca a la ventana, lo cual puede ser importante cuando la aplicación abre más de una ventana. De esto hablaremos más adelante.
En esta etapa, debemos recordar que buscaremos la ventana deseada utilizando regex a partir de la salida wmctrl -lx. Pero eso no significa que necesariamente debamos utilizar algo complicado. Normalmente, el nombre de la clase o el título de la ventana son suficientes.
En principio, la idea principal ya debería estar clara. En la configuración de teclas rápidas/globales de su gestor de ventanas, configuramos la combinación deseada para ejecutar el script.
Cómo utilizar scripts
Primero, necesitamos instalar las utilidades de consola wmctrl y xdotool:
$ sudo apt-get install wmctrl xdotoolLuego, debemos descargar los scripts y agregarlos a $PATH. Normalmente, los coloco en ~/bin:
$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetachSi no existía el directorio ~/bin , deberíamos crearlo y reiniciarnos (o volver a iniciar sesión), de lo contrario ~/bin no se incluirá en $PATH. Si todo está correctamente hecho, los scripts deberían estar disponibles desde la consola y la autocompleción debería funcionar con Tab.
El script principal showwin acepta 2 parámetros: el primero es regex, con el que buscaremos la ventana deseada, y el segundo es el comando que se debe ejecutar si no se encuentra la ventana deseada.
Podemos intentar ejecutar el script, por ejemplo:
$ showwin "Mozilla Firefox$" firefoxSi Firefox está instalado, la ventana debería recibir el foco. Incluso si Firefox no se había iniciado, debería iniciarse.
Si funcionó, podemos intentar configurar la ejecución de comandos con combinaciones. En la configuración de teclas rápidas/globales añadimos:
- Alt+F: showwin «Mozilla Firefox$» firefox
- Alt+D: showwin «Mozilla Firefox (Navegación Privada)$» «firefox -private-window»
- Alt+C: showwin «chromium-browser.Chromium-browser N*» chromium-browser
- Alt+X: showwin «chromium-browser.Chromium-browser I*» «chromium-browser -incognito»
- Alt+S: showwin «skype.Skype» skypeforlinux
- Alt+E: showwin «jetbrains-idea» idea.sh
Etcétera. Cada uno puede configurar las combinaciones de teclas y software como le parezca mejor.
Si todo ha salido bien, podemos alternar entre las ventanas con solo pulsar las teclas indicadas.
Desilusión para los amantes de Chrome: una ventana normal en modo incógnito se distingue por su salida wmctrl no se puede, ya que tienen los mismos nombres de clases y títulos de ventana. En las expresiones regulares propuestas, los símbolos N* e I* son necesarios solo para que estas expresiones regulares se diferencien entre sí y se puedan asignar diferentes ventanas como principales.
Para restablecer la ventana principal de la combinación anterior (de hecho para la expresión regular con la que showwin se llamó la última vez) es necesario ejecutar el script showwinDetach. Yo tengo asignado este script a una combinación de teclas Alt+Backspace.
El script showwin tiene otra función. Cuando se invoca con un solo parámetro (en este caso el parámetro es simplemente un identificador), no verifica la expresión regular en absoluto, sino que considera adecuadas todas las ventanas. En sí mismo, esto parece inútil, sin embargo, de este modo podemos asignar cualquier ventana como principal y cambiar rápidamente a esa ventana.
Tengo configuradas las siguientes combinaciones:
- Alt+1: showwin «CustomKey1»
- Alt+2: showwin «CustomKey2»
- …
- Alt+0: showwin «CustomKey0»
- Alt+Backspace: showwinDetach
De este modo, puedo vincular cualquier ventana a combinaciones Alt+1…Alt+0. Simplemente al presionar Alt+1 asigno la ventana actual a esta combinación. Puedo desasignarla presionando Alt+1, y luego Alt+Backspace. O cerrar la ventana, eso también funciona.
A continuación, hablaré un poco sobre detalles técnicos. Se pueden ignorar y simplemente intentar configurarlos y ver. Pero de todos modos, recomendaría entender los scripts de otras personas antes de ejecutarlos en su computadora :).
Cómo distinguir diferentes ventanas de una misma aplicación
En principio, el primer ejemplo «wmctrl -a skype.Skype -x» funcionaba y se puede utilizar. Pero revisemos nuevamente el ejemplo con Firefox, en el que están abiertas 2 ventanas:
0x04400003 0 Navigator.Firefox N/A Google Translator - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Publicaciones destacadas del día / Habr - Mozilla Firefox (Navegación Privada)La primera ventana es en modo normal, y la segunda es Navegación Privada. Nos gustaría considerar estas ventanas como diferentes aplicaciones y alternar entre ellas con diferentes combinaciones de teclas.
Es necesario complicar el script que cambia de ventanas. Usé esta solución: listar todas las ventanas, hacer grep a través de regex, tomar la primera línea con ayuda de head, extraer la primera columna (esto será el id de la ventana) usando cut, cambiar a la ventana por id.
Aquí debería haber una broma sobre expresiones regulares y dos problemas, pero en realidad no uso nada complicado. Necesito las expresiones regulares para poder indicar el final de la línea (el símbolo «$») y distinguir «Mozilla Firefox$» de «Mozilla Firefox (Navegación Privada)$».
El comando se ve aproximadamente así:
$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`Aquí ya se puede adivinar la segunda peculiaridad del script: si grep no devuelve nada, significa que la aplicación deseada no está abierta y debe ser iniciada ejecutando el comando del segundo parámetro. Luego, hay que comprobar periódicamente si se ha abierto la ventana deseada para poder darle el enfoque. No voy a profundizar en esto, quien lo necesite, que mire el código fuente.
Cuando las ventanas de la aplicación no son distinguibles
Así que hemos aprendido a dar enfoque a la ventana de la aplicación deseada. Pero, ¿qué pasa si hay más de una ventana abierta de la aplicación? ¿A cuál de ellas se le debe dar enfoque? El script anterior probablemente se lo dará a la primera ventana abierta. Sin embargo, nos gustaría tener más flexibilidad. Nos gustaría poder recordar qué ventana es la que necesitamos y alternar exactamente a esa ventana.
La idea era la siguiente: Si queremos recordar una ventana específica para una combinación de teclas, debemos presionar esa combinación cuando la ventana deseada esté enfocada. Más adelante, al presionar esa combinación, el enfoque se dará precisamente a esa ventana. Hasta que la ventana se cierre o no hagamos un reinicio para esa combinación del script. showwinDetach.
El algoritmo del script showwin es aproximadamente así:
- Verificar si hemos recordado antes el ID de la ventana a la que hay que dar enfoque.
Si hemos recordado y esa ventana aún existe, le damos el enfoque y salimos. - Miramos qué ventana está actualmente en foco, y si corresponde a nuestra solicitud, entonces recordamos su ID para pasar a ella más adelante y salimos.
- Pasamos a cualquier ventana adecuada si existe o abrimos la aplicación deseada.
Para saber qué ventana está actualmente en foco, podemos usar la utilidad de consola xdotool, transformando su salida al formato hexadecimal:
$ printf "0xx" `xdotool getwindowfocus`Recoger algo en bash es más fácil creando archivos en un sistema de archivos virtual que está en memoria. En Ubuntu, esto está conectado por defecto en /dev/shm/. No puedo hablar de otras distribuciones, espero que algo similar también exista. Se puede ver con el comando:
$ mount -l | grep tmpfsEl script creará directorios vacíos en esta carpeta, así: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Además, en cada llamada se creará un symlink /dev/shm/$USER/showwin/showwin_last en /dev/shm/$USER/showwin/$SEARCH_REGEX. Esto será necesario para poder eliminar el id de la ventana para una determinada combinación mediante el script showwinDetach.
Qué se puede mejorar
En primer lugar, los scripts deben configurarse manualmente. Seguramente, debido a la necesidad de involucrarse y hacer mucho a mano, muchos de ustedes ni siquiera intentarán configurar el sistema. Si hubiera una forma de simplemente instalar un paquete y configurarlo más fácilmente, tal vez esto ganaría algo de popularidad. Y con suerte, podría incluirse la aplicación en las distribuciones estándar.
Y tal vez se podría hacer más simple. Si se puede conocer el id del proceso que creó la ventana mediante el id de la ventana, y a partir del id del proceso saber qué comando lo creó, se podría automatizar la configuración. En realidad, no he investigado si lo que escribí en este párrafo es posible. Lo que pasa es que, personalmente, estoy satisfecho con cómo funciona ahora. Pero si a alguien más le parece conveniente el enfoque y lo mejora, estaré encantado de utilizar la mejor solución.
Otro problema, como ya mencioné, es que en algunas ocasiones no se pueden distinguir las ventanas. Hasta ahora, solo he observado esto con incognito en chrome/chromium, pero tal vez haya algo similar en otro lugar. En última instancia, siempre hay una opción de combinaciones universales Alt+1…Alt+0. Nuevamente, uso Firefox y para mí este problema no es significativo.
Pero un problema significativo para mí es que, por trabajo, uso Mac OS y allá no pude configurar nada similar. La utilidad wmctrl parece que pude instalarla, pero no funciona bien en Mac OS. Algo se puede hacer con la aplicación Automator, pero es tan lenta que no es conveniente usarla incluso cuando funciona. No pude configurar combinaciones de teclas para que funcionaran en todos los programas. Si alguien encuentra una solución, estaré feliz de usarla.
En conclusión
Resultó ser inesperadamente muchas palabras para una funcionalidad que parecía tan simple. Quería transmitir la idea sin sobrecargar el texto, pero aún no he logrado encontrar una manera más sencilla de contarlo. Quizás en formato de video sería mejor, pero aquí no les gusta tanto.
He hablado un poco sobre lo que hay detrás del script y cómo configurarlo. No profundicé en los detalles del propio script, pero son solo 50 líneas, así que no es complicado de entender.
Espero que alguien más pruebe esta idea y, quizás, incluso la valore. Puedo decir que el script fue escrito hace aproximadamente 3 años y me resulta MUY conveniente. Tan conveniente que causa un serio incomodidad al trabajar con computadoras ajenas. Y con el MacBook de trabajo.
Fuente: habr.com
