Добрый вечер, о гуру Линукса.
Учитель, у меня возникла небольшая проблема. ;-) Стоит графическое окружение Gnome 2.26.1 в Ubuntu 9.04. Навесил глобальные горячие клавиши для открытия нового сообщения в Pidgin (2.5.5). Окно по заданной комбинации клавиш открывается, но только есть одно НО. Если это окно уже открыто и висит на другом рабочем столе, то приходится в ручную перетаскивать его на активный рабочий стол.
Похожая ситуация со словарём stardict. Сделал глобальный хоткей на запуск словаря. Раньше при повторном запуске словаря на текущий активный стол выводилось его окно, если словарь уже загружен. Сейчас же загружается вторая копия словаря.
Скажи можно ли возможность как-нибудь сделать, чтобы нужное окно приложения перемещалось на активный в данный момент рабочий стол?
Перемещение окна по hotkey на текущий рабочий стол в Gnome
Модератор: Модераторы разделов
-
- Сообщения: 64
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
aniily писал(а): ↑16.11.2009 08:08Добрый вечер, о гуру Линукса.
Учитель, у меня возникла небольшая проблема. ;-) Стоит графическое окружение Gnome 2.26.1 в Ubuntu 9.04. Навесил глобальные горячие клавиши для открытия нового сообщения в Pidgin (2.5.5). Окно по заданной комбинации клавиш открывается, но только есть одно НО. Если это окно уже открыто и висит на другом рабочем столе, то приходится в ручную перетаскивать его на активный рабочий стол.
Похожая ситуация со словарём stardict. Сделал глобальный хоткей на запуск словаря. Раньше при повторном запуске словаря на текущий активный стол выводилось его окно, если словарь уже загружен. Сейчас же загружается вторая копия словаря.
Скажи можно ли возможность как-нибудь сделать, чтобы нужное окно приложения перемещалось на активный в данный момент рабочий стол?
Недавно наткнулся на утилиту wmctrl и понял, что она решает практически полностью мои проблемы с перемещением окон между рабочими столами по горячим клавишам.
По команде wmctrl -R <WIN> можно перемещать выбранное окно на текущий workspace, только вот это не работает в Compiz.
В Compiz используются не workspace, как обычно принято, а viewport'ы, а workspace только один. То есть если у вас четыре рабочих стола (2х2) разрешением 1024х768, то в Compiz у вас будет один workspace размером 2048х1536.
По команде
Код: Выделить всё
wmctrl -lG
Я, правда, пошёл более лёгким путём. Заменил compiz на metacity. С помощью
Код: Выделить всё
metacity --replace
Код: Выделить всё
wmctrl -R
На горячую клавишу повесил следующий скрипт:
Код: Выделить всё
#!/bin/bash
is_open=$( wmctrl -l | grep goldendict )
if [ ${#is_open} -eq 0 ];
then
goldendict
fi;
is_open=$( wmctrl -l | grep goldendict )
if [ ${#is_open} -eq 0 ];
then
wmctrl -R goldendict;
fi;
-
- Сообщения: 64
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
Для отображения по горячей клавиши контакт-лист Pidgin написал следующий скрипт:
Вот для отображения чата пришлось немного повозиться, потому что на bash такое написать нельзя. Проблема была в том, что функция PurpleGetConversations возвращает список (GList), который никак нельзя обработать, используя консольную команду dbus-send. Поэтому пришлось написать скрипт на python. Его код приведён ниже:
Код: Выделить всё
#!/bin/bash
pid_pidgin=$( ps -A | grep -e " pidgin$" | awk '{print $1}')
if [ ${#pid_pidgin} -ne 0 ];
then
echo Pidgin PID $pid_pidgin
window_id=$( wmctrl -lp | grep $pid_pidgin | grep "Buddy List" | grep -o -e "0x[a-z0-9]\{8,8\}" )
echo Window_id $window_id
if [ ${#window_id} -eq 0 ];
then
# show buddy list
echo Show buddy
dbus-send --session --print-reply --dest=im.pidgin.purple.PurpleService /im/pidgin/purple/PurpleObject im.pidgin.purple.PurpleInterface.PurpleBlistSetVisible int32:1
window_id=$( wmctrl -lp | grep $pid_pidgin | grep "Buddy List" | grep -o -e "0x[a-z0-9]\{8,8\}" )
fi;
if [ ${#window_id} -ne 0 ];
then
echo Switch to window
wmctrl -i -R $window_id
fi;
fi;
Вот для отображения чата пришлось немного повозиться, потому что на bash такое написать нельзя. Проблема была в том, что функция PurpleGetConversations возвращает список (GList), который никак нельзя обработать, используя консольную команду dbus-send. Поэтому пришлось написать скрипт на python. Его код приведён ниже:
Код: Выделить всё
#!/usr/bin/env python
import dbus, gobject
import commands
# get pid of running pidgin
pidgin_pid_str=commands.getoutput('ps -A | grep " pidgin$" | awk \'{print $1}\'')
try:
pidgin_pid = int(pidgin_pid_str)
except:
print "Pidgin is not running"
quit()
# open chat window with new messages
bus = dbus.SessionBus()
obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
for conv in purple.PurpleGetConversations():
user = purple.PurpleConversationGetName(conv)
purple.PurpleConversationPresent( conv)
# get windows ID of chat window
cmd_line = "wmctrl -lp | grep " + str(pidgin_pid) + " | grep -vw \"Buddy\" | awk '{print $1}'"
wnd_id_str = commands.getoutput( cmd_line );
if (len( wnd_id_str)==0):
print "Chat window is not open"
quit()
# focus on chat window
cmd_line = "wmctrl -i -R " + wnd_id_str
commands.getoutput( cmd_line )
-
- Сообщения: 62
- ОС: OpenSUSE
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
Зачетно) но я как человек ленивый взял бы готовое решение: http://live.gnome.org/DevilsPie
-
- Сообщения: 64
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
bigOne писал(а): ↑26.06.2011 03:05Зачетно) но я как человек ленивый взял бы готовое решение: http://live.gnome.org/DevilsPie
Спасибо, только вот данной утилитой можно заменить только wmctrl и то не полностью. В документации на DevilsPie не нашёл способа как узнать номер текущего workspace или как переместить окно на текущий workspace без указания номера. Показывать окно сразу на всех рабочих столах не очень хорошее решение, потому что хотелось бы избежать засорения других рабочих столов ненужными окнами. =)
И в любом случае пришлось использовать python для pidgin, потому что DevilsPie только перемещает окна, а приведённые скрипты также и управляют pidgin. =)
Единственное, что я не смог найти, это как узнать имя окна, у которого сейчас фокус. Тогда бы я по тому же хоткею закрывал окна, а то по Alt-F4 приходится сейчас. Может кто подскажет что-нибудь подходящее?
-
- Сообщения: 62
- ОС: OpenSUSE
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
На этот раз могу предложить глянуть на xdotool:
Естественно, я ее с такими целями не использую и man нефига не помню))
...
getwindowfocus [-f]
Prints the window id of the currently focused window. Saves the result to the window stack.
...
Естественно, я ее с такими целями не использую и man нефига не помню))
-
- Сообщения: 64
Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome
Спасибо большое за предложение. Выкладываю окончательные скрипты, которые у меня получились, надеюсь, что кому-нибудь они тоже облегчат жизнь )
Код: Выделить всё
#!/bin/bash
window_id=$( wmctrl -l | grep "GoldenDict" | awk '{print $1}')
if [ ${#window_id} -eq 0 ];
then
goldendict;
is_open=$( wmctrl -l | grep "GoldenDict" | awk '{print $1}')
echo ${window_id}
if [ ${#window_id} -ne 0 ];
then
wmctrl -i -R ${window_id};
fi;
else
window_id=$(( ${window_id} ))
cur_window_id=$( xdotool getwindowfocus )
if [ ${window_id} -eq ${cur_window_id} ];
then
echo Close window
wmctrl -i -c $window_id
else
echo Switch to window
wmctrl -i -R $window_id
fi;
fi;
Код: Выделить всё
#!/usr/bin/env python
import dbus, gobject
import commands
# get pid of running pidgin
pidgin_pid_str=commands.getoutput('ps -A | grep " pidgin$" | awk \'{print $1}\'')
try:
pidgin_pid = int(pidgin_pid_str)
except:
print "Pidgin is not running"
quit()
# open chat window with new messages
bus = dbus.SessionBus()
obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
for conv in purple.PurpleGetConversations():
user = purple.PurpleConversationGetName(conv)
purple.PurpleConversationPresent( conv)
# get windows ID of chat window
cmd_line = "wmctrl -lp | grep " + str(pidgin_pid) + " | grep -vw \"Buddy\" | awk '{print $1}' | sed 's/0x//g'"
wnd_id_str = commands.getoutput( cmd_line );
if (len( wnd_id_str)==0):
print "Chat window is not open"
quit()
# convert to number
try:
wnd_id = int(wnd_id_str, 16)
except:
print "Wrong window id: ", wnd_id_str
quit()
# get current window ID
cmd_line = "xdotool getwindowfocus"
cur_wnd_id_str = commands.getoutput( cmd_line );
# convert to number
try:
cur_wnd_id = int(cur_wnd_id_str)
except:
print "Wrong current window id: ", cur_wnd_id_str
quit()
# is current window a chat window?
if (cur_wnd_id==wnd_id):
cmd_line = "wmctrl -i -c 0x" + wnd_id_str
commands.getoutput( cmd_line )
quit()
# focus on chat window
cmd_line = "wmctrl -i -R 0x" + wnd_id_str
commands.getoutput( cmd_line )
Код: Выделить всё
#!/bin/bash
pid_pidgin=$( ps -A | grep -e " pidgin$" | awk '{print $1}')
if [ ${#pid_pidgin} -ne 0 ];
then
echo Pidgin PID $pid_pidgin
window_id=$( wmctrl -lp | grep $pid_pidgin | grep "Buddy List" | grep -o -e "0x[a-z0-9]\{8,8\}" )
echo Window_id $window_id
if [ ${#window_id} -eq 0 ];
then
# show buddy list
echo Show buddylist
dbus-send --session --print-reply --dest=im.pidgin.purple.PurpleService /im/pidgin/purple/PurpleObject im.pidgin.purple.PurpleInterface.PurpleBlistSetVisible int32:1
window_id=$( wmctrl -lp | grep $pid_pidgin | grep "Buddy List" | grep -o -e "0x[a-z0-9]\{8,8\}" )
if [ ${#window_id} -ne 0 ];
then
echo Switch to window
wmctrl -i -R $window_id
fi;
else
cur_window_id=$( xdotool getwindowfocus )
window_id=$(( ${window_id} ))
if [ ${window_id} -eq ${cur_window_id} ];
then
echo Close buddylist
dbus-send --session --print-reply --dest=im.pidgin.purple.PurpleService /im/pidgin/purple/PurpleObject im.pidgin.purple.PurpleInterface.PurpleBlistSetVisible int32:0
else
echo Switch to window
wmctrl -i -R $window_id
fi;
fi;
fi;