我的电源菜单看起来如下,我想拥有一个休眠选项: 。我在Loki中尝试了相同的步骤,但是没有添加休眠选项。

#1 楼

我也想要此功能,但无法在任何地方在线找到它。似乎Hibernate选项在很早以前就被删除了,因为它在某些系统上失败了(也许很久以前就是这种情况:-)。在我的Dell XPS 9350上,休眠模式可以与基本操作系统(通过'sudo systemctl hibernate')配合使用。

基本操作系统的这一方面由“翼面板”处理,更具体地说,由翼面板的会话指示器应用程序(在屏幕右上角提供“电源按钮”图标的特定指示器)。

为了获得此功能,我必须下载该指示器的最新源代码。 wingpanel会话指示器,了解如何编译和安装它,并了解如何添加缺少的功能。如果您有一定的编码背景,那么如果不是这样的话,希望它能帮助您解决。

请注意,以便以我的普通用户(而不是root用户)的身份休眠我在/ etc / sudoers中添加了以下内容(尽管现在我不确定这是否完全必要,以前我编写了自己的指标应用程序来执行休眠操作,但是这种选择更为优雅):


devin ALL =(root)NOPASSWD:/ bin / systemctl

(其中devin是我的常规用户名)

我必须进行的更改如下。请注意,构建说明将在本文的后面显示。


在文件夹src / Widgets中添加一个名为HibernateDialog.vala的新文件(基于同一文件夹中现有的EndSessionDialog.vala) ),其内容如下:


/*
 * Copyright (c) 2011-2015 Tom Beckmann
 *
 * 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 2 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, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 */

public class Session.Widgets.HibernateDialog : Gtk.Dialog {

    public HibernateDialog () {
        Object (
            title: "",
            deletable: false,
            resizable: false,
            skip_taskbar_hint: true,
            skip_pager_hint: true,
            type_hint: Gdk.WindowTypeHint.DIALOG
        );
    }

    construct {
        string icon_name, heading_text, button_text, content_text;

        icon_name = "system-log-out";
        heading_text = "Are you sure you want to Hibernate this computer?";
        content_text = "This will save the contents of RAM to disk and shut down the computer.";
        button_text = "Hibernate";

        set_position (Gtk.WindowPosition.CENTER_ALWAYS);
        set_keep_above (true);
        stick ();

        var image = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG);
        image.valign = Gtk.Align.START;

        var heading = new Gtk.Label (heading_text);
        heading.get_style_context ().add_class ("primary");
        heading.xalign = 0;

        var secondary_label = new Gtk.Label (content_text);
        secondary_label.xalign = 0;

        var grid = new Gtk.Grid ();
        grid.column_spacing = 12;
        grid.row_spacing = 6;
        grid.margin_left = grid.margin_right = grid.margin_bottom = 12;
        grid.attach (image, 0, 0, 1, 2);
        grid.attach (heading, 1, 0, 1, 1);
        grid.attach (secondary_label, 1, 1, 1, 1);

        var cancel = add_button (_("Cancel"), Gtk.ResponseType.CANCEL) as Gtk.Button;
        cancel.clicked.connect (() => { destroy (); });

        var confirm = add_button (button_text, Gtk.ResponseType.OK) as Gtk.Button;
        confirm.get_style_context ().add_class ("destructive-action");
        confirm.clicked.connect (() => {
            try {
                Posix.system("systemctl hibernate");
            } catch (IOError e) {
                stderr.printf ("%s\n", e.message);
            }

            destroy ();
        });

        set_default (confirm);

        get_content_area ().add (grid);

        var action_area = get_action_area ();
        action_area.margin = 6;
    }
}




修改Indicator.vala以添加休眠按钮:


/*
 * Copyright (c) 2011-2017 elementary LLC. 
 *
 * 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 2 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, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 */

public class Session.Indicator : Wingpanel.Indicator {
    private const string ICON_NAME = "system-shutdown-symbolic";

    private SystemInterface suspend_interface;
    private LockInterface lock_interface;
    private SeatInterface seat_interface;

    private Wingpanel.IndicatorManager.ServerType server_type;
    private Wingpanel.Widgets.OverlayIcon indicator_icon;
    private Wingpanel.Widgets.Separator users_separator;
    private Wingpanel.Widgets.Button lock_screen;
    private Wingpanel.Widgets.Button log_out;
    private Wingpanel.Widgets.Button suspend;
    private Wingpanel.Widgets.Button shutdown;
    private Wingpanel.Widgets.Button hibernate;

    private Session.Services.UserManager manager;

    private Gtk.Grid main_grid;
    private Session.Widgets.EndSessionDialog? shutdown_dialog = null;
    private Session.Widgets.HibernateDialog? hibernate_dialog = null;

    public Indicator (Wingpanel.IndicatorManager.ServerType server_type) {
        Object (code_name: Wingpanel.Indicator.SESSION,
                display_name: _("Session"),
                description: _("The session indicator"));
        this.server_type = server_type;
    }

    public override Gtk.Widget get_display_widget () {
        if (indicator_icon == null) {
            indicator_icon = new Wingpanel.Widgets.OverlayIcon (ICON_NAME);

            indicator_icon.button_press_event.connect ((e) => {
                if (e.button == Gdk.BUTTON_MIDDLE) {
                    close ();
                    show_shutdown_dialog ();
                    return Gdk.EVENT_STOP;
                }

                return Gdk.EVENT_PROPAGATE;
            });
        }

        return indicator_icon;
    }

    public override Gtk.Widget? get_widget () {
        if (main_grid == null) {
            init_interfaces ();

            main_grid = new Gtk.Grid ();
            main_grid.set_orientation (Gtk.Orientation.VERTICAL);

            log_out = new Wingpanel.Widgets.Button (_("Log Out…"));
            lock_screen = new Wingpanel.Widgets.Button (_("Lock"));
            shutdown = new Wingpanel.Widgets.Button (_("Shut Down…"));
            suspend = new Wingpanel.Widgets.Button (_("Suspend"));
            hibernate = new Wingpanel.Widgets.Button ("Hibernate");

            if (server_type == Wingpanel.IndicatorManager.ServerType.SESSION) {
                users_separator = new Wingpanel.Widgets.Separator ();
                manager = new Session.Services.UserManager (users_separator);

                var scrolled_box = new Wingpanel.Widgets.AutomaticScrollBox (null, null);
                scrolled_box.max_height = 300;
                scrolled_box.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
                scrolled_box.add (manager.user_grid);

                main_grid.add (scrolled_box);

                if (manager.has_guest) {
                    manager.add_guest (false);
                }

                main_grid.add (users_separator);
                main_grid.add (lock_screen);
                main_grid.add (log_out);
                main_grid.add (new Wingpanel.Widgets.Separator ());
            }

            main_grid.add (suspend);
            main_grid.add (hibernate);
            main_grid.add (shutdown);
            main_grid.margin_top = 6;

            connections ();
        }

        this.visible = true;

        return main_grid;
    }

    private void init_interfaces () {
        try {
            suspend_interface = Bus.get_proxy_sync (BusType.SYSTEM,"org.freedesktop.login1", "/org/freedesktop/login1");
        } catch (IOError e) {
            stderr.printf ("%s\n", e.message);
            suspend.set_sensitive (false);
        }

        if (server_type == Wingpanel.IndicatorManager.ServerType.SESSION) {
            try {
                lock_interface = Bus.get_proxy_sync(BusType.SESSION, "org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver");
            } catch (IOError e) {
                stderr.printf ("%s\n", e.message);
                lock_screen.set_sensitive (false);
            }

            try {
                seat_interface = Bus.get_proxy_sync (BusType.SESSION, "org.freedesktop.DisplayManager","/org/freedesktop/DisplayManager/Seat0");
            } catch (IOError e) {
                stderr.printf ("%s\n", e.message);
                lock_screen.set_sensitive (false);
            }
        }
    }

    public void connections () {
        manager.close.connect (() => close ());

        lock_screen.clicked.connect (() => {
            close ();
            try {
                lock_interface.lock ();
            } catch (IOError e) {
                stderr.printf ("%s\n", e.message);
            }
        });

        log_out.clicked.connect (() => {
            close ();
            var dialog = new Session.Widgets.EndSessionDialog (Session.Widgets.EndSessionDialogType.LOGOUT);
            dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window);
            dialog.show_all ();
        });

        shutdown.clicked.connect (() => {
            close ();
            show_shutdown_dialog ();
        });

        hibernate.clicked.connect (() => {
            close ();
            show_hibernate_dialog ();
        });

        suspend.clicked.connect (() => {
            close ();
            try {
                suspend_interface.suspend (true);
            } catch (IOError e) {
                stderr.printf ("%s\n", e.message);
            }
        });
    }

    public override void opened () {
        manager.update_all ();
    }

    public override void closed () {}

    private void show_shutdown_dialog () {
        if (shutdown_dialog == null) {
            shutdown_dialog = new Session.Widgets.EndSessionDialog (Session.Widgets.EndSessionDialogType.RESTART);
            shutdown_dialog.destroy.connect (() => { shutdown_dialog = null; });
            shutdown_dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window);
            shutdown_dialog.show_all ();
        }

        shutdown_dialog.present ();
    }

    private void show_hibernate_dialog () {
        if (hibernate_dialog == null) {
            hibernate_dialog = new Session.Widgets.HibernateDialog ();
            hibernate_dialog.destroy.connect (() => { hibernate_dialog = null; });
            hibernate_dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window);
            hibernate_dialog.show_all ();
        }

        hibernate_dialog.present ();
    }

}

public Wingpanel.Indicator? get_indicator (Module module, Wingpanel.IndicatorManager.ServerType server_type) {
    debug ("Activating Sample Indicator");
    var indicator = new Session.Indicator (server_type);

    return indicator;
}





修改src / CMakeLists.txt并添加Widgets / EndSessionDialog.vala和posix包依赖项,即我的src / CMakeLists。 txt现在看起来像这样:


find_package (PkgConfig)

# Add all your dependencies to the list below
pkg_check_modules (DEPS REQUIRED gthread-2.0 gtk+-3.0 gio-2.0 accountsservice wingpanel-2.0 granite)

add_definitions (${DEPS_CFLAGS})
link_directories (${DEPS_LIBRARY_DIRS})

find_package (Vala REQUIRED)
include (ValaVersion)
ensure_vala_version ("0.22.0" MINIMUM)

include (ValaPrecompile)
# Add all your vala files and requires packages to the List below to include them in the build
vala_precompile (VALA_C ${CMAKE_PROJECT_NAME}
  Indicator.vala
  Widgets/UserBox.vala
  Widgets/UserListBox.vala
  Widgets/EndSessionDialog.vala
  Widgets/HibernateDialog.vala
  Services/UserManager.vala
  Services/DbusInterfaces.vala
  ${CMAKE_CURRENT_BINARY_DIR}/config.vala
PACKAGES
  gio-2.0
  gtk+-3.0
  wingpanel-2.0
  granite
  AccountsService-1.0
  posix
OPTIONS
  --thread
)

add_library (${CMAKE_PROJECT_NAME} MODULE ${VALA_C})
target_link_libraries(${CMAKE_PROJECT_NAME} ${DEPS_LIBRARIES})

# Installation
install (TARGETS ${CMAKE_PROJECT_NAME} DESTINATION ${PKGDATADIR})



重新编译和安装新的wingpanel会话指示器的粗略准则如下。您可能需要安装几个缺少的库才能编译完成。

例如,如果遇到有关缺少依赖项的错误,则可以使用“ sudo apt-cache searchDependency_name”查找它。当我尝试这样做时,这是相当简单的。我认为有一个例外,那就是“ sudo apt-get install elementary-sdk”(用于“ GObject”)。


在此处下载最新的wingpanel会话指示器:
wingpanel会话指示器

通过'tar xf wingpanel-indicator-session-2.0.3.tar.xz'
cd wingpanel-indicator-session-2.0提取.tar.xf文件。 3
mkdir生成
cd生成
cmake .. -DCMAKE_INSTALL_PREFIX = / usr
make(当获取依赖项错误时,请使用'sudo apt-cache search'

警告:带有“ sudo make install”的最后一步将用这个替换当前的wingpanel会话指示器(并且可能无法恢复),只要您使用的是最新的基本版本,这应该没问题操作系统(在撰写本文时,我认为最新的版本是Loki,所以不要在较早的版本上尝试使用此操作系统)。
sudo make install

注意:我用自己的徽标替换了shutdown徽标。为此,请在/ usr / share中找到所有“系统关闭符号”图标,并将其替换为您自己的.svg图标文件。例如,通过以下网址查找现有的网址:


find /usr/share -name '*system-shutdown-symbolic*'

注意:我并不关心i18n的各种翻译,所以我只使用了硬编码的英语字符串而不是_(“ string”)。我不喜欢为此学习i18n,因为我只使用英语的PC。



评论


我选择这个答案是最好的。不幸的是,似乎没有一种更简单的方法。

–ns130291
17年9月5日在7:08

是否可以合并到github.com/elementary/wingpanel-indicator-session中?

–淹死了
18年4月18日在11:55

#2 楼

一个简单的解决方案可能是:
1。转到系统设置->电源。
2。启用电源按钮的休眠模式。

每次要休眠系统时,只需按电源按钮即可。

评论


在我的计算机上不起作用。

–阿里夫
17年5月5日在17:03

#3 楼

您可以安装pm-utilssudo apt install pm-utils)。它对我有用,尽管它没有显示在电源菜单中,但我可以通过以下方式进入休眠状态:

sudo pm-hibernate

它将休眠。

#4 楼

您可以通过以下方式分配电源按钮以进入系统休眠状态:->电源->选择“电源按钮”旁边的“休眠”,如下所示:



希望对您有所帮助。

干杯!

#5 楼

设置交换文件,并添加pm-utils和uswsusp对于sudo pm-hibernate来说对我来说很好,但是如果不重建翼板,则无法在电源菜单中添加它。.ouch。