编辑

编辑

我最近从 14.04 Trusty 升级到了 16.04 Xenial。升级之前,我使用指示器caffeine-plus图标来告诉笔记本电脑何时可以休眠。我通常使用的模式是启用 Caffeine,这样电脑只有在合上盖子时才会休眠/挂起。但是,有时我希望能够让空闲计时器发挥其预期作用。

升级后,Caffeine 似乎不再起作用。我可以让计算机运行一个长时间运行的进程,故意保持盖子打开,但回来时却发现计算机处于休眠状态,进程尚未完成。

我怎样才能恢复以前的行为?请注意,我正在寻找切换,而不是永久性更改。作为切换按钮,它应该有一个视觉指示,表明它是否已启用。指示图标会很棒。

笔记

在提出这个问题之前,我搜索了以下两种方法:a) 关于如何使用 Caffeine 的旧帖子(过时的帖子);或者 b) 永久禁用睡眠功能以解决各种硬件错误。我的问题只是关于如何恢复我在 14.04 中拥有的功能,但我没有找到解决该问题的方法。

答案1

编辑

经过一番努力,我写出了一个比下面更完整、更易于使用的解决方案。你可以下载程序在 GitHub 上。您还需要安装依赖项:

sudo apt install xdotool xprintidle

原始答案

Jacob Vlijm 向我指出了部分解决方案,我将他的脚本的修改版本与一些 Caffeine 和我自己的代码结合起来,并提出了 Caffeine 的替代品。

指示

  1. 确保安装了必要的软件包。注意:caffeine-plus仅用于图标。如果您不关心正确的图标,则不需要它。

    sudo apt install caffeine-plus xprintidle xdotool
    
  2. 将下面的脚本保存在某处并使其可执行。

    #!/usr/bin/python3
    # coding=utf-8
    #
    # Copyright © 2016 Scott Severance
    # Code mixed in from Caffeine Plus and Jacob Vlijm
    #
    # This program 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.
    #
    # This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
    
    import argparse
    import os
    import signal
    import time
    from subprocess import Popen, check_output, call
    import gi
    gi.require_version('Gtk', '3.0')
    gi.require_version('AppIndicator3', '0.1')
    from gi.repository import GObject, Gtk, AppIndicator3
    
    class SleepInhibit(GObject.GObject):
    
        def __init__(self):
            GObject.GObject.__init__(self)
            self.inhibited = False
            self._add_indicator()
            self.inhibit_proc = None
    
        def _add_indicator(self):
            self.AppInd = AppIndicator3.Indicator.new("sleep-inhibit-off",
                                                      "sleep-inhibit",
                                                      AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
            self.AppInd.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.AppInd.set_icon ("caffeine-cup-empty")
    
            self._build_indicator_menu(self.AppInd)
    
        def _build_indicator_menu(self, indicator):
            menu = Gtk.Menu()
    
            menu_item = Gtk.MenuItem("Toggle Sleep Inhibition")
            menu.append(menu_item)
            menu_item.connect("activate", self.on_toggle)
            menu_item.show()
    
            menu_item = Gtk.MenuItem("Quit")
            menu.append(menu_item)
            menu_item.connect("activate", self.on_quit)
            menu_item.show()
    
            indicator.set_menu(menu)
    
        def on_toggle(self, menuitem):
            self.inhibited = not self.inhibited
            self.flip_switch()
    
        def on_quit(self, menuitem):
            if self.inhibit_proc:
                self.kill_inhibit_proc()
            exit(0)
    
        def _set_icon_disabled(self):
            self.AppInd.set_icon('caffeine-cup-empty')
    
        def _set_icon_enabled(self):
            self.AppInd.set_icon('caffeine-cup-full')
    
        def flip_switch(self):
            if self.inhibited:
                self._set_icon_enabled()
                self.inhibit_proc = Popen([__file__, "--mode=inhibit-process"])
            else:
                self.kill_inhibit_proc()
                self._set_icon_disabled()
    
        def kill_inhibit_proc(self):
            self.inhibit_proc.terminate()
            self.inhibit_proc.wait()
            self.inhibit_proc = None
    
    def inhibit():
        seconds = 120 # number of seconds to start preventing blank screen / suspend
        while True:
            try:
                curr_idle = check_output(["xprintidle"]).decode("utf-8").strip()
                if int(curr_idle) > seconds*1000:
                    call(["xdotool", "key", "Control_L"])
                time.sleep(10)
            except FileNotFoundError:
                exit('ERROR: This program depends on xprintidle and xdotool being installed.')
            except KeyboardInterrupt:
                exit(0)
    
    def parse_args():
        parser = argparse.ArgumentParser(description='''Indicator to prevent
            computer from sleeping. It depends on the commands xprintidle and
            xdotool being properly installed on your system. If they aren't
            installed already, please install them. Also, the icons are taken from
            caffeine-plus, so if it isn't installed, you will probably see a broken
            icon.''')
        mode = '''The mode can be either indicator (default) or inhibit-process. If
            mode is indicator, then an indicator icon is created. inhibit-process is
            to be called by the indicator. When sleep is inhibited, it runs,
            preventing sleep.'''
        parser.add_argument('--mode', type=str, default='indicator', help=mode)
        return parser.parse_args()
    
    def main():
        args = parse_args()
        if args.mode == 'indicator':
            signal.signal(signal.SIGINT, signal.SIG_DFL)
            GObject.threads_init()
            SleepInhibit()
            Gtk.main()
        elif args.mode == 'inhibit-process':
            inhibit()
        else:
            exit('ERROR: Invalid value for --mode!')
    
    if __name__ == '__main__':
        main()
    
  3. 运行脚本。

相关内容