1つのアクションに、それが置かれているワークスペースに応じて2つの異なる効果を持たせる方法があるかどうか疑問に思います。
例:ワークスペース1の場合、Empathyのチャットリストにフォーカスするコマンドが使用されますが、ワークスペース2の場合、開くコマンドChromeが使用されます。
これは、Compizの画面の右端にマウスオーバーすることにリンクされます。
これは可能ですか?
xdotool
をご覧ください。 get_desktop
は現在のデスクトップを表示します。
Unityを使用するUbuntuの場合、ワークスペースはviewports
と呼ばれ、左上隅の座標形式、xおよびyの位置で表示されます。
例えば、
$ xdotool get_desktop_viewport
4780 0
その情報を使用して、現在のワークスペースを把握し、各ワークスペースごとにコマンドを実行できます。
注:回答はパフォーマンスを向上させるためにpythonに書き直されましたが、GUI要素はありません。セクションPythonバージョン
以下のスクリプトでは、現在アクティブなワークスペースに応じて特定のコマンドを実行できます。キーボードショートカットにバインドすることを目的としています。実際のスクリプトのデモはここにあります: https://www.youtube.com/watch?v=oxim3JbeiVM
この投稿からスクリプトソースをコピーするか、次の手順でインストールします。
Sudo apt-get install git
cd /opt ; Sudo git clone https://github.com/SergKolo/sergrep.git
Sudo chmod -R +x sergrep
ファイルは/opt/sergrep/unity_viewport_commands.sh
です
スクリプトには次のフラグがあります。
-r
現在のビューポートのコマンドを実行します-g
コマンドの新しいリストを生成します-h
ヘルプテキストを印刷する-v
現在の設定を表示-s
単一のビューポートの設定を変更スクリプトは、特定のフラグが付いたキーボードショートカットにバインドされることを目的としています。例えば、 Ctrl+Alt+I コマンドを呼び出すためにunity_viewport_commands.sh -r
にバインドされます。
スクリプトをショートカットにバインドするには、 。shファイルをキーボードの組み合わせにバインドするにはどうすればよいですか? を参照してください。
#!/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 "$@"
Ubuntuはワークスペースの代わりにビューポートを使用します。これは、正の数で上下にカウントする座標系です。ここで、0,0
は左上のワークスペースになります。
それを知ることで、現在の座標を取得してテストし、適切なコマンドを実行する簡単なスクリプトを作成できます。以下のスクリプトはそれを行います。
#!/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
notify-send
コマンドを必要なアクションに置き換えます。コマンドがスクリプトをハングさせないようにするには、Nohup COMMAND 2>/dev/null &
を使用します(notify-send
は例外であるため、そこに追加しませんでした)。
xprop -root -notype _NET_DESKTOP_VIEWPORT
を使用して、各ビューポートの座標を決定します。
最後に、caseステートメントのオプションにはスペースを入れないでください。 "0,0"
は機能しますが、"0, 0"
は機能しません。
このバージョンのスクリプトは同じ機能を実行しますが、単純さと使いやすさのために、コマンドライン引数またはGUI要素は含まれていません。スクリプトは Github Gist および以下として利用できます。
使用法は非常に簡単です:
python3 /path/to/workspace_command.py
スクリプトは現在のワークスペースを決定し、~/.workspace_commands.json
で定義された適切なコマンドを実行します。最初にこのファイルを作成してください。そうしないと、スクリプトが機能しません。各ワークスペースを定義するには二重引用符を使用する必要があることにも注意してください。コマンド+引数
サンプル~/workspace_commands.json
:
{
"1":["nautilus"],
"2":["firefox","google.com"],
"3":["virtualbox"]
}
#!/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()
元の質問は、画面の右側にあるマウスオーバーアクションで機能させることについて尋ねています。上記のスクリプトをキーボードショートカットにリンクして使用することをお勧めしますが、マウスオーバーアクションは可能です。以下は、マウスが画面の右上隅にある場合に上記のpythonバージョンを起動する簡単なスクリプトです。必要に応じて、スクリプトを自由に調整してください。
#!/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()
同様のマウスイベントスクリプトは、xdotool getmouselocation
コマンドを使用してその出力を解析するシェルスクリプトを使用して実行できます。これは次のようになります。
$ xdotool getmouselocation
x:1140 y:420 screen:0 window:14680095