Swayidle handles idle events and allows for dpms and lockscreen handling. It also handles systemd sleep events, and can raise a lockscreen on sleep Fixes #541master
							parent
							
								
									9d607b7253
								
							
						
					
					
						commit
						8fbafbfab5
					
				| @ -0,0 +1,49 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="idle"> | ||||
|   <copyright><![CDATA[ | ||||
|     Copyright (C) 2015 Martin Gräßlin | ||||
| 
 | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU Lesser General Public License as published by | ||||
|     the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details. | ||||
| 
 | ||||
|     You should have received a copy of the GNU Lesser General Public License | ||||
|     along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|   ]]></copyright> | ||||
|   <interface  name="org_kde_kwin_idle" version="1"> | ||||
|       <description summary="User idle time manager"> | ||||
|         This interface allows to monitor user idle time on a given seat. The interface | ||||
|         allows to register timers which trigger after no user activity was registered | ||||
|         on the seat for a given interval. It notifies when user activity resumes. | ||||
| 
 | ||||
|         This is useful for applications wanting to perform actions when the user is not | ||||
|         interacting with the system, e.g. chat applications setting the user as away, power | ||||
|         management features to dim screen, etc.. | ||||
|       </description> | ||||
|       <request name="get_idle_timeout"> | ||||
|         <arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/> | ||||
|         <arg name="seat" type="object" interface="wl_seat"/> | ||||
|         <arg name="timeout" type="uint" summary="The idle timeout in msec"/> | ||||
|       </request> | ||||
|   </interface> | ||||
|   <interface name="org_kde_kwin_idle_timeout" version="1"> | ||||
|       <request name="release" type="destructor"> | ||||
|         <description summary="release the timeout object"/> | ||||
|       </request> | ||||
|       <request name="simulate_user_activity"> | ||||
|           <description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/> | ||||
|       </request> | ||||
|       <event name="idle"> | ||||
|           <description summary="Triggered when there has not been any user activity in the requested idle time interval"/> | ||||
|       </event> | ||||
|       <event name="resumed"> | ||||
|           <description summary="Triggered on the first user activity after an idle event"/> | ||||
|       </event> | ||||
|   </interface> | ||||
| </protocol> | ||||
| @ -0,0 +1,414 @@ | ||||
| #define _XOPEN_SOURCE 500 | ||||
| #include <getopt.h> | ||||
| #include <signal.h> | ||||
| #include <pthread.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <wayland-client-protocol.h> | ||||
| #include <wayland-client.h> | ||||
| #include <wayland-util.h> | ||||
| #include <wlr/config.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include <wlr/types/wlr_output_layout.h> | ||||
| #include <wlr/types/wlr_output.h> | ||||
| #include "idle-client-protocol.h" | ||||
| #include "config.h" | ||||
| #include "list.h" | ||||
| #ifdef SWAY_IDLE_HAS_SYSTEMD | ||||
| #include <systemd/sd-bus.h> | ||||
| #include <systemd/sd-login.h> | ||||
| #elif defined(SWAY_IDLE_HAS_ELOGIND) | ||||
| #include <elogind/sd-bus.h> | ||||
| #include <elogind/sd-login.h> | ||||
| #endif | ||||
| 
 | ||||
| typedef void (*timer_callback_func)(void *data); | ||||
| 
 | ||||
| static struct org_kde_kwin_idle *idle_manager = NULL; | ||||
| static struct wl_seat *seat = NULL; | ||||
| bool debug = false; | ||||
| 
 | ||||
| struct swayidle_state { | ||||
| 	struct wl_display *display; | ||||
| 	struct org_kde_kwin_idle_timeout *idle_timer; | ||||
| 	struct org_kde_kwin_idle_timeout *lock_timer; | ||||
| 	struct wlr_output_layout *layout; | ||||
| 	struct wl_event_loop *event_loop; | ||||
| 	list_t *timeout_cmds; | ||||
| } state; | ||||
| 
 | ||||
| struct swayidle_cmd { | ||||
| 	timer_callback_func callback; | ||||
| 	char *param; | ||||
| }; | ||||
| 
 | ||||
| struct swayidle_cmd *lock_cmd = NULL; | ||||
| 
 | ||||
| struct swayidle_timeout_cmd { | ||||
| 	uint32_t timeout; | ||||
| 	struct swayidle_cmd *idle_cmd; | ||||
| 	struct swayidle_cmd *resume_cmd; | ||||
| }; | ||||
| 
 | ||||
| static void cmd_exec(void *data) { | ||||
| 	if (data == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 	char *param = (char *)data; | ||||
| 	wlr_log(L_DEBUG, "Cmd exec %s", param); | ||||
| 	int pid = fork(); | ||||
| 	if (pid == 0) { | ||||
| 		char *const cmd[] = { "sh", "-c", param, NULL, }; | ||||
| 		execvp(cmd[0], cmd); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	wlr_log(L_DEBUG, "Spawned process %d", pid); | ||||
| } | ||||
| 
 | ||||
| #if defined(SWAY_IDLE_HAS_SYSTEMD) || defined(SWAY_IDLE_HAS_ELOGIND) | ||||
| static int lock_fd = -1; | ||||
| static int ongoing_fd = -1; | ||||
| 
 | ||||
| static int release_lock(void *data) { | ||||
| 	wlr_log(L_INFO, "Releasing sleep lock %d", ongoing_fd); | ||||
| 	if (ongoing_fd >= 0) { | ||||
| 		close(ongoing_fd); | ||||
| 	} | ||||
| 	ongoing_fd = -1; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void acquire_sleep_lock() { | ||||
| 	sd_bus_message *msg = NULL; | ||||
| 	sd_bus_error error = SD_BUS_ERROR_NULL; | ||||
| 	struct sd_bus *bus; | ||||
| 	int ret = sd_bus_default_system(&bus); | ||||
| 
 | ||||
| 	if (ret < 0) { | ||||
| 		wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", | ||||
| 				strerror(-ret)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = sd_bus_call_method(bus, "org.freedesktop.login1", | ||||
| 			"/org/freedesktop/login1", | ||||
| 			"org.freedesktop.login1.Manager", "Inhibit", | ||||
| 			&error, &msg, "ssss", "sleep", "swayidle", | ||||
| 			"Setup Up Lock Screen", "delay"); | ||||
| 	if (ret < 0) { | ||||
| 		wlr_log(L_ERROR, "Failed to send Inhibit signal: %s", | ||||
| 				strerror(-ret)); | ||||
| 	} else { | ||||
| 		ret = sd_bus_message_read(msg, "h", &lock_fd); | ||||
| 		if (ret < 0) { | ||||
| 			wlr_log(L_ERROR, | ||||
| 					"Failed to parse D-Bus response for Inhibit: %s", | ||||
| 					strerror(-ret)); | ||||
| 		} | ||||
| 	} | ||||
| 	wlr_log(L_INFO, "Got sleep lock: %d", lock_fd); | ||||
| } | ||||
| 
 | ||||
| static int prepare_for_sleep(sd_bus_message *msg, void *userdata, | ||||
| 		sd_bus_error *ret_error) { | ||||
| 	bool going_down = true; | ||||
| 	int ret = sd_bus_message_read(msg, "b", &going_down); | ||||
| 	if (ret < 0) { | ||||
| 		wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s", | ||||
| 				strerror(-ret)); | ||||
| 	} | ||||
| 	wlr_log(L_DEBUG, "PrepareForSleep signal received %d", going_down); | ||||
| 	if (!going_down) { | ||||
| 		acquire_sleep_lock(); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	ongoing_fd = lock_fd; | ||||
| 
 | ||||
| 	if (lock_cmd && lock_cmd->callback) { | ||||
| 		lock_cmd->callback(lock_cmd->param); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ongoing_fd >= 0) { | ||||
| 		struct wl_event_source *source = | ||||
| 			wl_event_loop_add_timer(state.event_loop, release_lock, NULL); | ||||
| 		wl_event_source_timer_update(source, 1000); | ||||
| 	} | ||||
| 	wlr_log(L_DEBUG, "Prepare for sleep done"); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dbus_event(int fd, uint32_t mask, void *data) { | ||||
| 	sd_bus *bus = data; | ||||
| 	while (sd_bus_process(bus, NULL) > 0) { | ||||
| 		// Do nothing.
 | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| void setup_sleep_listener() { | ||||
| 	struct sd_bus *bus; | ||||
| 	 | ||||
| 	int ret = sd_bus_default_system(&bus); | ||||
| 	if (ret < 0) { | ||||
| 		wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", | ||||
| 				strerror(-ret)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	char str[256]; | ||||
| 	const char *fmt = "type='signal'," | ||||
| 		"sender='org.freedesktop.login1'," | ||||
| 		"interface='org.freedesktop.login1.%s'," | ||||
| 		"member='%s'," "path='%s'"; | ||||
| 
 | ||||
| 	snprintf(str, sizeof(str), fmt, "Manager", "PrepareForSleep", | ||||
| 			"/org/freedesktop/login1"); | ||||
| 	ret = sd_bus_add_match(bus, NULL, str, prepare_for_sleep, NULL); | ||||
| 	if (ret < 0) { | ||||
| 		wlr_log(L_ERROR, "Failed to add D-Bus match: %s", strerror(-ret)); | ||||
| 		return; | ||||
| 	} | ||||
| 	acquire_sleep_lock(); | ||||
| 
 | ||||
| 	wl_event_loop_add_fd(state.event_loop, sd_bus_get_fd(bus), | ||||
| 			WL_EVENT_READABLE, dbus_event, bus); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void handle_global(void *data, struct wl_registry *registry, | ||||
| 		uint32_t name, const char *interface, uint32_t version) { | ||||
| 	if (strcmp(interface, org_kde_kwin_idle_interface.name) == 0) { | ||||
| 		idle_manager = | ||||
| 			wl_registry_bind(registry, name, &org_kde_kwin_idle_interface, 1); | ||||
| 	} else if (strcmp(interface, wl_seat_interface.name) == 0) { | ||||
| 		seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_global_remove(void *data, struct wl_registry *registry, | ||||
| 		uint32_t name) { | ||||
| } | ||||
| 
 | ||||
| static const struct wl_registry_listener registry_listener = { | ||||
| 	.global = handle_global, | ||||
| 	.global_remove = handle_global_remove, | ||||
| }; | ||||
| 
 | ||||
| static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) { | ||||
| 	struct swayidle_timeout_cmd *cmd = data; | ||||
| 	wlr_log(L_DEBUG, "idle state"); | ||||
| 	if (cmd && cmd->idle_cmd && cmd->idle_cmd->callback) { | ||||
| 		cmd->idle_cmd->callback(cmd->idle_cmd->param); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) { | ||||
| 	struct swayidle_timeout_cmd *cmd = data; | ||||
| 	wlr_log(L_DEBUG, "active state"); | ||||
| 	if (cmd && cmd->resume_cmd && cmd->resume_cmd->callback) { | ||||
| 		cmd->resume_cmd->callback(cmd->resume_cmd->param); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = { | ||||
| 	.idle = handle_idle, | ||||
| 	.resumed = handle_resume, | ||||
| }; | ||||
| 
 | ||||
| struct swayidle_cmd *parse_command(int argc, char **argv) { | ||||
| 	if (argc < 1) { | ||||
| 		wlr_log(L_ERROR, "Too few parameters for command in parse_command"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	struct swayidle_cmd *cmd = calloc(1, sizeof(struct swayidle_cmd)); | ||||
| 	wlr_log(L_DEBUG, "Command: %s", argv[0]); | ||||
| 	cmd->callback = cmd_exec; | ||||
| 	cmd->param = argv[0]; | ||||
| 	return cmd; | ||||
| } | ||||
| 
 | ||||
| int parse_timeout(int argc, char **argv) { | ||||
| 	if (argc < 3) { | ||||
| 		wlr_log(L_ERROR, "Too few parameters to timeout command. " | ||||
| 				"Usage: timeout <seconds> <command>"); | ||||
| 		exit(-1); | ||||
| 	} | ||||
| 	errno = 0; | ||||
| 	char *endptr; | ||||
| 	int seconds = strtoul(argv[1], &endptr, 10); | ||||
| 	if (errno != 0 || *endptr != '\0') { | ||||
| 		wlr_log(L_ERROR, "Invalid timeout parameter '%s', it should be a " | ||||
| 				"numeric value representing seconds", optarg); | ||||
| 		exit(-1); | ||||
| 	} | ||||
| 	struct swayidle_timeout_cmd *cmd = | ||||
| 		calloc(1, sizeof(struct swayidle_timeout_cmd)); | ||||
| 	cmd->timeout = seconds * 1000; | ||||
| 
 | ||||
| 	wlr_log(L_DEBUG, "Register idle timeout at %d ms", cmd->timeout); | ||||
| 	wlr_log(L_DEBUG, "Setup idle"); | ||||
| 	cmd->idle_cmd = parse_command(argc - 2, &argv[2]); | ||||
| 
 | ||||
| 	int result = 3; | ||||
| 	if (argc >= 5 && !strcmp("resume", argv[3])) { | ||||
| 		wlr_log(L_DEBUG, "Setup resume"); | ||||
| 		cmd->resume_cmd = parse_command(argc - 4, &argv[4]); | ||||
| 		result = 5; | ||||
| 	} | ||||
| 	list_add(state.timeout_cmds, cmd); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| int parse_sleep(int argc, char **argv) { | ||||
| 	if (argc < 2) { | ||||
| 		wlr_log(L_ERROR, "Too few parameters to before-sleep command. " | ||||
| 				"Usage: before-sleep <command>"); | ||||
| 		exit(-1); | ||||
| 	} | ||||
| 
 | ||||
| 	lock_cmd = parse_command(argc - 1, &argv[1]); | ||||
| 	if (lock_cmd) { | ||||
| 		wlr_log(L_DEBUG, "Setup sleep lock: %s", lock_cmd->param); | ||||
| 	} | ||||
| 
 | ||||
| 	return 2; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int parse_args(int argc, char *argv[]) { | ||||
| 	int c; | ||||
| 
 | ||||
| 	while ((c = getopt(argc, argv, "hs:d")) != -1) { | ||||
| 		switch(c) { | ||||
| 		case 'd': | ||||
| 			debug = true; | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 		case '?': | ||||
| 			printf("Usage: %s [OPTIONS]\n", argv[0]); | ||||
| 			printf("  -d\tdebug\n"); | ||||
| 			printf("  -h\tthis help menu\n"); | ||||
| 			return 1; | ||||
| 		default: | ||||
| 			return 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (debug) { | ||||
| 		wlr_log_init(L_DEBUG, NULL); | ||||
| 		wlr_log(L_DEBUG, "Loglevel debug"); | ||||
| 	} else { | ||||
| 		wlr_log_init(L_INFO, NULL); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	state.timeout_cmds = create_list(); | ||||
| 
 | ||||
| 	int i = optind; | ||||
| 	while (i < argc) { | ||||
| 		if (!strcmp("timeout", argv[i])) { | ||||
| 			wlr_log(L_DEBUG, "Got timeout"); | ||||
| 			i += parse_timeout(argc - i, &argv[i]); | ||||
| 		} else if (!strcmp("before-sleep", argv[i])) { | ||||
| 			wlr_log(L_DEBUG, "Got before-sleep"); | ||||
| 			i += parse_sleep(argc - i, &argv[i]); | ||||
| 		} else { | ||||
| 			wlr_log(L_ERROR, "Unsupported command '%s'", argv[i]); | ||||
| 			exit(-1); | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void sway_terminate(int exit_code) { | ||||
| 	if (state.event_loop) { | ||||
| 		wl_event_loop_destroy(state.event_loop); | ||||
| 	} | ||||
| 	if (state.display) { | ||||
| 		wl_display_disconnect(state.display); | ||||
| 	} | ||||
| 	exit(exit_code); | ||||
| } | ||||
| 
 | ||||
| void sig_handler(int signal) { | ||||
| 	sway_terminate(0); | ||||
| } | ||||
| 
 | ||||
| static int display_event(int fd, uint32_t mask, void *data) { | ||||
| 	wl_display_dispatch(state.display); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void register_idle_timeout(void *item) { | ||||
| 	struct swayidle_timeout_cmd *cmd = item; | ||||
| 	if (cmd == NULL || !cmd->timeout) { | ||||
| 		wlr_log(L_ERROR, "Invalid idle cmd, will not register"); | ||||
| 		return; | ||||
| 	} | ||||
| 	state.idle_timer = | ||||
| 		org_kde_kwin_idle_get_idle_timeout(idle_manager, seat, cmd->timeout); | ||||
| 	if (state.idle_timer != NULL) { | ||||
| 		org_kde_kwin_idle_timeout_add_listener(state.idle_timer, | ||||
| 				&idle_timer_listener, cmd); | ||||
| 	} else { | ||||
| 		wlr_log(L_ERROR, "Could not create idle timer"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) { | ||||
| 	signal(SIGINT, sig_handler); | ||||
| 	signal(SIGTERM, sig_handler); | ||||
| 
 | ||||
| 	if (parse_args(argc, argv) != 0) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	state.display = wl_display_connect(NULL); | ||||
| 	if (state.display == NULL) { | ||||
| 		wlr_log(L_ERROR, "Failed to create display"); | ||||
| 		return -3; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_registry *registry = wl_display_get_registry(state.display); | ||||
| 	wl_registry_add_listener(registry, ®istry_listener, NULL); | ||||
| 	wl_display_roundtrip(state.display); | ||||
| 	state.layout = wlr_output_layout_create(); | ||||
| 	state.event_loop = wl_event_loop_create(); | ||||
| 
 | ||||
| 	if (idle_manager == NULL) { | ||||
| 		wlr_log(L_ERROR, "Display doesn't support idle protocol"); | ||||
| 		return -4; | ||||
| 	} | ||||
| 	if (seat == NULL) { | ||||
| 		wlr_log(L_ERROR, "Seat error"); | ||||
| 		return -5; | ||||
| 	} | ||||
| 
 | ||||
| 	bool should_run = state.timeout_cmds->length > 0; | ||||
| #if defined(SWAY_IDLE_HAS_SYSTEMD) || defined(SWAY_IDLE_HAS_ELOGIND) | ||||
| 	if (lock_cmd) { | ||||
| 		should_run = true; | ||||
| 		setup_sleep_listener(); | ||||
| 	} | ||||
| #endif | ||||
| 	if (!should_run) { | ||||
| 		wlr_log(L_INFO, "No command specified! Nothing to do, will exit"); | ||||
| 		sway_terminate(0); | ||||
| 	} | ||||
| 	list_foreach(state.timeout_cmds, register_idle_timeout); | ||||
| 
 | ||||
| 	wl_display_roundtrip(state.display); | ||||
| 
 | ||||
| 	wl_event_loop_add_fd(state.event_loop, wl_display_get_fd(state.display), | ||||
| 			WL_EVENT_READABLE, display_event, NULL); | ||||
| 
 | ||||
| 	while (wl_event_loop_dispatch(state.event_loop, 0) != -1) { | ||||
| 		; //Intentionally left blank;
 | ||||
| 	} | ||||
| 	sway_terminate(0); | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| threads = dependency('threads') | ||||
| 
 | ||||
| executable( | ||||
| 	'swayidle', [ | ||||
| 		'main.c', | ||||
| 	], | ||||
| 	include_directories: [sway_inc], | ||||
| 	dependencies: [ | ||||
| 		client_protos, | ||||
| 		wayland_client, | ||||
| 		wayland_server, | ||||
| 		wlroots, | ||||
| 		swayidle_deps, | ||||
| 	], | ||||
| 	link_with: [lib_sway_common, lib_sway_client], | ||||
| 	install: true | ||||
| ) | ||||
| @ -0,0 +1,61 @@ | ||||
| swayidle (1) | ||||
| 
 | ||||
| # NAME | ||||
| 
 | ||||
| swayidle - Idle manager for Wayland | ||||
| 
 | ||||
| # SYNOPSIS | ||||
| 
 | ||||
| *swayidle* [options] [events...] | ||||
| 
 | ||||
| # OPTIONS | ||||
| 
 | ||||
| *-h* | ||||
| 	Show help message and quit. | ||||
| 
 | ||||
| *-d* | ||||
| 	Enable debug output. | ||||
| 
 | ||||
| # DESCRIPTION | ||||
| 
 | ||||
| swayidle listens for idle activity on your Wayland compositor and executes tasks | ||||
| on various idle-related events. You can specify any number of events at the | ||||
| command line. | ||||
| 
 | ||||
| # EVENTS | ||||
| 
 | ||||
| *timeout* <timeout> <timeout command> [resume <resume command>] | ||||
| 	Execute _timeout command_ if there is no activity for <timeout> seconds. | ||||
| 	 | ||||
| 	If you specify "resume <resume command>", _resume command_ will be run when | ||||
| 	there is activity again. | ||||
| 
 | ||||
| *before-sleep* <command> | ||||
| 	If built with systemd support, executes _command_ before systemd puts the | ||||
| 	computer to sleep. | ||||
| 
 | ||||
| All commands are executed in a shell. | ||||
| 
 | ||||
| # EXAMPLE | ||||
| 
 | ||||
| ``` | ||||
|  swayidle \ | ||||
|      timeout 300 'swaylock -c 000000' \ | ||||
|      timeout 600 'swaymsg "output * dpms off"' \ | ||||
| 		resume 'swaymsg "output * dpms on"' \ | ||||
|      before-sleep 'swaylock -c 000000' | ||||
| ``` | ||||
| 
 | ||||
| This will lock your screen after 300 seconds of inactivity, then turn off your | ||||
| displays after another 600 seconds, and turn your screens back on when resumed. | ||||
| It will also lock your screen before your computer goes to sleep. | ||||
| 
 | ||||
| # AUTHORS | ||||
| 
 | ||||
| Maintained by Drew DeVault <sir@cmpwn.com>, who is assisted by other open | ||||
| source contributors. For more information about sway development, see | ||||
| https://github.com/swaywm/sway. | ||||
| 
 | ||||
| # SEE ALSO | ||||
| 
 | ||||
| *sway*(5) *swaymsg*(1) *swaygrab*(1) *sway-input*(5) *sway-bar*(5) | ||||
| @ -0,0 +1,67 @@ | ||||
| ///// | ||||
| vim:set ts=4 sw=4 tw=82 noet: | ||||
| ///// | ||||
| :quotes.~: | ||||
| 
 | ||||
| swayidle (1) | ||||
| ============ | ||||
| 
 | ||||
| Name | ||||
| ---- | ||||
| swayidle - Idle manager for Wayland | ||||
| 
 | ||||
| Synopsis | ||||
| -------- | ||||
| 'swayidle' [options] [events...] | ||||
| 
 | ||||
| Options | ||||
| ------- | ||||
| 
 | ||||
| *-h*:: | ||||
| 	Show help message and quit. | ||||
| 
 | ||||
| *-d*:: | ||||
| 	Enable debug output. | ||||
| 
 | ||||
| Description | ||||
| ----------- | ||||
| 
 | ||||
| swayidle listens for idle activity on your Wayland compositor and executes tasks | ||||
| on various idle-related events. You can specify any number of events at the | ||||
| command line. | ||||
| 
 | ||||
| Events | ||||
| ------ | ||||
| 
 | ||||
| *timeout* <timeout> <timeout command> [resume <resume command>]:: | ||||
| 	Execute <timeout command> if there is no activity for <timeout> seconds. | ||||
| 	+ | ||||
| 	If you specify "resume <resume command>", <resume command> will be run when | ||||
| 	there is activity again. | ||||
| 
 | ||||
| *before-sleep* <command>:: | ||||
| 	If built with systemd support, executes <command> before systemd puts the | ||||
| 	computer to sleep. | ||||
| 
 | ||||
| All commands are executed in a shell. | ||||
| 
 | ||||
| Example | ||||
| ------- | ||||
| 
 | ||||
|  swayidle \ | ||||
|      timeout 300 'swaylock -c 000000' \ | ||||
|      timeout 600 'swaymsg "output * dpms off"' \ | ||||
| 		resume 'swaymsg "output * dpms on"' \ | ||||
|      before-sleep 'swaylock -c 000000' | ||||
| 
 | ||||
| This will lock your screen after 300 seconds of inactivity, then turn off your | ||||
| displays after another 600 seconds, and turn your screens back on when resumed. | ||||
| It will also lock your screen before your computer goes to sleep. | ||||
| 
 | ||||
| Authors | ||||
| ------- | ||||
| 
 | ||||
| Maintained by Drew DeVault <sir@cmpwn.com>, who is assisted by other open | ||||
| source contributors. For more information about sway development, see | ||||
| <https://github.com/swaywm/sway>. | ||||
| 
 | ||||
					Loading…
					
					
				
		Reference in new issue