mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge pull request #179 from taiyu-len/master
new_workspace null behavior + testmap functions + regex
This commit is contained in:
		
						commit
						9c8f1fb964
					
				
					 12 changed files with 581 additions and 370 deletions
				
			
		| 
						 | 
					@ -3,19 +3,21 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cmd_handler {
 | 
					typedef enum  cmd_status {
 | 
				
			||||||
	char *command;
 | 
					 | 
				
			||||||
	enum  cmd_status {
 | 
					 | 
				
			||||||
	CMD_SUCCESS,
 | 
						CMD_SUCCESS,
 | 
				
			||||||
	CMD_FAILURE,
 | 
						CMD_FAILURE,
 | 
				
			||||||
	CMD_DEFER,
 | 
						CMD_DEFER,
 | 
				
			||||||
	} (*handle)(int argc, char **argv);
 | 
					} sway_cmd(char *criteria, int argc, char **argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_handler {
 | 
				
			||||||
 | 
						const char*command;
 | 
				
			||||||
 | 
						sway_cmd  *handle;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum cmd_status handle_command(char *command);
 | 
					enum cmd_status handle_command(char *command);
 | 
				
			||||||
// Handles commands during config
 | 
					// Handles commands during config
 | 
				
			||||||
enum cmd_status config_command(char *command);
 | 
					enum cmd_status config_command(char *command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void remove_view_from_scratchpad();
 | 
					void remove_view_from_scratchpad(swayc_t *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,10 @@ bool load_config(const char *file);
 | 
				
			||||||
bool read_config(FILE *file, bool is_active);
 | 
					bool read_config(FILE *file, bool is_active);
 | 
				
			||||||
char *do_var_replacement(char *str);
 | 
					char *do_var_replacement(char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Find workspace_output from config by workspace or output name
 | 
				
			||||||
 | 
					struct workspace_output *wsop_find_workspace(const char *);
 | 
				
			||||||
 | 
					struct workspace_output *wsop_find_output(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct sway_config *config;
 | 
					extern struct sway_config *config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,29 +2,25 @@
 | 
				
			||||||
#define _SWAY_CONTAINER_H
 | 
					#define _SWAY_CONTAINER_H
 | 
				
			||||||
#include <wlc/wlc.h>
 | 
					#include <wlc/wlc.h>
 | 
				
			||||||
typedef struct sway_container swayc_t;
 | 
					typedef struct sway_container swayc_t;
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "layout.h"
 | 
					#include "layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum swayc_types{
 | 
					enum swayc_types {
 | 
				
			||||||
	C_ROOT,
 | 
						C_ROOT      = 1 << 0,
 | 
				
			||||||
	C_OUTPUT,
 | 
						C_OUTPUT    = 1 << 1,
 | 
				
			||||||
	C_WORKSPACE,
 | 
						C_WORKSPACE = 1 << 2,
 | 
				
			||||||
	C_CONTAINER,
 | 
						C_CONTAINER = 1 << 3,
 | 
				
			||||||
	C_VIEW,
 | 
						C_VIEW      = 1 << 4,
 | 
				
			||||||
	// Keep last
 | 
						C_TYPES     = 5,
 | 
				
			||||||
	C_TYPES,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum swayc_layouts {
 | 
				
			||||||
enum swayc_layouts{
 | 
						L_NONE     = 1 << 0,
 | 
				
			||||||
	L_NONE,
 | 
						L_HORIZ    = 1 << 1,
 | 
				
			||||||
	L_HORIZ,
 | 
						L_VERT     = 1 << 2,
 | 
				
			||||||
	L_VERT,
 | 
						L_STACKED  = 1 << 3,
 | 
				
			||||||
	L_STACKED,
 | 
						L_TABBED   = 1 << 4,
 | 
				
			||||||
	L_TABBED,
 | 
						L_FLOATING = 1 << 5,
 | 
				
			||||||
	L_FLOATING,
 | 
						L_LAYOUTS  = 6,
 | 
				
			||||||
	// Keep last
 | 
					 | 
				
			||||||
	L_LAYOUTS,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_container {
 | 
					struct sway_container {
 | 
				
			||||||
| 
						 | 
					@ -35,13 +31,16 @@ struct sway_container {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Not including borders or margins
 | 
						// Not including borders or margins
 | 
				
			||||||
	double width, height;
 | 
						double width, height;
 | 
				
			||||||
 | 
						double x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Used for setting floating geometry
 | 
						// Used for setting floating geometry
 | 
				
			||||||
	int desired_width, desired_height;
 | 
						int desired_width, desired_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double x, y;
 | 
						enum visibility_mask {
 | 
				
			||||||
 | 
							INVISIBLE = false,
 | 
				
			||||||
 | 
							VISIBLE = true,
 | 
				
			||||||
 | 
						} visible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool visible;
 | 
					 | 
				
			||||||
	bool is_floating;
 | 
						bool is_floating;
 | 
				
			||||||
	bool is_focused;
 | 
						bool is_focused;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,70 +55,120 @@ struct sway_container {
 | 
				
			||||||
	struct sway_container *focused;
 | 
						struct sway_container *focused;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum visibility_mask {
 | 
					// swayc Creation
 | 
				
			||||||
	VISIBLE = 1
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Container Creation
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Creates and returns new, or an already created output.
 | 
				
			||||||
 | 
					 * If it creates a new output, it also creates a workspace using
 | 
				
			||||||
 | 
					 * `new_workspace(outputname, NULL);` */
 | 
				
			||||||
swayc_t *new_output(wlc_handle handle);
 | 
					swayc_t *new_output(wlc_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Creates workspace with given name, under given output.
 | 
				
			||||||
 | 
					 * If workspace with that name already exists, returns that workspace
 | 
				
			||||||
 | 
					 * If name is NULL, it will choose a name automatically.
 | 
				
			||||||
 | 
					 * If output is NULL, it will choose an output automatically. */
 | 
				
			||||||
swayc_t *new_workspace(swayc_t *output, const char *name);
 | 
					swayc_t *new_workspace(swayc_t *output, const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Creates container Around child (parent child) -> (parent (container child))
 | 
					// Creates container Around child (parent child) -> (parent (container child))
 | 
				
			||||||
swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
 | 
					swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Creates view as a sibling of current focused container, or as child of a workspace
 | 
					// Creates view as a sibling of current focused container, or as child of a workspace
 | 
				
			||||||
swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
 | 
					swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Creates view as a new floating view which is in the active workspace
 | 
					// Creates view as a new floating view which is in the active workspace
 | 
				
			||||||
swayc_t *new_floating_view(wlc_handle handle);
 | 
					swayc_t *new_floating_view(wlc_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Container Destroying
 | 
					// Container Destroying
 | 
				
			||||||
 | 
					// Destroys output and moves workspaces to another output
 | 
				
			||||||
swayc_t *destroy_output(swayc_t *output);
 | 
					swayc_t *destroy_output(swayc_t *output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Destroys workspace if empty and returns parent pointer, else returns NULL
 | 
					// Destroys workspace if empty and returns parent pointer, else returns NULL
 | 
				
			||||||
swayc_t *destroy_workspace(swayc_t *workspace);
 | 
					swayc_t *destroy_workspace(swayc_t *workspace);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Destroyes container and all parent container if they are empty, returns
 | 
					// Destroyes container and all parent container if they are empty, returns
 | 
				
			||||||
// topmost non-empty parent. returns NULL otherwise
 | 
					// topmost non-empty parent. returns NULL otherwise
 | 
				
			||||||
swayc_t *destroy_container(swayc_t *container);
 | 
					swayc_t *destroy_container(swayc_t *container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Destroys view and all empty parent containers. return topmost non-empty
 | 
					// Destroys view and all empty parent containers. return topmost non-empty
 | 
				
			||||||
// parent
 | 
					// parent
 | 
				
			||||||
swayc_t *destroy_view(swayc_t *view);
 | 
					swayc_t *destroy_view(swayc_t *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Container Lookup
 | 
					// Container Mapping and testing functions
 | 
				
			||||||
 | 
					typedef bool swayc_test_func(swayc_t *view, void *data);
 | 
				
			||||||
 | 
					typedef void swayc_map_func(swayc_t *view, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns the first swayc that matches test()
 | 
				
			||||||
 | 
					swayc_t *swayc_by_test_r(swayc_t *root, swayc_test_func test, void *data);
 | 
				
			||||||
 | 
					swayc_t *swayc_by_test(swayc_test_func test, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Calls func for all children.
 | 
				
			||||||
 | 
					void swayc_map_r(swayc_t *root, swayc_map_func func, void *data);
 | 
				
			||||||
 | 
					void swayc_map(swayc_map_func func, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Call func on container if test passes
 | 
				
			||||||
 | 
					void swayc_map_by_test_r(swayc_t *root,
 | 
				
			||||||
 | 
							swayc_map_func func, swayc_test_func test,
 | 
				
			||||||
 | 
							void *funcdata, void *testdata);
 | 
				
			||||||
 | 
					void swayc_map_by_test(
 | 
				
			||||||
 | 
							swayc_map_func func, swayc_test_func test,
 | 
				
			||||||
 | 
							void *funcdata, void *testdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Map functions
 | 
				
			||||||
 | 
					swayc_map_func set_gaps;
 | 
				
			||||||
 | 
					swayc_map_func add_gaps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Test functions
 | 
				
			||||||
 | 
					// generic swayc tests
 | 
				
			||||||
 | 
					swayc_test_func test_name;
 | 
				
			||||||
 | 
					swayc_test_func test_name_regex;
 | 
				
			||||||
 | 
					swayc_test_func test_layout;
 | 
				
			||||||
 | 
					swayc_test_func test_type;
 | 
				
			||||||
 | 
					swayc_test_func test_visibility;
 | 
				
			||||||
 | 
					swayc_test_func test_handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// C_VIEW tests
 | 
				
			||||||
 | 
					// See wlc_view_*_bit enums
 | 
				
			||||||
 | 
					swayc_test_func test_view_state;
 | 
				
			||||||
 | 
					swayc_test_func test_view_type;
 | 
				
			||||||
 | 
					swayc_test_func test_view_title;
 | 
				
			||||||
 | 
					swayc_test_func test_view_class;
 | 
				
			||||||
 | 
					swayc_test_func test_view_appid;
 | 
				
			||||||
 | 
					swayc_test_func test_view_title_regex;
 | 
				
			||||||
 | 
					swayc_test_func test_view_class_regex;
 | 
				
			||||||
 | 
					swayc_test_func test_view_appid_regex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// functions for test_*_regex
 | 
				
			||||||
 | 
					void *compile_regex(const char *regex);
 | 
				
			||||||
 | 
					void free_regex(void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// these take a NULL terminated array of test_list struct.
 | 
				
			||||||
 | 
					struct test_list { swayc_test_func *test; void *data ; };
 | 
				
			||||||
 | 
					swayc_test_func test_and;
 | 
				
			||||||
 | 
					swayc_test_func test_or;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
 | 
					 | 
				
			||||||
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
 | 
					swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
 | 
				
			||||||
swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
 | 
					swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
 | 
				
			||||||
// Follow focused until type/layout
 | 
					// Follow focused until type/layout
 | 
				
			||||||
swayc_t *swayc_focus_by_type(swayc_t *container, enum swayc_types);
 | 
					swayc_t *swayc_focus_by_type(swayc_t *container, enum swayc_types);
 | 
				
			||||||
swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts);
 | 
					swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
swayc_t *swayc_by_handle(wlc_handle handle);
 | 
					 | 
				
			||||||
swayc_t *swayc_by_name(const char *name);
 | 
					 | 
				
			||||||
swayc_t *swayc_active_output(void);
 | 
					swayc_t *swayc_active_output(void);
 | 
				
			||||||
swayc_t *swayc_active_workspace(void);
 | 
					swayc_t *swayc_active_workspace(void);
 | 
				
			||||||
swayc_t *swayc_active_workspace_for(swayc_t *view);
 | 
					swayc_t *swayc_active_workspace_for(swayc_t *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Container information
 | 
					// Container information
 | 
				
			||||||
 | 
					// if `parent` is the parent of `child`
 | 
				
			||||||
bool swayc_is_fullscreen(swayc_t *view);
 | 
					 | 
				
			||||||
bool swayc_is_active(swayc_t *view);
 | 
					 | 
				
			||||||
// Is `parent` the parent of `child`
 | 
					 | 
				
			||||||
bool swayc_is_parent_of(swayc_t *parent, swayc_t *child);
 | 
					bool swayc_is_parent_of(swayc_t *parent, swayc_t *child);
 | 
				
			||||||
// Is `child` a child of `parent`
 | 
					// If `child` is a child of `parent`
 | 
				
			||||||
bool swayc_is_child_of(swayc_t *child, swayc_t *parent);
 | 
					bool swayc_is_child_of(swayc_t *child, swayc_t *parent);
 | 
				
			||||||
// Return gap of specified container
 | 
					// Return gap of specified container
 | 
				
			||||||
int swayc_gap(swayc_t *container);
 | 
					int swayc_gap(swayc_t *container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mapping functions
 | 
					bool swayc_is_fullscreen(swayc_t *view);
 | 
				
			||||||
 | 
					bool swayc_is_active(swayc_t *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Mappings
 | 
					 | 
				
			||||||
void set_view_visibility(swayc_t *view, void *data);
 | 
					 | 
				
			||||||
// Set or add to gaps
 | 
					 | 
				
			||||||
void set_gaps(swayc_t *view, void *amount);
 | 
					 | 
				
			||||||
void add_gaps(swayc_t *view, void *amount);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Specialized mapping functions
 | 
				
			||||||
void update_visibility(swayc_t *container);
 | 
					void update_visibility(swayc_t *container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ void free_argv(int argc, char **argv);
 | 
				
			||||||
char *code_strchr(const char *string, char delimiter);
 | 
					char *code_strchr(const char *string, char delimiter);
 | 
				
			||||||
char *code_strstr(const char *haystack, const char *needle);
 | 
					char *code_strstr(const char *haystack, const char *needle);
 | 
				
			||||||
int unescape_string(char *string);
 | 
					int unescape_string(char *string);
 | 
				
			||||||
char *join_args(char **argv, int argc);
 | 
					char *join_args(int argc, char **argv);
 | 
				
			||||||
char *join_list(list_t *list, char *separator);
 | 
					char *join_list(list_t *list, char *separator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *strdup(const char *);
 | 
					char *strdup(const char *);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,13 +7,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern char *prev_workspace_name;
 | 
					extern char *prev_workspace_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *workspace_next_name(void);
 | 
					// Search for available workspace name on output from config
 | 
				
			||||||
swayc_t *workspace_create(const char*);
 | 
					const char *workspace_output_open_name(swayc_t *output);
 | 
				
			||||||
 | 
					// Search for any available workspace name
 | 
				
			||||||
 | 
					const char *workspace_next_name(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_by_name(const char*);
 | 
					swayc_t *workspace_by_name(const char*);
 | 
				
			||||||
void workspace_switch(swayc_t*);
 | 
					void workspace_switch(swayc_t*);
 | 
				
			||||||
swayc_t *workspace_output_next();
 | 
					swayc_t *workspace_output_next(void);
 | 
				
			||||||
swayc_t *workspace_next();
 | 
					swayc_t *workspace_next(void);
 | 
				
			||||||
swayc_t *workspace_output_prev();
 | 
					swayc_t *workspace_output_prev(void);
 | 
				
			||||||
swayc_t *workspace_prev();
 | 
					swayc_t *workspace_prev(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										167
									
								
								sway/commands.c
									
										
									
									
									
								
							
							
						
						
									
										167
									
								
								sway/commands.c
									
										
									
									
									
								
							| 
						 | 
					@ -21,6 +21,35 @@
 | 
				
			||||||
swayc_t *sp_view;
 | 
					swayc_t *sp_view;
 | 
				
			||||||
int sp_index = 0;
 | 
					int sp_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Commands
 | 
				
			||||||
 | 
					static sway_cmd cmd_bindsym;
 | 
				
			||||||
 | 
					static sway_cmd cmd_orientation;
 | 
				
			||||||
 | 
					static sway_cmd cmd_exec;
 | 
				
			||||||
 | 
					static sway_cmd cmd_exec_always;
 | 
				
			||||||
 | 
					static sway_cmd cmd_exit;
 | 
				
			||||||
 | 
					static sway_cmd cmd_floating;
 | 
				
			||||||
 | 
					static sway_cmd cmd_floating_mod;
 | 
				
			||||||
 | 
					static sway_cmd cmd_focus;
 | 
				
			||||||
 | 
					static sway_cmd cmd_focus_follows_mouse;
 | 
				
			||||||
 | 
					static sway_cmd cmd_for_window;
 | 
				
			||||||
 | 
					static sway_cmd cmd_fullscreen;
 | 
				
			||||||
 | 
					static sway_cmd cmd_gaps;
 | 
				
			||||||
 | 
					static sway_cmd cmd_kill;
 | 
				
			||||||
 | 
					static sway_cmd cmd_layout;
 | 
				
			||||||
 | 
					static sway_cmd cmd_log_colors;
 | 
				
			||||||
 | 
					static sway_cmd cmd_mode;
 | 
				
			||||||
 | 
					static sway_cmd cmd_move;
 | 
				
			||||||
 | 
					static sway_cmd cmd_output;
 | 
				
			||||||
 | 
					static sway_cmd cmd_reload;
 | 
				
			||||||
 | 
					static sway_cmd cmd_resize;
 | 
				
			||||||
 | 
					static sway_cmd cmd_scratchpad;
 | 
				
			||||||
 | 
					static sway_cmd cmd_set;
 | 
				
			||||||
 | 
					static sway_cmd cmd_split;
 | 
				
			||||||
 | 
					static sway_cmd cmd_splith;
 | 
				
			||||||
 | 
					static sway_cmd cmd_splitv;
 | 
				
			||||||
 | 
					static sway_cmd cmd_workspace;
 | 
				
			||||||
 | 
					static sway_cmd cmd_ws_auto_back_and_forth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct modifier_key {
 | 
					static struct modifier_key {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
	uint32_t mod;
 | 
						uint32_t mod;
 | 
				
			||||||
| 
						 | 
					@ -94,7 +123,7 @@ static int bindsym_sort(const void *_lbind, const void *_rbind) {
 | 
				
			||||||
	return (rbind->keys->length + rmod) - (lbind->keys->length + lmod);
 | 
						return (rbind->keys->length + rmod) - (lbind->keys->length + lmod);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_bindsym(int argc, char **argv) {
 | 
					enum cmd_status cmd_bindsym(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)
 | 
						if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)
 | 
				
			||||||
			|| !config->reading) {
 | 
								|| !config->reading) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -103,7 +132,7 @@ static enum cmd_status cmd_bindsym(int argc, char **argv) {
 | 
				
			||||||
	struct sway_binding *binding = malloc(sizeof(struct sway_binding));
 | 
						struct sway_binding *binding = malloc(sizeof(struct sway_binding));
 | 
				
			||||||
	binding->keys = create_list();
 | 
						binding->keys = create_list();
 | 
				
			||||||
	binding->modifiers = 0;
 | 
						binding->modifiers = 0;
 | 
				
			||||||
	binding->command = join_args(argv + 1, argc - 1);
 | 
						binding->command = join_args(argc - 1, argv + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_t *split = split_string(argv[0], "+");
 | 
						list_t *split = split_string(argv[0], "+");
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -144,7 +173,7 @@ static enum cmd_status cmd_bindsym(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_exec_always(int argc, char **argv) {
 | 
					enum cmd_status cmd_exec_always(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0)) {
 | 
						if (!checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -160,7 +189,7 @@ static enum cmd_status cmd_exec_always(int argc, char **argv) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* Child process */
 | 
						/* Child process */
 | 
				
			||||||
	if (pid == 0) {
 | 
						if (pid == 0) {
 | 
				
			||||||
		char *args = join_args(argv, argc);
 | 
							char *args = join_args(argc, argv);
 | 
				
			||||||
		sway_log(L_DEBUG, "Executing %s", args);
 | 
							sway_log(L_DEBUG, "Executing %s", args);
 | 
				
			||||||
		execl("/bin/sh", "sh", "-c", args, (char *)NULL);
 | 
							execl("/bin/sh", "sh", "-c", args, (char *)NULL);
 | 
				
			||||||
		/* Execl doesnt return unless failure */
 | 
							/* Execl doesnt return unless failure */
 | 
				
			||||||
| 
						 | 
					@ -172,17 +201,17 @@ static enum cmd_status cmd_exec_always(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_exec(int argc, char **argv) {
 | 
					enum cmd_status cmd_exec(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!config->active) {
 | 
						if (!config->active) {
 | 
				
			||||||
		return CMD_DEFER;
 | 
							return CMD_DEFER;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (config->reloading) {
 | 
						if (config->reloading) {
 | 
				
			||||||
		char *args = join_args(argv, argc);
 | 
							char *args = join_args(argc, argv);
 | 
				
			||||||
		sway_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args);
 | 
							sway_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args);
 | 
				
			||||||
		free(args);
 | 
							free(args);
 | 
				
			||||||
		return CMD_SUCCESS;
 | 
							return CMD_SUCCESS;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return cmd_exec_always(argc, argv);
 | 
						return cmd_exec_always(criteria, argc, argv);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void kill_views(swayc_t *container, void *data) {
 | 
					static void kill_views(swayc_t *container, void *data) {
 | 
				
			||||||
| 
						 | 
					@ -191,18 +220,19 @@ static void kill_views(swayc_t *container, void *data) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_exit(int argc, char **argv) {
 | 
					enum cmd_status cmd_exit(char *criteria, int argc, char **argv) {
 | 
				
			||||||
 | 
						(void) argv;
 | 
				
			||||||
	if (!checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0)
 | 
						if (!checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Close all views
 | 
						// Close all views
 | 
				
			||||||
	container_map(&root_container, kill_views, NULL);
 | 
						swayc_map(kill_views, NULL);
 | 
				
			||||||
	sway_terminate();
 | 
						sway_terminate();
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_floating(int argc, char **argv) {
 | 
					enum cmd_status cmd_floating(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -264,7 +294,7 @@ static enum cmd_status cmd_floating(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_floating_mod(int argc, char **argv) {
 | 
					enum cmd_status cmd_floating_mod(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| !config->reading) {
 | 
								|| !config->reading) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -289,7 +319,7 @@ static enum cmd_status cmd_floating_mod(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_focus(int argc, char **argv) {
 | 
					enum cmd_status cmd_focus(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	static int floating_toggled_index = 0;
 | 
						static int floating_toggled_index = 0;
 | 
				
			||||||
	static int tiled_toggled_index = 0;
 | 
						static int tiled_toggled_index = 0;
 | 
				
			||||||
	if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
| 
						 | 
					@ -347,7 +377,7 @@ static enum cmd_status cmd_focus(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_focus_follows_mouse(int argc, char **argv) {
 | 
					enum cmd_status cmd_focus_follows_mouse(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1)) {
 | 
						if (!checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -356,6 +386,21 @@ static enum cmd_status cmd_focus_follows_mouse(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void debug_for_window(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						layout_log(view, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum cmd_status cmd_for_window(char *criteria, int argc, char **argv) {
 | 
				
			||||||
 | 
						if (!checkarg(argc, "for_window", EXPECTED_AT_LEAST, 1)) {
 | 
				
			||||||
 | 
							return CMD_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//TODO
 | 
				
			||||||
 | 
						void *re = compile_regex(argv[0]);
 | 
				
			||||||
 | 
						swayc_map_by_test(debug_for_window, test_view_title_regex, NULL, re);
 | 
				
			||||||
 | 
						free_regex(re);
 | 
				
			||||||
 | 
						return CMD_FAILURE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hide_view_in_scratchpad(swayc_t *sp_view) {
 | 
					static void hide_view_in_scratchpad(swayc_t *sp_view) {
 | 
				
			||||||
	if(sp_view == NULL) {
 | 
						if(sp_view == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -372,7 +417,7 @@ static void hide_view_in_scratchpad(swayc_t *sp_view) {
 | 
				
			||||||
	set_focused_container(container_under_pointer());
 | 
						set_focused_container(container_under_pointer());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_mode(int argc, char **argv) {
 | 
					enum cmd_status cmd_mode(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) {
 | 
						if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -381,7 +426,7 @@ static enum cmd_status cmd_mode(int argc, char **argv) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *mode_name = join_args(argv, argc - mode_make);
 | 
						char *mode_name = join_args(argc - mode_make, argv);
 | 
				
			||||||
	struct sway_mode *mode = NULL;
 | 
						struct sway_mode *mode = NULL;
 | 
				
			||||||
	// Find mode
 | 
						// Find mode
 | 
				
			||||||
	int i, len = config->modes->length;
 | 
						int i, len = config->modes->length;
 | 
				
			||||||
| 
						 | 
					@ -411,7 +456,7 @@ static enum cmd_status cmd_mode(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_move(int argc, char **argv) {
 | 
					enum cmd_status cmd_move(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)
 | 
						if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -444,11 +489,7 @@ static enum cmd_status cmd_move(int argc, char **argv) {
 | 
				
			||||||
			// move "container to workspace number x"
 | 
								// move "container to workspace number x"
 | 
				
			||||||
			ws_name = argv[4];
 | 
								ws_name = argv[4];
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							swayc_t *ws = new_workspace(NULL, ws_name);
 | 
				
			||||||
		swayc_t *ws = workspace_by_name(ws_name);
 | 
					 | 
				
			||||||
		if (ws == NULL) {
 | 
					 | 
				
			||||||
			ws = workspace_create(ws_name);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		move_container_to(view, get_focused_container(ws));
 | 
							move_container_to(view, get_focused_container(ws));
 | 
				
			||||||
	} else if (strcasecmp(argv[0], "scratchpad") == 0) {
 | 
						} else if (strcasecmp(argv[0], "scratchpad") == 0) {
 | 
				
			||||||
		if (view->type != C_CONTAINER && view->type != C_VIEW) {
 | 
							if (view->type != C_CONTAINER && view->type != C_VIEW) {
 | 
				
			||||||
| 
						 | 
					@ -482,7 +523,7 @@ static enum cmd_status cmd_move(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_orientation(int argc, char **argv) {
 | 
					enum cmd_status cmd_orientation(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "orientation", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "orientation", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| !config->reading) {
 | 
								|| !config->reading) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -499,7 +540,7 @@ static enum cmd_status cmd_orientation(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_output(int argc, char **argv) {
 | 
					enum cmd_status cmd_output(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) {
 | 
						if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -564,7 +605,7 @@ static enum cmd_status cmd_output(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_gaps(int argc, char **argv) {
 | 
					enum cmd_status cmd_gaps(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) {
 | 
						if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -698,15 +739,14 @@ static enum cmd_status cmd_gaps(int argc, char **argv) {
 | 
				
			||||||
			top = &root_container;
 | 
								top = &root_container;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		int top_gap = top->gaps;
 | 
							int top_gap = top->gaps;
 | 
				
			||||||
		container_map(top, method == SET ? set_gaps : add_gaps, &amount);
 | 
							swayc_map_r(top, method == SET ? set_gaps : add_gaps, &amount);
 | 
				
			||||||
		top->gaps = top_gap;
 | 
							top->gaps = top_gap;
 | 
				
			||||||
		arrange_windows(top, -1, -1);
 | 
							arrange_windows(top, -1, -1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_kill(int argc, char **argv) {
 | 
					enum cmd_status cmd_kill(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (config->reading || !config->active) {
 | 
						if (config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -715,7 +755,7 @@ static enum cmd_status cmd_kill(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_layout(int argc, char **argv) {
 | 
					enum cmd_status cmd_layout(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "layout", EXPECTED_MORE_THAN, 0)
 | 
						if (!checkarg(argc, "layout", EXPECTED_MORE_THAN, 0)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -741,7 +781,7 @@ static enum cmd_status cmd_layout(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_reload(int argc, char **argv) {
 | 
					enum cmd_status cmd_reload(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)
 | 
						if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)
 | 
				
			||||||
			|| config->reading
 | 
								|| config->reading
 | 
				
			||||||
			|| !load_config(NULL)) {
 | 
								|| !load_config(NULL)) {
 | 
				
			||||||
| 
						 | 
					@ -751,7 +791,7 @@ static enum cmd_status cmd_reload(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_resize(int argc, char **argv) {
 | 
					enum cmd_status cmd_resize(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)
 | 
						if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -781,7 +821,7 @@ static enum cmd_status cmd_resize(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static swayc_t *fetch_view_from_scratchpad() {
 | 
					static swayc_t *fetch_view_from_scratchpad(void) {
 | 
				
			||||||
	if (sp_index >= scratchpad->length) {
 | 
						if (sp_index >= scratchpad->length) {
 | 
				
			||||||
		sp_index = 0;
 | 
							sp_index = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -826,7 +866,7 @@ void remove_view_from_scratchpad(swayc_t *view) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_scratchpad(int argc, char **argv) {
 | 
					enum cmd_status cmd_scratchpad(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -860,7 +900,7 @@ static int compare_set(const void *_l, const void *_r) {
 | 
				
			||||||
	return strlen((*r)->name) - strlen((*l)->name);
 | 
						return strlen((*r)->name) - strlen((*l)->name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_set(int argc, char **argv) {
 | 
					enum cmd_status cmd_set(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "set", EXPECTED_AT_LEAST, 2)
 | 
						if (!checkarg(argc, "set", EXPECTED_AT_LEAST, 2)
 | 
				
			||||||
			|| !config->reading) {
 | 
								|| !config->reading) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -883,11 +923,11 @@ static enum cmd_status cmd_set(int argc, char **argv) {
 | 
				
			||||||
		list_add(config->symbols, var);
 | 
							list_add(config->symbols, var);
 | 
				
			||||||
		list_sort(config->symbols, compare_set);
 | 
							list_sort(config->symbols, compare_set);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var->value = join_args(argv + 1, argc - 1);
 | 
						var->value = join_args(argc - 1, argv + 1);
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status _do_split(int argc, char **argv, int layout) {
 | 
					static enum cmd_status _do_split(char *criteria, int argc, char **argv, int layout) {
 | 
				
			||||||
	char *name = layout == L_VERT  ? "splitv" :
 | 
						char *name = layout == L_VERT  ? "splitv" :
 | 
				
			||||||
		layout == L_HORIZ ? "splith" : "split";
 | 
							layout == L_HORIZ ? "splith" : "split";
 | 
				
			||||||
	if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)
 | 
						if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)
 | 
				
			||||||
| 
						 | 
					@ -919,16 +959,16 @@ static enum cmd_status _do_split(int argc, char **argv, int layout) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_split(int argc, char **argv) {
 | 
					enum cmd_status cmd_split(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "split", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "split", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) {
 | 
						if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) {
 | 
				
			||||||
		_do_split(argc - 1, argv + 1, L_VERT);
 | 
							_do_split(criteria, argc - 1, argv + 1, L_VERT);
 | 
				
			||||||
	} else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) {
 | 
						} else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) {
 | 
				
			||||||
		_do_split(argc - 1, argv + 1, L_HORIZ);
 | 
							_do_split(criteria, argc - 1, argv + 1, L_HORIZ);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical).");
 | 
							sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical).");
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -936,15 +976,15 @@ static enum cmd_status cmd_split(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_splitv(int argc, char **argv) {
 | 
					enum cmd_status cmd_splitv(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	return _do_split(argc, argv, L_VERT);
 | 
						return _do_split(criteria, argc, argv, L_VERT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_splith(int argc, char **argv) {
 | 
					enum cmd_status cmd_splith(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	return _do_split(argc, argv, L_HORIZ);
 | 
						return _do_split(criteria, argc, argv, L_HORIZ);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_log_colors(int argc, char **argv) {
 | 
					enum cmd_status cmd_log_colors(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1)
 | 
						if (!checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1)
 | 
				
			||||||
			|| !config->reading) {
 | 
								|| !config->reading) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -960,7 +1000,7 @@ static enum cmd_status cmd_log_colors(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_fullscreen(int argc, char **argv) {
 | 
					enum cmd_status cmd_fullscreen(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0)
 | 
						if (!checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0)
 | 
				
			||||||
			|| config->reading || !config->active) {
 | 
								|| config->reading || !config->active) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
| 
						 | 
					@ -980,7 +1020,7 @@ static enum cmd_status cmd_fullscreen(int argc, char **argv) {
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_workspace(int argc, char **argv) {
 | 
					enum cmd_status cmd_workspace(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1)) {
 | 
						if (!checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -989,28 +1029,7 @@ static enum cmd_status cmd_workspace(int argc, char **argv) {
 | 
				
			||||||
		if (config->reading || !config->active) {
 | 
							if (config->reading || !config->active) {
 | 
				
			||||||
			return CMD_DEFER;
 | 
								return CMD_DEFER;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Handle workspace next/prev
 | 
							workspace_switch(new_workspace(NULL, argv[0]));
 | 
				
			||||||
		swayc_t *ws = NULL;
 | 
					 | 
				
			||||||
		if (strcasecmp(argv[0], "next") == 0) {
 | 
					 | 
				
			||||||
			ws = workspace_next();
 | 
					 | 
				
			||||||
		} else if (strcasecmp(argv[0], "prev") == 0) {
 | 
					 | 
				
			||||||
			ws = workspace_prev();
 | 
					 | 
				
			||||||
		} else if (strcasecmp(argv[0], "next_on_output") == 0) {
 | 
					 | 
				
			||||||
			ws = workspace_output_next();
 | 
					 | 
				
			||||||
		} else if (strcasecmp(argv[0], "prev_on_output") == 0) {
 | 
					 | 
				
			||||||
			ws = workspace_output_prev();
 | 
					 | 
				
			||||||
		} else if (strcasecmp(argv[0], "back_and_forth") == 0) {
 | 
					 | 
				
			||||||
			if (prev_workspace_name) {
 | 
					 | 
				
			||||||
				if (!(ws = workspace_by_name(prev_workspace_name))) {
 | 
					 | 
				
			||||||
					ws = workspace_create(prev_workspace_name);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if (!(ws= workspace_by_name(argv[0]))) {
 | 
					 | 
				
			||||||
				ws = workspace_create(argv[0]);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		workspace_switch(ws);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (strcasecmp(argv[1], "output") == 0) {
 | 
							if (strcasecmp(argv[1], "output") == 0) {
 | 
				
			||||||
			if (!checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3)) {
 | 
								if (!checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3)) {
 | 
				
			||||||
| 
						 | 
					@ -1021,15 +1040,12 @@ static enum cmd_status cmd_workspace(int argc, char **argv) {
 | 
				
			||||||
			wso->workspace = strdup(argv[0]);
 | 
								wso->workspace = strdup(argv[0]);
 | 
				
			||||||
			wso->output = strdup(argv[2]);
 | 
								wso->output = strdup(argv[2]);
 | 
				
			||||||
			list_add(config->workspace_outputs, wso);
 | 
								list_add(config->workspace_outputs, wso);
 | 
				
			||||||
			if (!config->reading) {
 | 
					 | 
				
			||||||
				// TODO: Move workspace to output. (dont do so when reloading)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return CMD_SUCCESS;
 | 
						return CMD_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum cmd_status cmd_ws_auto_back_and_forth(int argc, char **argv) {
 | 
					enum cmd_status cmd_ws_auto_back_and_forth(char *criteria, int argc, char **argv) {
 | 
				
			||||||
	if (!checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1)) {
 | 
						if (!checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1)) {
 | 
				
			||||||
		return CMD_FAILURE;
 | 
							return CMD_FAILURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1044,7 +1060,7 @@ static enum cmd_status cmd_ws_auto_back_and_forth(int argc, char **argv) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Keep alphabetized */
 | 
					/* Keep alphabetized */
 | 
				
			||||||
static struct cmd_handler handlers[] = {
 | 
					static const struct cmd_handler handlers[] = {
 | 
				
			||||||
	{ "bindsym", cmd_bindsym },
 | 
						{ "bindsym", cmd_bindsym },
 | 
				
			||||||
	{ "default_orientation", cmd_orientation },
 | 
						{ "default_orientation", cmd_orientation },
 | 
				
			||||||
	{ "exec", cmd_exec },
 | 
						{ "exec", cmd_exec },
 | 
				
			||||||
| 
						 | 
					@ -1054,6 +1070,7 @@ static struct cmd_handler handlers[] = {
 | 
				
			||||||
	{ "floating_modifier", cmd_floating_mod },
 | 
						{ "floating_modifier", cmd_floating_mod },
 | 
				
			||||||
	{ "focus", cmd_focus },
 | 
						{ "focus", cmd_focus },
 | 
				
			||||||
	{ "focus_follows_mouse", cmd_focus_follows_mouse },
 | 
						{ "focus_follows_mouse", cmd_focus_follows_mouse },
 | 
				
			||||||
 | 
						{ "for_window", cmd_for_window },
 | 
				
			||||||
	{ "fullscreen", cmd_fullscreen },
 | 
						{ "fullscreen", cmd_fullscreen },
 | 
				
			||||||
	{ "gaps", cmd_gaps },
 | 
						{ "gaps", cmd_gaps },
 | 
				
			||||||
	{ "kill", cmd_kill },
 | 
						{ "kill", cmd_kill },
 | 
				
			||||||
| 
						 | 
					@ -1090,6 +1107,7 @@ static struct cmd_handler *find_handler(char *line) {
 | 
				
			||||||
enum cmd_status handle_command(char *exec) {
 | 
					enum cmd_status handle_command(char *exec) {
 | 
				
			||||||
	sway_log(L_INFO, "Handling command '%s'", exec);
 | 
						sway_log(L_INFO, "Handling command '%s'", exec);
 | 
				
			||||||
	int argc;
 | 
						int argc;
 | 
				
			||||||
 | 
						char *criteria = NULL;
 | 
				
			||||||
	char **argv = split_args(exec, &argc);
 | 
						char **argv = split_args(exec, &argc);
 | 
				
			||||||
	enum cmd_status status = CMD_FAILURE;
 | 
						enum cmd_status status = CMD_FAILURE;
 | 
				
			||||||
	struct cmd_handler *handler;
 | 
						struct cmd_handler *handler;
 | 
				
			||||||
| 
						 | 
					@ -1097,7 +1115,7 @@ enum cmd_status handle_command(char *exec) {
 | 
				
			||||||
		return status;
 | 
							return status;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ((handler = find_handler(argv[0])) == NULL
 | 
						if ((handler = find_handler(argv[0])) == NULL
 | 
				
			||||||
			|| (status = handler->handle(argc - 1, argv + 1)) != CMD_SUCCESS) {
 | 
								|| (status = handler->handle(criteria, argc - 1, argv + 1)) != CMD_SUCCESS) {
 | 
				
			||||||
		sway_log(L_ERROR, "Command failed: %s", argv[0]);
 | 
							sway_log(L_ERROR, "Command failed: %s", argv[0]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free_argv(argc, argv);
 | 
						free_argv(argc, argv);
 | 
				
			||||||
| 
						 | 
					@ -1108,6 +1126,7 @@ enum cmd_status config_command(char *exec) {
 | 
				
			||||||
	sway_log(L_INFO, "handling config command '%s'", exec);
 | 
						sway_log(L_INFO, "handling config command '%s'", exec);
 | 
				
			||||||
	int argc;
 | 
						int argc;
 | 
				
			||||||
	char **argv = split_args(exec, &argc);
 | 
						char **argv = split_args(exec, &argc);
 | 
				
			||||||
 | 
						char *criteria = NULL;
 | 
				
			||||||
	enum cmd_status status = CMD_FAILURE;
 | 
						enum cmd_status status = CMD_FAILURE;
 | 
				
			||||||
	struct cmd_handler *handler;
 | 
						struct cmd_handler *handler;
 | 
				
			||||||
	if (!argc) {
 | 
						if (!argc) {
 | 
				
			||||||
| 
						 | 
					@ -1127,7 +1146,7 @@ enum cmd_status config_command(char *exec) {
 | 
				
			||||||
		for (; i < e; ++i) {
 | 
							for (; i < e; ++i) {
 | 
				
			||||||
			argv[i] = do_var_replacement(argv[i]);
 | 
								argv[i] = do_var_replacement(argv[i]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		status = handler->handle(argc - 1, argv + 1);
 | 
							status = handler->handle(criteria, argc - 1, argv + 1);
 | 
				
			||||||
		if (status == CMD_FAILURE) {
 | 
							if (status == CMD_FAILURE) {
 | 
				
			||||||
			sway_log(L_ERROR, "Config load failed for line `%s'", exec);
 | 
								sway_log(L_ERROR, "Config load failed for line `%s'", exec);
 | 
				
			||||||
		} else if (status == CMD_DEFER) {
 | 
							} else if (status == CMD_DEFER) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,3 +286,28 @@ char *do_var_replacement(char *str) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct workspace_output *wsop_find_workspace(const char *name) {
 | 
				
			||||||
 | 
						int i, len = config->workspace_outputs->length;
 | 
				
			||||||
 | 
						struct workspace_output *wsop;
 | 
				
			||||||
 | 
						for (i = 0; i < len; ++i) {
 | 
				
			||||||
 | 
							wsop = config->workspace_outputs->items[i];
 | 
				
			||||||
 | 
							if (strcasecmp(wsop->workspace, name) == 0) {
 | 
				
			||||||
 | 
								return wsop;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct workspace_output *wsop_find_output(const char *name) {
 | 
				
			||||||
 | 
						int i, len = config->workspace_outputs->length;
 | 
				
			||||||
 | 
						struct workspace_output *wsop;
 | 
				
			||||||
 | 
						for (i = 0; i < len; ++i) {
 | 
				
			||||||
 | 
							wsop = config->workspace_outputs->items[i];
 | 
				
			||||||
 | 
							if (strcasecmp(wsop->output, name) == 0) {
 | 
				
			||||||
 | 
								return wsop;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										401
									
								
								sway/container.c
									
										
									
									
									
								
							
							
						
						
									
										401
									
								
								sway/container.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <strings.h>
 | 
					#include <strings.h>
 | 
				
			||||||
 | 
					#include <pcre.h>
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "container.h"
 | 
					#include "container.h"
 | 
				
			||||||
#include "workspace.h"
 | 
					#include "workspace.h"
 | 
				
			||||||
| 
						 | 
					@ -53,26 +54,30 @@ static void free_swayc(swayc_t *cont) {
 | 
				
			||||||
// New containers
 | 
					// New containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *new_output(wlc_handle handle) {
 | 
					swayc_t *new_output(wlc_handle handle) {
 | 
				
			||||||
	const struct wlc_size *size = wlc_output_get_resolution(handle);
 | 
					 | 
				
			||||||
	const char *name = wlc_output_get_name(handle);
 | 
						const char *name = wlc_output_get_name(handle);
 | 
				
			||||||
 | 
						int i, len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find current outputs to see if this already exists
 | 
						// Find current outputs to see if this already exists
 | 
				
			||||||
	{
 | 
						if (name) {
 | 
				
			||||||
		int i, len = root_container.children->length;
 | 
							len = root_container.children->length;
 | 
				
			||||||
		for (i = 0; i < len; ++i) {
 | 
							for (i = 0; i < len; ++i) {
 | 
				
			||||||
			swayc_t *op = root_container.children->items[i];
 | 
								swayc_t *op = root_container.children->items[i];
 | 
				
			||||||
			const char *op_name = op->name;
 | 
								if (strcmp(op->name, name) == 0) {
 | 
				
			||||||
			if (op_name && name && strcmp(op_name, name) == 0) {
 | 
									sway_log(L_DEBUG, "restoring output %lu:%s", handle, op->name);
 | 
				
			||||||
				sway_log(L_DEBUG, "restoring output %lu:%s", handle, op_name);
 | 
					 | 
				
			||||||
				return op;
 | 
									return op;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							sway_log(L_ERROR, "Output has no given name");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
 | 
						sway_log(L_DEBUG, "Adding output %lu:%s", handle, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Find output config
 | 
				
			||||||
	struct output_config *oc = NULL;
 | 
						struct output_config *oc = NULL;
 | 
				
			||||||
	int i;
 | 
						len = config->output_configs->length;
 | 
				
			||||||
	for (i = 0; i < config->output_configs->length; ++i) {
 | 
						for (i = 0; i < len; ++i) {
 | 
				
			||||||
		oc = config->output_configs->items[i];
 | 
							oc = config->output_configs->items[i];
 | 
				
			||||||
		if (strcasecmp(name, oc->name) == 0) {
 | 
							if (strcasecmp(name, oc->name) == 0) {
 | 
				
			||||||
			sway_log(L_DEBUG, "Matched output config for %s", name);
 | 
								sway_log(L_DEBUG, "Matched output config for %s", name);
 | 
				
			||||||
| 
						 | 
					@ -86,77 +91,88 @@ swayc_t *new_output(wlc_handle handle) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	swayc_t *output = new_swayc(C_OUTPUT);
 | 
						swayc_t *output = new_swayc(C_OUTPUT);
 | 
				
			||||||
	if (oc && oc->width != -1 && oc->height != -1) {
 | 
					 | 
				
			||||||
		output->width = oc->width;
 | 
					 | 
				
			||||||
		output->height = oc->height;
 | 
					 | 
				
			||||||
		struct wlc_size new_size = { .w = oc->width, .h = oc->height };
 | 
					 | 
				
			||||||
		wlc_output_set_resolution(handle, &new_size);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		output->width = size->w;
 | 
					 | 
				
			||||||
		output->height = size->h;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	output->handle = handle;
 | 
						output->handle = handle;
 | 
				
			||||||
	output->name = name ? strdup(name) : NULL;
 | 
						output->name = name ? strdup(name) : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find position for it
 | 
						if (oc) {
 | 
				
			||||||
	if (oc && oc->x != -1 && oc->y != -1) {
 | 
							// Set output width/height
 | 
				
			||||||
		sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y);
 | 
							if (oc->width > 0 && oc->height > 0) {
 | 
				
			||||||
 | 
								output->width = oc->width;
 | 
				
			||||||
 | 
								output->height = oc->height;
 | 
				
			||||||
 | 
								struct wlc_size geo = { .w = oc->width, .h = oc->height};
 | 
				
			||||||
 | 
								wlc_output_set_resolution(handle, &geo);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								struct wlc_size geo = *wlc_output_get_resolution(handle);
 | 
				
			||||||
 | 
								output->width = geo.w;
 | 
				
			||||||
 | 
								output->height = geo.h;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// find position in config or find where it should go
 | 
				
			||||||
 | 
							// TODO more intelligent method
 | 
				
			||||||
 | 
							if (oc->x > 0 && oc->y > 0) {
 | 
				
			||||||
			output->x = oc->x;
 | 
								output->x = oc->x;
 | 
				
			||||||
			output->y = oc->y;
 | 
								output->y = oc->y;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
		int x = 0;
 | 
								unsigned int x = 0;
 | 
				
			||||||
		for (i = 0; i < root_container.children->length; ++i) {
 | 
								len = root_container.children->length;
 | 
				
			||||||
 | 
								for (i = 0; i < len; ++i) {
 | 
				
			||||||
				swayc_t *c = root_container.children->items[i];
 | 
									swayc_t *c = root_container.children->items[i];
 | 
				
			||||||
				if (c->type == C_OUTPUT) {
 | 
									if (c->type == C_OUTPUT) {
 | 
				
			||||||
				if (c->width + c->x > x) {
 | 
										unsigned int cx = c->width + c->x;
 | 
				
			||||||
					x = c->width + c->x;
 | 
										if (cx > x) {
 | 
				
			||||||
 | 
											x = cx;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			output->x = x;
 | 
								output->x = x;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Add as child to root
 | 
				
			||||||
	add_child(&root_container, output);
 | 
						add_child(&root_container, output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create workspace
 | 
					 | 
				
			||||||
	char *ws_name = NULL;
 | 
					 | 
				
			||||||
	if (name) {
 | 
					 | 
				
			||||||
		for (i = 0; i < config->workspace_outputs->length; ++i) {
 | 
					 | 
				
			||||||
			struct workspace_output *wso = config->workspace_outputs->items[i];
 | 
					 | 
				
			||||||
			if (strcasecmp(wso->output, name) == 0) {
 | 
					 | 
				
			||||||
				sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output);
 | 
					 | 
				
			||||||
				// Check if any other workspaces are using this name
 | 
					 | 
				
			||||||
				if (workspace_by_name(wso->workspace)) {
 | 
					 | 
				
			||||||
					sway_log(L_DEBUG, "But it's already taken");
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				sway_log(L_DEBUG, "So we're going to use it");
 | 
					 | 
				
			||||||
				ws_name = strdup(wso->workspace);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!ws_name) {
 | 
					 | 
				
			||||||
		ws_name = workspace_next_name();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// create and initilize default workspace
 | 
						// create and initilize default workspace
 | 
				
			||||||
	swayc_t *ws = new_workspace(output, ws_name);
 | 
						swayc_t *ws = new_workspace(output, NULL);
 | 
				
			||||||
	ws->is_focused = true;
 | 
						ws->is_focused = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(ws_name);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	return output;
 | 
						return output;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *new_workspace(swayc_t *output, const char *name) {
 | 
					swayc_t *new_workspace(swayc_t *output, const char *name) {
 | 
				
			||||||
	if (!ASSERT_NONNULL(output)) {
 | 
						swayc_t *ws = NULL;
 | 
				
			||||||
		return NULL;
 | 
						struct workspace_output *wsop;
 | 
				
			||||||
 | 
						if (name) {
 | 
				
			||||||
 | 
							// Find existing workspace with same name.
 | 
				
			||||||
 | 
							// or workspace found by special name
 | 
				
			||||||
 | 
							if ((ws = workspace_by_name(name))) {
 | 
				
			||||||
 | 
								return ws;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Find matching output from config
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								if ((wsop = wsop_find_workspace(name))) {
 | 
				
			||||||
 | 
									int i, len = root_container.children->length;
 | 
				
			||||||
 | 
									for (i = 0; i < len; ++i) {
 | 
				
			||||||
 | 
										swayc_t *op = root_container.children->items[i];
 | 
				
			||||||
 | 
										if (strcasecmp(op->name, wsop->output) == 0) {
 | 
				
			||||||
 | 
											output = op;
 | 
				
			||||||
 | 
											goto find_wsop_end;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Set output to active_output if there is no output.
 | 
				
			||||||
 | 
								output = swayc_active_output();
 | 
				
			||||||
 | 
								find_wsop_end:;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// No name or output, use active_output
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								output = swayc_active_output();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// search for available output name
 | 
				
			||||||
 | 
							if (!(name = workspace_output_open_name(output))) {
 | 
				
			||||||
 | 
								// otherwise just use simple next name
 | 
				
			||||||
 | 
								name = workspace_next_name();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
 | 
					 | 
				
			||||||
	swayc_t *workspace = new_swayc(C_WORKSPACE);
 | 
						swayc_t *workspace = new_swayc(C_WORKSPACE);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO: default_layout
 | 
					 | 
				
			||||||
	if (config->default_layout != L_NONE) {
 | 
						if (config->default_layout != L_NONE) {
 | 
				
			||||||
		workspace->layout = config->default_layout;
 | 
							workspace->layout = config->default_layout;
 | 
				
			||||||
	} else if (config->default_orientation != L_NONE) {
 | 
						} else if (config->default_orientation != L_NONE) {
 | 
				
			||||||
| 
						 | 
					@ -374,7 +390,7 @@ swayc_t *destroy_view(swayc_t *view) {
 | 
				
			||||||
// Container lookup
 | 
					// Container lookup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
 | 
					swayc_t *swayc_by_test_r(swayc_t *container, swayc_test_func test, void *data) {
 | 
				
			||||||
	if (!container->children) {
 | 
						if (!container->children) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -393,7 +409,7 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat
 | 
				
			||||||
		if (test(child, data)) {
 | 
							if (test(child, data)) {
 | 
				
			||||||
			return child;
 | 
								return child;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			swayc_t *res = swayc_by_test(child, test, data);
 | 
								swayc_t *res = swayc_by_test_r(child, test, data);
 | 
				
			||||||
			if (res) {
 | 
								if (res) {
 | 
				
			||||||
				return res;
 | 
									return res;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -401,17 +417,192 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					swayc_t *swayc_by_test(swayc_test_func test, void *data) {
 | 
				
			||||||
 | 
						return swayc_by_test_r(&root_container, test, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool test_name(swayc_t *view, void *data) {
 | 
					void swayc_map_r(swayc_t *container, swayc_map_func f, void *data) {
 | 
				
			||||||
	if (!view && !view->name) {
 | 
						if (container) {
 | 
				
			||||||
 | 
							f(container, data);
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							if (container->children)  {
 | 
				
			||||||
 | 
								for (i = 0; i < container->children->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *child = container->children->items[i];
 | 
				
			||||||
 | 
									swayc_map_r(child, f, data);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (container->floating) {
 | 
				
			||||||
 | 
								for (i = 0; i < container->floating->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *child = container->floating->items[i];
 | 
				
			||||||
 | 
									swayc_map_r(child, f, data);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void swayc_map(swayc_map_func f, void *data) {
 | 
				
			||||||
 | 
						swayc_map_r(&root_container, f, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void swayc_map_by_test_r(swayc_t *container,
 | 
				
			||||||
 | 
							swayc_map_func func, swayc_test_func test,
 | 
				
			||||||
 | 
							void *funcdata, void *testdata) {
 | 
				
			||||||
 | 
						if (container) {
 | 
				
			||||||
 | 
							if (test(container, testdata)) {
 | 
				
			||||||
 | 
								func(container, funcdata);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							if (container->children)  {
 | 
				
			||||||
 | 
								for (i = 0; i < container->children->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *child = container->children->items[i];
 | 
				
			||||||
 | 
									swayc_map_by_test_r(child, func, test, funcdata, testdata);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (container->floating) {
 | 
				
			||||||
 | 
								for (i = 0; i < container->floating->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *child = container->floating->items[i];
 | 
				
			||||||
 | 
									swayc_map_by_test_r(child, func, test, funcdata, testdata);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void swayc_map_by_test(
 | 
				
			||||||
 | 
							swayc_map_func func, swayc_test_func test,
 | 
				
			||||||
 | 
							void *funcdata, void *testdata) {
 | 
				
			||||||
 | 
						swayc_map_by_test_r(&root_container, func, test, funcdata, testdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Map functions
 | 
				
			||||||
 | 
					void set_gaps(swayc_t *view, void *_data) {
 | 
				
			||||||
 | 
						int *data = _data;
 | 
				
			||||||
 | 
						if (view->type == C_WORKSPACE || view->type == C_VIEW) {
 | 
				
			||||||
 | 
							view->gaps = *data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void add_gaps(swayc_t *view, void *_data) {
 | 
				
			||||||
 | 
						int *data = _data;
 | 
				
			||||||
 | 
						if (view->type == C_WORKSPACE || view->type == C_VIEW) {
 | 
				
			||||||
 | 
							if ((view->gaps += *data) < 0) {
 | 
				
			||||||
 | 
								view->gaps = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Test functions
 | 
				
			||||||
 | 
					bool test_name(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->name && strcmp(view->name, data) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// test_name_regex
 | 
				
			||||||
 | 
					struct test_name_regex {
 | 
				
			||||||
 | 
						pcre *reg;
 | 
				
			||||||
 | 
						pcre_extra *regext;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *compile_regex(const char *pattern) {
 | 
				
			||||||
 | 
						struct test_name_regex *regex = malloc(sizeof *regex);
 | 
				
			||||||
 | 
						const char *error;
 | 
				
			||||||
 | 
						int erroffset;
 | 
				
			||||||
 | 
						if (!(regex->reg = pcre_compile(pattern, 0, &error, &erroffset, NULL))) {
 | 
				
			||||||
 | 
							sway_log(L_ERROR, "Regex compilation failed:%s:%s", pattern, error);
 | 
				
			||||||
 | 
							free(regex);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						regex->regext = pcre_study(regex->reg, 0, &error);
 | 
				
			||||||
 | 
						if (error) {
 | 
				
			||||||
 | 
							sway_log(L_DEBUG, "Regex study failed:%s:%s", pattern, error);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return regex;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void free_regex(void *_regex) {
 | 
				
			||||||
 | 
						struct test_name_regex *regex = _regex;
 | 
				
			||||||
 | 
						pcre_free(regex->reg);
 | 
				
			||||||
 | 
						pcre_free_study(regex->regext);
 | 
				
			||||||
 | 
						free(regex);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool exec_regex(const char *pattern, struct test_name_regex *regex) {
 | 
				
			||||||
 | 
						int ovector[300];
 | 
				
			||||||
 | 
						return 0 < pcre_exec(regex->reg, regex->regext, pattern,
 | 
				
			||||||
 | 
								strlen(pattern), 0, 0, ovector, 300);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool test_name_regex(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->name && exec_regex(view->name, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_layout(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->layout & *(enum swayc_layouts *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_type(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->layout & *(enum swayc_types *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_visibility(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->visible == *(bool *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_handle(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->handle == *(wlc_handle *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// C_VIEW tests
 | 
				
			||||||
 | 
					bool test_view_state(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& wlc_view_get_state(view->handle) & *(int *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_type(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& wlc_view_get_type(view->handle) & *(int *)data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_title(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& strcmp(view->name, data) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_class(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& strcmp(wlc_view_get_class(view->handle), data) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_appid(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& strcmp(wlc_view_get_app_id(view->handle), data) == 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_title_regex(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& exec_regex(view->name, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_class_regex(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& exec_regex(wlc_view_get_class(view->handle), data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_view_appid_regex(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						return view->type == C_VIEW
 | 
				
			||||||
 | 
							&& exec_regex(wlc_view_get_app_id(view->handle), data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Fancy test combiners
 | 
				
			||||||
 | 
					bool test_and(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						struct test_list *list = data;
 | 
				
			||||||
 | 
						while (list->test) {
 | 
				
			||||||
 | 
							if (!list->test(view, list->data)) {
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	return strcmp(view->name, data) == 0;
 | 
							++list;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool test_or(swayc_t *view, void *data) {
 | 
				
			||||||
 | 
						struct test_list *list = data;
 | 
				
			||||||
 | 
						while (list->test) {
 | 
				
			||||||
 | 
							if (list->test(view, list->data)) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							++list;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *swayc_by_name(const char *name) {
 | 
					// Focus|parent lookup
 | 
				
			||||||
	return swayc_by_test(&root_container, test_name, (void *)name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
 | 
					swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
 | 
				
			||||||
	if (!ASSERT_NONNULL(container)) {
 | 
						if (!ASSERT_NONNULL(container)) {
 | 
				
			||||||
| 
						 | 
					@ -465,42 +656,6 @@ swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts layout) {
 | 
				
			||||||
	return container;
 | 
						return container;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) {
 | 
					 | 
				
			||||||
	if (!parent || !parent->children) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	int i, len;
 | 
					 | 
				
			||||||
	swayc_t **child;
 | 
					 | 
				
			||||||
	if (parent->type == C_WORKSPACE) {
 | 
					 | 
				
			||||||
		len = parent->floating->length;
 | 
					 | 
				
			||||||
		child = (swayc_t **)parent->floating->items;
 | 
					 | 
				
			||||||
		for (i = 0; i < len; ++i, ++child) {
 | 
					 | 
				
			||||||
			if ((*child)->handle == handle) {
 | 
					 | 
				
			||||||
				return *child;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = parent->children->length;
 | 
					 | 
				
			||||||
	child = (swayc_t**)parent->children->items;
 | 
					 | 
				
			||||||
	for (i = 0; i < len; ++i, ++child) {
 | 
					 | 
				
			||||||
		if ((*child)->handle == handle) {
 | 
					 | 
				
			||||||
			return *child;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			swayc_t *res;
 | 
					 | 
				
			||||||
			if ((res = _swayc_by_handle_helper(handle, *child))) {
 | 
					 | 
				
			||||||
				return res;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
swayc_t *swayc_by_handle(wlc_handle handle) {
 | 
					 | 
				
			||||||
	return _swayc_by_handle_helper(handle, &root_container);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
swayc_t *swayc_active_output(void) {
 | 
					swayc_t *swayc_active_output(void) {
 | 
				
			||||||
	return root_container.focused;
 | 
						return root_container.focused;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -533,11 +688,13 @@ swayc_t *swayc_active_workspace_for(swayc_t *cont) {
 | 
				
			||||||
// Container information
 | 
					// Container information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool swayc_is_fullscreen(swayc_t *view) {
 | 
					bool swayc_is_fullscreen(swayc_t *view) {
 | 
				
			||||||
	return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN);
 | 
						return view && view->type == C_VIEW
 | 
				
			||||||
 | 
							&& wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool swayc_is_active(swayc_t *view) {
 | 
					bool swayc_is_active(swayc_t *view) {
 | 
				
			||||||
	return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED);
 | 
						return view && view->type == C_VIEW
 | 
				
			||||||
 | 
							&& wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) {
 | 
					bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) {
 | 
				
			||||||
| 
						 | 
					@ -566,25 +723,6 @@ int swayc_gap(swayc_t *container) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mapping
 | 
					// Mapping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
 | 
					 | 
				
			||||||
	if (container) {
 | 
					 | 
				
			||||||
		f(container, data);
 | 
					 | 
				
			||||||
		int i;
 | 
					 | 
				
			||||||
		if (container->children)  {
 | 
					 | 
				
			||||||
			for (i = 0; i < container->children->length; ++i) {
 | 
					 | 
				
			||||||
				swayc_t *child = container->children->items[i];
 | 
					 | 
				
			||||||
				container_map(child, f, data);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (container->floating) {
 | 
					 | 
				
			||||||
			for (i = 0; i < container->floating->length; ++i) {
 | 
					 | 
				
			||||||
				swayc_t *child = container->floating->items[i];
 | 
					 | 
				
			||||||
				container_map(child, f, data);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void update_visibility_output(swayc_t *container, wlc_handle output) {
 | 
					void update_visibility_output(swayc_t *container, wlc_handle output) {
 | 
				
			||||||
	// Inherit visibility
 | 
						// Inherit visibility
 | 
				
			||||||
	swayc_t *parent = container->parent;
 | 
						swayc_t *parent = container->parent;
 | 
				
			||||||
| 
						 | 
					@ -653,24 +791,3 @@ void update_visibility(swayc_t *container) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void set_gaps(swayc_t *view, void *_data) {
 | 
					 | 
				
			||||||
	int *data = _data;
 | 
					 | 
				
			||||||
	if (!ASSERT_NONNULL(view)) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (view->type == C_WORKSPACE || view->type == C_VIEW) {
 | 
					 | 
				
			||||||
		view->gaps = *data;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void add_gaps(swayc_t *view, void *_data) {
 | 
					 | 
				
			||||||
	int *data = _data;
 | 
					 | 
				
			||||||
	if (!ASSERT_NONNULL(view)) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (view->type == C_WORKSPACE || view->type == C_VIEW) {
 | 
					 | 
				
			||||||
		if ((view->gaps += *data) < 0) {
 | 
					 | 
				
			||||||
			view->gaps = 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,7 @@ static void handle_output_destroyed(wlc_handle output) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
 | 
					static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
 | 
				
			||||||
	sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
 | 
						sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
 | 
				
			||||||
	swayc_t *c = swayc_by_handle(output);
 | 
						swayc_t *c = swayc_by_test(test_handle, &output);
 | 
				
			||||||
	if (!c) return;
 | 
						if (!c) return;
 | 
				
			||||||
	c->width = to->w;
 | 
						c->width = to->w;
 | 
				
			||||||
	c->height = to->h;
 | 
						c->height = to->h;
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,7 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_output_focused(wlc_handle output, bool focus) {
 | 
					static void handle_output_focused(wlc_handle output, bool focus) {
 | 
				
			||||||
	swayc_t *c = swayc_by_handle(output);
 | 
						swayc_t *c = swayc_by_test(test_handle, &output);
 | 
				
			||||||
	// if for some reason this output doesnt exist, create it.
 | 
						// if for some reason this output doesnt exist, create it.
 | 
				
			||||||
	if (!c) {
 | 
						if (!c) {
 | 
				
			||||||
		handle_output_created(output);
 | 
							handle_output_created(output);
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ static bool handle_view_created(wlc_handle handle) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get parent container, to add view in
 | 
						// Get parent container, to add view in
 | 
				
			||||||
	if (parent) {
 | 
						if (parent) {
 | 
				
			||||||
		focused = swayc_by_handle(parent);
 | 
							focused = swayc_by_test(test_handle, &parent);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!focused || focused->type == C_OUTPUT) {
 | 
						if (!focused || focused->type == C_OUTPUT) {
 | 
				
			||||||
		focused = get_focused_container(&root_container);
 | 
							focused = get_focused_container(&root_container);
 | 
				
			||||||
| 
						 | 
					@ -221,7 +221,7 @@ static bool handle_view_created(wlc_handle handle) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_view_destroyed(wlc_handle handle) {
 | 
					static void handle_view_destroyed(wlc_handle handle) {
 | 
				
			||||||
	sway_log(L_DEBUG, "Destroying window %lu", handle);
 | 
						sway_log(L_DEBUG, "Destroying window %lu", handle);
 | 
				
			||||||
	swayc_t *view = swayc_by_handle(handle);
 | 
						swayc_t *view = swayc_by_test(test_handle, &handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// destroy views by type
 | 
						// destroy views by type
 | 
				
			||||||
	switch (wlc_view_get_type(handle)) {
 | 
						switch (wlc_view_get_type(handle)) {
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
 | 
				
			||||||
	// If the view is floating, then apply the geometry.
 | 
						// If the view is floating, then apply the geometry.
 | 
				
			||||||
	// Otherwise save the desired width/height for the view.
 | 
						// Otherwise save the desired width/height for the view.
 | 
				
			||||||
	// This will not do anything for the time being as WLC improperly sends geometry requests
 | 
						// This will not do anything for the time being as WLC improperly sends geometry requests
 | 
				
			||||||
	swayc_t *view = swayc_by_handle(handle);
 | 
						swayc_t *view = swayc_by_test(test_handle, &handle);
 | 
				
			||||||
	if (view) {
 | 
						if (view) {
 | 
				
			||||||
		view->desired_width = geometry->size.w;
 | 
							view->desired_width = geometry->size.w;
 | 
				
			||||||
		view->desired_height = geometry->size.h;
 | 
							view->desired_height = geometry->size.h;
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
 | 
					static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
 | 
				
			||||||
	swayc_t *c = swayc_by_handle(view);
 | 
						swayc_t *c = swayc_by_test(test_handle, &view);
 | 
				
			||||||
	switch (state) {
 | 
						switch (state) {
 | 
				
			||||||
	case WLC_BIT_FULLSCREEN:
 | 
						case WLC_BIT_FULLSCREEN:
 | 
				
			||||||
		// i3 just lets it become fullscreen
 | 
							// i3 just lets it become fullscreen
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -207,7 +207,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
 | 
				
			||||||
	case IPC_GET_WORKSPACES:
 | 
						case IPC_GET_WORKSPACES:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		json_object *workspaces = json_object_new_array();
 | 
							json_object *workspaces = json_object_new_array();
 | 
				
			||||||
		container_map(&root_container, ipc_get_workspaces_callback, workspaces);
 | 
							swayc_map(ipc_get_workspaces_callback, workspaces);
 | 
				
			||||||
		const char *json_string = json_object_to_json_string(workspaces);
 | 
							const char *json_string = json_object_to_json_string(workspaces);
 | 
				
			||||||
		ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
 | 
							ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
 | 
				
			||||||
		json_object_put(workspaces); // free
 | 
							json_object_put(workspaces); // free
 | 
				
			||||||
| 
						 | 
					@ -216,7 +216,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
 | 
				
			||||||
	case IPC_GET_OUTPUTS:
 | 
						case IPC_GET_OUTPUTS:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		json_object *outputs = json_object_new_array();
 | 
							json_object *outputs = json_object_new_array();
 | 
				
			||||||
		container_map(&root_container, ipc_get_outputs_callback, outputs);
 | 
							swayc_map(ipc_get_outputs_callback, outputs);
 | 
				
			||||||
		const char *json_string = json_object_to_json_string(outputs);
 | 
							const char *json_string = json_object_to_json_string(outputs);
 | 
				
			||||||
		ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
 | 
							ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
 | 
				
			||||||
		json_object_put(outputs); // free
 | 
							json_object_put(outputs); // free
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ int unescape_string(char *string) {
 | 
				
			||||||
	return len - shift;
 | 
						return len - shift;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *join_args(char **argv, int argc) {
 | 
					char *join_args(int argc, char **argv) {
 | 
				
			||||||
	int len = 0, i;
 | 
						int len = 0, i;
 | 
				
			||||||
	for (i = 0; i < argc; ++i) {
 | 
						for (i = 0; i < argc; ++i) {
 | 
				
			||||||
		len += strlen(argv[i]) + 1;
 | 
							len += strlen(argv[i]) + 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										147
									
								
								sway/workspace.c
									
										
									
									
									
								
							
							
						
						
									
										147
									
								
								sway/workspace.c
									
										
									
									
									
								
							| 
						 | 
					@ -15,7 +15,26 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *prev_workspace_name = NULL;
 | 
					char *prev_workspace_name = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *workspace_next_name(void) {
 | 
					static swayc_t *workspace_by_name_only(const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *workspace_output_open_name(swayc_t *output) {
 | 
				
			||||||
 | 
						struct workspace_output *wsop;
 | 
				
			||||||
 | 
						int i, len = config->workspace_outputs->length;
 | 
				
			||||||
 | 
						// Search config for output
 | 
				
			||||||
 | 
						for (i = 0; i < len; ++i) {
 | 
				
			||||||
 | 
							wsop = config->workspace_outputs->items[i];
 | 
				
			||||||
 | 
							// Find matching outputs
 | 
				
			||||||
 | 
							if (strcasecmp(wsop->output, output->name)) {
 | 
				
			||||||
 | 
								// Check if workspace is available and use that name
 | 
				
			||||||
 | 
								if (!workspace_by_name(wsop->workspace)) {
 | 
				
			||||||
 | 
									return wsop->workspace;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *workspace_next_name(void) {
 | 
				
			||||||
	sway_log(L_DEBUG, "Workspace: Generating new name");
 | 
						sway_log(L_DEBUG, "Workspace: Generating new name");
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int l = 1;
 | 
						int l = 1;
 | 
				
			||||||
| 
						 | 
					@ -25,42 +44,29 @@ char *workspace_next_name(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < mode->bindings->length; ++i) {
 | 
						for (i = 0; i < mode->bindings->length; ++i) {
 | 
				
			||||||
		struct sway_binding *binding = mode->bindings->items[i];
 | 
							struct sway_binding *binding = mode->bindings->items[i];
 | 
				
			||||||
		const char* command = binding->command;
 | 
							const char *command = binding->command;
 | 
				
			||||||
		list_t *args = split_string(command, " ");
 | 
							const char *ws = "workspace";
 | 
				
			||||||
 | 
							const int wslen = sizeof("workspace") - 1;
 | 
				
			||||||
		if (strcmp("workspace", args->items[0]) == 0 && args->length > 1) {
 | 
							if (strncmp(ws, command, wslen) == 0) {
 | 
				
			||||||
			sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", (char *)args->items[1]);
 | 
								command += wslen;
 | 
				
			||||||
			char* target = malloc(strlen(args->items[1]) + 1);
 | 
								// Skip whitespace
 | 
				
			||||||
			strcpy(target, args->items[1]);
 | 
								command += strspn(command, whitespace);
 | 
				
			||||||
			while (*target == ' ' || *target == '\t')
 | 
								// make sure its not a special command
 | 
				
			||||||
				target++;
 | 
								if (strcmp(command, "next") == 0
 | 
				
			||||||
 | 
										|| strcmp(command, "prev") == 0
 | 
				
			||||||
			// Make sure that the command references an actual workspace
 | 
										|| strcmp(command, "next_on_output") == 0
 | 
				
			||||||
			// not a command about workspaces
 | 
										|| strcmp(command, "prev_on_output") == 0
 | 
				
			||||||
			if (strcmp(target, "next") == 0 ||
 | 
										|| strcmp(command, "number") == 0
 | 
				
			||||||
				strcmp(target, "prev") == 0 ||
 | 
										|| strcmp(command, "back_and_forth") == 0
 | 
				
			||||||
				strcmp(target, "next_on_output") == 0 ||
 | 
										|| strcmp(command, "current") == 0
 | 
				
			||||||
				strcmp(target, "prev_on_output") == 0 ||
 | 
										// Or if it already exists
 | 
				
			||||||
				strcmp(target, "number") == 0 ||
 | 
										|| workspace_by_name_only(command)) {
 | 
				
			||||||
				strcmp(target, "back_and_forth") == 0 ||
 | 
					 | 
				
			||||||
				strcmp(target, "current") == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				free_flat_list(args);
 | 
					 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									// otherwise we found it
 | 
				
			||||||
 | 
									return command;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Make sure that the workspace doesn't already exist
 | 
					 | 
				
			||||||
			if (workspace_by_name(target)) {
 | 
					 | 
				
			||||||
				free_flat_list(args);
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			free_flat_list(args);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			sway_log(L_DEBUG, "Workspace: Found free name %s", target);
 | 
					 | 
				
			||||||
			return target;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		free_flat_list(args);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// As a fall back, get the current number of active workspaces
 | 
						// As a fall back, get the current number of active workspaces
 | 
				
			||||||
	// and return that + 1 for the next workspace's name
 | 
						// and return that + 1 for the next workspace's name
 | 
				
			||||||
| 
						 | 
					@ -75,55 +81,40 @@ char *workspace_next_name(void) {
 | 
				
			||||||
	return name;
 | 
						return name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_create(const char* name) {
 | 
					swayc_t *workspace_by_name_only(const char *name) {
 | 
				
			||||||
	swayc_t *parent;
 | 
						int i, len = root_container.children->length;
 | 
				
			||||||
	// Search for workspace<->output pair
 | 
						for (i = 0; i < len; ++i) {
 | 
				
			||||||
	int i, e = config->workspace_outputs->length;
 | 
							swayc_t *op = root_container.children->items[i];
 | 
				
			||||||
	for (i = 0; i < e; ++i) {
 | 
							int i, len = op->children->length;
 | 
				
			||||||
		struct workspace_output *wso = config->workspace_outputs->items[i];
 | 
							for (i = 0; i < len; ++i) {
 | 
				
			||||||
		if (strcasecmp(wso->workspace, name) == 0)
 | 
								swayc_t *ws = op->children->items[i];
 | 
				
			||||||
		{
 | 
								if (strcasecmp(ws->name, name) == 0) {
 | 
				
			||||||
			// Find output to use if it exists
 | 
									return ws;
 | 
				
			||||||
			e = root_container.children->length;
 | 
					 | 
				
			||||||
			for (i = 0; i < e; ++i) {
 | 
					 | 
				
			||||||
				parent = root_container.children->items[i];
 | 
					 | 
				
			||||||
				if (strcmp(parent->name, wso->output) == 0) {
 | 
					 | 
				
			||||||
					return new_workspace(parent, name);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
						return NULL;
 | 
				
			||||||
	// Otherwise create a new one
 | 
					 | 
				
			||||||
	parent = get_focused_container(&root_container);
 | 
					 | 
				
			||||||
	parent = swayc_parent_by_type(parent, C_OUTPUT);
 | 
					 | 
				
			||||||
	return new_workspace(parent, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool _workspace_by_name(swayc_t *view, void *data) {
 | 
					 | 
				
			||||||
	return (view->type == C_WORKSPACE) &&
 | 
					 | 
				
			||||||
		   (strcasecmp(view->name, (char *) data) == 0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_by_name(const char* name) {
 | 
					swayc_t *workspace_by_name(const char* name) {
 | 
				
			||||||
	if (strcmp(name, "prev") == 0) {
 | 
						if (strcmp(name, "prev") == 0) {
 | 
				
			||||||
		return workspace_prev();
 | 
							return workspace_prev();
 | 
				
			||||||
	}
 | 
						} else if (!strcmp(name, "prev_on_output")) {
 | 
				
			||||||
	else if (strcmp(name, "prev_on_output") == 0) {
 | 
					 | 
				
			||||||
		return workspace_output_prev();
 | 
							return workspace_output_prev();
 | 
				
			||||||
	}
 | 
						} else if (!strcmp(name, "next")) {
 | 
				
			||||||
	else if (strcmp(name, "next") == 0) {
 | 
					 | 
				
			||||||
		return workspace_next();
 | 
							return workspace_next();
 | 
				
			||||||
	}
 | 
						} else if (!strcmp(name, "next_on_output")) {
 | 
				
			||||||
	else if (strcmp(name, "next_on_output") == 0) {
 | 
					 | 
				
			||||||
		return workspace_output_next();
 | 
							return workspace_output_next();
 | 
				
			||||||
	}
 | 
						} else if (!strcmp(name, "current")) {
 | 
				
			||||||
	else if (strcmp(name, "current") == 0) {
 | 
							return swayc_active_workspace();
 | 
				
			||||||
 | 
						} else if (!strcmp(name, "back_and_forth")) {
 | 
				
			||||||
 | 
							if (prev_workspace_name) {
 | 
				
			||||||
 | 
								name = prev_workspace_name;
 | 
				
			||||||
 | 
							} else { // If there is no prev workspace name. just return current
 | 
				
			||||||
			return swayc_active_workspace();
 | 
								return swayc_active_workspace();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return workspace_by_name_only(name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -181,19 +172,19 @@ swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) {
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_output_next() {
 | 
					swayc_t *workspace_output_next(void) {
 | 
				
			||||||
	return workspace_output_prev_next_impl(swayc_active_output(), true);
 | 
						return workspace_output_prev_next_impl(swayc_active_output(), true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_next() {
 | 
					swayc_t *workspace_next(void) {
 | 
				
			||||||
	return workspace_prev_next_impl(swayc_active_workspace(), true);
 | 
						return workspace_prev_next_impl(swayc_active_workspace(), true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_output_prev() {
 | 
					swayc_t *workspace_output_prev(void) {
 | 
				
			||||||
	return workspace_output_prev_next_impl(swayc_active_output(), false);
 | 
						return workspace_output_prev_next_impl(swayc_active_output(), false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *workspace_prev() {
 | 
					swayc_t *workspace_prev(void) {
 | 
				
			||||||
	return workspace_prev_next_impl(swayc_active_workspace(), false);
 | 
						return workspace_prev_next_impl(swayc_active_workspace(), false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,17 +193,17 @@ void workspace_switch(swayc_t *workspace) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	swayc_t *active_ws = swayc_active_workspace();
 | 
						swayc_t *active_ws = swayc_active_workspace();
 | 
				
			||||||
	if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) {
 | 
						// set workspace to prev_workspace
 | 
				
			||||||
		swayc_t *new_ws = workspace_by_name(prev_workspace_name);
 | 
						if (config->auto_back_and_forth && active_ws == workspace) {
 | 
				
			||||||
		workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
 | 
							workspace = new_workspace(NULL, "back_and_forth");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// set prev workspace name
 | 
				
			||||||
	if (!prev_workspace_name
 | 
						if (!prev_workspace_name
 | 
				
			||||||
			|| (strcmp(prev_workspace_name, active_ws->name)
 | 
								|| (strcmp(prev_workspace_name, active_ws->name)
 | 
				
			||||||
				&& active_ws != workspace)) {
 | 
									&& active_ws != workspace)) {
 | 
				
			||||||
		free(prev_workspace_name);
 | 
							free(prev_workspace_name);
 | 
				
			||||||
		prev_workspace_name = malloc(strlen(active_ws->name)+1);
 | 
							prev_workspace_name = strdup(active_ws->name);
 | 
				
			||||||
		strcpy(prev_workspace_name, active_ws->name);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
 | 
						sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue