Автор Гілка: Перемикання між програмами з клавіатури  (Прочитано 4453 раз)

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3739
  • Карма: +9/-0
  • Програміст
Якщо у вас на клавіатурі є мультимедійні клавіші, або вам зручніше перемикатися між програмами з клавіатури, то вам згодиться цей рецепт:

Встановіть програму wmctrl.

В Гномі, в параметрах скорочень клавіатури додайте нову команду, напр.

Назва: Firefox
Команда: bash -c 'wmctrl -a firefox || firefox  >/dev/null 2>&1'
Призначте цій команді якусь клавішу чи комбінацію, напр. Win+F .

Тепер, при натиснені цієї комбінації має відбутися перемикання на вікно зі словом "firefox" в заголовку, якщо він вже є, або запуститися новий екземпляр фаєрфоксу. Переключення відбувається прямо на потрібну програму, навіть якщо вона на іншому столі, без зайвих рухів.
[Fedora Linux]

Відсутній interruptor

  • Дописувач
  • **
  • дописів: 62
  • Карма: +0/-0
  • Сергій
Щойно написав собі таке:
#!/bin/bash
command=$1
wmctrl -xF -R $command.${command[@]^} || $command

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3739
  • Карма: +9/-0
  • Програміст
Щойно написав собі таке:
Код: Bash
  1. #!/bin/bash
  2. command=$1
  3. wmctrl -xF -R $command.${command[@]^} || $command

Дякуючи інтераптору, написав нормальний скрипт (вимагає bash-modules):
switch-or-exec:
Код: Bash
  1. #!/bin/bash
  2. # switch-org-exec - swith to open window or launch new instance of a program
  3. # License: GPLv2+
  4. # Author: Volodymyr M. Lisivka <vlisivka@gmail.com>
  5.  
  6. set -ue
  7.  
  8. . import.sh log arguments
  9.  
  10. WINDOW_CLASS=""
  11. STARTUP_COMMAND=""
  12.  
  13. main() {
  14.   wmctrl -xF -a "$WINDOW_CLASS" || $STARTUP_COMMAND "$@" </dev/null >/dev/null 2>&1 &
  15. }
  16.  
  17. parse_arguments "-w|--window-class)WINDOW_CLASS;S" "-c|--command)STARTUP_COMMAND;S" -- "${@}" || exit $?
  18.  
  19. [ -n "$STARTUP_COMMAND" ] || {
  20.   error "Startup command is required for this script."
  21.   exit 1
  22. }
  23.  
  24. # Generate window class, if not filled
  25. [ -n "$WINDOW_CLASS" ] || {
  26.   # Strip options, if any
  27.   FIRST_WORD_OF_COMMAND="${STARTUP_COMMAND%% *}"
  28.  
  29.   # Generate window class from command. Example:
  30.   # COMMAND: gnome-terminal
  31.   # WINDOW_CLASS: gnome-terminal.Gnome-terminal
  32.   WINDOW_CLASS="$FIRST_WORD_OF_COMMAND.${FIRST_WORD_OF_COMMAND[@]^}"
  33. }
  34.  
  35. main "${ARGUMENTS[@]:+${ARGUMENTS[@]}}"
  36.  
  37. exit $?
  38. __END__
  39.  
  40. =pod
  41.  
  42. =head1 NAME
  43.  
  44. switch-or-exec - switch to open window or launch new instance of program
  45.  
  46. =head1 SYNOPSIS
  47.  
  48. switch-or-exec [OPTIONS] [-- COMMAND_ARGUMENTS]
  49.  
  50. =head1 OPTIONS
  51.  
  52. =over 4
  53.  
  54. =item B<--help> | B<-h>
  55.  
  56. Print a brief help message and exit.
  57.  
  58. =item B<--man>
  59.  
  60. Show manual page.
  61.  
  62. =item B<-w> | B<--window-class> WINDOW_CLASS
  63.  
  64. Window class to switch to.
  65.  
  66. Hint: use command "wmctrl -lx" to list windows with their classes.
  67.  
  68. If not given, then command will be used to generate window class
  69. ( "cmd" -> "cmd.Cmd" ).
  70.  
  71. Examples:
  72.  
  73.   gnome-terminal.Gnome-terminal
  74.   Navigator.Firefox
  75.  
  76. =item B<-c> | B<--command>  STARTUP_COMMAND
  77.  
  78. Command to run when window with given class is not found. Options are
  79. allowed.
  80.  
  81. Required field. Use "/bin/true" for no operation.
  82.  
  83. =back
  84.  
  85. Unlike many other programs, this program stops option parsing at first
  86. non-option argument.
  87.  
  88. Use -- in commandline arguments to strictly separate options and arguments.
  89.  
  90. All arguments are passed to command, when it is run.
  91.  
  92. =head1 DESCRIPTION
  93.  
  94. This script tries to switch to first window of already running program,
  95. using window class, or launch new instance of program in background,
  96. when no open windows are found.
  97.  
  98. Examples:
  99.  
  100.   # Try to switch to window with class "gedit.Gedit"
  101.   # or execute command "gedit --encoding=utf-8" in the background
  102.   switch-or-exec -c gedit -- --encoding=utf-8
  103.  
  104.   # Try to switch to window with class "Navigator.Firefox"
  105.   # or execute command "firefox" in the background
  106.   switch-or-exec -w Navigator.Firefox -c firefox
  107.  
  108. Hint: script set-gnome-shell-custom-binding can be used to assign keybinding from command line.
  109.  
  110. Examples:
  111.  
  112.   set-gnome-shell-custom-binding -n "Gedit" -a "switch-or-exec -c gedit" -b "<Mod4>g"
  113.   set-gnome-shell-custom-binding -n "Firefox" -a "switch-or-exec -w Navigator.Firefox -c firefox" -b "<Mod4>f"
  114.   set-gnome-shell-custom-binding -n "gnome-Terminal" -a "switch-or-exec -c gnome-terminal" -b "<Mod4>t"
  115.   set-gnome-shell-custom-binding -n "eClipse" -a "switch-or-exec -w Eclipse.Eclipse -c eclipse" -b "<Mod4>c"
  116.   set-gnome-shell-custom-binding -n "evolution (Mail)" -a "switch-or-exec -c evolution" -b "<Mod4>m"
  117.   set-gnome-shell-custom-binding -n "LibreOffice writer" -a "switch-or-exec -w VCLSalFrame.libreoffice-writer -c oowrite" -b "<Mod4>w"
  118.   set-gnome-shell-custom-binding -n "Stardict" -a "switch-or-exec -c stardict" -b "<Mod4>s"
  119.  
  120. =head1 SEE ALSO
  121.  
  122. wmctrl(1)
  123.  
  124. =head1 AUTHOUR
  125.  
  126. Volodymyr M. Lisivka <vlisivka@gmail.com>
  127.  
  128. =cut
  129.  

Також написав скриптик для зв’язування клавіш з командами з клавіатури в Ґномі (set-gnome-shell-custom-binding ) :
Код: Bash
  1. #!/bin/bash
  2. # Set custom bindings for gnome shell
  3. # License: GPLv2+
  4. # Author: Volodymyr M. Lisivka <vlisivka@gmail.com>
  5.  
  6. set -ue
  7.  
  8. . import.sh log arguments
  9.  
  10. SLOT_NAME="/desktop/gnome/keybindings/custom"
  11. SLOT_NUMBER="0"
  12.  
  13. NAME=""
  14. ACTION=""
  15. BINDING=""
  16.  
  17. main() {
  18.   gconftool-2 --type "string" --set "$SLOT_NAME$SLOT_NUMBER/name" "$NAME"
  19.   gconftool-2 --type "string" --set "$SLOT_NAME$SLOT_NUMBER/action" "$ACTION"
  20.   gconftool-2 --type "string" --set "$SLOT_NAME$SLOT_NUMBER/binding" "$BINDING"
  21. }
  22.  
  23. parse_arguments "-n|--name)NAME;S" "-a|--action)ACTION;S" "-b|--binding)BINDING;S" -- "$@" || exit $?
  24.  
  25. [ -n "$NAME" -a -n "$ACTION" -a -n "$BINDING" ] || {
  26.   error "Name, action, and binding are required. Use --help for synopsis."
  27.   exit 1
  28. }
  29.  
  30. (( ${#ARGUMENTS[@]} == 0 )) || {
  31.   error "Arguments are not allowed. Use --help for synopsis."
  32.   exit 1
  33. }
  34.  
  35. # Find first free custom slot
  36. SLOT_NUMBERS=( $( gconftool-2 -R /desktop/gnome/keybindings | grep /desktop/gnome/keybindings/custom | grep -oE '[0-9]+' | sort -n ) )
  37. if (( ${#SLOT_NUMBERS[@]} > 0 ))
  38. then
  39.   for((I=0; I < ${#SLOT_NUMBERS[@]} ; I++ ))
  40.   do
  41.     # If value is lesser than it index, then hole is found
  42.     (( I == ${SLOT_NUMBERS[I]} )) || break
  43.   done
  44.   let SLOT_NUMBER=I || :
  45. fi
  46.  
  47. main
  48.  
  49. exit $?
  50.  
  51. __END__
  52.  
  53. =pod
  54.  
  55. =head1 NAME
  56.  
  57. set-gnome-shell-custom-binding - add new custom key binding for given command
  58.  
  59. =head1 SYNOPSIS
  60.  
  61. set-gnome-shell-custom-binding OPTIONS
  62.  
  63. =head1 OPTIONS
  64.  
  65. =over 4
  66.  
  67. =item B<--help> | B<-h>
  68.  
  69. Print a brief help message and exit.
  70.  
  71. =item B<--man>
  72.  
  73. Show manual page.
  74.  
  75. =item B<-n> | B<--name> NAME
  76.  
  77. Name of key binding.
  78.  
  79. =item B<-a> | B<--action> ACTION
  80.  
  81. Command to execute when key combination is pressed.
  82.  
  83. =item B<-b> | B<--binding> BINDING
  84.  
  85. Key combination.
  86.  
  87. Example:
  88.  
  89.   -b "<Alt>c"
  90.  
  91. =back
  92.  
  93. Arguments are not allowed.
  94.  
  95. =head1 DESCRIPTION
  96.  
  97. Find free slot and assign key binding for given command.
  98.  
  99. Hint: use command "gconftool-2 -R /desktop/gnome/keybindings" to list
  100. current assignments. Use gnome shell settings dialog to edit custom bindings.
  101.  
  102. Example:
  103.  
  104.   set-gnome-shell-custom-binding -n "Calculator" -a "gnome-calculator" -b "<Alt>c"
  105.  
  106. =head1 SEE ALSO
  107.  
  108. gconftool-2
  109.  
  110. =head1 AUTHOUR
  111.  
  112. Volodymyr M. Lisivka <vlisivka@gmail.com>
  113.  
  114. =cut
  115.  
« Змінено: 2012-06-11 18:37:21 від lvm »
[Fedora Linux]

Відсутній Дмитро Редчук

  • Кореспондент
  • ***
  • дописів: 104
  • Карма: +0/-0
Щойно написав собі таке:
Код: Bash
  1. #!/bin/bash
  2. command=$1
  3. wmctrl -xF -R $command.${command[@]^} || $command

Дякуючи інтераптору, написав нормальний скрипт (вимагає bash-modules):
Цікаво.

Як я розумію, це те, що робить Unity по Win+<цифра> для тих, хто на «запускачі». Але дає змогу прив’язувати також аргументи.
«Критика має бути конструктивною. Інакше вона деструктивна» ©
Щось не так? — Зроби так.

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3739
  • Карма: +9/-0
  • Програміст
Як я розумію, це те, що робить Unity по Win+<цифра> для тих, хто на «запускачі». Але дає змогу прив’язувати також аргументи.

Це аналог функції jump-or-exec з SawFish-а, який керував вікнами в 1-му Ґномі: http://sawfish.wikia.com/wiki/Jump-or-exec_%28adopted%29 , http://sawfish.wikia.com/wiki/Gimme (я в Gimme числюся серед авторів :-/ ). І ця ідея була вже не нова ще десять років тому.

До речі, не вистачає можливості перемикатися по кільком відкритим вікнам. Напр. якщо відкрито декілька вікон терміналів, то Win+t має перемикати спочатку на перше вікно, а потім на наступне. Не знаю як це зробити.  [smiley=20.gif]
[Fedora Linux]

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3739
  • Карма: +9/-0
  • Програміст
Зробив перемикання між вікнами однієї програми по наступним натисканням гарячої клавіші.

switch-or-exec :
Код: Bash
  1. #!/bin/bash
  2. # switch-org-exec - swith to open window or launch new instance of a program
  3. # License: GPLv2+
  4. # Author: Volodymyr M. Lisivka <vlisivka@gmail.com>
  5.  
  6. set -ue
  7.  
  8. . import.sh log arguments
  9.  
  10. WINDOW_CLASS=""
  11. STARTUP_COMMAND=""
  12.  
  13. # Return ID of active window in hexadecimal form without leading zeroes after 0x (e.g. 0x30000d4 )
  14. activeWindowId() {
  15.   xprop -root _NET_ACTIVE_WINDOW | cut -d '#' -f 2 | sed 's/ //g; s/0x0*/0x/; '
  16. }
  17.  
  18. # Return class of given window (e.g. gedit.Gedit )
  19. windowClass() {
  20.   WINDOW_ID="$1"
  21.  
  22.   xprop -id "$WINDOW_ID" WM_CLASS | cut -d '=' -f 2 | sed 's/", "/./; s/[" ]//g;'
  23. }
  24.  
  25. # Main function
  26. main() {
  27.  
  28.   # Get ID and class of active window
  29.   ACTIVE_WINDOW_ID=$( activeWindowId )
  30.   ACTIVE_WINDOW_CLASS=$( windowClass "$ACTIVE_WINDOW_ID" )
  31.  
  32.   # If class of active window is not equal to class of target window
  33.   if [ "$ACTIVE_WINDOW_CLASS" != "$WINDOW_CLASS" ]
  34.   then
  35.     # Just switch to first target window of given class (or execute command)
  36.     wmctrl -xF -a "$WINDOW_CLASS" || $STARTUP_COMMAND "$@" </dev/null >/dev/null 2>&1 &
  37.   else
  38.     # Program is already ran and one of it windows is active.
  39.     # Try to find more open windows of same class and switch to next available (or do nothing).
  40.  
  41.     # For all windows
  42.     wmctrl -lx | (
  43.       # Iterate over windows and find ID's of first window and next window of given class
  44.  
  45.       FIRST_WINDOW_ID=''
  46.       NEXT_WINDOW_ID='not found'
  47.  
  48.       while read ID DESKTOP CLASS HOST TITLE
  49.       do
  50.         # Skip windows with different class
  51.         [ "$CLASS" == "$WINDOW_CLASS" ] || continue
  52.  
  53.         [ -n "$FIRST_WINDOW_ID" ] || FIRST_WINDOW_ID="$ID"
  54.         [ -n "$NEXT_WINDOW_ID" ] || NEXT_WINDOW_ID="$ID"
  55.  
  56.         # If ID of current window is *numerically* equal to active window ID,
  57.         # then reset variable NEXT_WINDOW_ID to be set at next iteration
  58.         if (( ID ==  ACTIVE_WINDOW_ID ))
  59.         then
  60.           NEXT_WINDOW_ID=''
  61.         fi
  62.       done
  63.  
  64.       # Activate next window or first findow, if next window is not found
  65.       if [ "$NEXT_WINDOW_ID" != 'not found' -a -n "$NEXT_WINDOW_ID" ]
  66.       then
  67.         wmctrl -ia "$NEXT_WINDOW_ID" || :
  68.       elif [ -n "$FIRST_WINDOW_ID" ]
  69.       then
  70.         wmctrl -ia "$FIRST_WINDOW_ID" || :
  71.       fi
  72.     )
  73.   fi
  74. }
  75.  
  76. parse_arguments "-w|--window-class)WINDOW_CLASS;S" "-c|--command)STARTUP_COMMAND;S" -- "${@}" || exit $?
  77.  
  78. [ -n "$STARTUP_COMMAND" ] || {
  79.   error "Startup command is required for this script."
  80.   exit 1
  81. }
  82.  
  83. # Generate window class, if not filled
  84. [ -n "$WINDOW_CLASS" ] || {
  85.   # Strip options, if any
  86.   FIRST_WORD_OF_COMMAND="${STARTUP_COMMAND%% *}"
  87.  
  88.   # Generate window class from command. Example:
  89.   # COMMAND: gnome-terminal
  90.   # WINDOW_CLASS: gnome-terminal.Gnome-terminal
  91.   WINDOW_CLASS="$FIRST_WORD_OF_COMMAND.${FIRST_WORD_OF_COMMAND[@]^}"
  92. }
  93.  
  94. main "${ARGUMENTS[@]:+${ARGUMENTS[@]}}"
  95.  
  96. exit $?
  97. __END__
  98.  
  99. =pod
  100.  
  101. =head1 NAME
  102.  
  103. switch-or-exec - switch to open window or launch new instance of program
  104.  
  105. =head1 SYNOPSIS
  106.  
  107. switch-or-exec [OPTIONS] [-- COMMAND_ARGUMENTS]
  108.  
  109. =head1 OPTIONS
  110.  
  111. =over 4
  112.  
  113. =item B<--help> | B<-h>
  114.  
  115. Print a brief help message and exit.
  116.  
  117. =item B<--man>
  118.  
  119. Show manual page.
  120.  
  121. =item B<-w> | B<--window-class> WINDOW_CLASS
  122.  
  123. Window class to switch to.
  124.  
  125. Hint: use command "wmctrl -lx" to list windows with their classes.
  126.  
  127. If not given, then command will be used to generate window class
  128. ( "cmd" -> "cmd.Cmd" ).
  129.  
  130. Examples:
  131.  
  132.   gnome-terminal.Gnome-terminal
  133.   Navigator.Firefox
  134.  
  135. =item B<-c> | B<--command>  STARTUP_COMMAND
  136.  
  137. Command to run when window with given class is not found. Options are
  138. allowed.
  139.  
  140. Required field. Use "/bin/true" for no operation.
  141.  
  142. =back
  143.  
  144. Unlike many other programs, this program stops option parsing at first
  145. non-option argument.
  146.  
  147. Use -- in commandline arguments to strictly separate options and arguments.
  148.  
  149. All arguments are passed to command, when it is run.
  150.  
  151. =head1 DESCRIPTION
  152.  
  153. This script tries to switch to first or next window of already running program,
  154. using window class, or launch new instance of program in background,
  155. when no open windows are found.
  156.  
  157. Examples:
  158.  
  159.   # Try to switch to window with class "gedit.Gedit"
  160.   # or execute command "gedit --encoding=utf-8" in the background
  161.   switch-or-exec -c gedit -- --encoding=utf-8
  162.  
  163.   # Try to switch to window with class "Navigator.Firefox"
  164.   # or execute command "firefox" in the background
  165.   switch-or-exec -w Navigator.Firefox -c firefox
  166.  
  167. Hint: script set-gnome-shell-custom-binding can be used to assign keybinding from command line.
  168.  
  169. Examples:
  170.  
  171.   set-gnome-shell-custom-binding -n "Gedit" -a "switch-or-exec -c gedit" -b "<Mod4>g"
  172.   set-gnome-shell-custom-binding -n "Firefox" -a "switch-or-exec -w Navigator.Firefox -c firefox" -b "<Mod4>f"
  173.   set-gnome-shell-custom-binding -n "gnome-Terminal" -a "switch-or-exec -c gnome-terminal" -b "<Mod4>t"
  174.   set-gnome-shell-custom-binding -n "eClipse" -a "switch-or-exec -w Eclipse.Eclipse -c eclipse" -b "<Mod4>c"
  175.   set-gnome-shell-custom-binding -n "evolution (Mail)" -a "switch-or-exec -c evolution" -b "<Mod4>m"
  176.   set-gnome-shell-custom-binding -n "libre office Writer" -a "switch-or-exec -w VCLSalFrame.libreoffice-writer -c oowrite" -b "<Mod4>w"
  177.   set-gnome-shell-custom-binding -n "starDict" -a "switch-or-exec -c stardict" -b "<Mod4>d"
  178.  
  179. =head1 SEE ALSO
  180.  
  181. wmctrl(1)
  182.  
  183. =head1 AUTHOUR
  184.  
  185. Volodymyr M. Lisivka <vlisivka@gmail.com>
  186.  
  187. =cut
  188.  
  189.  
« Змінено: 2012-06-07 15:17:48 від lvm »
[Fedora Linux]

Відсутній Дмитро Редчук

  • Кореспондент
  • ***
  • дописів: 104
  • Карма: +0/-0
Як я розумію, це те, що робить Unity по Win+<цифра> для тих, хто на «запускачі». Але дає змогу прив’язувати також аргументи.

Це аналог функції jump-or-exec з SawFish-а
Але дає змогу прив’язувати також аргументи. Чи це можливо і в jump-or-exec? Хоча «прикрутити», напевно, і там можна.
«Критика має бути конструктивною. Інакше вона деструктивна» ©
Щось не так? — Зроби так.