Содержание
Можно по разному получить на локальном компьютере окно программы запущенной на удалённом компьютере.
- Можно использовать SSH X-Forward. Чтобы не запускать каждую программу по одной штуке, можно из консоли с SSH сессией, или даже по кнопке из меню, сразу запустить панель задач.
- При использовании VNC доступа и т.п. может быть полезно иметь независимые панели задач.
- При перемещениях между машинами с разными дистрибутивами, при смене версий дистрибутивов, удобно иметь привычные, один раз настроенные панели, оставаться независимым от перехода с Gnome2 на Unity и подобное. Файлы-профили панелей на флешке или на http://one.ubuntu.com места не займут, а скопировать их на нужную машину - минутное дело.
Пускай такая панель будет Fbpanel, версии 6 или новее. Легковесная, её использование не конфликтует с наиболее известными дистрибутивами.
Команда инсталляции Fbpanel из репозитория:
sudo apt-get install fbpanel
Fbpanel хранит файлы конфигурации (профили) в каталоге '~/.config/fbpanel', как я понимаю, это не изменяется. В другом каталоге она не будет искать профили.
В приложении дан пример файла-профиля fbpanel. Наполнение панели кнопками, меню, индикаторами делается вручную. Если набор любимых программ устоялся, то редактировать профиль не приходится, для главной панели. Для остальных - это редкость. Основные элементы приведены в примере. Полное, англоязычное описание доступно на сайте программы. Cимвол '#' в начале строки означает начало комментария, такие строки Fbpanel пропускает.
Ниже приложены скрипты, вызываемые кнопками в панели - переключение режима 'прятать панель автоматически', перечитать конфигурацию панели, закрыть панель. В результате панель становится похожа на обыкновенное GUI приложение - где-то есть ярлык запуска, есть кнопки 'свернуть', 'закрыть'. Удобно на удалённом компьютере иметь набор таких панелей, наполненных под специфические задачи удалённой работы.
В примере профиля Fbpanel эти скрипты задействованы. Автоскрытие и выключение вынесены на панель как кнопки. Перечитывание конфигурации и открытие в файл-менеджере каталога с профилями убраны в Главное меню. Сами скрипты нужно скопировать в каталог '/usr/bin', сохраняя указанные здесь имена файлов.
Для облегчения наполнения панели кнопками и меню, в приложении есть скрипт 'desktop2fbpanel'. Этот скрипт ищет в основных системных каталогах *desktop файлы, смотрит в них нужную информацию, создаёт в каталоге '~/.config/fbpanel' файл с Fbpanel шаблонами кнопок и пунктов меню для всех программ в системе. Этот файл не готовый профиль, это только заготовки кнопок. Остаётся в простом редакторе текста сделать копировать-вставить для интересующей программы.
Запускается Fbpanel командой:
fbpanel --profile имя-файла-профиля &
Указывать нужно только имя файла профиля, без полного пути - без каталога.
Или, имея SSH доступ, запуск на удалённой машине:
ssh -X user@host fbpanel --profile имя-файла-профиля
При желании запускать панели при входе в систему, можно создать в каталоге '~/.config/autostart' соответствующий *desktop файл. См. пример. В этом файле есть строка:
OnlyShowIn=GNOME
Эта строка указывает запускать этот файл только для Gnome. Можно написать «OnlyShowIn=LXDE» - запуск только для Lubuntu Lxsession. Можно написать «GNOME; KDE» - несколько оконных менеджеров. Если строку убрать совсем, то файл будет запускаться независимо от выбора оконного менеджера. Тем самым, можно иметь разные панели для сессии Gnome и для сессии Openbox, но единое место автозапуска.
Приложения
Конфигурация fbpanel
- fbpanel_x-forward_openbox.conf
Global { edge = bottom allign = center margin = 0 # widthtype = percent widthtype = request width = 24 height = 48 transparent = true tintcolor = #0e0e0e alpha = 150 setdocktype = true setpartialstrut = true autohide = false heightWhenHidden = 2 roundcorners = false roundcornersradius = 7 layer = none MaxElemHeight = 24 } Plugin { type = space config { size = 10 } } Plugin { type = menu config { IconSize = 22 icon = start-here #icon = logo systemmenu { } separator { } menu { name = Computer icon = computer item { name = Show fbPanel profiles directory icon = file-manager #image = action = bash -c "pcmanfm ~/.config/fbpanel" 2>/dev/null 1>/dev/null & } item { name = This fbPanel restart icon = gnome-session-reboot #image = action = fbpanel-restart --profile=fbPanel-6-1-example.conf } separator { } item { name = Terminal icon = terminal #image = action = x-terminal-emulator } item { name = Lock Display icon = gnome-lockscreen #image = #action = slock action = xscreensaver-command -lock } item { name = Suspend icon = xfpm-suspend #image = action = dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Suspend } item { name = Hibernate icon = xfpm-hibernate #image = action = dbus-send --print-reply --system --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Hibernate } separator { } item { name = Reboot icon = gnome-session-reboot #image = action = dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart } item { name = Shutdown icon = gnome-session-halt #image = action = dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop } item { name = logout icon = gnome-session-logout #image = action = /bin/bash -c "sync && openbox --exit" #action = lxsession-logout } } } } Plugin { type = space config { size = 15 } } Plugin { type = launchbar config { button { icon = terminal #image = tooltip = Terminal emulator action = /usr/bin/lxterminal } button { icon = file-manager #image = tooltip = File manager action = pcmanfm } button { icon = leafpad #image = tooltip = Leafpad text editor action = geany } } } Plugin { type = space config { size = 10 } } #Plugin { # type = wincmd # config { # icon = gtk-directory # image = gtk-directory # tooltip = Left click to iconify all windows. Middle click to shade them. # } #} #Plugin { # type = pager # config { # showwallpaper = true # } #} Plugin { type = space config { size = 2 } } Plugin { type = mem expand = false padding = 2 config { ShowSwap = false } } Plugin { type = space config { size = 2 } } Plugin { type = cpu config { Color = green } } Plugin { type = space config { size = 3 } } #plugin { # type = volume #} #plugin { # type = battery #} #Plugin { # type = tray #} Plugin { type = space config { size = 3 } } Plugin { type = tclock config { ClockFmt = <span font="Sans 14" color="#ffffff"><b>%H:%M</b></span>
<span font="Sans 10" color="#ffffff"><b>%a/%d</b></span> TooltipFmt = %A %x #Action = xmessage Please define some command & ShowCalendar = true ShowTooltip = true } } Plugin { type = space config { size = 3 } } Plugin { type = launchbar config { button { icon = edit-undo #image = tooltip = Switch autohide. action = fbpanel-autohide-switch --profile=fbPanel-6-1-example.conf } button { icon = window-close #image = tooltip = Close panel. action = fbpanel-close --profile=fbPanel-6-1-example.conf } } } Plugin { type = space config { size = 10 } } # 'icons' plugin lets you customize window icons. # these changes apply to entire desktop Plugin { type = icons config { DefaultIcon = /usr/share/fbpanel/images/default.xpm application { icon = gnome-emacs ClassName = Emacs } application { icon = mozilla-firefox ClassName = Firefox-bin } application { icon = mozilla-firefox ClassName = Firefox } } }
Скрипт переключения автоскрытия
- fbpanel-autohide-switch
#!/bin/bash # # Copyright 2011-2012, Stac # # Script name: fbpanel-autohide-switch # # This script is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Script. If not, see <http://www.gnu.org/licenses/>. # ## declare -r dirFBPannelConf="${HOME}/.config/fbpanel" declare fileFBPanelMainConf="" # The configuration file to be changed. declare -r fileTmp1Conf="$( mktemp )" # A copy of current configuration. declare -r fileTmp2Conf="$( mktemp )" # New configuration file. trap "rm -f \"${fileTmp1Conf}\" \"${fileTmp2Conf}\"" TERM EXIT INT function initRunConditions { return 0 } function validateRunConditions { # Exist? [ ! -d "${dirFBPannelConf}" ] \ && echo "ERROR:${0}:${LINENO}: Not found directory '${dirFBPannelConf}'." >&2\ && exit 1 [ ! -e "${dirFBPannelConf}/${fileFBPanelMainConf}" ] \ && echo "ERROR:${0}:${LINENO}: Not found '${dirFBPannelConf}/${fileFBPanelMainConf}'." >&2\ && exit 1 [ ! -e "${fileTmp1Conf}" ] \ && echo "ERROR:${0}:${LINENO}: Not found '${fileTmp1Conf}'." >&2\ && exit 1 [ ! -e "${fileTmp2Conf}" ] \ && echo "ERROR:${0}:${LINENO}: Not found '${fileTmp2Conf}'." >&2\ && exit 1 } function createTemporaryCopies { if ! cp "${dirFBPannelConf}/${fileFBPanelMainConf}" "${fileTmp1Conf}" ; then echo "ERROR:${0}:${LINENO}: Failed to copy '${fileFBPanelMainConf}' to '${fileTmp1Conf}'." >&2 exit 1 fi } function normaliseAutohideOptionString { local valPat="" for valPat in true false ; do # Convert into: 'name = value', no leading spaces. sed "s/^[[:space:]]*autohide[[:space:]]*=[[:space:]]*${valPat}/autohide = ${valPat}/g" "${fileTmp1Conf}" > "${fileTmp2Conf}" if ! mv --force "${fileTmp2Conf}" "${fileTmp1Conf}" ; then echo "ERROR:${0}:${LINENO}: Failed to replace '${fileFBPanelMainConf}' with new one." >&2 exit 1 fi done } function rotateConfigurationFile { # Backup main configuration file to '*~'. if ! mv --force "${dirFBPannelConf}/${fileFBPanelMainConf}" "${dirFBPannelConf}/${fileFBPanelMainConf}~" ; then echo "ERROR:${0}:${LINENO}: Failed to backup '${fileFBPanelMainConf}'." >&2 exit 1 fi # Replace main configuration file. if ! mv --force "${fileTmp2Conf}" "${dirFBPannelConf}/${fileFBPanelMainConf}" ; then echo "ERROR:${0}:${LINENO}: Failed to replace '${fileFBPanelMainConf}' with new one." >&2 exit 1 fi } function switchAutohideOption { chksum1="$( md5sum -b "${fileTmp1Conf}" )" chksum1="${chksum1% *}" sed "s/autohide = true/autohide = false/g" "${fileTmp1Conf}" > "${fileTmp2Conf}" chksum2="$( md5sum -b "${fileTmp2Conf}")" chksum2="${chksum2% *}" [ "${chksum1}" == "${chksum2}" ] \ && sed "s/autohide = false/autohide = true/g" "${fileTmp1Conf}" > "${fileTmp2Conf}" } function doHouseKeep { return 0 } function showDoc { echo "USAGE $( basename "$0" ) option OPTIONS --profile[=\"filename\"] Locate file 'filename' inside fbPanel profiles directory and try to invert it's 'autohide' option value. If filename is not specified, a hardcoded name will be used. --help Show some documentation. Output file location is hardcoded - see it in fbPanel profiles directory. COPYRIGHT AND LICENCE Copyright © 2011-2012 Stac. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. " } # Let's do the job: [ "${#*}" == 0 ] \ && showDoc \ && exit 0 while [ "${#*}" != "0" ] ; do argument="${1#--}" # Strip leading '--'. argument="${argument%%=*}" # Strip trailing '=*' case "${argument}" in help|h) showDoc exit 0 ;; profile) fileFBPanelMainConf="${1#*=}" declare -r fileFBPanelMainConf="${fileFBPanelMainConf:-fbpanel.conf}" break ;; *) echo "Unknown option '${1}'." echo "" showDoc exit 1 ;; esac shift 1 done initRunConditions validateRunConditions createTemporaryCopies normaliseAutohideOptionString switchAutohideOption rotateConfigurationFile # Restart the panel to be reconfigured. while read processId command; do if [ -n "${processId}" ] ; then kill -USR1 "${processId}" else echo "WARNING:${0}:${LINENO}: Not found any active fbPanel process with profile '${fileFBPanelMainConf}'." fi done <<< "$( ps x | grep fbpanel | grep "\-\-profile ${fileFBPanelMainConf/-/\\-}" )" doHouseKeep exit ${?}
Скрипт перечитывания конфигурации
- fbpanel-restart
#!/bin/bash # # Copyright 2011-2012, Stac # # Script name: fbpanel-restart # # This script is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Script. If not, see <http://www.gnu.org/licenses/>. # ## declare profileWanted="${1}" declare -r dirFBPannelConf="${HOME}/.config/fbpanel" function showDoc { echo "USAGE $( basename "$0" ) option OPTIONS --profile[=\"filename\"] Try to close fbPanel instance corresponding to 'filename' (file with fbPanel profile). --help Show some documentation. Output file location is hardcoded - see it in fbPanel profiles directory. COPYRIGHT AND LICENCE Copyright © 2011-2012 Stac. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. " } # Let's do the job: [ "${#*}" == 0 ] \ && showDoc \ && exit 0 while [ "${#*}" != "0" ] ; do argument="${1#--}" # Strip leading '--'. argument="${argument%%=*}" # Strip trailing '=*' case "${argument}" in help|h) showDoc exit 0 ;; profile) profileWanted="${1#*=}" declare -r profileWanted="${profileWanted:-fbpanel.conf}" break ;; *) echo "Unknown option '${1}'." echo "" showDoc exit 1 ;; esac shift 1 done [ -z "${profileWanted}" ] \ && echo "Error [ $0 ]:${LINENO}: Specify configuration file name as first argument and without path, only short file name." >&2 \ && exit 1 [ ! -f "${dirFBPannelConf}/${profileWanted}" ] \ && echo "Error [ $0 ]:${LINENO}: Not found configuration file '${${dirFBPannelConf}/${profileWanted}}'." >&2 \ && exit 1 while read processId ; do kill -USR1 "${processId}" done <<< "$( ps aux | grep fbpanel | grep "\-\-profile ${profileWanted/-/\\-}" | awk '{print $2}' )"
Скрипт выключения панели
- fbpanel-close
#!/bin/bash # # Copyright 2011-2012, Stac # # Script name: fbpanel-close # # This script is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Script. If not, see <http://www.gnu.org/licenses/>. # ## declare profileWanted="" declare -r dirProfileLocation="${HOME}/.config/fbpanel" function showDoc { echo "USAGE $( basename "$0" ) option OPTIONS --profile[=\"filename\"] Try to close fbPanel instance corresponding to 'filename' (file with fbPanel profile). --help Show some documentation. Output file location is hardcoded - see it in fbPanel profiles directory. COPYRIGHT AND LICENCE Copyright © 2011-2012 Stac. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. " } # Let's do the job: [ "${#*}" == 0 ] \ && showDoc \ && exit 0 while [ "${#*}" != "0" ] ; do argument="${1#--}" # Strip leading '--'. argument="${argument%%=*}" # Strip trailing '=*' case "${argument}" in help|h) showDoc exit 0 ;; profile) profileWanted="${1#*=}" declare -r profileWanted="${profileWanted:-fbpanel.conf}" break ;; *) echo "Unknown option '${1}'." echo "" showDoc exit 1 ;; esac shift 1 done [ -z "${profileWanted}" ] \ && echo "ERROR:${0}:${LINENO}: Need profile file short name as argiment." >&2 \ && exit 1 [ ! -f "${dirProfileLocation}/${profileWanted}" ] \ && echo "ERROR:${0}:${LINENO}: In directory '${dirProfileLocation}' there is no file '${profileWanted}'." >&2 \ && exit 1 while read pid misc ; do kill -9 ${pid} done <<< "$( ps axo pid,command | egrep "fbpanel --profile ${profileWanted}" )"
Разбор Desktop файлов
- desktop2fbpanel
#!/bin/bash # # Copyright 2011-2012, Stac # # Script name: desktop2fbpanel # # This script is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Script. If not, see <http://www.gnu.org/licenses/>. # ## declare -r dirGnome2PanelItems="${HOME}/.gnome2" declare -r dirFbConfig="${HOME}/.config/fbpanel" declare -r fileOutput="${dirFbConfig}/desktop2fbpanel.txt" declare -r fileToBeLocatedNamesListDefault="${dirFbConfig}/gnome-panels-item-list.txt" declare -r tmpFile="$( mktemp )" trap "rm -f \"${tmpFile}\"" TERM EXIT INT function printOutFBPanelStruct { local targetName="${1}" local iconId="${2}" local commentString="${3}" local executableString="${4}" echo "# \"${fullFileName}\" button { #name = ${targetName} icon = ${iconId} #image = tooltip = ${commentString} action = ${executableString} } item { name = ${targetName} icon = ${iconId} #image = tooltip = ${commentString} action = ${executableString} }" } function processDesktopFile { local fullFileName="${1}" local targetName="" local iconId="" local commentString="" local executableString="" if [ ! -f "${fullFileName}" ] ; then echo "Error:${0}:$LINENO: Not found file '${fullFileName}'." >&2 return 1 fi shopt -s extglob while read parameterString; do parameterName="${parameterString/#*([[:space:]])/}" # Strip leading space. parameterName="${parameterName%%=*}" # Strip trailing '=*'. case "${parameterName}" in Name) targetName="${parameterString#*=}" ;; Icon) iconId="${parameterString#*=}" ;; Comment) commentString="${parameterString#*=}" ;; Exec) executableString="${parameterString#*=}" ;; esac done <<< "$( cat "${fullFileName}" | egrep "(Name|Icon|Comment|Exec)" )" printOutFBPanelStruct "${targetName}" "${iconId}" "${commentString}" "${executableString}" } function processListOfDesktopFiles { local itemsListFile="${1}" while read fullFileName ; do processDesktopFile "${fullFileName}" done < "${itemsListFile}" } function showDoc { echo "USAGE $( basename "$0" ) options OPTIONS --locate-all Create file with items mentioned in desktop files from main system directories. --locate-panel-items[=filename] Create file with items used in user's Gnome 2 panels. In case was specified file, it will be used as source of file names where to search for items. --help Show some documentation. Output file location is hardcoded - see it in fbPanel profiles directory. COPYRIGHT AND LICENCE Copyright © 2011-2012 Stac. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. " } [ "${#*}" == 0 ] \ && showDoc \ && exit 0 while [ "${#*}" != "0" ] ; do argument="${1#--}" # Strip leading '--'. argument="${argument%%=*}" # Strip trailing '=*' case "${argument}" in help|h) showDoc exit 0 ;; locate-all) [ -z "${routineName}" ] \ && declare -r routineName="${argument}" break ;; locate-panel-items) [ -z "${routineName}" ] \ && declare -r routineName="${argument}" itemsListFile="${1#*=}" [ "${itemsListFile}" == "${routineName}" ] \ && itemsListFile="${fileToBeLocatedNamesListDefault}" break ;; *) echo "Error:${0}:$LINENO: Unknown option '${argument}'." echo "" showDoc exit 1 ;; esac shift 1 done [ ! -d "${dirFbConfig}" ] \ && mkdir -p "${dirFbConfig}" if [ -f "${fileOutput}" ] ; then if ! mv --force "${fileOutput}" "${fileOutput}~" ; then echo "Error:${0}:$LINENO: Failed to rename into backup existent file '${fileOutput}'." >&2 exit 1 fi else if ! touch "${fileOutput}" ; then echo "Error:${0}:$LINENO: Failed to create file '${fileOutput}'." >&2 exit 1 fi fi case "${routineName}" in locate-all) echo "Search started, $( date )." searchPath="/usr/share/app*" find ${searchPath} -type f -name '*desktop' > "${tmpFile}" processListOfDesktopFiles "${tmpFile}" > "${fileOutput}" rm -rf "${tmpFile}" ;; locate-panel-items) echo "Processing started, $( date )." if [ -z "${itemsListFile}" ] ; then find "${dirGnome2PanelItems}" -type f -name '*desktop' > "${tmpFile}" processListOfDesktopFiles "${tmpFile}" > "${fileOutput}" rm -f "${tmpFile}" else [ ! -e "${itemsListFile}" ] \ && echo "Error:${0}:$LINENO: Not found file '${itemsListFile}'." >&2 \ && exit 1 processListOfDesktopFiles "${itemsListFile}" > "${fileOutput}" fi ;; esac echo "Job done, $( date )." >&2 echo "See generated file '${fileOutput}'." >&2
Пример файла запуска
- fbpanel_x-forward_openbox.desktop
[Desktop Entry] Type=Application Name=FbPanel - X-Forward and Openbox Exec=fbpanel --profile fbpanel_x-forward_openbox.conf OnlyShowIn=OPENBOX