logind: rework power key/suspend key/lid switch handling
http://lists.freedesktop.org/archives/systemd-devel/2012-September/006604.html https://bugzilla.gnome.org/show_bug.cgi?id=680689 This changes the meaning of the HandlePowerKey=/HandleSleepKey=/HandleLidSwitch= setting of logind.conf
This commit is contained in:
parent
468b21de7c
commit
beaafb2ea6
|
@ -204,49 +204,57 @@
|
||||||
<listitem><para>Controls whether
|
<listitem><para>Controls whether
|
||||||
logind shall handle the system power
|
logind shall handle the system power
|
||||||
and sleep keys and the lid switch to
|
and sleep keys and the lid switch to
|
||||||
trigger system power-off or
|
trigger actions such as system
|
||||||
suspend. Can be one of
|
power-off or suspend. Can be one of
|
||||||
<literal>off</literal>,
|
<literal>ignore</literal>,
|
||||||
<literal>no-session</literal>,
|
<literal>poweroff</literal>,
|
||||||
<literal>tty-session</literal>,
|
<literal>reboot</literal>,
|
||||||
<literal>any-session</literal> and
|
<literal>halt</literal>,
|
||||||
<literal>always</literal>. If
|
<literal>kexec</literal> and
|
||||||
<literal>off</literal> logind will
|
<literal>hibernate</literal>. If
|
||||||
never handle these keys. If
|
<literal>ignore</literal> logind will
|
||||||
<literal>no-session</literal> logind
|
never handle these keys. Otherwise the
|
||||||
will handle these keys when no user is
|
specified action will be taken in the
|
||||||
logged in and no inhibitor lock is
|
respective event. Only input devices
|
||||||
taken, and trigger a warning beep
|
with the
|
||||||
otherwise. If set to
|
|
||||||
<literal>tty-session</literal> logind
|
|
||||||
will handle these keys if no inhibitor
|
|
||||||
lock is taken, and either no user is
|
|
||||||
logged in or the foreground session is
|
|
||||||
a text login and the only one
|
|
||||||
existing. If
|
|
||||||
<literal>any-session</literal> is set
|
|
||||||
logind will handle these keys if no
|
|
||||||
inhibitor lock is taken, and either no
|
|
||||||
user is logged in or the foreground
|
|
||||||
session is the only one existing
|
|
||||||
(regardless whether graphical or
|
|
||||||
text). If set to
|
|
||||||
<literal>always</literal> logind will
|
|
||||||
handle these keys in any case, even if
|
|
||||||
one or more users are logged in or an
|
|
||||||
inhibitor lock is taken. Only input
|
|
||||||
devices with the
|
|
||||||
<literal>power-switch</literal> udev
|
<literal>power-switch</literal> udev
|
||||||
tag will be watched for key
|
tag will be watched for key/lid switch
|
||||||
events. <varname>HandlePowerKey=</varname>
|
events. <varname>HandlePowerKey=</varname>
|
||||||
defaults to
|
defaults to
|
||||||
<literal>no-session</literal>.
|
<literal>poweroff</literal>.
|
||||||
<varname>HandleSleepKey=</varname>
|
<varname>HandleSleepKey=</varname> and
|
||||||
defaults to
|
|
||||||
<literal>tty-session</literal>,
|
|
||||||
<varname>HandleLidSwitch=</varname>
|
<varname>HandleLidSwitch=</varname>
|
||||||
|
default to
|
||||||
|
<literal>suspend</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>PowerKeyIgnoreInhibited=</varname></term>
|
||||||
|
<term><varname>SleepKeyIgnoreInhibited=</varname></term>
|
||||||
|
<term><varname>LidSwitchIgnoreInhibited=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Controls whether
|
||||||
|
actions triggered by the power and
|
||||||
|
sleep keys and the lid switch are
|
||||||
|
subject to inhibitor locks. These
|
||||||
|
settings take boolean arguments. If
|
||||||
|
<literal>off</literal> the inhibitor
|
||||||
|
locks taken by applications in order
|
||||||
|
to block the requested operation are
|
||||||
|
respected, if <literal>on</literal>
|
||||||
|
the requested operation is executed in
|
||||||
|
any
|
||||||
|
case. <varname>PowerKeyIgnoreInhibited=</varname>
|
||||||
|
and
|
||||||
|
<varname>SleepKeyIgnoreInhibited=</varname>
|
||||||
|
defaults to <literal>off</literal>,
|
||||||
|
<varname>LidSwitchIgnoreInhibited=</varname>
|
||||||
defaults to
|
defaults to
|
||||||
<literal>off</literal>.</para></listitem>
|
<literal>yes</literal>. This means
|
||||||
|
that the lid switch does not respect
|
||||||
|
suspend blockers by default, but the
|
||||||
|
power and sleep keys do.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
|
@ -150,127 +150,60 @@ fail:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Session *button_get_session(Button *b) {
|
static int button_handle(Button *b, InhibitWhat inhibit_key, HandleButton handle, bool ignore_inhibited) {
|
||||||
Seat *seat;
|
|
||||||
assert(b);
|
|
||||||
|
|
||||||
if (!b->seat)
|
static const char * const message_table[_HANDLE_BUTTON_MAX] = {
|
||||||
return NULL;
|
[HANDLE_POWEROFF] = "Powering Off...",
|
||||||
|
[HANDLE_REBOOT] = "Rebooting...",
|
||||||
|
[HANDLE_HALT] = "Halting...",
|
||||||
|
[HANDLE_KEXEC] = "Rebooting via kexec...",
|
||||||
|
[HANDLE_SUSPEND] = "Suspending...",
|
||||||
|
[HANDLE_HIBERNATE] = "Hibernating..."
|
||||||
|
};
|
||||||
|
|
||||||
seat = hashmap_get(b->manager->seats, b->seat);
|
static const char * const target_table[_HANDLE_BUTTON_MAX] = {
|
||||||
if (!seat)
|
[HANDLE_POWEROFF] = "poweroff.target",
|
||||||
return NULL;
|
[HANDLE_REBOOT] = "reboot.target",
|
||||||
|
[HANDLE_HALT] = "halt.target",
|
||||||
|
[HANDLE_KEXEC] = "kexec.target",
|
||||||
|
[HANDLE_SUSPEND] = "suspend.target",
|
||||||
|
[HANDLE_HIBERNATE] = "hibernate.target"
|
||||||
|
};
|
||||||
|
|
||||||
return seat->active;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int button_power_off(Button *b, HandleButton handle) {
|
|
||||||
DBusError error;
|
DBusError error;
|
||||||
int r;
|
int r;
|
||||||
|
InhibitWhat inhibit_operation;
|
||||||
|
|
||||||
assert(b);
|
assert(b);
|
||||||
|
|
||||||
if (handle == HANDLE_OFF)
|
/* If the key handling is turned off, don't do anything */
|
||||||
|
if (handle == HANDLE_IGNORE) {
|
||||||
|
log_debug("Refusing key handling, as it is turned off.");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (handle == HANDLE_NO_SESSION) {
|
|
||||||
if (hashmap_size(b->manager->sessions) > 0) {
|
|
||||||
log_error("Refusing power-off, user is logged in.");
|
|
||||||
warn_melody();
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (handle == HANDLE_TTY_SESSION ||
|
|
||||||
handle == HANDLE_ANY_SESSION) {
|
|
||||||
unsigned n;
|
|
||||||
Session *s;
|
|
||||||
|
|
||||||
n = hashmap_size(b->manager->sessions);
|
|
||||||
s = button_get_session(b);
|
|
||||||
|
|
||||||
/* Silently ignore events of graphical sessions */
|
|
||||||
if (handle == HANDLE_TTY_SESSION &&
|
|
||||||
s && s->type == SESSION_X11)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (n > 1 || (n == 1 && !s)) {
|
|
||||||
log_error("Refusing power-off, other user is logged in.");
|
|
||||||
warn_melody();
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle != HANDLE_ALWAYS) {
|
/* If the key handling is inhibited, don't do anything */
|
||||||
if (manager_is_inhibited(b->manager, INHIBIT_SHUTDOWN, INHIBIT_BLOCK, NULL)) {
|
if (manager_is_inhibited(b->manager, inhibit_key, INHIBIT_BLOCK, NULL, true)) {
|
||||||
log_error("Refusing power-off, shutdown is inhibited.");
|
log_debug("Refusing key handling, %s is inhibited.", inhibit_what_to_string(inhibit_key));
|
||||||
warn_melody();
|
return 0;
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("Powering off...");
|
inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
|
||||||
|
|
||||||
|
/* If the actual operation is inhibited, warn and fail */
|
||||||
|
if (!ignore_inhibited &&
|
||||||
|
manager_is_inhibited(b->manager, inhibit_operation, INHIBIT_BLOCK, NULL, false)) {
|
||||||
|
log_error("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
|
||||||
|
warn_melody();
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info("%s", message_table[handle]);
|
||||||
|
|
||||||
dbus_error_init(&error);
|
dbus_error_init(&error);
|
||||||
r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_POWEROFF_TARGET, INHIBIT_SHUTDOWN, &error);
|
r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, target_table[handle], inhibit_operation, &error);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error("Failed to power off: %s", bus_error_message(&error));
|
log_error("Failed to execute operation: %s", bus_error_message(&error));
|
||||||
dbus_error_free(&error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int button_suspend(Button *b, HandleButton handle) {
|
|
||||||
DBusError error;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(b);
|
|
||||||
|
|
||||||
if (handle == HANDLE_OFF)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (handle == HANDLE_NO_SESSION) {
|
|
||||||
if (hashmap_size(b->manager->sessions) > 0) {
|
|
||||||
log_error("Refusing suspend, user is logged in.");
|
|
||||||
warn_melody();
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (handle == HANDLE_TTY_SESSION ||
|
|
||||||
handle == HANDLE_ANY_SESSION) {
|
|
||||||
unsigned n;
|
|
||||||
Session *s;
|
|
||||||
|
|
||||||
n = hashmap_size(b->manager->sessions);
|
|
||||||
s = button_get_session(b);
|
|
||||||
|
|
||||||
/* Silently ignore events of graphical sessions */
|
|
||||||
if (handle == HANDLE_TTY_SESSION &&
|
|
||||||
s && s->type == SESSION_X11)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (n > 1 || (n == 1 && !s)) {
|
|
||||||
log_error("Refusing suspend, other user is logged in.");
|
|
||||||
warn_melody();
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle != HANDLE_ALWAYS) {
|
|
||||||
if (manager_is_inhibited(b->manager, INHIBIT_SLEEP, INHIBIT_BLOCK, NULL)) {
|
|
||||||
log_error("Refusing suspend, sleeping is inhibited.");
|
|
||||||
warn_melody();
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("Suspending...");
|
|
||||||
|
|
||||||
dbus_error_init(&error);
|
|
||||||
r = bus_manager_shutdown_or_sleep_now_or_later(b->manager, SPECIAL_SUSPEND_TARGET, INHIBIT_SLEEP, &error);
|
|
||||||
if (r < 0) {
|
|
||||||
log_error("Failed to suspend: %s", bus_error_message(&error));
|
|
||||||
dbus_error_free(&error);
|
dbus_error_free(&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,12 +229,12 @@ int button_process(Button *b) {
|
||||||
case KEY_POWER:
|
case KEY_POWER:
|
||||||
case KEY_POWER2:
|
case KEY_POWER2:
|
||||||
log_info("Power key pressed.");
|
log_info("Power key pressed.");
|
||||||
return button_power_off(b, b->manager->handle_power_key);
|
return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited);
|
||||||
|
|
||||||
case KEY_SLEEP:
|
case KEY_SLEEP:
|
||||||
case KEY_SUSPEND:
|
case KEY_SUSPEND:
|
||||||
log_info("Sleep key pressed.");
|
log_info("Sleep key pressed.");
|
||||||
return button_suspend(b, b->manager->handle_sleep_key);
|
return button_handle(b, INHIBIT_HANDLE_SLEEP_KEY, b->manager->handle_sleep_key, b->manager->sleep_key_ignore_inhibited);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (ev.type == EV_SW && ev.value > 0) {
|
} else if (ev.type == EV_SW && ev.value > 0) {
|
||||||
|
@ -310,7 +243,7 @@ int button_process(Button *b) {
|
||||||
|
|
||||||
case SW_LID:
|
case SW_LID:
|
||||||
log_info("Lid closed.");
|
log_info("Lid closed.");
|
||||||
return button_suspend(b, b->manager->handle_lid_switch);
|
return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,11 +251,13 @@ int button_process(Button *b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
|
static const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
|
||||||
[HANDLE_OFF] = "off",
|
[HANDLE_IGNORE] = "ignore",
|
||||||
[HANDLE_NO_SESSION] = "no-session",
|
[HANDLE_POWEROFF] = "poweroff",
|
||||||
[HANDLE_TTY_SESSION] = "tty-session",
|
[HANDLE_REBOOT] = "reboot",
|
||||||
[HANDLE_ANY_SESSION] = "any-session",
|
[HANDLE_HALT] = "halt",
|
||||||
[HANDLE_ALWAYS] = "always"
|
[HANDLE_KEXEC] = "kexec",
|
||||||
|
[HANDLE_SUSPEND] = "suspend",
|
||||||
|
[HANDLE_HIBERNATE] = "hibernate"
|
||||||
};
|
};
|
||||||
DEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
|
DEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");
|
||||||
|
|
|
@ -25,11 +25,13 @@
|
||||||
typedef struct Button Button;
|
typedef struct Button Button;
|
||||||
|
|
||||||
typedef enum HandleButton {
|
typedef enum HandleButton {
|
||||||
HANDLE_OFF,
|
HANDLE_IGNORE,
|
||||||
HANDLE_NO_SESSION, /* Only handle key when nobody is logged in; honour inhibitors */
|
HANDLE_POWEROFF,
|
||||||
HANDLE_TTY_SESSION, /* Only handle key when nobody is logged in, or the fg session is the only one and non-graphical; honour inhibitors */
|
HANDLE_REBOOT,
|
||||||
HANDLE_ANY_SESSION, /* Only handle key when nobody is logged in, or the fg session is the only one; honour inhibtors */
|
HANDLE_HALT,
|
||||||
HANDLE_ALWAYS, /* Always handle, ignore sessions; ignore inhibitors */
|
HANDLE_KEXEC,
|
||||||
|
HANDLE_SUSPEND,
|
||||||
|
HANDLE_HIBERNATE,
|
||||||
_HANDLE_BUTTON_MAX,
|
_HANDLE_BUTTON_MAX,
|
||||||
_HANDLE_BUTTON_INVALID = -1
|
_HANDLE_BUTTON_INVALID = -1
|
||||||
} HandleButton;
|
} HandleButton;
|
||||||
|
|
|
@ -722,10 +722,19 @@ static int bus_manager_inhibit(Manager *m, DBusConnection *connection, DBusMessa
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Delay is only supported for shutdown/sleep */
|
||||||
|
if (mm == INHIBIT_DELAY && (w & ~(INHIBIT_SHUTDOWN|INHIBIT_SLEEP))) {
|
||||||
|
r = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
r = verify_polkit(connection, message,
|
r = verify_polkit(connection, message,
|
||||||
w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
|
w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
|
||||||
w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
|
w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
|
||||||
(mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-idle" : "org.freedesktop.login1.inhibit-delay-idle"),
|
w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
|
||||||
|
w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
|
||||||
|
w == INHIBIT_HANDLE_SLEEP_KEY ? "org.freedesktop.login1.inhibit-handle-sleep-key" :
|
||||||
|
"org.freedesktop.login1.inhibit-handle-lid-switch",
|
||||||
false, NULL, error);
|
false, NULL, error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1079,7 +1088,7 @@ static int bus_manager_can_shutdown_or_sleep(
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
multiple_sessions = r > 0;
|
multiple_sessions = r > 0;
|
||||||
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL);
|
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false);
|
||||||
|
|
||||||
if (multiple_sessions) {
|
if (multiple_sessions) {
|
||||||
r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error);
|
r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error);
|
||||||
|
@ -1193,7 +1202,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
|
||||||
|
|
||||||
delayed =
|
delayed =
|
||||||
m->inhibit_delay_max > 0 &&
|
m->inhibit_delay_max > 0 &&
|
||||||
manager_is_inhibited(m, w, INHIBIT_DELAY, NULL);
|
manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false);
|
||||||
|
|
||||||
if (delayed)
|
if (delayed)
|
||||||
/* Shutdown is delayed, keep in mind what we
|
/* Shutdown is delayed, keep in mind what we
|
||||||
|
@ -1261,7 +1270,7 @@ static int bus_manager_do_shutdown_or_sleep(
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
multiple_sessions = r > 0;
|
multiple_sessions = r > 0;
|
||||||
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL);
|
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false);
|
||||||
|
|
||||||
if (multiple_sessions) {
|
if (multiple_sessions) {
|
||||||
r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error);
|
r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error);
|
||||||
|
@ -2294,7 +2303,7 @@ int manager_dispatch_delayed(Manager *manager) {
|
||||||
/* Continue delay? */
|
/* Continue delay? */
|
||||||
delayed =
|
delayed =
|
||||||
manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) &&
|
manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) &&
|
||||||
manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL);
|
manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL, false);
|
||||||
if (delayed)
|
if (delayed)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,17 @@ struct ConfigPerfItem;
|
||||||
%struct-type
|
%struct-type
|
||||||
%includes
|
%includes
|
||||||
%%
|
%%
|
||||||
Login.NAutoVTs, config_parse_unsigned, 0, offsetof(Manager, n_autovts)
|
Login.NAutoVTs, config_parse_unsigned, 0, offsetof(Manager, n_autovts)
|
||||||
Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manager, reserve_vt)
|
Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manager, reserve_vt)
|
||||||
Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes)
|
Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes)
|
||||||
Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users)
|
Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users)
|
||||||
Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users)
|
Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users)
|
||||||
Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers)
|
Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers)
|
||||||
Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers)
|
Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers)
|
||||||
Login.InhibitDelayMaxSec,config_parse_usec, 0, offsetof(Manager, inhibit_delay_max)
|
Login.InhibitDelayMaxSec, config_parse_usec, 0, offsetof(Manager, inhibit_delay_max)
|
||||||
Login.HandlePowerKey, config_parse_handle_button, 0, offsetof(Manager, handle_power_key)
|
Login.HandlePowerKey, config_parse_handle_button, 0, offsetof(Manager, handle_power_key)
|
||||||
Login.HandleSleepKey, config_parse_handle_button, 0, offsetof(Manager, handle_sleep_key)
|
Login.HandleSleepKey, config_parse_handle_button, 0, offsetof(Manager, handle_sleep_key)
|
||||||
Login.HandleLidSwitch, config_parse_handle_button, 0, offsetof(Manager, handle_lid_switch)
|
Login.HandleLidSwitch, config_parse_handle_button, 0, offsetof(Manager, handle_lid_switch)
|
||||||
|
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
|
||||||
|
Login.SleepKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, sleep_key_ignore_inhibited)
|
||||||
|
Login.LidSwitchIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, lid_switch_ignore_inhibited)
|
||||||
|
|
|
@ -348,7 +348,24 @@ InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
|
||||||
return what;
|
return what;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since) {
|
static int pid_is_active(Manager *m, pid_t pid) {
|
||||||
|
Session *s;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = manager_get_session_by_pid(m, pid, &s);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return session_is_active(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool manager_is_inhibited(
|
||||||
|
Manager *m,
|
||||||
|
InhibitWhat w,
|
||||||
|
InhibitMode mm,
|
||||||
|
dual_timestamp *since,
|
||||||
|
bool only_active) {
|
||||||
|
|
||||||
Inhibitor *i;
|
Inhibitor *i;
|
||||||
Iterator j;
|
Iterator j;
|
||||||
struct dual_timestamp ts = { 0, 0 };
|
struct dual_timestamp ts = { 0, 0 };
|
||||||
|
@ -364,6 +381,9 @@ bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timest
|
||||||
if (i->mode != mm)
|
if (i->mode != mm)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (only_active && pid_is_active(m, i->pid) <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!inhibited ||
|
if (!inhibited ||
|
||||||
i->since.monotonic < ts.monotonic)
|
i->since.monotonic < ts.monotonic)
|
||||||
ts = i->since;
|
ts = i->since;
|
||||||
|
@ -378,22 +398,32 @@ bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timest
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *inhibit_what_to_string(InhibitWhat w) {
|
const char *inhibit_what_to_string(InhibitWhat w) {
|
||||||
|
static __thread char buffer[73];
|
||||||
static const char* const table[_INHIBIT_WHAT_MAX] = {
|
char *p;
|
||||||
[0] = "",
|
|
||||||
[INHIBIT_SHUTDOWN] = "shutdown",
|
|
||||||
[INHIBIT_SLEEP] = "sleep",
|
|
||||||
[INHIBIT_IDLE] = "idle",
|
|
||||||
[INHIBIT_SHUTDOWN|INHIBIT_SLEEP] = "shutdown:sleep",
|
|
||||||
[INHIBIT_SHUTDOWN|INHIBIT_IDLE] = "shutdown:idle",
|
|
||||||
[INHIBIT_SHUTDOWN|INHIBIT_SLEEP|INHIBIT_IDLE] = "shutdown:sleep:idle",
|
|
||||||
[INHIBIT_SLEEP|INHIBIT_IDLE] = "sleep:idle"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
|
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return table[w];
|
p = buffer;
|
||||||
|
if (w & INHIBIT_SHUTDOWN)
|
||||||
|
p = stpcpy(p, "shutdown:");
|
||||||
|
if (w & INHIBIT_SLEEP)
|
||||||
|
p = stpcpy(p, "sleep:");
|
||||||
|
if (w & INHIBIT_IDLE)
|
||||||
|
p = stpcpy(p, "idle:");
|
||||||
|
if (w & INHIBIT_HANDLE_POWER_KEY)
|
||||||
|
p = stpcpy(p, "handle-power-key:");
|
||||||
|
if (w & INHIBIT_HANDLE_SLEEP_KEY)
|
||||||
|
p = stpcpy(p, "handle-sleep-key:");
|
||||||
|
if (w & INHIBIT_HANDLE_LID_SWITCH)
|
||||||
|
p = stpcpy(p, "handle-lid-switch:");
|
||||||
|
|
||||||
|
if (p > buffer)
|
||||||
|
*(p-1) = 0;
|
||||||
|
else
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
InhibitWhat inhibit_what_from_string(const char *s) {
|
InhibitWhat inhibit_what_from_string(const char *s) {
|
||||||
|
@ -408,12 +438,17 @@ InhibitWhat inhibit_what_from_string(const char *s) {
|
||||||
what |= INHIBIT_SLEEP;
|
what |= INHIBIT_SLEEP;
|
||||||
else if (l == 4 && strncmp(w, "idle", l) == 0)
|
else if (l == 4 && strncmp(w, "idle", l) == 0)
|
||||||
what |= INHIBIT_IDLE;
|
what |= INHIBIT_IDLE;
|
||||||
|
else if (l == 16 && strncmp(w, "handle-power-key", l) == 0)
|
||||||
|
what |= INHIBIT_HANDLE_POWER_KEY;
|
||||||
|
else if (l == 16 && strncmp(w, "handle-sleep-key", l) == 0)
|
||||||
|
what |= INHIBIT_HANDLE_SLEEP_KEY;
|
||||||
|
else if (l == 16 && strncmp(w, "handle-lid-switch", l) == 0)
|
||||||
|
what |= INHIBIT_HANDLE_LID_SWITCH;
|
||||||
else
|
else
|
||||||
return _INHIBIT_WHAT_INVALID;
|
return _INHIBIT_WHAT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return what;
|
return what;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
|
static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
|
||||||
|
|
|
@ -31,7 +31,10 @@ typedef enum InhibitWhat {
|
||||||
INHIBIT_SHUTDOWN = 1,
|
INHIBIT_SHUTDOWN = 1,
|
||||||
INHIBIT_SLEEP = 2,
|
INHIBIT_SLEEP = 2,
|
||||||
INHIBIT_IDLE = 4,
|
INHIBIT_IDLE = 4,
|
||||||
_INHIBIT_WHAT_MAX = 8,
|
INHIBIT_HANDLE_POWER_KEY = 8,
|
||||||
|
INHIBIT_HANDLE_SLEEP_KEY = 16,
|
||||||
|
INHIBIT_HANDLE_LID_SWITCH = 32,
|
||||||
|
_INHIBIT_WHAT_MAX = 64,
|
||||||
_INHIBIT_WHAT_INVALID = -1
|
_INHIBIT_WHAT_INVALID = -1
|
||||||
} InhibitWhat;
|
} InhibitWhat;
|
||||||
|
|
||||||
|
@ -80,7 +83,7 @@ int inhibitor_create_fifo(Inhibitor *i);
|
||||||
void inhibitor_remove_fifo(Inhibitor *i);
|
void inhibitor_remove_fifo(Inhibitor *i);
|
||||||
|
|
||||||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
|
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
|
||||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since);
|
bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool only_active);
|
||||||
|
|
||||||
const char *inhibit_what_to_string(InhibitWhat k);
|
const char *inhibit_what_to_string(InhibitWhat k);
|
||||||
InhibitWhat inhibit_what_from_string(const char *s);
|
InhibitWhat inhibit_what_from_string(const char *s);
|
||||||
|
|
|
@ -55,9 +55,10 @@ Manager *manager_new(void) {
|
||||||
m->n_autovts = 6;
|
m->n_autovts = 6;
|
||||||
m->reserve_vt = 6;
|
m->reserve_vt = 6;
|
||||||
m->inhibit_delay_max = 5 * USEC_PER_SEC;
|
m->inhibit_delay_max = 5 * USEC_PER_SEC;
|
||||||
m->handle_power_key = HANDLE_NO_SESSION;
|
m->handle_power_key = HANDLE_POWEROFF;
|
||||||
m->handle_sleep_key = HANDLE_TTY_SESSION;
|
m->handle_sleep_key = HANDLE_SUSPEND;
|
||||||
m->handle_lid_switch = HANDLE_OFF;
|
m->handle_lid_switch = HANDLE_SUSPEND;
|
||||||
|
m->lid_switch_ignore_inhibited = true;
|
||||||
|
|
||||||
m->devices = hashmap_new(string_hash_func, string_compare_func);
|
m->devices = hashmap_new(string_hash_func, string_compare_func);
|
||||||
m->seats = hashmap_new(string_hash_func, string_compare_func);
|
m->seats = hashmap_new(string_hash_func, string_compare_func);
|
||||||
|
@ -494,9 +495,9 @@ int manager_enumerate_buttons(Manager *m) {
|
||||||
|
|
||||||
/* Loads buttons from udev */
|
/* Loads buttons from udev */
|
||||||
|
|
||||||
if (m->handle_power_key == HANDLE_OFF &&
|
if (m->handle_power_key == HANDLE_IGNORE &&
|
||||||
m->handle_sleep_key == HANDLE_OFF &&
|
m->handle_sleep_key == HANDLE_IGNORE &&
|
||||||
m->handle_lid_switch == HANDLE_OFF)
|
m->handle_lid_switch == HANDLE_IGNORE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
e = udev_enumerate_new(m->udev);
|
e = udev_enumerate_new(m->udev);
|
||||||
|
@ -1304,9 +1305,9 @@ static int manager_connect_udev(Manager *m) {
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
/* Don't watch keys if nobody cares */
|
/* Don't watch keys if nobody cares */
|
||||||
if (m->handle_power_key != HANDLE_OFF ||
|
if (m->handle_power_key != HANDLE_IGNORE ||
|
||||||
m->handle_sleep_key != HANDLE_OFF ||
|
m->handle_sleep_key != HANDLE_IGNORE ||
|
||||||
m->handle_lid_switch != HANDLE_OFF) {
|
m->handle_lid_switch != HANDLE_IGNORE) {
|
||||||
|
|
||||||
m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
|
m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
|
||||||
if (!m->udev_button_monitor)
|
if (!m->udev_button_monitor)
|
||||||
|
@ -1406,7 +1407,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t);
|
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false);
|
||||||
|
|
||||||
HASHMAP_FOREACH(s, m->sessions, i) {
|
HASHMAP_FOREACH(s, m->sessions, i) {
|
||||||
dual_timestamp k;
|
dual_timestamp k;
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#Controllers=
|
#Controllers=
|
||||||
#ResetControllers=cpu
|
#ResetControllers=cpu
|
||||||
#InhibitDelayMaxSec=5
|
#InhibitDelayMaxSec=5
|
||||||
#HandlePowerKey=no-session
|
#HandlePowerKey=poweroff
|
||||||
#HandleSleepKey=tty-session
|
#HandleSleepKey=suspend
|
||||||
#HandleLidSwitch=off
|
#HandleLidSwitch=suspend
|
||||||
|
#PowerKeyIgnoreInhibited=no
|
||||||
|
#SleepKeyIgnoreInhibited=no
|
||||||
|
#LidSwitchIgnoreInhibited=yes
|
||||||
|
|
|
@ -102,6 +102,10 @@ struct Manager {
|
||||||
HandleButton handle_power_key;
|
HandleButton handle_power_key;
|
||||||
HandleButton handle_sleep_key;
|
HandleButton handle_sleep_key;
|
||||||
HandleButton handle_lid_switch;
|
HandleButton handle_lid_switch;
|
||||||
|
|
||||||
|
bool power_key_ignore_inhibited;
|
||||||
|
bool sleep_key_ignore_inhibited;
|
||||||
|
bool lid_switch_ignore_inhibited;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -20,27 +20,7 @@
|
||||||
<_description>Allow applications to inhibit system shutdown</_description>
|
<_description>Allow applications to inhibit system shutdown</_description>
|
||||||
<_message>Authentication is required to allow an application to inhibit system shutdown.</_message>
|
<_message>Authentication is required to allow an application to inhibit system shutdown.</_message>
|
||||||
<defaults>
|
<defaults>
|
||||||
<allow_any>auth_admin_keep</allow_any>
|
<allow_any>no</allow_any>
|
||||||
<allow_inactive>yes</allow_inactive>
|
|
||||||
<allow_active>yes</allow_active>
|
|
||||||
</defaults>
|
|
||||||
</action>
|
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.inhibit-block-sleep">
|
|
||||||
<_description>Allow applications to inhibit system sleep</_description>
|
|
||||||
<_message>Authentication is required to allow an application to inhibit system sleep.</_message>
|
|
||||||
<defaults>
|
|
||||||
<allow_any>auth_admin_keep</allow_any>
|
|
||||||
<allow_inactive>yes</allow_inactive>
|
|
||||||
<allow_active>yes</allow_active>
|
|
||||||
</defaults>
|
|
||||||
</action>
|
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.inhibit-block-idle">
|
|
||||||
<_description>Allow applications to inhibit automatic system suspend</_description>
|
|
||||||
<_message>Authentication is required to allow an application to inhibit automatic system suspend.</_message>
|
|
||||||
<defaults>
|
|
||||||
<allow_any>yes</allow_any>
|
|
||||||
<allow_inactive>yes</allow_inactive>
|
<allow_inactive>yes</allow_inactive>
|
||||||
<allow_active>yes</allow_active>
|
<allow_active>yes</allow_active>
|
||||||
</defaults>
|
</defaults>
|
||||||
|
@ -56,6 +36,16 @@
|
||||||
</defaults>
|
</defaults>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.inhibit-block-sleep">
|
||||||
|
<_description>Allow applications to inhibit system sleep</_description>
|
||||||
|
<_message>Authentication is required to allow an application to inhibit system sleep.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>no</allow_any>
|
||||||
|
<allow_inactive>yes</allow_inactive>
|
||||||
|
<allow_active>yes</allow_active>
|
||||||
|
</defaults>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.inhibit-delay-sleep">
|
<action id="org.freedesktop.login1.inhibit-delay-sleep">
|
||||||
<_description>Allow applications to delay system sleep</_description>
|
<_description>Allow applications to delay system sleep</_description>
|
||||||
<_message>Authentication is required to allow an application to delay system sleep.</_message>
|
<_message>Authentication is required to allow an application to delay system sleep.</_message>
|
||||||
|
@ -66,9 +56,9 @@
|
||||||
</defaults>
|
</defaults>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.inhibit-delay-idle">
|
<action id="org.freedesktop.login1.inhibit-block-idle">
|
||||||
<_description>Allow applications to delay automatic system suspend</_description>
|
<_description>Allow applications to inhibit automatic system suspend</_description>
|
||||||
<_message>Authentication is required to allow an application to delay automatic system suspend.</_message>
|
<_message>Authentication is required to allow an application to inhibit automatic system suspend.</_message>
|
||||||
<defaults>
|
<defaults>
|
||||||
<allow_any>yes</allow_any>
|
<allow_any>yes</allow_any>
|
||||||
<allow_inactive>yes</allow_inactive>
|
<allow_inactive>yes</allow_inactive>
|
||||||
|
@ -76,6 +66,36 @@
|
||||||
</defaults>
|
</defaults>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.inhibit-handle-power-key">
|
||||||
|
<_description>Allow applications to inhibit system handling of the power key</_description>
|
||||||
|
<_message>Authentication is required to allow an application to inhibit system handling of the power key.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>no</allow_any>
|
||||||
|
<allow_inactive>yes</allow_inactive>
|
||||||
|
<allow_active>yes</allow_active>
|
||||||
|
</defaults>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.inhibit-handle-sleep-key">
|
||||||
|
<_description>Allow applications to inhibit system handling of the sleep key</_description>
|
||||||
|
<_message>Authentication is required to allow an application to inhibit system handling of the sleep key.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>no</allow_any>
|
||||||
|
<allow_inactive>yes</allow_inactive>
|
||||||
|
<allow_active>yes</allow_active>
|
||||||
|
</defaults>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.inhibit-handle-lid-switch">
|
||||||
|
<_description>Allow applications to inhibit system handling of the lid switch</_description>
|
||||||
|
<_message>Authentication is required to allow an application to inhibit system handling of the lid switch.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>no</allow_any>
|
||||||
|
<allow_inactive>yes</allow_inactive>
|
||||||
|
<allow_active>yes</allow_active>
|
||||||
|
</defaults>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.set-user-linger">
|
<action id="org.freedesktop.login1.set-user-linger">
|
||||||
<_description>Allow non-logged-in users to run programs</_description>
|
<_description>Allow non-logged-in users to run programs</_description>
|
||||||
<_message>Authentication is required to allow a non-logged-in user to run programs.</_message>
|
<_message>Authentication is required to allow a non-logged-in user to run programs.</_message>
|
||||||
|
|
Loading…
Reference in a new issue