Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix commands: criteria, layout, move, workspace #2392

Merged
merged 11 commits into from
Aug 6, 2018
2 changes: 1 addition & 1 deletion include/sway/tree/container.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct sway_container {

enum sway_container_type type;
enum sway_container_layout layout;
enum sway_container_layout prev_layout;
enum sway_container_layout prev_split_layout;

bool is_sticky;

Expand Down
5 changes: 5 additions & 0 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ void view_update_title(struct sway_view *view, bool force);
*/
void view_execute_criteria(struct sway_view *view);

/**
* Find any view that has the given mark and return it.
*/
struct sway_view *view_find_mark(char *mark);

/**
* Find any view that has the given mark and remove the mark from the view.
* Returns true if it matched a view.
Expand Down
4 changes: 3 additions & 1 deletion include/sway/tree/workspace.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _SWAY_WORKSPACE_H
#define _SWAY_WORKSPACE_H

#include <stdbool.h>
#include "sway/tree/container.h"

struct sway_view;
Expand All @@ -17,7 +18,8 @@ extern char *prev_workspace_name;

char *workspace_next_name(const char *output_name);

bool workspace_switch(struct sway_container *workspace);
bool workspace_switch(struct sway_container *workspace,
bool no_auto_back_and_forth);

struct sway_container *workspace_by_number(const char* name);

Expand Down
105 changes: 80 additions & 25 deletions sway/commands/layout.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "log.h"

static bool parse_layout_string(char *s, enum sway_container_layout *ptr) {
if (strcasecmp(s, "splith") == 0) {
*ptr = L_HORIZ;
} else if (strcasecmp(s, "splitv") == 0) {
*ptr = L_VERT;
} else if (strcasecmp(s, "tabbed") == 0) {
*ptr = L_TABBED;
} else if (strcasecmp(s, "stacking") == 0) {
*ptr = L_STACKED;
} else {
return false;
}
return true;
}

static const char* expected_syntax =
"Expected 'layout default|tabbed|stacking|splitv|splith' or "
"'layout toggle [split|all]' or "
"'layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]...'";

struct cmd_results *cmd_layout(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
Expand All @@ -21,35 +42,69 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
parent = parent->parent;
}

if (strcasecmp(argv[0], "default") == 0) {
parent->layout = parent->prev_layout;
if (parent->layout == L_NONE) {
parent->layout = container_get_default_layout(parent);
}
} else {
if (parent->layout != L_TABBED && parent->layout != L_STACKED) {
parent->prev_layout = parent->layout;
}

if (strcasecmp(argv[0], "splith") == 0) {
parent->layout = L_HORIZ;
} else if (strcasecmp(argv[0], "splitv") == 0) {
parent->layout = L_VERT;
} else if (strcasecmp(argv[0], "tabbed") == 0) {
parent->layout = L_TABBED;
} else if (strcasecmp(argv[0], "stacking") == 0) {
parent->layout = L_STACKED;
} else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
if (parent->layout == L_HORIZ) {
parent->layout = L_VERT;
enum sway_container_layout prev = parent->layout;
bool assigned_directly = parse_layout_string(argv[0], &parent->layout);
if (!assigned_directly) {
if (strcasecmp(argv[0], "default") == 0) {
parent->layout = parent->prev_split_layout;
} else if (strcasecmp(argv[0], "toggle") == 0) {
if (argc == 1) {
parent->layout =
parent->layout == L_STACKED ? L_TABBED :
parent->layout == L_TABBED ? parent->prev_split_layout : L_STACKED;
} else if (argc == 2) {
if (strcasecmp(argv[1], "all") == 0) {
parent->layout =
parent->layout == L_HORIZ ? L_VERT :
parent->layout == L_VERT ? L_STACKED :
parent->layout == L_STACKED ? L_TABBED : L_HORIZ;
} else if (strcasecmp(argv[1], "split") == 0) {
parent->layout =
parent->layout == L_HORIZ ? L_VERT :
parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
} else {
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
}
} else {
parent->layout = L_HORIZ;
enum sway_container_layout parsed_layout;
int curr = 1;
for (; curr < argc; curr++) {
bool valid = parse_layout_string(argv[curr], &parsed_layout);
if ((valid && parsed_layout == parent->layout) ||
(strcmp(argv[curr], "split") == 0 &&
(parent->layout == L_VERT || parent->layout == L_HORIZ))) {
break;
}
}
for (int i = curr + 1; i != curr; ++i) {
// cycle round to find next valid layout
if (i >= argc) {
i = 1;
}
if (parse_layout_string(argv[i], &parent->layout)) {
break;
} else if (strcmp(argv[i], "split") == 0) {
parent->layout =
parent->layout == L_HORIZ ? L_VERT :
parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
break;
} // invalid layout strings are silently ignored
}
}
} else {
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
}
}

container_notify_subtree_changed(parent);
arrange_windows(parent);
if (parent->layout == L_NONE) {
parent->layout = container_get_default_layout(parent);
}
if (prev != parent->layout) {
if (prev != L_TABBED && prev != L_STACKED) {
parent->prev_split_layout = prev;
}
container_notify_subtree_changed(parent);
arrange_windows(parent);
}

return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
Loading