Posso criar acionadores de comando dependentes do espaço de trabalho?

3

Gostaria de saber se há uma maneira de fazer com que uma ação tenha dois efeitos diferentes, dependendo do espaço de trabalho em que está.

Por exemplo: se no espaço de trabalho 1, o comando para enfocar a lista de bate-papo do Empathy é usado, mas se estiver no espaço de trabalho 2, o comando para abrir o Chrome é usado.

Ele estaria vinculado ao mouse para a borda direita da tela no Compiz.

Isso é possível?

    
por Leron 09.08.2011 / 00:20

2 respostas

5

Dê uma olhada em xdotool . get_desktop exibirá a área de trabalho atual na visualização.

Para o Ubuntu com Unity, as áreas de trabalho são chamadas viewports e são apresentadas em forma de coordenadas, xey posição do canto superior esquerdo.

Por exemplo,

$ xdotool get_desktop_viewport     
4780 0

Você pode usar essas informações para descobrir em qual espaço de trabalho está e executar o comando para cada espaço de trabalho.

    
por Rinzwind 09.08.2011 / 09:10
4

Nota : A resposta foi reescrita em python para melhor desempenho, mas sem elementos GUI. Veja a seção Versão em Python

Versão do script da Shell

Introdução

O script abaixo permite a execução de um comando específico, dependendo da área de trabalho ativa no momento. Destina-se a ser ligado a um atalho de teclado. Demonstração do script em ação pode ser encontrada aqui: link

Obtendo o script

Copie a fonte do script desta postagem ou instale por meio das seguintes etapas:

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

O arquivo é /opt/sergrep/unity_viewport_commands.sh

Visão geral de uso e opções

O script tem os seguintes sinalizadores:

  • -r executa um comando para a viewport atual
  • -g geram nova lista de comandos
  • -h imprime o texto de ajuda
  • -v ver configurações atuais
  • -s alterar configuração para uma única viewport

O script deve ser vinculado a um atalho de teclado com um sinalizador específico. Por exemplo, Ctrl + Alt + I seria associado a unity_viewport_commands.sh -r para invocar um comando.

Para vincular o script a um atalho, consulte Como vinculo arquivos .sh à combinação de teclado?

Origem do script

#!/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 "$@"

Versão simples do script de shell (resposta original)

O Ubuntu usa viewports em vez de espaços de trabalho. Esse é um sistema de coordenadas que conta em números positivos para baixo e para a direita, onde 0,0 seria seu espaço de trabalho superior esquerdo.

Sabendo disso, podemos ter um script simples que obtenha coordenadas atuais, teste-as e execute o comando apropriado. O roteiro abaixo faz isso.

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

Substitua os comandos notify-send pela ação desejada. Use nohup COMMAND 2>/dev/null & para evitar comandos pendentes no script ( notify-send é uma exceção, portanto, não o incluiu lá).

Use o xprop -root -notype _NET_DESKTOP_VIEWPORT para determinar as coordenadas de cada uma das suas viewports.

Por fim, não deve haver espaços nas opções da declaração de caso, por exemplo "0,0" funciona, mas "0, 0" não.

Versão do Python

Introdução

Esta versão do script executa a mesma função, mas não contém argumentos de linha de comando ou elementos GUI por questões de simplicidade e usabilidade. O script está disponível como Github Gist , assim como abaixo:

Uso:

O uso é muito simples:

python3 /path/to/workspace_command.py

O script determina a área de trabalho atual e executa o comando apropriado definido em ~/.workspace_commands.json . Certifique-se de criar este arquivo primeiro, caso contrário o script não funcionará. Observe também que você deve usar aspas duplas para definir cada espaço de trabalho e o comando + argumento

Amostra ~/workspace_commands.json :

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

Código-fonte do 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()

Ação de passar o mouse:

A pergunta original pergunta sobre como fazer isso funcionar com a ação de passar o mouse no lado direito da tela. Embora eu sugira usar os scripts acima como vinculados a atalhos de teclado, a ação de passar o mouse é possível. Abaixo está um script simples que inicia a versão do python acima se o mouse estiver no canto superior direito da tela. Sinta-se à vontade para ajustar o roteiro de acordo com suas necessidades

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

Script de evento de mouse semelhante pode ser feito com um script de shell que usa o comando xdotool getmouselocation e analisa sua saída, que seria algo assim:

$ xdotool getmouselocation
x:1140 y:420 screen:0 window:14680095
    
por Sergiy Kolodyazhnyy 17.04.2016 / 12:57