Выключение монитора горячей клавишей

Автор оригинала: howtogeek.com
  • Перевод


Жаль, что возможность обычным способом выключать монитор горячей клавишей сломалась в одной из предыдуших версиях Убунту. Простенький симпатичный скрипт может вернуть этот нужный функционал (предположительно обладателям ноутбуков) за несколько несложных телодвижений.

Как, наверное, многие знают, старый способ выключения монитора через использование команды xset:

xset dpms force off

Вообще существует несколько вариаций на сию тему, но по крайней мере начинай от Ubuntu Karmic (9.10), эта возможность была сломана. Некоторые системные вызовы, по-видимому, не очень хорошо справляются с этой командой, вызывая пробуждение экрана приблизительно через минуту. Это, конечно, вызывало неудобства некоторое время, пока я не нашел для себя способа, заслуживающего на использование. На убунтуфорумах предлагалось использовать данную команду в цикле, что, естественно, повышало показатели использования процессора, а другие способы не были столь элегантными. Но благодаря пользователю nxmehta, было найдено решение — а именно использовать Python для достижения цели. Скрипт, который был написан работает по крайней мере на релизах от Karmic по Natty.

Для начала, вы должны установить, кроме самого питона пакет python-xlib. Для этого достаточно в терминале выполнить команду:

sudo apt-get install python python-xlib

Следующее, что нужно сделать — это открыть текстовый редактор (например, gedit) и скопипастить следующий код:

  1. #!/usr/bin/python
  2.  
  3.     import time
  4.     import subprocess
  5.     from Xlib import X
  6.     from Xlib.display import Display
  7.  
  8.     display = Display(':0')
  9.     root = display.screen().root
  10.     root.grab_pointer(True,
  11.             X.ButtonPressMask | X.ButtonReleaseMask | X.PointerMotionMask,
  12.             X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime)
  13.     root.grab_keyboard(True,
  14.             X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime)
  15.  
  16.     subprocess.call('xset dpms force off'.split())
  17.     p = subprocess.Popen('gnome-screensaver-command -i'.split())
  18.     time.sleep(1)
  19.  
  20.     while True:
  21.         print display.next_event()
  22.         p.terminate()
  23.         break
* This source code was highlighted with Source Code Highlighter.


Что он делает — я думаю, останавливаться не стоит из-за его простоты.


Сохраните ваш файл где-нибудь, дав нужное название. У меня выработалась привычка для исполняемых скриптов использовать папку bin, которая хранится в моей домашней папке. Кстати, скрипты в этой папке будут «видны» без указывания абсолютного пути. Все благодаря нехитрым строкам в файле ~/.profile:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi

Итак, файл ~/bin/screen_off.py занял место возле других моих скриптов.

Следующий шаг — сделать его исполняемым. Можете это сделать быстрым chmod +x ~/bin/screen_off.py, но если вы пока не умеете пользоваться консолью (что зря), то можете воспользоваться графической частью оболочки:
Правокликните на файле и выберите пункт Свойства (Properties):

На вкладке Права (Permissions) и установите галочку Позволить выполнение файла как программы «Allow executing file as program».

Теперь вы можете назначить любое клавиатурное сокращение этому скрипту. Я выбрал Caps Lock, но если у вас кривые пальцы предпочтение использовать другую клавишу — без проблем. В моем случае мне нужно вначале деактивировать использование этой клавиши. Это можно сделать через меню Клавиатура > Раскладки > Параметры раскладки (Keyboard > Layouts > Options):

Вот здесь и можно ее отключить, отыскав и выбрав пункт «Поведение клавиши Caps Lock» (Caps Lock behavior) и снять соответственную галочку.

Впрочем все это тоже можно без труда сделать, не прибегая графической оболочки через gconftool-2, как, например, у меня:
$ # Отключить Caps Lock
$ xmodmap -e "remove lock = Caps_Lock"
$ # Сделать биндинг на свой скрипт:
$ gconftool-2 -a /desktop/gnome/keybindings/custom0
binding = VoidSymbol
action = /home/your_username/bin/screen_off.py
name = Screen_Off


Наконец, чтобы назначить скрипт клавише, откройте диалог Комбинации клавиш клавиатуры, (Keyboard Shortcuts).

Нажмите Добавить, дайте любое имя клавиатурному сокращению, и команду — путь к созданному файлу. Нажмите Применить и потом щелкните на поле Комбинация клавиш, после чего нажмите нужную клавишу-сокращение. Если вы деактивировали Caps Lock, вы увидите текст «VoidSymbol».

Все! Жмите! Надеюсь, этот способ пригодится для того, чтобы немножко сэкономить батарею вашего ноута.

Комментарии 30

    –6
    "… обычным способом выключать монитор горячей клавишей была сломалась несколько релизов тому назад..."
      0
      Все хорошо, но для user-friendly дистра, каковым Ubuntu себя позиционирует, такая довольно важная фича должна быть.

      А собственно, что стряслось со штатной функцией? Порылся сейчас из интереса на ланчпаде, но так и не нашел — ссылочку на баг если можно.
        0
        И таки да — посту зачет. skymanphp +, за то что потрудился так хорошо все оформить.

        К сожалению войны в комментах сегодня лишили меня возможности плюсануть автору… Да и топику тоже, так что чисто на словах=)
          0
          Добавил плюс за вас :)
          Хотя самому было бы очень интересно, как сделать аналогичное на Win7. Стоит такая же проблема на ноубтуке — хочется кнопкой отключать монитор.
            +2
            На Win7 делается тоже просто, смотрите.
              +2
              Или вот так.
                +1
                Хронически не люблю сторонние утилиты, висящие в памяти и почти ничего не делающие, поэтому хотелось бы решить проблему стандартными средствами.
                Но за подсказку все равно спасибо, в крайнем случае так и сделаю.
                  0
                  Почитали бы, для начала…
                  По первой ссылке (nircmd.exe) в памяти не висит, исполняет команду и закрывается.
                    0
                    Не досмотрел, извиняюсь.
                    +2
                    PowerShell решение, не требующее сторонних утилит:

                    add-type -name Window -namespace Win32 @"
                    [DllImport("user32.dll")]
                    public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);
                    "@
                    [Win32.Window]::SendMessage(-1, 0x0112, 0xF170, 2)
                      0
                      Спасибо большое, вообще сказка!
                        0
                        С другой стороны, PowerShell может оказаться гораздо тяжелее иных сторонних утилит.
                          +1
                          простое и интуитивно понятное
                0
                Ссылочка на баг.
                +1
                Хм, у меня кнопка выключения монитора работает, зато сломалась кнопка Bluetooth. :(
                  +2
                  Может немного не в тему, но у меня Caps Lock занят переключением раскладок. Настолько удобно, оказывается, то когда случайно сажусь за Windows, уходит минут 5, а то и больше на привыкание к Shift+Alt
                    0
                    Scroll Lock :)
                  +2
                  Как, наверное, многие знают, старый способ выключения монитора через использование команды xset:
                  xset dpms force off
                  Миллиард раз спасибо! Я пользовался ddcontrol, но он у меня поломался и отказывался работать.
                    +2
                    Объясните, пожалуйста в чем смысл while True: break?
                      0
                      Присоединяюсь к вопросу
                      0
                      На CapsLock легко можно попасть случайно, вслепую нажимая Tab или Shift. Не думаю, что постоянное включение-выключение монитора продлит его здоровье (если LED-подсветка, то наверное некритично).

                      Кстати, зачем вообще его выключать по горячей клавише? В чем смысл? Скринсейвер и так его выключит.

                      И зачем while True: break тоже интересно.
                        +2
                        Не сейвер-то выключит, но через несколько минут. Если хочется сэкономить заряд батареи, то неплохо бы выключать питание монитора на неиспользуемое время.
                        Некоторые разъяснения.
                        • p = subprocess.Popen('gnome-screensaver-command -i'.split())
                          запускает процесс, который задерживает появление заставки (опция -i = ihnibit). После выполения этой команды хранитель экрана не запустится, пока процесс не будет прерван.
                        • time.sleep(1)
                          Нужен для того, чтобы когда пользователь отпустит нажатую горячую клавишу — экран ложно не включился, замачая пользовательскую активность.
                        • Дальше на команде display.next_event() выполнение приостанавливается и система ждет новых событий от Х-сервера (ввод с клавиатуры, движение мышкой итд), после каких выполнение продолжается и командой p.terminate() убивается запущенная ранее сохраненная инстанция задержки хранителя экрана.
                          0
                          Спасибо за подробные разъяснения. Но цикл-то все равно не нужен, достаточно просто оставить next_event()
                            0
                            Да, Вы правы. Но это workaround — не у всех сия конструкция работала. Хотя и сейчас до универсальности вряд ли дотягивает.
                            Впрочем, данный пост был скорее всего наглядным примером, как можно кастомизировать операционку.
                            0
                            root.grab(всёдокучи) нужен чтобы евенты пирлетели?
                            а рутового окна достаточно, если у мене там браузер в полныйэкран?
                          0
                          Еще бы понять, как отключить автоматическое включение отключенного монитора при нажатии кнопок на клавиатуре или использовании мыши? типичный пример использования — использование ноутбука как аудиоплеер, монитор во время прослушивания не нужен, а сменить трек или поставить паузу хочется без его включения.
                            0
                            > Для начала, вы должны установить, кроме самого питона
                            Самого Питона не нужно ставить, он уже стоит.
                              0
                              ну малоли, чем у человека последний апгрейд обернулся :)
                              0
                              Как бывший виндузятник, пользуюсь в убунте стандартным Lock screen(Alt+Ctrl+L), он заодно и экран гасит.

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое