| 
									
										
										
										
											2017-03-10 23:41:24 -05:00
										 |  |  | #define _XOPEN_SOURCE 500
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <sys/wait.h>
 | 
					
						
							| 
									
										
										
										
											2017-03-10 23:41:24 -05:00
										 |  |  | #include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2016-02-24 13:30:54 +01:00
										 |  |  | #include <poll.h>
 | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | #include <linux/input-event-codes.h>
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #ifdef ENABLE_TRAY
 | 
					
						
							|  |  |  | #include <dbus/dbus.h>
 | 
					
						
							|  |  |  | #include "swaybar/tray/sni_watcher.h"
 | 
					
						
							|  |  |  | #include "swaybar/tray/tray.h"
 | 
					
						
							|  |  |  | #include "swaybar/tray/sni.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-01 08:18:37 -04:00
										 |  |  | #include "swaybar/ipc.h"
 | 
					
						
							|  |  |  | #include "swaybar/render.h"
 | 
					
						
							|  |  |  | #include "swaybar/config.h"
 | 
					
						
							|  |  |  | #include "swaybar/status_line.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #include "swaybar/event_loop.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-01 08:18:37 -04:00
										 |  |  | #include "swaybar/bar.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | #include "ipc-client.h"
 | 
					
						
							|  |  |  | #include "list.h"
 | 
					
						
							|  |  |  | #include "log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void bar_init(struct bar *bar) { | 
					
						
							|  |  |  | 	bar->config = init_config(); | 
					
						
							|  |  |  | 	bar->status = init_status_line(); | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 	bar->outputs = create_list(); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void spawn_status_cmd_proc(struct bar *bar) { | 
					
						
							|  |  |  | 	if (bar->config->status_command) { | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 		int pipe_read_fd[2]; | 
					
						
							|  |  |  | 		int pipe_write_fd[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (pipe(pipe_read_fd) != 0) { | 
					
						
							|  |  |  | 			sway_log(L_ERROR, "Unable to create pipes for status_command fork"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (pipe(pipe_write_fd) != 0) { | 
					
						
							|  |  |  | 			sway_log(L_ERROR, "Unable to create pipe for status_command fork (write)"); | 
					
						
							|  |  |  | 			close(pipe_read_fd[0]); | 
					
						
							|  |  |  | 			close(pipe_read_fd[1]); | 
					
						
							| 
									
										
										
										
											2016-04-29 11:04:21 -04:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 		bar->status_command_pid = fork(); | 
					
						
							|  |  |  | 		if (bar->status_command_pid == 0) { | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 			close(pipe_read_fd[0]); | 
					
						
							|  |  |  | 			dup2(pipe_read_fd[1], STDOUT_FILENO); | 
					
						
							|  |  |  | 			close(pipe_read_fd[1]); | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			dup2(pipe_write_fd[0], STDIN_FILENO); | 
					
						
							|  |  |  | 			close(pipe_write_fd[0]); | 
					
						
							|  |  |  | 			close(pipe_write_fd[1]); | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 			char *const cmd[] = { | 
					
						
							|  |  |  | 				"sh", | 
					
						
							|  |  |  | 				"-c", | 
					
						
							|  |  |  | 				bar->config->status_command, | 
					
						
							|  |  |  | 				NULL, | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			execvp(cmd[0], cmd); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 		close(pipe_read_fd[1]); | 
					
						
							|  |  |  | 		bar->status_read_fd = pipe_read_fd[0]; | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 		fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK); | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		close(pipe_write_fd[0]); | 
					
						
							|  |  |  | 		bar->status_write_fd = pipe_write_fd[1]; | 
					
						
							|  |  |  | 		fcntl(bar->status_write_fd, F_SETFL, O_NONBLOCK); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | struct output *new_output(const char *name) { | 
					
						
							|  |  |  | 	struct output *output = malloc(sizeof(struct output)); | 
					
						
							|  |  |  | 	output->name = strdup(name); | 
					
						
							|  |  |  | 	output->window = NULL; | 
					
						
							|  |  |  | 	output->registry = NULL; | 
					
						
							|  |  |  | 	output->workspaces = create_list(); | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #ifdef ENABLE_TRAY
 | 
					
						
							|  |  |  | 	output->items = create_list(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 	return output; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-16 09:09:22 -04:00
										 |  |  | static void mouse_button_notify(struct window *window, int x, int y, | 
					
						
							|  |  |  | 		uint32_t button, uint32_t state_w) { | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 	sway_log(L_DEBUG, "Mouse button %d clicked at %d %d %d", button, x, y, state_w); | 
					
						
							| 
									
										
										
										
											2016-07-16 09:09:22 -04:00
										 |  |  | 	if (!state_w) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-11 00:11:38 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct output *clicked_output = NULL; | 
					
						
							|  |  |  | 	for (int i = 0; i < swaybar.outputs->length; i++) { | 
					
						
							|  |  |  | 		struct output *output = swaybar.outputs->items[i]; | 
					
						
							|  |  |  | 		if (window == output->window) { | 
					
						
							|  |  |  | 			clicked_output = output; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!sway_assert(clicked_output != NULL, "Got pointer event for non-existing output")) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	double button_x = 0.5; | 
					
						
							|  |  |  | 	for (int i = 0; i < clicked_output->workspaces->length; i++) { | 
					
						
							|  |  |  | 		struct workspace *workspace = clicked_output->workspaces->items[i]; | 
					
						
							|  |  |  | 		int button_width, button_height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		workspace_button_size(window, workspace->name, &button_width, &button_height); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		button_x += button_width; | 
					
						
							|  |  |  | 		if (x <= button_x) { | 
					
						
							|  |  |  | 			ipc_send_workspace_command(workspace->name); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 	switch (button) { | 
					
						
							| 
									
										
										
										
											2017-08-29 17:33:06 +02:00
										 |  |  | 	case BTN_LEFT: | 
					
						
							|  |  |  | 		status_line_mouse_event(&swaybar, x, y, 1); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case BTN_MIDDLE: | 
					
						
							|  |  |  | 		status_line_mouse_event(&swaybar, x, y, 2); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case BTN_RIGHT: | 
					
						
							|  |  |  | 		status_line_mouse_event(&swaybar, x, y, 3); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #ifdef ENABLE_TRAY
 | 
					
						
							| 
									
										
										
										
											2017-06-07 21:32:48 -07:00
										 |  |  | 	tray_mouse_event(clicked_output, x, y, button, state_w); | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-10 22:23:47 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 22:14:20 -05:00
										 |  |  | static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) { | 
					
						
							|  |  |  | 	sway_log(L_DEBUG, "Mouse wheel scrolled %s", direction == SCROLL_UP ? "up" : "down"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-17 11:26:38 -04:00
										 |  |  | 	if (!swaybar.config->wrap_scroll) { | 
					
						
							|  |  |  | 		// Find output this window lives on
 | 
					
						
							|  |  |  | 		int i; | 
					
						
							| 
									
										
										
										
											2016-07-18 00:57:49 +03:00
										 |  |  | 		struct output *output = NULL; | 
					
						
							| 
									
										
										
										
											2016-07-17 11:26:38 -04:00
										 |  |  | 		for (i = 0; i < swaybar.outputs->length; ++i) { | 
					
						
							|  |  |  | 			output = swaybar.outputs->items[i]; | 
					
						
							|  |  |  | 			if (output->window == window) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!sway_assert(i != swaybar.outputs->length, "Unknown window in scroll event")) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		int focused = -1; | 
					
						
							|  |  |  | 		for (i = 0; i < output->workspaces->length; ++i) { | 
					
						
							|  |  |  | 			struct workspace *ws = output->workspaces->items[i]; | 
					
						
							|  |  |  | 			if (ws->focused) { | 
					
						
							|  |  |  | 				focused = i; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!sway_assert(focused != -1, "Scroll wheel event received on inactive output")) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((focused == 0 && direction == SCROLL_UP) || | 
					
						
							|  |  |  | 				(focused == output->workspaces->length - 1 && direction == SCROLL_DOWN)) { | 
					
						
							|  |  |  | 			// Do not wrap
 | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 22:14:20 -05:00
										 |  |  | 	const char *workspace_name = direction == SCROLL_UP ? "prev_on_output" : "next_on_output"; | 
					
						
							|  |  |  | 	ipc_send_workspace_command(workspace_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	/* initialize bar with default values */ | 
					
						
							|  |  |  | 	bar_init(bar); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 	/* Initialize event loop lists */ | 
					
						
							|  |  |  | 	init_event_loop(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	/* connect to sway ipc */ | 
					
						
							|  |  |  | 	bar->ipc_socketfd = ipc_open_socket(socket_path); | 
					
						
							|  |  |  | 	bar->ipc_event_socketfd = ipc_open_socket(socket_path); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 	ipc_bar_init(bar, bar_id); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 	for (i = 0; i < bar->outputs->length; ++i) { | 
					
						
							|  |  |  | 		struct output *bar_output = bar->outputs->items[i]; | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		bar_output->registry = registry_poll(); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		if (!bar_output->registry->desktop_shell) { | 
					
						
							|  |  |  | 			sway_abort("swaybar requires the compositor to support the desktop-shell extension."); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 11:36:48 -04:00
										 |  |  | 		bar_output->window = window_setup(bar_output->registry, | 
					
						
							|  |  |  | 				output->width / output->scale, 30, output->scale, false); | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		if (!bar_output->window) { | 
					
						
							|  |  |  | 			sway_abort("Failed to create window."); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-05 11:36:48 -04:00
										 |  |  | 		desktop_shell_set_panel(bar_output->registry->desktop_shell, | 
					
						
							|  |  |  | 				output->output, bar_output->window->surface); | 
					
						
							|  |  |  | 		desktop_shell_set_panel_position(bar_output->registry->desktop_shell, | 
					
						
							|  |  |  | 				bar->config->position); | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-04 17:03:55 -05:00
										 |  |  | 		window_make_shell(bar_output->window); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		/* set font */ | 
					
						
							|  |  |  | 		bar_output->window->font = bar->config->font; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 22:14:20 -05:00
										 |  |  | 		/* set mouse event callbacks */ | 
					
						
							| 
									
										
										
										
											2016-07-11 22:51:50 -05:00
										 |  |  | 		bar_output->window->pointer_input.notify_button = mouse_button_notify; | 
					
						
							| 
									
										
										
										
											2016-07-12 22:14:20 -05:00
										 |  |  | 		bar_output->window->pointer_input.notify_scroll = mouse_scroll_notify; | 
					
						
							| 
									
										
										
										
											2016-07-10 22:23:47 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 		/* set window height */ | 
					
						
							|  |  |  | 		set_window_height(bar_output->window, bar->config->height); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	/* spawn status command */ | 
					
						
							|  |  |  | 	spawn_status_cmd_proc(bar); | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef ENABLE_TRAY
 | 
					
						
							| 
									
										
										
										
											2017-06-07 21:32:48 -07:00
										 |  |  | 	init_tray(bar); | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | bool dirty = true; | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | static void respond_ipc(int fd, short mask, void *_bar) { | 
					
						
							|  |  |  | 	struct bar *bar = (struct bar *)_bar; | 
					
						
							|  |  |  | 	sway_log(L_DEBUG, "Got IPC event."); | 
					
						
							|  |  |  | 	dirty = handle_ipc_event(bar); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void respond_command(int fd, short mask, void *_bar) { | 
					
						
							|  |  |  | 	struct bar *bar = (struct bar *)_bar; | 
					
						
							|  |  |  | 	dirty = handle_status_line(bar); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void respond_output(int fd, short mask, void *_output) { | 
					
						
							|  |  |  | 	struct output *output = (struct output *)_output; | 
					
						
							|  |  |  | 	if (wl_display_dispatch(output->registry->display) == -1) { | 
					
						
							|  |  |  | 		sway_log(L_ERROR, "failed to dispatch wl: %d", errno); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void bar_run(struct bar *bar) { | 
					
						
							|  |  |  | 	add_event(bar->ipc_event_socketfd, POLLIN, respond_ipc, bar); | 
					
						
							|  |  |  | 	add_event(bar->status_read_fd, POLLIN, respond_command, bar); | 
					
						
							| 
									
										
										
										
											2016-02-24 13:30:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	for (i = 0; i < bar->outputs->length; ++i) { | 
					
						
							|  |  |  | 		struct output *output = bar->outputs->items[i]; | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 		add_event(wl_display_get_fd(output->registry->display), | 
					
						
							|  |  |  | 				POLLIN, respond_output, output); | 
					
						
							| 
									
										
										
										
											2016-02-24 13:30:54 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	while (1) { | 
					
						
							|  |  |  | 		if (dirty) { | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | 			int i; | 
					
						
							|  |  |  | 			for (i = 0; i < bar->outputs->length; ++i) { | 
					
						
							|  |  |  | 				struct output *output = bar->outputs->items[i]; | 
					
						
							|  |  |  | 				if (window_prerender(output->window) && output->window->cairo) { | 
					
						
							|  |  |  | 					render(output, bar->config, bar->status); | 
					
						
							|  |  |  | 					window_render(output->window); | 
					
						
							| 
									
										
										
										
											2016-02-24 13:30:54 +01:00
										 |  |  | 					wl_display_flush(output->registry->display); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dirty = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 16:45:28 -07:00
										 |  |  | 		event_loop_poll(); | 
					
						
							|  |  |  | #ifdef ENABLE_TRAY
 | 
					
						
							|  |  |  | 		dispatch_dbus(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void free_workspaces(list_t *workspaces) { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	for (i = 0; i < workspaces->length; ++i) { | 
					
						
							|  |  |  | 		struct workspace *ws = workspaces->items[i]; | 
					
						
							|  |  |  | 		free(ws->name); | 
					
						
							|  |  |  | 		free(ws); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	list_free(workspaces); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_output(struct output *output) { | 
					
						
							|  |  |  | 	window_teardown(output->window); | 
					
						
							|  |  |  | 	if (output->registry) { | 
					
						
							|  |  |  | 		registry_teardown(output->registry); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	free(output->name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (output->workspaces) { | 
					
						
							|  |  |  | 		free_workspaces(output->workspaces); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	free(output); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 17:27:17 +01:00
										 |  |  | static void free_outputs(list_t *outputs) { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	for (i = 0; i < outputs->length; ++i) { | 
					
						
							|  |  |  | 		free_output(outputs->items[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	list_free(outputs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | static void terminate_status_command(pid_t pid) { | 
					
						
							|  |  |  | 	if (pid) { | 
					
						
							|  |  |  | 		// terminate status_command process
 | 
					
						
							| 
									
										
										
										
											2017-06-29 13:22:54 -04:00
										 |  |  | 		int ret = kill(pid, SIGTERM); | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 		if (ret != 0) { | 
					
						
							|  |  |  | 			sway_log(L_ERROR, "Unable to terminate status_command [pid: %d]", pid); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			int status; | 
					
						
							|  |  |  | 			waitpid(pid, &status, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void bar_teardown(struct bar *bar) { | 
					
						
							| 
									
										
										
										
											2016-03-31 20:50:07 +11:00
										 |  |  | 	if (bar->config) { | 
					
						
							|  |  |  | 		free_config(bar->config); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bar->outputs) { | 
					
						
							|  |  |  | 		free_outputs(bar->outputs); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bar->status) { | 
					
						
							|  |  |  | 		free_status_line(bar->status); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* close sockets/pipes */ | 
					
						
							|  |  |  | 	if (bar->status_read_fd) { | 
					
						
							|  |  |  | 		close(bar->status_read_fd); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-29 11:19:43 +02:00
										 |  |  | 	if (bar->status_write_fd) { | 
					
						
							|  |  |  | 		close(bar->status_write_fd); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 02:34:20 +01:00
										 |  |  | 	if (bar->ipc_socketfd) { | 
					
						
							|  |  |  | 		close(bar->ipc_socketfd); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bar->ipc_event_socketfd) { | 
					
						
							|  |  |  | 		close(bar->ipc_event_socketfd); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* terminate status command process */ | 
					
						
							|  |  |  | 	terminate_status_command(bar->status_command_pid); | 
					
						
							|  |  |  | } |