Перемещение окна по hotkey на текущий рабочий стол в Gnome

Модератор: Модераторы разделов

Ответить
aniily
Сообщения: 64

Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение aniily »

Добрый вечер, о гуру Линукса.
Учитель, у меня возникла небольшая проблема. ;-) Стоит графическое окружение Gnome 2.26.1 в Ubuntu 9.04. Навесил глобальные горячие клавиши для открытия нового сообщения в Pidgin (2.5.5). Окно по заданной комбинации клавиш открывается, но только есть одно НО. Если это окно уже открыто и висит на другом рабочем столе, то приходится в ручную перетаскивать его на активный рабочий стол.

Похожая ситуация со словарём stardict. Сделал глобальный хоткей на запуск словаря. Раньше при повторном запуске словаря на текущий активный стол выводилось его окно, если словарь уже загружен. Сейчас же загружается вторая копия словаря.
Скажи можно ли возможность как-нибудь сделать, чтобы нужное окно приложения перемещалось на активный в данный момент рабочий стол?
Спасибо сказали:
aniily
Сообщения: 64

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение aniily »

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
можно получить список открытых окон, на каких workspace и где они располагаются. У всех окон будет общий workspace ( 0 ), но по координатам окна можно будет определить на каком viewport он располагается, а после чего переместить на желаемый viewport. Проблема усложняется, если иногда используется один монитор, а иногда два, то есть размеры viewport не фиксированы.

Я, правда, пошёл более лёгким путём. Заменил compiz на metacity. С помощью

Код: Выделить всё

metacity --replace
. Проблема с viewport's ушла и можно спокойно пользоваться командой

Код: Выделить всё

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;





Спасибо сказали:
aniily
Сообщения: 64

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение aniily »

Для отображения по горячей клавиши контакт-лист Pidgin написал следующий скрипт:

Код: Выделить всё

#!/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 )
Спасибо сказали:
Аватара пользователя
bigOne
Сообщения: 62
ОС: OpenSUSE

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение bigOne »

Зачетно) но я как человек ленивый взял бы готовое решение: http://live.gnome.org/DevilsPie
Спасибо сказали:
aniily
Сообщения: 64

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение aniily »

bigOne писал(а):
26.06.2011 03:05
Зачетно) но я как человек ленивый взял бы готовое решение: http://live.gnome.org/DevilsPie

Спасибо, только вот данной утилитой можно заменить только wmctrl и то не полностью. В документации на DevilsPie не нашёл способа как узнать номер текущего workspace или как переместить окно на текущий workspace без указания номера. Показывать окно сразу на всех рабочих столах не очень хорошее решение, потому что хотелось бы избежать засорения других рабочих столов ненужными окнами. =)

И в любом случае пришлось использовать python для pidgin, потому что DevilsPie только перемещает окна, а приведённые скрипты также и управляют pidgin. =)

Единственное, что я не смог найти, это как узнать имя окна, у которого сейчас фокус. Тогда бы я по тому же хоткею закрывал окна, а то по Alt-F4 приходится сейчас. Может кто подскажет что-нибудь подходящее?
Спасибо сказали:
Аватара пользователя
bigOne
Сообщения: 62
ОС: OpenSUSE

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение bigOne »

На этот раз могу предложить глянуть на xdotool:

...
getwindowfocus [-f]
Prints the window id of the currently focused window. Saves the result to the window stack.
...


Естественно, я ее с такими целями не использую и man нефига не помню))
Спасибо сказали:
aniily
Сообщения: 64

Re: Перемещение окна по hotkey на текущий рабочий стол в Gnome

Сообщение aniily »

bigOne писал(а):
26.06.2011 19:21
На этот раз могу предложить глянуть на xdotool:

...
getwindowfocus [-f]
Prints the window id of the currently focused window. Saves the result to the window stack.
...


Естественно, я ее с такими целями не использую и man нефига не помню))

Спасибо большое за предложение. Выкладываю окончательные скрипты, которые у меня получились, надеюсь, что кому-нибудь они тоже облегчат жизнь )

Код: Выделить всё

#!/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;
Спасибо сказали:
Ответить