Versión del script de Shell

Versión del script de Shell

Me pregunto si hay una manera de hacer que una acción tenga dos efectos diferentes dependiendo del espacio de trabajo en el que se encuentre.

Por ejemplo: si está en el espacio de trabajo 1, se usa el comando para enfocar la lista de chat de Empathy, pero si está en el espacio de trabajo 2, entonces se usa el comando para abrir Chrome.

Estaría vinculado al pasar el mouse sobre el borde derecho de la pantalla en Compiz.

es posible?

Respuesta1

Mira estoxdotool. get_desktopmostrará el escritorio actual a la vista.

Para Ubuntu con Unity, los espacios de trabajo se llaman viewportsy se presentan en forma de coordenadas, posición xey de la esquina superior izquierda.

Por ejemplo,

$ xdotool get_desktop_viewport     
4780 0

Puede usar esa información para determinar en qué espacio de trabajo se encuentra y ejecutar comandos para cada espacio de trabajo.

Respuesta2

Nota: La respuesta se ha reescrito en Python para un mejor rendimiento, pero sin elementos GUI. Ver la secciónVersión de Python

Versión del script de Shell

Introducción

El siguiente script permite ejecutar un comando específico según el espacio de trabajo actualmente activo. Está destinado a estar vinculado a un método abreviado de teclado. Puede encontrar una demostración del script en acción aquí: https://www.youtube.com/watch?v=oxim3JbeiVM

Obtener el guión

Copie la fuente del script de esta publicación o instálela siguiendo los siguientes pasos:

  1. sudo apt-get install git
  2. cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
  3. sudo chmod -R +x sergrep

El archivo es/opt/sergrep/unity_viewport_commands.sh

Descripción general del uso y las opciones

El script tiene las siguientes banderas:

  • -rejecutar un comando para la ventana gráfica actual
  • -ggenerar nueva lista de comandos
  • -himprimir el texto de ayuda
  • -vver la configuración actual
  • -scambiar la configuración para una única ventana gráfica

El script está destinado a estar vinculado a un método abreviado de teclado con un indicador particular. Por ejemplo, Ctrl+ Alt+ I estaría obligado unity_viewport_commands.sh -ra invocar un comando.

Para vincular el script a un acceso directo, consulte¿Cómo vinculo archivos .sh a una combinación de teclado?

Fuente del guión

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: [email protected] 
# Date: April 18th, 2016
# Purpose: Script that runs a command depending
#          on the current viewport
# Written for: https://askubuntu.com/q/56367/295286
# Tested on: Ubuntu 14.04 , Unity 7.2.6
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     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.

ARGV0="$0"
ARGC=$#
get_screen_geometry()
{
 xwininfo -root | awk '/-geometry/{gsub(/+|x/," ");print $2,$3}'  
}

gui_dialog()
{
  SCHEMA="org.compiz.core:/org/compiz/profiles/unity/plugins/core/"
  read swidth sdepth  <<< "$(get_screen_geometry)" 
  vwidth=$(gsettings get $SCHEMA hsize)
  vheight=$(gsettings get $SCHEMA vsize)
  
 width=0
 for horizontal in $(seq 1 $vwidth); do
    height=0 
    for vertical in $(seq 1 $vheight);  do

      # array+=( FALSE  )
      viewport+=( $(echo "$width"x"$height") )

    height=$(($height+$sdepth))
    done
 width=$(($width+$swidth))
 done

  local fmtstr=""
  for i in ${viewport[@]} ; do
    fmtstr=$fmtstr"$(printf "%s\"%s\" " "--add-entry=" $i)"
  done

  STR=$(zenity --forms --title="Set Viewport Commands" \
           --text='Please avoid using # character' --separator="#" \
           $fmtstr 2>/dev/null) 

  OLDIFS=$IFS
  IFS="#"
  commands=( $STR   )
  IFS=$OLDIFS
 
# for loop done with while loop
  counter=0
  while [ $counter -lt ${#viewport[@]}   ] ;
  do 
    echo "${viewport[$counter]}":"${commands[$counter]}"
    counter=$(($counter+1))
  done
}

get_current_viewport()
{
  xprop -root -notype _NET_DESKTOP_VIEWPORT  | \
      awk -F'=' '{gsub(/\,/,"x");gsub(/\ /,"");print $2}'
}

run_viewport_command()
{
  [ -r "$HOME"/"$DATAFILE"  ] || \
      { printf ">>> ERR: commands file doesn't exit. \
        \nCreate new one using -g flag" > /dev/stderr ; exit 1 ;}
  local VP=$(get_current_viewport)
  cmd=$(awk -v regex="^$VP" -F ':' '$0~regex{ $1="";print }' "$HOME"/"$DATAFILE")
  eval $cmd " &> /dev/null  &"
}


view_current_settings()
{
  if [ -r "$HOME"/"$DATAFILE"   ]; then
     cat "$HOME"/"$DATAFILE"  | \
     zenity --list --height=250 --width=250  \
     --title="current settings"  --column=""  2> /dev/null
  else
      printf ">>> ERR: commands file doesn't exist
      \\nCreate new one using -g flag" > /dev/stderr
      exit 1
  fi

}
 
change_single()
{
  if [ -r "$HOME"/"$DATAFILE"  ] ;then
    NEWLINE="$(zenity --forms --separator='#' \
         --add-entry="viewport to change(XPOSxYPOS):"\
         --add-entry="new command")"
    remove_this=$(awk -F '#' '{ print $1  }' <<< "$NEWLINE")
    sed -i '/^'$remove_this'/d' "$HOME"/"$DATAFILE"
    new_cmd=$(awk -F '#' '{$1="";printf "%s",$0}' <<< "$NEWLINE")
    echo "$remove_this":"$new_cmd" >> "$HOME"/"$DATAFILE"
  fi
}

print_usage()
{
cat << EOF

Usage: viewport_commands.sh [option] 
Copyright Serg Kolo , 2016

-r run a command for current viewport
-g generate new list of commands
-h print this text
-v view current settings
-s change setting for a single viewport

EOF
}



parse_args()
{
  [ $# -eq 0  ] && print_usage && exit 0
  local option OPTIND
  while getopts "grvhs" option ;
  do
     case ${option} in
        g) gui_dialog > "$HOME"/"$DATAFILE"
        ;;
        r) run_viewport_command 
        ;;
        v) view_current_settings
        ;;
        s) change_single
        ;;
        h) print_usage && exit 0
        ;;
        \?) echo "Invalid option: -$OPTARG" >&2
        ;;
     esac
  done
  shift $((OPTIND-1))

}

main()
{
  local DATAFILE=".viewport_commands"
  parse_args "$@"
  exit 0
}

main "$@"

Versión de script de shell simple (respuesta original)

Ubuntu usa ventanas gráficas en lugar de espacios de trabajo. Se trata de un sistema de coordenadas que cuenta en números positivos hacia abajo y hacia la derecha, donde 0,0estaría el espacio de trabajo superior izquierdo.

Sabiendo eso, podemos tener un script simple que obtiene las coordenadas actuales, las prueba y ejecuta el comando apropiado. El siguiente guión hace eso.

#!/bin/bash
  
get_viewport()
{
  xprop -root -notype _NET_DESKTOP_VIEWPORT  | \
      awk -F '=' '{ gsub(/\ /,"");print $2 }'
}

get_viewport

case "$(get_viewport)" in 

   "0,0") notify-send 'You are in the top left viewport'
            ;;
   "2732,768") notify-send 'You are in the bottom right viewport'
            ;;

esac

Reemplace notify-sendlos comandos con la acción que desee. Úselo nohup COMMAND 2>/dev/null & para evitar que los comandos cuelguen el script ( notify-sendes una excepción, por lo tanto, no lo agregó allí).

Utilice xprop -root -notype _NET_DESKTOP_VIEWPORTpara determinar las coordenadas de cada una de sus ventanas gráficas.

Finalmente, no debe haber espacios en las opciones de la declaración del caso, por ejemplo, "0,0"funciona pero "0, 0"no lo hará.


Versión de Python

Introducción

Esta versión del script realiza la misma función, pero no contiene argumentos de línea de comando ni elementos GUI en aras de la simplicidad y la usabilidad. El guión está disponible comoEsencia de Githubasí como a continuación:

Uso:

El uso es muy simple:

python3 /path/to/workspace_command.py

El script determina el espacio de trabajo actual y ejecuta el comando apropiado definido en ~/.workspace_commands.json. Asegúrese de crear este archivo primero; de lo contrario, el script no funcionará. Tenga en cuenta también que debe utilizar comillas dobles para definir cada espacio de trabajo y comando + argumento.

Muestra ~/workspace_commands.json:

{
  "1":["nautilus"],
  "2":["firefox","google.com"],
  "3":["virtualbox"]
}

Código fuente del script

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Author: Serg Kolo , contact: [email protected] 
Date: August 9th, 2016
Purpose: Spawns a command depending on current
         viewport, as defined in ~/.workspace_commands.json
Written for: https://askubuntu.com/q/56367/295286
Tested on: Ubuntu 16.04 LTS , Unity desktop


The MIT License (MIT)

Copyright © 2016 Sergiy Kolodyazhnyy <[email protected]>

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
"""


# Just in case the user runs 
# the script with python 2, import
# print function
from __future__ import print_function
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gio,Gdk
import json
import subprocess
import os

def gsettings_get(schema,path,key):
    """Get value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema,path)
    return gsettings.get_value(key)

def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError:
        print(">>> subprocess:",cmdlist)
        sys.exit(1)
    else:
        if stdout:
            return stdout

def enumerate_viewports():
    """ generates enumerated dictionary of viewports and their
        indexes, counting left to right """
    schema="org.compiz.core"
    path="/org/compiz/profiles/unity/plugins/core/"
    keys=['hsize','vsize']
    screen = Gdk.Screen.get_default()
    screen_size=[ screen.get_width(),screen.get_height()]
    grid=[ int(str(gsettings_get(schema,path,key))) for key in keys]
    x_vals=[ screen_size[0]*x for x in range(0,grid[0]) ]
    y_vals=[screen_size[1]*x for x in range(0,grid[1]) ]
    
    viewports=[(x,y)  for y in y_vals for x in x_vals ]
    
    return {vp:ix for ix,vp in enumerate(viewports,1)}

def get_current_viewport():
    """returns tuple representing current viewport, 
       in format (width,height)"""
    vp_string = run_cmd(['xprop', '-root', 
                         '-notype', '_NET_DESKTOP_VIEWPORT'])
    vp_list=vp_string.decode().strip().split('=')[1].split(',')
    return tuple( int(i)  for i in vp_list )

def read_config_file():
    """ reads ~/.workspace_commands file """
    rcfile = os.path.join( os.path.expanduser('~'), 
                           '.workspace_commands.json')
    try:
        with open(rcfile) as config_file:
            config_data = json.load(config_file)
    except IOError as error:
        print(error.__repr__())
    else:
        if config_data:
            return config_data


def main():
   # get all the info we need first
   viewports_dict=enumerate_viewports()
   current_viewport = get_current_viewport()
   current_vp_number = viewports_dict[current_viewport]
   viewport_config = read_config_file()

   for vp,command in viewport_config.items():
       if int(vp) == current_vp_number:
          # spawn the command and let us exit
          pid = subprocess.Popen(command).pid
          break
   
if __name__ == '__main__':
    main()

Acción de pasar el mouse por encima:

La pregunta original es cómo hacer que funcione con la acción del mouse sobre el lado derecho de la pantalla. Si bien sugiero usar los scripts anteriores vinculados a los atajos de teclado, es posible pasar el mouse por encima. A continuación se muestra un script simple que inicia la versión de Python anterior si el mouse está en la esquina superior derecha de la pantalla. Siéntase libre de ajustar el guión para adaptarlo a sus necesidades.

#!/usr/bin/env python3
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gio,Gdk
import subprocess
from time import  sleep
def main():
    screen = Gdk.Screen.get_default()
    root_window = screen.get_root_window()

    while True:
        if root_window.get_pointer()[2] == 0 and \
           root_window.get_pointer()[1] >= root_window.get_width()-2:
               proc = subprocess.Popen(['python3','/home/user/bin/python/workspace_command.py']).pid
        sleep(0.75)

if __name__ == '__main__':
    main()

Notas:

Se puede realizar un script de eventos del mouse similar con un script de shell que use xdotool getmouselocationun comando y analice su salida, que sería algo como esto:

$ xdotool getmouselocation
x:1140 y:420 screen:0 window:14680095

información relacionada