summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaiyu <taiyu.len@gmail.com>2015-09-12 02:38:03 -0700
committertaiyu <taiyu.len@gmail.com>2015-09-12 02:38:03 -0700
commite1d18e42a8f3a597b9bf5f1bb2ab6c346e4e7983 (patch)
tree8a8ac30c539f4a63bb249b8c5e27e724a4241c9f
parentf5343adae4d631e4cdade7869b4d73fc97b4ac5f (diff)
new_workspace null behavior + testmap functions + regex
-rw-r--r--include/commands.h16
-rw-r--r--include/config.h4
-rw-r--r--include/container.h139
-rw-r--r--include/stringop.h2
-rw-r--r--include/workspace.h16
-rw-r--r--sway/commands.c167
-rw-r--r--sway/config.c25
-rw-r--r--sway/container.c415
-rw-r--r--sway/handlers.c12
-rw-r--r--sway/ipc.c4
-rw-r--r--sway/stringop.c2
-rw-r--r--sway/workspace.c149
12 files changed, 581 insertions, 370 deletions
diff --git a/include/commands.h b/include/commands.h
index 5c87be51..69ab1380 100644
--- a/include/commands.h
+++ b/include/commands.h
@@ -3,19 +3,21 @@
#include <stdbool.h>
#include "config.h"
+typedef enum cmd_status {
+ CMD_SUCCESS,
+ CMD_FAILURE,
+ CMD_DEFER,
+} sway_cmd(char *criteria, int argc, char **argv);
+
struct cmd_handler {
- char *command;
- enum cmd_status {
- CMD_SUCCESS,
- CMD_FAILURE,
- CMD_DEFER,
- } (*handle)(int argc, char **argv);
+ const char*command;
+ sway_cmd *handle;
};
enum cmd_status handle_command(char *command);
// Handles commands during config
enum cmd_status config_command(char *command);
-void remove_view_from_scratchpad();
+void remove_view_from_scratchpad(swayc_t *view);
#endif
diff --git a/include/config.h b/include/config.h
index 676218c8..04db3e5c 100644
--- a/include/config.h
+++ b/include/config.h
@@ -63,6 +63,10 @@ bool load_config(const char *file);
bool read_config(FILE *file, bool is_active);
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;
#endif
diff --git a/include/container.h b/include/container.h
index a9b95229..d8590149 100644
--- a/include/container.h
+++ b/include/container.h
@@ -2,29 +2,25 @@
#define _SWAY_CONTAINER_H
#include <wlc/wlc.h>
typedef struct sway_container swayc_t;
-
#include "layout.h"
-enum swayc_types{
- C_ROOT,
- C_OUTPUT,
- C_WORKSPACE,
- C_CONTAINER,
- C_VIEW,
- // Keep last
- C_TYPES,
+enum swayc_types {
+ C_ROOT = 1 << 0,
+ C_OUTPUT = 1 << 1,
+ C_WORKSPACE = 1 << 2,
+ C_CONTAINER = 1 << 3,
+ C_VIEW = 1 << 4,
+ C_TYPES = 5,
};
-
-enum swayc_layouts{
- L_NONE,
- L_HORIZ,
- L_VERT,
- L_STACKED,
- L_TABBED,
- L_FLOATING,
- // Keep last
- L_LAYOUTS,
+enum swayc_layouts {
+ L_NONE = 1 << 0,
+ L_HORIZ = 1 << 1,
+ L_VERT = 1 << 2,
+ L_STACKED = 1 << 3,
+ L_TABBED = 1 << 4,
+ L_FLOATING = 1 << 5,
+ L_LAYOUTS = 6,
};
struct sway_container {
@@ -35,13 +31,16 @@ struct sway_container {
// Not including borders or margins
double width, height;
+ double x, y;
// Used for setting floating geometry
int desired_width, desired_height;
- double x, y;
+ enum visibility_mask {
+ INVISIBLE = 0,
+ VISIBLE = 1,
+ } visible;
- bool visible;
bool is_floating;
bool is_focused;
@@ -56,70 +55,120 @@ struct sway_container {
struct sway_container *focused;
};
-enum visibility_mask {
- VISIBLE = 1
-};
-
-// Container Creation
+// swayc 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);
+
+/* 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);
+
// Creates container Around child (parent child) -> (parent (container child))
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
swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
+
// Creates view as a new floating view which is in the active workspace
swayc_t *new_floating_view(wlc_handle handle);
// Container Destroying
-
+// Destroys output and moves workspaces to another output
swayc_t *destroy_output(swayc_t *output);
+
// Destroys workspace if empty and returns parent pointer, else returns NULL
swayc_t *destroy_workspace(swayc_t *workspace);
+
// Destroyes container and all parent container if they are empty, returns
// topmost non-empty parent. returns NULL otherwise
swayc_t *destroy_container(swayc_t *container);
+
// Destroys view and all empty parent containers. return topmost non-empty
// parent
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_layout(swayc_t *container, enum swayc_layouts);
// Follow focused until type/layout
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_by_handle(wlc_handle handle);
-swayc_t *swayc_by_name(const char *name);
swayc_t *swayc_active_output(void);
swayc_t *swayc_active_workspace(void);
swayc_t *swayc_active_workspace_for(swayc_t *view);
// Container information
-
-bool swayc_is_fullscreen(swayc_t *view);
-bool swayc_is_active(swayc_t *view);
-// Is `parent` the parent of `child`
+// if `parent` is the parent of `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);
// Return gap of specified container
int swayc_gap(swayc_t *container);
-// Mapping functions
-
-void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
+bool swayc_is_fullscreen(swayc_t *view);
+bool swayc_is_active(swayc_t *view);
-// 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);
#endif
diff --git a/include/stringop.h b/include/stringop.h
index dde50f13..6e80e729 100644
--- a/include/stringop.h
+++ b/include/stringop.h
@@ -19,7 +19,7 @@ void free_argv(int argc, char **argv);
char *code_strchr(const char *string, char delimiter);
char *code_strstr(const char *haystack, const char *needle);
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 *strdup(const char *);
diff --git a/include/workspace.h b/include/workspace.h
index 7343b055..3a63ea38 100644
--- a/include/workspace.h
+++ b/include/workspace.h
@@ -7,13 +7,17 @@
extern char *prev_workspace_name;
-char *workspace_next_name(void);
-swayc_t *workspace_create(const char*);
+// Search for available workspace name on output from config
+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*);
void workspace_switch(swayc_t*);
-swayc_t *workspace_output_next();
-swayc_t *workspace_next();
-swayc_t *workspace_output_prev();
-swayc_t *workspace_prev();
+swayc_t *workspace_output_next(void);
+swayc_t *workspace_next(void);
+swayc_t *workspace_output_prev(void);
+swayc_t *workspace_prev(void);
#endif
diff --git a/sway/commands.c b/sway/commands.c
index e79746ae..74e13d6c 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -21,6 +21,35 @@
swayc_t *sp_view;
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 {
char *name;
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);
}
-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)
|| !config->reading) {
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));
binding->keys = create_list();
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], "+");
int i;
@@ -144,7 +173,7 @@ static enum cmd_status cmd_bindsym(int argc, char **argv) {
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)) {
return CMD_FAILURE;
}
@@ -160,7 +189,7 @@ static enum cmd_status cmd_exec_always(int argc, char **argv) {
}
/* Child process */
if (pid == 0) {
- char *args = join_args(argv, argc);
+ char *args = join_args(argc, argv);
sway_log(L_DEBUG, "Executing %s", args);
execl("/bin/sh", "sh", "-c", args, (char *)NULL);
/* Execl doesnt return unless failure */
@@ -172,17 +201,17 @@ static enum cmd_status cmd_exec_always(int argc, char **argv) {
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) {
return CMD_DEFER;
}
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);
free(args);
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) {
@@ -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)
|| config->reading || !config->active) {
return CMD_FAILURE;
}
// Close all views
- container_map(&root_container, kill_views, NULL);
+ swayc_map(kill_views, NULL);
sway_terminate();
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -264,7 +294,7 @@ static enum cmd_status cmd_floating(int argc, char **argv) {
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)
|| !config->reading) {
return CMD_FAILURE;
@@ -289,7 +319,7 @@ static enum cmd_status cmd_floating_mod(int argc, char **argv) {
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 tiled_toggled_index = 0;
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;
}
-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)) {
return CMD_FAILURE;
}
@@ -356,6 +386,21 @@ static enum cmd_status cmd_focus_follows_mouse(int argc, char **argv) {
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, 2)) {
+ 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) {
if(sp_view == NULL) {
return;
@@ -372,7 +417,7 @@ static void hide_view_in_scratchpad(swayc_t *sp_view) {
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)) {
return CMD_FAILURE;
}
@@ -381,7 +426,7 @@ static enum cmd_status cmd_mode(int argc, char **argv) {
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;
// Find mode
int i, len = config->modes->length;
@@ -411,7 +456,7 @@ static enum cmd_status cmd_mode(int argc, char **argv) {
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -444,11 +489,7 @@ static enum cmd_status cmd_move(int argc, char **argv) {
// move "container to workspace number x"
ws_name = argv[4];
}
-
- swayc_t *ws = workspace_by_name(ws_name);
- if (ws == NULL) {
- ws = workspace_create(ws_name);
- }
+ swayc_t *ws = new_workspace(NULL, ws_name);
move_container_to(view, get_focused_container(ws));
} else if (strcasecmp(argv[0], "scratchpad") == 0) {
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;
}
-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)
|| !config->reading) {
return CMD_FAILURE;
@@ -499,7 +540,7 @@ static enum cmd_status cmd_orientation(int argc, char **argv) {
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)) {
return CMD_FAILURE;
}
@@ -564,7 +605,7 @@ static enum cmd_status cmd_output(int argc, char **argv) {
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)) {
return CMD_FAILURE;
}
@@ -698,15 +739,14 @@ static enum cmd_status cmd_gaps(int argc, char **argv) {
top = &root_container;
}
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;
arrange_windows(top, -1, -1);
}
-
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) {
return CMD_FAILURE;
}
@@ -715,7 +755,7 @@ static enum cmd_status cmd_kill(int argc, char **argv) {
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -741,7 +781,7 @@ static enum cmd_status cmd_layout(int argc, char **argv) {
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)
|| config->reading
|| !load_config(NULL)) {
@@ -751,7 +791,7 @@ static enum cmd_status cmd_reload(int argc, char **argv) {
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -781,7 +821,7 @@ static enum cmd_status cmd_resize(int argc, char **argv) {
return CMD_SUCCESS;
}
-static swayc_t *fetch_view_from_scratchpad() {
+static swayc_t *fetch_view_from_scratchpad(void) {
if (sp_index >= scratchpad->length) {
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -860,7 +900,7 @@ static int compare_set(const void *_l, const void *_r) {
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)
|| !config->reading) {
return CMD_FAILURE;
@@ -883,11 +923,11 @@ static enum cmd_status cmd_set(int argc, char **argv) {
list_add(config->symbols, var);
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;
}
-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" :
layout == L_HORIZ ? "splith" : "split";
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;
}
-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)
|| config->reading || !config->active) {
return CMD_FAILURE;
}
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) {
- _do_split(argc - 1, argv + 1, L_HORIZ);
+ _do_split(criteria, argc - 1, argv + 1, L_HORIZ);
} else {
sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical).");
return CMD_FAILURE;
@@ -936,15 +976,15 @@ static enum cmd_status cmd_split(int argc, char **argv) {
return CMD_SUCCESS;
}
-static enum cmd_status cmd_splitv(int argc, char **argv) {
- return _do_split(argc, argv, L_VERT);
+enum cmd_status cmd_splitv(char *criteria, int argc, char **argv) {
+ return _do_split(criteria, argc, argv, L_VERT);
}
-static enum cmd_status cmd_splith(int argc, char **argv) {
- return _do_split(argc, argv, L_HORIZ);
+enum cmd_status cmd_splith(char *criteria, int argc, char **argv) {
+ 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)
|| !config->reading) {
return CMD_FAILURE;
@@ -960,7 +1000,7 @@ static enum cmd_status cmd_log_colors(int argc, char **argv) {
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)
|| config->reading || !config->active) {
return CMD_FAILURE;
@@ -980,7 +1020,7 @@ static enum cmd_status cmd_fullscreen(int argc, char **argv) {
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)) {
return CMD_FAILURE;
}
@@ -989,28 +1029,7 @@ static enum cmd_status cmd_workspace(int argc, char **argv) {
if (config->reading || !config->active) {
return CMD_DEFER;
}
- // Handle workspace next/prev
- 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);
+ workspace_switch(new_workspace(NULL, argv[0]));
} else {
if (strcasecmp(argv[1], "output") == 0) {
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->output = strdup(argv[2]);
list_add(config->workspace_outputs, wso);
- if (!config->reading) {
- // TODO: Move workspace to output. (dont do so when reloading)
- }
}
}
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)) {
return CMD_FAILURE;
}
@@ -1044,7 +1060,7 @@ static enum cmd_status cmd_ws_auto_back_and_forth(int argc, char **argv) {
}
/* Keep alphabetized */
-static struct cmd_handler handlers[] = {
+static const struct cmd_handler handlers[] = {
{ "bindsym", cmd_bindsym },
{ "default_orientation", cmd_orientation },
{ "exec", cmd_exec },
@@ -1054,6 +1070,7 @@ static struct cmd_handler handlers[] = {
{ "floating_modifier", cmd_floating_mod },
{ "focus", cmd_focus },
{ "focus_follows_mouse", cmd_focus_follows_mouse },
+ { "for_window", cmd_for_window },
{ "fullscreen", cmd_fullscreen },
{ "gaps", cmd_gaps },
{ "kill", cmd_kill },
@@ -1090,6 +1107,7 @@ static struct cmd_handler *find_handler(char *line) {
enum cmd_status handle_command(char *exec) {
sway_log(L_INFO, "Handling command '%s'", exec);
int argc;
+ char *criteria = NULL;
char **argv = split_args(exec, &argc);
enum cmd_status status = CMD_FAILURE;
struct cmd_handler *handler;
@@ -1097,7 +1115,7 @@ enum cmd_status handle_command(char *exec) {
return status;
}
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]);
}
free_argv(argc, argv);
@@ -1108,6 +1126,7 @@ enum cmd_status config_command(char *exec) {
sway_log(L_INFO, "handling config command '%s'", exec);
int argc;
char **argv = split_args(exec, &argc);
+ char *criteria = NULL;
enum cmd_status status = CMD_FAILURE;
struct cmd_handler *handler;
if (!argc) {
@@ -1127,7 +1146,7 @@ enum cmd_status config_command(char *exec) {
for (; i < e; ++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) {
sway_log(L_ERROR, "Config load failed for line `%s'", exec);
} else if (status == CMD_DEFER) {
diff --git a/sway/config.c b/sway/config.c
index 23d6ac0d..da92030e 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -286,3 +286,28 @@ char *do_var_replacement(char *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;
+}
+
diff --git a/sway/container.c b/sway/container.c
index ef0e6c55..baf84378 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <strings.h>
+#include <pcre.h>
#include "config.h"
#include "container.h"
#include "workspace.h"
@@ -53,26 +54,30 @@ static void free_swayc(swayc_t *cont) {
// New containers
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);
+ int i, len;
+
// Find current outputs to see if this already exists
- {
- int i, len = root_container.children->length;
+ if (name) {
+ len = root_container.children->length;
for (i = 0; i < len; ++i) {
swayc_t *op = root_container.children->items[i];
- const char *op_name = op->name;
- if (op_name && name && strcmp(op_name, name) == 0) {
- sway_log(L_DEBUG, "restoring output %lu:%s", handle, op_name);
+ if (strcmp(op->name, name) == 0) {
+ sway_log(L_DEBUG, "restoring output %lu:%s", handle, op->name);
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;
- int i;
- for (i = 0; i < config->output_configs->length; ++i) {
+ len = config->output_configs->length;
+ for (i = 0; i < len; ++i) {
oc = config->output_configs->items[i];
if (strcasecmp(name, oc->name) == 0) {
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);
- 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->name = name ? strdup(name) : NULL;
-
- // Find position for it
- if (oc && oc->x != -1 && oc->y != -1) {
- sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y);
- output->x = oc->x;
- output->y = oc->y;
- } else {
- int x = 0;
- for (i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (c->type == C_OUTPUT) {
- if (c->width + c->x > x) {
- x = c->width + c->x;
- }
- }
- }
- output->x = x;
- }
- 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;
+ if (oc) {
+ // Set output width/height
+ 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->y = oc->y;
+ } else {
+ unsigned int x = 0;
+ len = root_container.children->length;
+ for (i = 0; i < len; ++i) {
+ swayc_t *c = root_container.children->items[i];
+ if (c->type == C_OUTPUT) {
+ unsigned int cx = c->width + c->x;
+ if (cx > x) {
+ x = cx;
+ }
}
- sway_log(L_DEBUG, "So we're going to use it");
- ws_name = strdup(wso->workspace);
- break;
}
+ output->x = x;
}
}
- if (!ws_name) {
- ws_name = workspace_next_name();
- }
+ // Add as child to root
+ add_child(&root_container, output);
// create and initilize default workspace
- swayc_t *ws = new_workspace(output, ws_name);
+ swayc_t *ws = new_workspace(output, NULL);
ws->is_focused = true;
- free(ws_name);
-
return output;
}
swayc_t *new_workspace(swayc_t *output, const char *name) {
- if (!ASSERT_NONNULL(output)) {
- return NULL;
+ swayc_t *ws = NULL;
+ struct workspace_output *wsop;
+ if (name) {
+ // Find existing workspace with same name.
+ /