
Ich frage mich, ob es eine Möglichkeit gibt, einer Aktion je nach Arbeitsbereich zwei unterschiedliche Auswirkungen zu verleihen.
Beispiel: Wenn auf Arbeitsbereich 1, wird der Befehl zum Fokussieren der Chatliste von Empathy verwendet, wenn jedoch auf Arbeitsbereich 2, wird der Befehl zum Öffnen von Chrome verwendet.
In Compiz wäre dies mit dem Bewegen der Maus über den rechten Bildschirmrand verknüpft.
Ist das möglich?
Antwort1
Schauen Sie sich anxdotool
. get_desktop
gibt den aktuell angezeigten Desktop aus.
Bei Ubuntu mit Unity werden Arbeitsbereiche aufgerufen viewports
und in Koordinatenform, X- und Y-Position der oberen linken Ecke dargestellt.
Zum Beispiel,
$ xdotool get_desktop_viewport
4780 0
Anhand dieser Informationen können Sie ermitteln, in welchem Arbeitsbereich Sie sich befinden, und für jeden Arbeitsbereich einen Befehl ausführen.
Antwort2
Notiz: Die Antwort wurde für eine bessere Leistung in Python neu geschrieben, jedoch ohne GUI-Elemente. Siehe den AbschnittPython-Version
Shell-Skript-Version
Einführung
Das folgende Skript ermöglicht die Ausführung eines bestimmten Befehls abhängig vom aktuell aktiven Arbeitsbereich. Es ist dafür vorgesehen, an eine Tastenkombination gebunden zu sein. Eine Demo des Skripts in Aktion finden Sie hier: https://www.youtube.com/watch?v=oxim3JbeiVM
Das Skript abrufen
Kopieren Sie die Skriptquelle aus diesem Beitrag oder installieren Sie sie mit den folgenden Schritten:
sudo apt-get install git
cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
sudo chmod -R +x sergrep
Die Datei ist/opt/sergrep/unity_viewport_commands.sh
Übersicht über Nutzung und Optionen
Das Skript hat die folgenden Flags:
-r
Führen Sie einen Befehl für das aktuelle Ansichtsfenster aus-g
neue Befehlsliste generieren-h
Hilfetext drucken-v
Aktuelle Einstellungen anzeigen-s
Einstellung für ein einzelnes Ansichtsfenster ändern
Das Skript muss an eine Tastenkombination mit einem bestimmten Flag gebunden sein. Zum Aufrufen eines Befehls wäre beispielsweise Ctrl+ Alt+ an gebunden.Iunity_viewport_commands.sh -r
Um das Skript an eine Verknüpfung zu binden, sieheWie binde ich .sh-Dateien an Tastaturkombinationen?
Skriptquelle
#!/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 "$@"
Einfache Shell-Skript-Version (ursprüngliche Antwort)
Ubuntu verwendet Ansichtsfenster statt Arbeitsbereiche. Das ist ein Koordinatensystem, das in positiven Zahlen nach unten und rechts zählt, wo 0,0
sich Ihr oberer linker Arbeitsbereich befindet.
Wenn wir das wissen, können wir ein einfaches Skript erstellen, das die aktuellen Koordinaten abruft, sie testet und den entsprechenden Befehl ausführt. Das folgende Skript erledigt das.
#!/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
Ersetzen Sie notify-send
Befehle durch die gewünschte Aktion. Verwenden Sie nohup COMMAND 2>/dev/null &
diese Option, um zu verhindern, dass Befehle das Skript blockieren ( notify-send
ist eine Ausnahme und wurde daher dort nicht hinzugefügt).
Verwenden Sie dies, xprop -root -notype _NET_DESKTOP_VIEWPORT
um die Koordinaten jedes Ihrer Ansichtsfenster zu bestimmen.
Und schließlich dürfen die Optionen der Case-Anweisung keine Leerzeichen enthalten, z. B. „ "0,0"
funktioniert“, „will aber "0, 0"
nicht“.
Python-Version
Einführung
Diese Version des Skripts führt dieselbe Funktion aus, enthält jedoch aus Gründen der Einfachheit und Benutzerfreundlichkeit keine Befehlszeilenargumente oder GUI-Elemente. Das Skript ist verfügbar alsGithub Gistsowie unten:
Verwendung:
Die Anwendung ist ganz einfach:
python3 /path/to/workspace_command.py
Das Skript ermittelt den aktuellen Arbeitsbereich und führt den entsprechenden in definierten Befehl aus ~/.workspace_commands.json
. Stellen Sie sicher, dass Sie diese Datei zuerst erstellen, sonst funktioniert das Skript nicht. Beachten Sie auch, dass Sie doppelte Anführungszeichen verwenden müssen, um jeden Arbeitsbereich und Befehl + Argument zu definieren
Probe ~/workspace_commands.json
:
{
"1":["nautilus"],
"2":["firefox","google.com"],
"3":["virtualbox"]
}
Skript-Quellcode
#!/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()
Mouse-Over-Aktion:
Die ursprüngliche Frage bezieht sich darauf, wie es mit der Mouseover-Aktion auf der rechten Seite des Bildschirms funktioniert. Ich schlage vor, die oben genannten Skripts als Verknüpfung mit Tastaturkürzeln zu verwenden, aber die Mouseover-Aktion ist möglich. Unten finden Sie ein einfaches Skript, das die oben genannte Python-Version startet, wenn sich die Maus in der oberen rechten Ecke des Bildschirms befindet. Sie können das Skript gerne an Ihre Bedürfnisse anpassen.
#!/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()
Anmerkungen:
Ein ähnliches Mausereignisskript kann mit einem Shellskript ausgeführt werden, das xdotool getmouselocation
einen Befehl verwendet und dessen Ausgabe analysiert. Diese sähe etwa so aus:
$ xdotool getmouselocation
x:1140 y:420 screen:0 window:14680095