Revert "Refactor tree"

master
Drew DeVault 7 years ago committed by GitHub
parent 6b7841b11f
commit d0c7f66e95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,8 +10,8 @@
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <time.h> #include <time.h>
#include "list.h" #include "list.h"
#include "tree/layout.h" #include "layout.h"
#include "tree/container.h" #include "container.h"
/** /**
* Describes a variable created via the `set` command. * Describes a variable created via the `set` command.
@ -299,8 +299,8 @@ struct sway_config {
char *floating_scroll_down_cmd; char *floating_scroll_down_cmd;
char *floating_scroll_left_cmd; char *floating_scroll_left_cmd;
char *floating_scroll_right_cmd; char *floating_scroll_right_cmd;
enum sway_container_layout default_orientation; enum swayc_layouts default_orientation;
enum sway_container_layout default_layout; enum swayc_layouts default_layout;
char *font; char *font;
int font_height; int font_height;
@ -324,8 +324,8 @@ struct sway_config {
list_t *config_chain; list_t *config_chain;
const char *current_config; const char *current_config;
enum sway_container_border border; enum swayc_border_types border;
enum sway_container_border floating_border; enum swayc_border_types floating_border;
int border_thickness; int border_thickness;
int floating_border_thickness; int floating_border_thickness;
enum edge_border_types hide_edge_borders; enum edge_border_types hide_edge_borders;
@ -356,7 +356,7 @@ struct sway_config {
struct input_config *input_config; struct input_config *input_config;
struct seat_config *seat_config; struct seat_config *seat_config;
struct sway_seat *seat; struct sway_seat *seat;
struct sway_container *current_container; swayc_t *current_container;
} handler_context; } handler_context;
}; };
@ -416,8 +416,7 @@ void output_get_identifier(char *identifier, size_t len,
struct sway_output *output); struct sway_output *output);
struct output_config *new_output_config(const char *name); struct output_config *new_output_config(const char *name);
void merge_output_config(struct output_config *dst, struct output_config *src); void merge_output_config(struct output_config *dst, struct output_config *src);
void apply_output_config(struct output_config *oc, void apply_output_config(struct output_config *oc, swayc_t *output);
struct sway_container *output);
void free_output_config(struct output_config *oc); void free_output_config(struct output_config *oc);
/** /**

@ -0,0 +1,169 @@
#ifndef _SWAY_CONTAINER_H
#define _SWAY_CONTAINER_H
#include <stdint.h>
#include <sys/types.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_surface.h>
#include "list.h"
typedef struct sway_container swayc_t;
extern swayc_t root_container;
struct sway_view;
struct sway_seat;
/**
* Different kinds of containers.
*
* This enum is in order. A container will never be inside of a container below
* it on this list.
*/
enum swayc_types {
C_ROOT, /**< The root container. Only one of these ever exists. */
C_OUTPUT, /**< An output (aka monitor, head, etc). */
C_WORKSPACE, /**< A workspace. */
C_CONTAINER, /**< A manually created container. */
C_VIEW, /**< A view (aka window). */
C_TYPES,
};
/**
* Different ways to arrange a container.
*/
enum swayc_layouts {
L_NONE, /**< Used for containers that have no layout (views, root) */
L_HORIZ,
L_VERT,
L_STACKED,
L_TABBED,
L_FLOATING, /**< A psuedo-container, removed from the tree, to hold floating windows */
/* Awesome/Monad style auto layouts */
L_AUTO_LEFT,
L_AUTO_RIGHT,
L_AUTO_TOP,
L_AUTO_BOTTOM,
L_AUTO_FIRST = L_AUTO_LEFT,
L_AUTO_LAST = L_AUTO_BOTTOM,
// Keep last
L_LAYOUTS,
};
enum swayc_border_types {
B_NONE, /**< No border */
B_PIXEL, /**< 1px border */
B_NORMAL, /**< Normal border with title bar */
};
struct sway_root;
struct sway_output;
struct sway_view;
/**
* Stores information about a container.
*
* The tree is made of these. Views are containers that cannot have children.
*/
struct sway_container {
union {
// TODO: Encapsulate state for other node types as well like C_CONTAINER
struct sway_root *sway_root; // C_ROOT
struct sway_output *sway_output; // C_OUTPUT
struct sway_view *sway_view; // C_VIEW
};
/**
* A unique ID to identify this container. Primarily used in the
* get_tree JSON output.
*/
size_t id;
char *name;
enum swayc_types type;
enum swayc_layouts layout;
enum swayc_layouts prev_layout;
enum swayc_layouts workspace_layout;
/**
* The coordinates that this view appear at, relative to the output they
* are located on (output containers have absolute coordinates).
*/
double x, y;
/**
* Width and height of this container, without borders or gaps.
*/
double width, height;
list_t *children;
/**
* The parent of this container. NULL for the root container.
*/
struct sway_container *parent;
/**
* Number of master views in auto layouts.
*/
size_t nb_master;
/**
* Number of slave groups (e.g. columns) in auto layouts.
*/
size_t nb_slave_groups;
/**
* Marks applied to the container, list_t of char*.
*/
list_t *marks;
struct {
struct wl_signal destroy;
} events;
};
void swayc_descendants_of_type(swayc_t *root, enum swayc_types type,
void (*func)(swayc_t *item, void *data), void *data);
swayc_t *new_output(struct sway_output *sway_output);
swayc_t *new_workspace(swayc_t *output, const char *name);
swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view);
swayc_t *destroy_output(swayc_t *output);
swayc_t *destroy_view(swayc_t *view);
swayc_t *next_view_sibling(struct sway_seat *seat);
/**
* Finds a container based on test criteria. Returns the first container that
* passes the test.
*/
swayc_t *swayc_by_test(swayc_t *container,
bool (*test)(swayc_t *view, void *data), void *data);
/**
* Finds a parent container with the given swayc_type.
*/
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type);
/**
* Maps a container's children over a function.
*/
void container_map(swayc_t *container,
void (*f)(swayc_t *view, void *data), void *data);
swayc_t *swayc_at(swayc_t *parent, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy);
/**
* Apply the function for each child of the container breadth first.
*/
void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
void *data);
swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout);
#endif

@ -1,7 +1,7 @@
#ifndef _SWAY_CRITERIA_H #ifndef _SWAY_CRITERIA_H
#define _SWAY_CRITERIA_H #define _SWAY_CRITERIA_H
#include "tree/container.h" #include "container.h"
#include "list.h" #include "list.h"
/** /**
@ -31,12 +31,12 @@ char *extract_crit_tokens(list_t *tokens, const char *criteria);
// Returns list of criteria that match given container. These criteria have // Returns list of criteria that match given container. These criteria have
// been set with `for_window` commands and have an associated cmdlist. // been set with `for_window` commands and have an associated cmdlist.
list_t *criteria_for(struct sway_container *cont); list_t *criteria_for(swayc_t *cont);
// Returns a list of all containers that match the given list of tokens. // Returns a list of all containers that match the given list of tokens.
list_t *container_for_crit_tokens(list_t *tokens); list_t *container_for_crit_tokens(list_t *tokens);
// Returns true if any criteria in the given list matches this container // Returns true if any criteria in the given list matches this container
bool criteria_any(struct sway_container *cont, list_t *criteria); bool criteria_any(swayc_t *cont, list_t *criteria);
#endif #endif

@ -31,10 +31,10 @@ struct sway_input_manager *sway_input_manager_create(
struct sway_server *server); struct sway_server *server);
bool sway_input_manager_has_focus(struct sway_input_manager *input, bool sway_input_manager_has_focus(struct sway_input_manager *input,
struct sway_container *container); swayc_t *container);
void sway_input_manager_set_focus(struct sway_input_manager *input, void sway_input_manager_set_focus(struct sway_input_manager *input,
struct sway_container *container); swayc_t *container);
void sway_input_manager_configure_xcursor(struct sway_input_manager *input); void sway_input_manager_configure_xcursor(struct sway_input_manager *input);

@ -14,7 +14,7 @@ struct sway_seat_device {
struct sway_seat_container { struct sway_seat_container {
struct sway_seat *seat; struct sway_seat *seat;
struct sway_container *container; swayc_t *container;
struct wl_list link; // sway_seat::focus_stack struct wl_list link; // sway_seat::focus_stack
@ -54,9 +54,9 @@ void sway_seat_remove_device(struct sway_seat *seat,
void sway_seat_configure_xcursor(struct sway_seat *seat); void sway_seat_configure_xcursor(struct sway_seat *seat);
void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *container); void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container);
struct sway_container *sway_seat_get_focus(struct sway_seat *seat); swayc_t *sway_seat_get_focus(struct sway_seat *seat);
/** /**
* Return the last container to be focused for the seat (or the most recently * Return the last container to be focused for the seat (or the most recently
@ -67,11 +67,10 @@ struct sway_container *sway_seat_get_focus(struct sway_seat *seat);
* is destroyed, or focus moves to a container with children and we need to * is destroyed, or focus moves to a container with children and we need to
* descend into the next leaf in focus order. * descend into the next leaf in focus order.
*/ */
struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container);
struct sway_container *container);
struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat,
enum sway_container_type type); enum swayc_types type);
void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config); void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config);

@ -1,13 +1,13 @@
#ifndef _SWAY_IPC_JSON_H #ifndef _SWAY_IPC_JSON_H
#define _SWAY_IPC_JSON_H #define _SWAY_IPC_JSON_H
#include <json-c/json.h> #include <json-c/json.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
json_object *ipc_json_get_version(); json_object *ipc_json_get_version();
json_object *ipc_json_describe_container(struct sway_container *c); json_object *ipc_json_describe_container(swayc_t *c);
json_object *ipc_json_describe_container_recursive(struct sway_container *c); json_object *ipc_json_describe_container_recursive(swayc_t *c);
json_object *ipc_json_describe_input(struct sway_input_device *device); json_object *ipc_json_describe_input(struct sway_input_device *device);
#endif #endif

@ -1,17 +1,15 @@
#ifndef _SWAY_IPC_SERVER_H #ifndef _SWAY_IPC_SERVER_H
#define _SWAY_IPC_SERVER_H #define _SWAY_IPC_SERVER_H
#include <sys/socket.h> #include <sys/socket.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "ipc.h" #include "ipc.h"
struct sway_server; struct sway_server;
void ipc_init(struct sway_server *server); void ipc_init(struct sway_server *server);
void ipc_terminate(void); void ipc_terminate(void);
struct sockaddr_un *ipc_user_sockaddr(void); struct sockaddr_un *ipc_user_sockaddr(void);
void ipc_event_window(struct sway_container *window, const char *change); void ipc_event_window(swayc_t *window, const char *change);
#endif #endif

@ -0,0 +1,43 @@
#ifndef _SWAY_LAYOUT_H
#define _SWAY_LAYOUT_H
#include <wlr/types/wlr_output_layout.h>
#include "sway/container.h"
enum movement_direction {
MOVE_LEFT,
MOVE_RIGHT,
MOVE_UP,
MOVE_DOWN,
MOVE_PARENT,
MOVE_CHILD,
MOVE_NEXT,
MOVE_PREV,
MOVE_FIRST
};
struct sway_container;
struct sway_root {
struct wlr_output_layout *output_layout;
struct wl_listener output_layout_change;
struct wl_list unmanaged_views; // sway_view::unmanaged_view_link
struct {
struct wl_signal new_container;
} events;
};
void init_layout(void);
void add_child(struct sway_container *parent, struct sway_container *child);
swayc_t *add_sibling(swayc_t *parent, swayc_t *child);
struct sway_container *remove_child(struct sway_container *child);
enum swayc_layouts default_layout(struct sway_container *output);
void sort_workspaces(struct sway_container *output);
void arrange_windows(struct sway_container *container, double width, double height);
swayc_t *get_swayc_in_direction(swayc_t *container,
struct sway_seat *seat, enum movement_direction dir);
#endif

@ -1,137 +0,0 @@
#ifndef _SWAY_CONTAINER_H
#define _SWAY_CONTAINER_H
#include <stdint.h>
#include <sys/types.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_surface.h>
#include "list.h"
extern struct sway_container root_container;
struct sway_view;
struct sway_seat;
/**
* Different kinds of containers.
*
* This enum is in order. A container will never be inside of a container below
* it on this list.
*/
enum sway_container_type {
C_ROOT,
C_OUTPUT,
C_WORKSPACE,
C_CONTAINER,
C_VIEW,
C_TYPES,
};
enum sway_container_layout {
L_NONE,
L_HORIZ,
L_VERT,
L_STACKED,
L_TABBED,
L_FLOATING,
// Keep last
L_LAYOUTS,
};
enum sway_container_border {
B_NONE,
B_PIXEL,
B_NORMAL,
};
struct sway_root;
struct sway_output;
struct sway_view;
struct sway_container {
union {
// TODO: Encapsulate state for other node types as well like C_CONTAINER
struct sway_root *sway_root;
struct sway_output *sway_output;
struct sway_view *sway_view;
};
/**
* A unique ID to identify this container. Primarily used in the
* get_tree JSON output.
*/
size_t id;
char *name;
enum sway_container_type type;
enum sway_container_layout layout;
enum sway_container_layout prev_layout;
enum sway_container_layout workspace_layout;
// TODO convert to layout coordinates
double x, y;
// does not include borders or gaps.
double width, height;
list_t *children;
struct sway_container *parent;
list_t *marks; // list of char*
struct {
struct wl_signal destroy;
} events;
};
// TODO only one container create function and pass the type?
struct sway_container *container_output_create(
struct sway_output *sway_output);
struct sway_container *container_workspace_create(
struct sway_container *output, const char *name);
struct sway_container *container_view_create(
struct sway_container *sibling, struct sway_view *sway_view);
struct sway_container *container_output_destroy(struct sway_container *output);
struct sway_container *container_view_destroy(struct sway_container *view);
struct sway_container *container_set_layout(struct sway_container *container,
enum sway_container_layout layout);
void container_descendents(struct sway_container *root,
enum sway_container_type type,
void (*func)(struct sway_container *item, void *data), void *data);
/**
* Finds a container based on test criteria. Returns the first container that
* passes the test.
*/
struct sway_container *container_find(struct sway_container *container,
bool (*test)(struct sway_container *view, void *data), void *data);
/**
* Finds a parent container with the given struct sway_containerype.
*/
struct sway_container *container_parent(struct sway_container *container,
enum sway_container_type type);
/**
* Find a container at the given coordinates.
*/
struct sway_container *container_at(struct sway_container *parent,
double lx, double ly, struct wlr_surface **surface,
double *sx, double *sy);
/**
* Apply the function for each child of the container breadth first.
*/
void container_for_each_descendent(struct sway_container *container,
void (*f)(struct sway_container *container, void *data), void *data);
#endif

@ -1,52 +0,0 @@
#ifndef _SWAY_LAYOUT_H
#define _SWAY_LAYOUT_H
#include <wlr/types/wlr_output_layout.h>
#include "sway/tree/container.h"
enum movement_direction {
MOVE_LEFT,
MOVE_RIGHT,
MOVE_UP,
MOVE_DOWN,
MOVE_PARENT,
MOVE_CHILD,
MOVE_NEXT,
MOVE_PREV,
MOVE_FIRST
};
struct sway_container;
struct sway_root {
struct wlr_output_layout *output_layout;
struct wl_listener output_layout_change;
struct wl_list unmanaged_views; // sway_view::unmanaged_view_link
struct {
struct wl_signal new_container;
} events;
};
void layout_init(void);
void container_add_child(struct sway_container *parent, struct sway_container *child);
struct sway_container *container_add_sibling(struct sway_container *parent,
struct sway_container *child);
struct sway_container *container_remove_child(struct sway_container *child);
enum sway_container_layout container_get_default_layout(struct sway_container *output);
void container_sort_workspaces(struct sway_container *output);
void arrange_windows(struct sway_container *container,
double width, double height);
struct sway_container *container_get_in_direction(struct sway_container
*container, struct sway_seat *seat, enum movement_direction dir);
#endif

@ -1,26 +0,0 @@
#ifndef _SWAY_WORKSPACE_H
#define _SWAY_WORKSPACE_H
#include "sway/tree/container.h"
extern char *prev_workspace_name;
char *workspace_next_name(const char *output_name);
struct sway_container *workspace_create(const char *name);
bool workspace_switch(struct sway_container *workspace);
struct sway_container *workspace_by_number(const char* name);
struct sway_container *workspace_by_name(const char*);
struct sway_container *workspace_output_next(struct sway_container *current);
struct sway_container *workspace_next(struct sway_container *current);
struct sway_container *workspace_output_prev(struct sway_container *current);
struct sway_container *workspace_prev(struct sway_container *current);
#endif

@ -62,6 +62,10 @@ enum sway_view_prop {
VIEW_PROP_INSTANCE, VIEW_PROP_INSTANCE,
}; };
/**
* sway_view is a state container for surfaces that are arranged in the sway
* tree (shell surfaces).
*/
struct sway_view { struct sway_view {
enum sway_view_type type; enum sway_view_type type;
struct sway_container *swayc; struct sway_container *swayc;

@ -0,0 +1,20 @@
#ifndef _SWAY_WORKSPACE_H
#define _SWAY_WORKSPACE_H
#include "sway/container.h"
extern char *prev_workspace_name;
char *workspace_next_name(const char *output_name);
swayc_t *workspace_create(const char *name);
bool workspace_switch(swayc_t *workspace);
struct sway_container *workspace_by_number(const char* name);
swayc_t *workspace_by_name(const char*);
struct sway_container *workspace_output_next(swayc_t *current);
struct sway_container *workspace_next(swayc_t *current);
struct sway_container *workspace_output_prev(swayc_t *current);
struct sway_container *workspace_prev(swayc_t *current);
#endif

@ -6,8 +6,8 @@
#include <unistd.h> #include <unistd.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/workspace.h" #include "sway/workspace.h"
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"

@ -3,11 +3,10 @@
#include "log.h" #include "log.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/commands.h" #include "sway/commands.h"
static bool parse_movement_direction(const char *name, static bool parse_movement_direction(const char *name, enum movement_direction *out) {
enum movement_direction *out) {
if (strcasecmp(name, "left") == 0) { if (strcasecmp(name, "left") == 0) {
*out = MOVE_LEFT; *out = MOVE_LEFT;
} else if (strcasecmp(name, "right") == 0) { } else if (strcasecmp(name, "right") == 0) {
@ -32,7 +31,7 @@ static bool parse_movement_direction(const char *name,
} }
struct cmd_results *cmd_focus(int argc, char **argv) { struct cmd_results *cmd_focus(int argc, char **argv) {
struct sway_container *con = config->handler_context.current_container; swayc_t *con = config->handler_context.current_container;
struct sway_seat *seat = config->handler_context.seat; struct sway_seat *seat = config->handler_context.seat;
if (con->type < C_WORKSPACE) { if (con->type < C_WORKSPACE) {
return cmd_results_new(CMD_FAILURE, "focus", return cmd_results_new(CMD_FAILURE, "focus",
@ -51,7 +50,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
"Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'"); "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
} }
struct sway_container *next_focus = container_get_in_direction(con, seat, direction); swayc_t *next_focus = get_swayc_in_direction(con, seat, direction);
if (next_focus) { if (next_focus) {
sway_seat_set_focus(seat, next_focus); sway_seat_set_focus(seat, next_focus);
} }

@ -2,11 +2,11 @@
#include "log.h" #include "log.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/commands.h" #include "sway/commands.h"
struct cmd_results *cmd_kill(int argc, char **argv) { struct cmd_results *cmd_kill(int argc, char **argv) {
enum sway_container_type type = config->handler_context.current_container->type; enum swayc_types type = config->handler_context.current_container->type;
if (type != C_VIEW && type != C_CONTAINER) { if (type != C_VIEW && type != C_CONTAINER) {
return cmd_results_new(CMD_INVALID, NULL, return cmd_results_new(CMD_INVALID, NULL,
"Can only kill views and containers with this command"); "Can only kill views and containers with this command");

@ -1,8 +1,8 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "log.h" #include "log.h"
struct cmd_results *cmd_layout(int argc, char **argv) { struct cmd_results *cmd_layout(int argc, char **argv) {
@ -10,7 +10,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) { if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
return error; return error;
} }
struct sway_container *parent = config->handler_context.current_container; swayc_t *parent = config->handler_context.current_container;
// TODO: floating // TODO: floating
/* /*
@ -26,10 +26,10 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
// TODO: stacks and tabs // TODO: stacks and tabs
if (strcasecmp(argv[0], "default") == 0) { if (strcasecmp(argv[0], "default") == 0) {
container_set_layout(parent, parent->prev_layout); swayc_change_layout(parent, parent->prev_layout);
if (parent->layout == L_NONE) { if (parent->layout == L_NONE) {
struct sway_container *output = container_parent(parent, C_OUTPUT); swayc_t *output = swayc_parent_by_type(parent, C_OUTPUT);
container_set_layout(parent, container_get_default_layout(output)); swayc_change_layout(parent, default_layout(output));
} }
} else { } else {
if (parent->layout != L_TABBED && parent->layout != L_STACKED) { if (parent->layout != L_TABBED && parent->layout != L_STACKED) {
@ -37,15 +37,15 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
} }
if (strcasecmp(argv[0], "splith") == 0) { if (strcasecmp(argv[0], "splith") == 0) {
container_set_layout(parent, L_HORIZ); swayc_change_layout(parent, L_HORIZ);
} else if (strcasecmp(argv[0], "splitv") == 0) { } else if (strcasecmp(argv[0], "splitv") == 0) {
container_set_layout(parent, L_VERT); swayc_change_layout(parent, L_VERT);
} else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE
|| parent->workspace_layout == L_HORIZ)) { || parent->workspace_layout == L_HORIZ)) {
container_set_layout(parent, L_VERT); swayc_change_layout(parent, L_VERT);
} else { } else {
container_set_layout(parent, L_HORIZ); swayc_change_layout(parent, L_HORIZ);
} }
} }
} }

@ -296,7 +296,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
char identifier[128]; char identifier[128];
bool all = strcmp(output->name, "*") == 0; bool all = strcmp(output->name, "*") == 0;
for (int i = 0; i < root_container.children->length; ++i) { for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *cont = root_container.children->items[i]; swayc_t *cont = root_container.children->items[i];
if (cont->type != C_OUTPUT) { if (cont->type != C_OUTPUT) {
continue; continue;
} }

@ -1,6 +1,6 @@
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
struct cmd_results *cmd_reload(int argc, char **argv) { struct cmd_results *cmd_reload(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;

@ -4,7 +4,7 @@
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/workspace.h" #include "sway/workspace.h"
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"
@ -17,15 +17,15 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
int output_location = -1; int output_location = -1;
struct sway_container *current_container = config->handler_context.current_container; swayc_t *current_container = config->handler_context.current_container;
struct sway_container *old_workspace = NULL, *old_output = NULL; swayc_t *old_workspace = NULL, *old_output = NULL;
if (current_container) { if (current_container) {
if (current_container->type == C_WORKSPACE) { if (current_container->type == C_WORKSPACE) {
old_workspace = current_container; old_workspace = current_container;
} else { } else {
old_workspace = container_parent(current_container, C_WORKSPACE); old_workspace = swayc_parent_by_type(current_container, C_WORKSPACE);
} }
old_output = container_parent(current_container, C_OUTPUT); old_output = swayc_parent_by_type(current_container, C_OUTPUT);
} }
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
@ -57,7 +57,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
if (config->reading || !config->active) { if (config->reading || !config->active) {
return cmd_results_new(CMD_DEFER, "workspace", NULL); return cmd_results_new(CMD_DEFER, "workspace", NULL);
} }
struct sway_container *ws = NULL; swayc_t *ws = NULL;
if (strcasecmp(argv[0], "number") == 0) { if (strcasecmp(argv[0], "number") == 0) {
if (!(ws = workspace_by_number(argv[1]))) { if (!(ws = workspace_by_number(argv[1]))) {
char *name = join_args(argv + 1, argc - 1); char *name = join_args(argv + 1, argc - 1);
@ -92,7 +92,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
workspace_switch(ws); workspace_switch(ws);
current_container = current_container =
sway_seat_get_focus(config->handler_context.seat); sway_seat_get_focus(config->handler_context.seat);
struct sway_container *new_output = container_parent(current_container, C_OUTPUT); swayc_t *new_output = swayc_parent_by_type(current_container, C_OUTPUT);
if (config->mouse_warping && old_output != new_output) { if (config->mouse_warping && old_output != new_output) {
// TODO: Warp mouse // TODO: Warp mouse

@ -24,7 +24,7 @@
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "readline.h" #include "readline.h"
#include "stringop.h" #include "stringop.h"
#include "list.h" #include "list.h"

@ -120,14 +120,14 @@ void terminate_swaybg(pid_t pid) {
} }
} }
void apply_output_config(struct output_config *oc, struct sway_container *output) { void apply_output_config(struct output_config *oc, swayc_t *output) {
assert(output->type == C_OUTPUT); assert(output->type == C_OUTPUT);
struct wlr_output *wlr_output = output->sway_output->wlr_output; struct wlr_output *wlr_output = output->sway_output->wlr_output;
if (oc && oc->enabled == 0) { if (oc && oc->enabled == 0) {
wlr_output_layout_remove(root_container.sway_root->output_layout, wlr_output_layout_remove(root_container.sway_root->output_layout,
wlr_output); wlr_output);
container_output_destroy(output); destroy_output(output);
return; return;
} }

@ -4,9 +4,9 @@
#include <stdbool.h> #include <stdbool.h>
#include <pcre.h> #include <pcre.h>
#include "sway/criteria.h" #include "sway/criteria.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "stringop.h" #include "stringop.h"
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
@ -272,7 +272,7 @@ static int regex_cmp(const char *item, const pcre *regex) {
} }
// test a single view if it matches list of criteria tokens (all of them). // test a single view if it matches list of criteria tokens (all of them).
static bool criteria_test(struct sway_container *cont, list_t *tokens) { static bool criteria_test(swayc_t *cont, list_t *tokens) {
if (cont->type != C_VIEW) { if (cont->type != C_VIEW) {
return false; return false;
} }
@ -398,7 +398,7 @@ void free_criteria(struct criteria *crit) {
free(crit); free(crit);
} }
bool criteria_any(struct sway_container *cont, list_t *criteria) { bool criteria_any(swayc_t *cont, list_t *criteria) {
for (int i = 0; i < criteria->length; i++) { for (int i = 0; i < criteria->length; i++) {
struct criteria *bc = criteria->items[i]; struct criteria *bc = criteria->items[i];
if (criteria_test(cont, bc->tokens)) { if (criteria_test(cont, bc->tokens)) {
@ -408,7 +408,7 @@ bool criteria_any(struct sway_container *cont, list_t *criteria) {
return false; return false;
} }
list_t *criteria_for(struct sway_container *cont) { list_t *criteria_for(swayc_t *cont) {
list_t *criteria = config->criteria, *matches = create_list(); list_t *criteria = config->criteria, *matches = create_list();
for (int i = 0; i < criteria->length; i++) { for (int i = 0; i < criteria->length; i++) {
struct criteria *bc = criteria->items[i]; struct criteria *bc = criteria->items[i];
@ -424,7 +424,7 @@ struct list_tokens {
list_t *tokens; list_t *tokens;
}; };
static void container_match_add(struct sway_container *container, static void container_match_add(swayc_t *container,
struct list_tokens *list_tokens) { struct list_tokens *list_tokens) {
if (criteria_test(container, list_tokens->tokens)) { if (criteria_test(container, list_tokens->tokens)) {
list_add(list_tokens->list, container); list_add(list_tokens->list, container);
@ -435,8 +435,8 @@ list_t *container_for_crit_tokens(list_t *tokens) {
struct list_tokens list_tokens = struct list_tokens list_tokens =
(struct list_tokens){create_list(), tokens}; (struct list_tokens){create_list(), tokens};
container_for_each_descendent(&root_container, container_map(&root_container,
(void (*)(struct sway_container *, void *))container_match_add, (void (*)(swayc_t *, void *))container_match_add,
&list_tokens); &list_tokens);
// TODO look in the scratchpad // TODO look in the scratchpad

@ -7,7 +7,7 @@
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "sway/layers.h" #include "sway/layers.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"

@ -11,14 +11,14 @@
#include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_surface.h>
#include <wlr/types/wlr_wl_shell.h> #include <wlr/types/wlr_wl_shell.h>
#include "log.h" #include "log.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/layers.h" #include "sway/layers.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/view.h"
/** /**
* Rotate a child's position relative to a parent. The parent size is (pw, ph), * Rotate a child's position relative to a parent. The parent size is (pw, ph),
@ -145,7 +145,7 @@ struct render_data {
struct timespec *now; struct timespec *now;
}; };
static void output_frame_view(struct sway_container *view, void *data) { static void output_frame_view(swayc_t *view, void *data) {
struct render_data *rdata = data; struct render_data *rdata = data;
struct sway_output *output = rdata->output; struct sway_output *output = rdata->output;
struct timespec *now = rdata->now; struct timespec *now = rdata->now;
@ -219,16 +219,16 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
&soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); &soutput->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = sway_seat_get_focus_inactive(seat, soutput->swayc); swayc_t *focus = sway_seat_get_focus_inactive(seat, soutput->swayc);
struct sway_container *workspace = (focus->type == C_WORKSPACE ? swayc_t *workspace = (focus->type == C_WORKSPACE ?
focus : focus :
container_parent(focus, C_WORKSPACE)); swayc_parent_by_type(focus, C_WORKSPACE));
struct render_data rdata = { struct render_data rdata = {
.output = soutput, .output = soutput,
.now = &now, .now = &now,
}; };
container_descendents(workspace, C_VIEW, output_frame_view, &rdata); swayc_descendants_of_type(workspace, C_VIEW, output_frame_view, &rdata);
// render unmanaged views on top // render unmanaged views on top
struct sway_view *view; struct sway_view *view;
@ -259,7 +259,7 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) {
struct wlr_output *wlr_output = data; struct wlr_output *wlr_output = data;
wlr_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name); wlr_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name);
container_output_destroy(output->swayc); destroy_output(output->swayc);
} }
static void handle_output_mode(struct wl_listener *listener, void *data) { static void handle_output_mode(struct wl_listener *listener, void *data) {
@ -287,7 +287,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
wlr_output_set_mode(wlr_output, mode); wlr_output_set_mode(wlr_output, mode);
} }
output->swayc = container_output_create(output); output->swayc = new_output(output);
if (!output->swayc) { if (!output->swayc) {
free(output); free(output);
return; return;

@ -3,10 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_wl_shell.h> #include <wlr/types/wlr_wl_shell.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "log.h" #include "log.h"
@ -74,7 +74,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
wl_container_of(listener, sway_surface, destroy); wl_container_of(listener, sway_surface, destroy);
wl_list_remove(&sway_surface->commit.link); wl_list_remove(&sway_surface->commit.link);
wl_list_remove(&sway_surface->destroy.link); wl_list_remove(&sway_surface->destroy.link);
struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); swayc_t *parent = destroy_view(sway_surface->view->swayc);
free(sway_surface->view); free(sway_surface->view);
free(sway_surface); free(sway_surface);
arrange_windows(parent, -1, -1); arrange_windows(parent, -1, -1);
@ -132,8 +132,8 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy); wl_signal_add(&shell_surface->events.destroy, &sway_surface->destroy);
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
struct sway_container *cont = container_view_create(focus, sway_view); swayc_t *cont = new_view(focus, sway_view);
sway_view->swayc = cont; sway_view->swayc = cont;
arrange_windows(cont->parent, -1, -1); arrange_windows(cont->parent, -1, -1);

@ -3,10 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_xdg_shell_v6.h> #include <wlr/types/wlr_xdg_shell_v6.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "log.h" #include "log.h"
@ -83,7 +83,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
wl_container_of(listener, sway_xdg_surface, destroy); wl_container_of(listener, sway_xdg_surface, destroy);
wl_list_remove(&sway_xdg_surface->commit.link); wl_list_remove(&sway_xdg_surface->commit.link);
wl_list_remove(&sway_xdg_surface->destroy.link); wl_list_remove(&sway_xdg_surface->destroy.link);
struct sway_container *parent = container_view_destroy(sway_xdg_surface->view->swayc); swayc_t *parent = destroy_view(sway_xdg_surface->view->swayc);
free(sway_xdg_surface->view); free(sway_xdg_surface->view);
free(sway_xdg_surface); free(sway_xdg_surface);
arrange_windows(parent, -1, -1); arrange_windows(parent, -1, -1);
@ -137,8 +137,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy); wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy);
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
struct sway_container *cont = container_view_create(focus, sway_view); swayc_t *cont = new_view(focus, sway_view);
sway_view->swayc = cont; sway_view->swayc = cont;
arrange_windows(cont->parent, -1, -1); arrange_windows(cont->parent, -1, -1);

@ -5,10 +5,10 @@
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
@ -49,11 +49,11 @@ static void set_position(struct sway_view *view, double ox, double oy) {
if (!assert_xwayland(view)) { if (!assert_xwayland(view)) {
return; return;
} }
struct sway_container *output = container_parent(view->swayc, C_OUTPUT); swayc_t *output = swayc_parent_by_type(view->swayc, C_OUTPUT);
if (!sway_assert(output, "view must be within tree to set position")) { if (!sway_assert(output, "view must be within tree to set position")) {
return; return;
} }
struct sway_container *root = container_parent(output, C_ROOT); swayc_t *root = swayc_parent_by_type(output, C_ROOT);
if (!sway_assert(root, "output must be within tree to set position")) { if (!sway_assert(root, "output must be within tree to set position")) {
return; return;
} }
@ -114,7 +114,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
} }
} }
struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); swayc_t *parent = destroy_view(sway_surface->view->swayc);
if (parent) { if (parent) {
arrange_windows(parent, -1, -1); arrange_windows(parent, -1, -1);
} }
@ -132,7 +132,7 @@ static void handle_unmap_notify(struct wl_listener *listener, void *data) {
} }
// take it out of the tree // take it out of the tree
struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); swayc_t *parent = destroy_view(sway_surface->view->swayc);
if (parent) { if (parent) {
arrange_windows(parent, -1, -1); arrange_windows(parent, -1, -1);
} }
@ -155,12 +155,12 @@ static void handle_map_notify(struct wl_listener *listener, void *data) {
&sway_surface->view->unmanaged_view_link); &sway_surface->view->unmanaged_view_link);
} else { } else {
struct sway_view *view = sway_surface->view; struct sway_view *view = sway_surface->view;
container_view_destroy(view->swayc); destroy_view(view->swayc);
struct sway_container *parent = root_container.children->items[0]; swayc_t *parent = root_container.children->items[0];
parent = parent->children->items[0]; // workspace parent = parent->children->items[0]; // workspace
struct sway_container *cont = container_view_create(parent, view); swayc_t *cont = new_view(parent, view);
view->swayc = cont; view->swayc = cont;
arrange_windows(cont->parent, -1, -1); arrange_windows(cont->parent, -1, -1);
@ -238,8 +238,8 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
} }
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
struct sway_container *cont = container_view_create(focus, sway_view); swayc_t *cont = new_view(focus, sway_view);
sway_view->swayc = cont; sway_view->swayc = cont;
arrange_windows(cont->parent, -1, -1); arrange_windows(cont->parent, -1, -1);

@ -7,7 +7,7 @@
#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xcursor_manager.h>
#include "sway/input/cursor.h" #include "sway/input/cursor.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
@ -49,8 +49,8 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor,
} }
} }
struct sway_container *swayc = swayc_t *swayc =
container_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy); swayc_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy);
if (swayc) { if (swayc) {
wlr_seat_pointer_notify_enter(seat, surface, sx, sy); wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
wlr_seat_pointer_notify_motion(seat, time, sx, sy); wlr_seat_pointer_notify_motion(seat, time, sx, sy);
@ -87,8 +87,8 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
if (event->button == BTN_LEFT) { if (event->button == BTN_LEFT) {
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
double sx, sy; double sx, sy;
struct sway_container *swayc = swayc_t *swayc =
container_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy); swayc_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy);
sway_seat_set_focus(cursor->seat, swayc); sway_seat_set_focus(cursor->seat, swayc);
} }

@ -278,7 +278,7 @@ struct sway_input_manager *sway_input_manager_create(
} }
bool sway_input_manager_has_focus(struct sway_input_manager *input, bool sway_input_manager_has_focus(struct sway_input_manager *input,
struct sway_container *container) { swayc_t *container) {
struct sway_seat *seat = NULL; struct sway_seat *seat = NULL;
wl_list_for_each(seat, &input->seats, link) { wl_list_for_each(seat, &input->seats, link) {
if (sway_seat_get_focus(seat) == container) { if (sway_seat_get_focus(seat) == container) {
@ -290,7 +290,7 @@ bool sway_input_manager_has_focus(struct sway_input_manager *input,
} }
void sway_input_manager_set_focus(struct sway_input_manager *input, void sway_input_manager_set_focus(struct sway_input_manager *input,
struct sway_container *container) { swayc_t *container) {
struct sway_seat *seat ; struct sway_seat *seat ;
wl_list_for_each(seat, &input->seats, link) { wl_list_for_each(seat, &input->seats, link) {
sway_seat_set_focus(seat, container); sway_seat_set_focus(seat, container);

@ -1,13 +1,13 @@
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xcursor_manager.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/input/cursor.h" #include "sway/input/cursor.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/keyboard.h" #include "sway/input/keyboard.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "log.h" #include "log.h"
static void seat_device_destroy(struct sway_seat_device *seat_device) { static void seat_device_destroy(struct sway_seat_device *seat_device) {
@ -37,7 +37,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
struct sway_seat_container *seat_con = struct sway_seat_container *seat_con =
wl_container_of(listener, seat_con, destroy); wl_container_of(listener, seat_con, destroy);
struct sway_seat *seat = seat_con->seat; struct sway_seat *seat = seat_con->seat;
struct sway_container *con = seat_con->container; swayc_t *con = seat_con->container;
bool is_focus = (sway_seat_get_focus(seat) == con); bool is_focus = (sway_seat_get_focus(seat) == con);
@ -46,7 +46,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
if (is_focus) { if (is_focus) {
// pick next focus // pick next focus
sway_seat_set_focus(seat, NULL); sway_seat_set_focus(seat, NULL);
struct sway_container *next = sway_seat_get_focus_inactive(seat, con->parent); swayc_t *next = sway_seat_get_focus_inactive(seat, con->parent);
if (next == NULL) { if (next == NULL) {
next = con->parent; next = con->parent;
} }
@ -59,7 +59,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
} }
static struct sway_seat_container *seat_container_from_container( static struct sway_seat_container *seat_container_from_container(
struct sway_seat *seat, struct sway_container *con) { struct sway_seat *seat, swayc_t *con) {
if (con->type < C_WORKSPACE) { if (con->type < C_WORKSPACE) {
// these don't get seat containers ever // these don't get seat containers ever
return NULL; return NULL;
@ -89,11 +89,11 @@ static struct sway_seat_container *seat_container_from_container(
static void handle_new_container(struct wl_listener *listener, void *data) { static void handle_new_container(struct wl_listener *listener, void *data) {
struct sway_seat *seat = wl_container_of(listener, seat, new_container); struct sway_seat *seat = wl_container_of(listener, seat, new_container);
struct sway_container *con = data; swayc_t *con = data;
seat_container_from_container(seat, con); seat_container_from_container(seat, con);
} }
static void collect_focus_iter(struct sway_container *con, void *data) { static void collect_focus_iter(swayc_t *con, void *data) {
struct sway_seat *seat = data; struct sway_seat *seat = data;
if (con->type > C_WORKSPACE) { if (con->type > C_WORKSPACE) {
return; return;
@ -130,7 +130,7 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input,
// init the focus stack // init the focus stack
wl_list_init(&seat->focus_stack); wl_list_init(&seat->focus_stack);
container_for_each_descendent(&root_container, collect_focus_iter, seat); container_for_each_bfs(&root_container, collect_focus_iter, seat);
wl_signal_add(&root_container.sway_root->events.new_container, wl_signal_add(&root_container.sway_root->events.new_container,
&seat->new_container); &seat->new_container);
@ -166,7 +166,7 @@ static void seat_configure_keyboard(struct sway_seat *seat,
sway_keyboard_configure(seat_device->keyboard); sway_keyboard_configure(seat_device->keyboard);
wlr_seat_set_keyboard(seat->wlr_seat, wlr_seat_set_keyboard(seat->wlr_seat,
seat_device->input_device->wlr_device); seat_device->input_device->wlr_device);
struct sway_container *focus = sway_seat_get_focus(seat); swayc_t *focus = sway_seat_get_focus(seat);
if (focus && focus->type == C_VIEW) { if (focus && focus->type == C_VIEW) {
// force notify reenter to pick up the new configuration // force notify reenter to pick up the new configuration
wlr_seat_keyboard_clear_focus(seat->wlr_seat); wlr_seat_keyboard_clear_focus(seat->wlr_seat);
@ -270,7 +270,7 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
} }
for (int i = 0; i < root_container.children->length; ++i) { for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *output_container = root_container.children->items[i]; swayc_t *output_container = root_container.children->items[i];
struct wlr_output *output = struct wlr_output *output =
output_container->sway_output->wlr_output; output_container->sway_output->wlr_output;
bool result = bool result =
@ -289,8 +289,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
seat->cursor->cursor->y); seat->cursor->cursor->y);
} }
void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *container) { void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
struct sway_container *last_focus = sway_seat_get_focus(seat); swayc_t *last_focus = sway_seat_get_focus(seat);
if (container && last_focus == container) { if (container && last_focus == container) {
return; return;
@ -330,9 +330,9 @@ void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *containe
seat->has_focus = (container != NULL); seat->has_focus = (container != NULL);
} }
struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container) {
struct sway_seat_container *current = NULL; struct sway_seat_container *current = NULL;
struct sway_container *parent = NULL; swayc_t *parent = NULL;
wl_list_for_each(current, &seat->focus_stack, link) { wl_list_for_each(current, &seat->focus_stack, link) {
parent = current->container->parent; parent = current->container->parent;
@ -351,21 +351,21 @@ struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, stru
return NULL; return NULL;
} }
struct sway_container *sway_seat_get_focus(struct sway_seat *seat) { swayc_t *sway_seat_get_focus(struct sway_seat *seat) {
if (!seat->has_focus) { if (!seat->has_focus) {
return NULL; return NULL;
} }
return sway_seat_get_focus_inactive(seat, &root_container); return sway_seat_get_focus_inactive(seat, &root_container);
} }
struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat,
enum sway_container_type type) { enum swayc_types type) {
struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
if (focus->type == type) { if (focus->type == type) {
return focus; return focus;
} }
return container_parent(focus, type); return swayc_parent_by_type(focus, type);
} }
void sway_seat_set_config(struct sway_seat *seat, void sway_seat_set_config(struct sway_seat *seat,

@ -3,7 +3,7 @@
#include <ctype.h> #include <ctype.h>
#include "log.h" #include "log.h"
#include "sway/ipc-json.h" #include "sway/ipc-json.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
@ -25,7 +25,7 @@ json_object *ipc_json_get_version() {
return version; return version;
} }
static json_object *ipc_json_create_rect(struct sway_container *c) { static json_object *ipc_json_create_rect(swayc_t *c) {
json_object *rect = json_object_new_object(); json_object *rect = json_object_new_object();
json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x)); json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x));
@ -36,7 +36,7 @@ static json_object *ipc_json_create_rect(struct sway_container *c) {
return rect; return rect;
} }
static void ipc_json_describe_root(struct sway_container *root, json_object *object) { static void ipc_json_describe_root(swayc_t *root, json_object *object) {
json_object_object_add(object, "type", json_object_new_string("root")); json_object_object_add(object, "type", json_object_new_string("root"));
json_object_object_add(object, "layout", json_object_new_string("splith")); json_object_object_add(object, "layout", json_object_new_string("splith"));
} }
@ -63,7 +63,7 @@ static const char *ipc_json_get_output_transform(enum wl_output_transform transf
return NULL; return NULL;
} }
static void ipc_json_describe_output(struct sway_container *container, json_object *object) { static void ipc_json_describe_output(swayc_t *container, json_object *object) {
struct wlr_output *wlr_output = container->sway_output->wlr_output; struct wlr_output *wlr_output = container->sway_output->wlr_output;
json_object_object_add(object, "type", json_object_new_string("output")); json_object_object_add(object, "type", json_object_new_string("output"));
json_object_object_add(object, "active", json_object_new_boolean(true)); json_object_object_add(object, "active", json_object_new_boolean(true));
@ -94,7 +94,7 @@ static void ipc_json_describe_output(struct sway_container *container, json_obje
json_object_object_add(object, "modes", modes_array); json_object_object_add(object, "modes", modes_array);
} }
static void ipc_json_describe_workspace(struct sway_container *workspace, json_object *object) { static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) {
int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1; int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1;
json_object_object_add(object, "num", json_object_new_int(num)); json_object_object_add(object, "num", json_object_new_int(num));
@ -102,11 +102,11 @@ static void ipc_json_describe_workspace(struct sway_container *workspace, json_o
json_object_object_add(object, "type", json_object_new_string("workspace")); json_object_object_add(object, "type", json_object_new_string("workspace"));
} }
static void ipc_json_describe_view(struct sway_container *c, json_object *object) { static void ipc_json_describe_view(swayc_t *c, json_object *object) {
json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL); json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL);
} }
json_object *ipc_json_describe_container(struct sway_container *c) { json_object *ipc_json_describe_container(swayc_t *c) {
if (!(sway_assert(c, "Container must not be null."))) { if (!(sway_assert(c, "Container must not be null."))) {
return NULL; return NULL;
} }
@ -147,7 +147,7 @@ json_object *ipc_json_describe_container(struct sway_container *c) {
return object; return object;
} }
json_object *ipc_json_describe_container_recursive(struct sway_container *c) { json_object *ipc_json_describe_container_recursive(swayc_t *c) {
json_object *object = ipc_json_describe_container(c); json_object *object = ipc_json_describe_container(c);
int i; int i;

@ -279,7 +279,7 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event)
} }
} }
void ipc_event_window(struct sway_container *window, const char *change) { void ipc_event_window(swayc_t *window, const char *change) {
wlr_log(L_DEBUG, "Sending window::%s event", change); wlr_log(L_DEBUG, "Sending window::%s event", change);
json_object *obj = json_object_new_object(); json_object *obj = json_object_new_object();
json_object_object_add(obj, "change", json_object_new_string(change)); json_object_object_add(obj, "change", json_object_new_string(change));
@ -400,7 +400,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
{ {
json_object *outputs = json_object_new_array(); json_object *outputs = json_object_new_array();
for (int i = 0; i < root_container.children->length; ++i) { for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *container = root_container.children->items[i]; swayc_t *container = root_container.children->items[i];
if (container->type == C_OUTPUT) { if (container->type == C_OUTPUT) {
json_object_array_add(outputs, json_object_array_add(outputs,
ipc_json_describe_container(container)); ipc_json_describe_container(container));

@ -18,7 +18,7 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "sway/config.h" #include "sway/config.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/ipc-server.h" #include "sway/ipc-server.h"
#include "ipc-client.h" #include "ipc-client.h"
#include "readline.h" #include "readline.h"
@ -382,7 +382,7 @@ int main(int argc, char **argv) {
wlr_log(L_INFO, "Starting sway version " SWAY_VERSION); wlr_log(L_INFO, "Starting sway version " SWAY_VERSION);
layout_init(); init_layout();
if (!server_init(&server)) { if (!server_init(&server)) {
return 1; return 1;

@ -7,14 +7,14 @@
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_wl_shell.h> #include <wlr/types/wlr_wl_shell.h>
#include "sway/config.h" #include "sway/config.h"
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/tree/workspace.h" #include "sway/workspace.h"
#include "sway/ipc-server.h" #include "sway/ipc-server.h"
#include "log.h" #include "log.h"
@ -33,15 +33,48 @@ static list_t *get_bfs_queue() {
return bfs_queue; return bfs_queue;
} }
static void notify_new_container(struct sway_container *container) { static void notify_new_container(swayc_t *container) {
wl_signal_emit(&root_container.sway_root->events.new_container, container); wl_signal_emit(&root_container.sway_root->events.new_container, container);
ipc_event_window(container, "new"); ipc_event_window(container, "new");
} }
static struct sway_container *container_create(enum sway_container_type type) { swayc_t *swayc_by_test(swayc_t *container,
bool (*test)(swayc_t *view, void *data), void *data) {
if (!container->children) {
return NULL;
}
// TODO: floating windows
for (int i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
if (test(child, data)) {
return child;
} else {
swayc_t *res = swayc_by_test(child, test, data);
if (res) {
return res;
}
}
}
return NULL;
}
void swayc_descendants_of_type(swayc_t *root, enum swayc_types type,
void (*func)(swayc_t *item, void *data), void *data) {
for (int i = 0; i < root->children->length; ++i) {
swayc_t *item = root->children->items[i];
if (item->type == type) {
func(item, data);
}
if (item->children && item->children->length) {
swayc_descendants_of_type(item, type, func, data);
}
}
}
static swayc_t *new_swayc(enum swayc_types type) {
// next id starts at 1 because 0 is assigned to root_container in layout.c // next id starts at 1 because 0 is assigned to root_container in layout.c
static size_t next_id = 1; static size_t next_id = 1;
struct sway_container *c = calloc(1, sizeof(struct sway_container)); swayc_t *c = calloc(1, sizeof(swayc_t));
if (!c) { if (!c) {
return NULL; return NULL;
} }
@ -49,6 +82,8 @@ static struct sway_container *container_create(enum sway_container_type type) {
c->layout = L_NONE; c->layout = L_NONE;
c->workspace_layout = L_NONE; c->workspace_layout = L_NONE;
c->type = type; c->type = type;
c->nb_master = 1;
c->nb_slave_groups = 1;
if (type != C_VIEW) { if (type != C_VIEW) {
c->children = create_list(); c->children = create_list();
} }
@ -58,18 +93,18 @@ static struct sway_container *container_create(enum sway_container_type type) {
return c; return c;
} }
static void container_destroy(struct sway_container *cont) { static void free_swayc(swayc_t *cont) {
if (cont == NULL) { if (!sway_assert(cont, "free_swayc passed NULL")) {
return; return;
} }
wl_signal_emit(&cont->events.destroy, cont); wl_signal_emit(&cont->events.destroy, cont);
if (cont->children) { if (cont->children) {
// remove children until there are no more, container_destroy calls // remove children until there are no more, free_swayc calls
// container_remove_child, which removes child from this container // remove_child, which removes child from this container
while (cont->children->length) { while (cont->children->length) {
container_destroy(cont->children->items[0]); free_swayc(cont->children->items[0]);
} }
list_free(cont->children); list_free(cont->children);
} }
@ -78,7 +113,7 @@ static void container_destroy(struct sway_container *cont) {
list_free(cont->marks); list_free(cont->marks);
} }
if (cont->parent) { if (cont->parent) {
container_remove_child(cont); remove_child(cont);
} }
if (cont->name) { if (cont->name) {
free(cont->name); free(cont->name);
@ -86,8 +121,7 @@ static void container_destroy(struct sway_container *cont) {
free(cont); free(cont);
} }
struct sway_container *container_output_create( swayc_t *new_output(struct sway_output *sway_output) {
struct sway_output *sway_output) {
struct wlr_box size; struct wlr_box size;
wlr_output_effective_resolution(sway_output->wlr_output, &size.width, wlr_output_effective_resolution(sway_output->wlr_output, &size.width,
&size.height); &size.height);
@ -122,22 +156,22 @@ struct sway_container *container_output_create(
return NULL; return NULL;
} }
struct sway_container *output = container_create(C_OUTPUT); swayc_t *output = new_swayc(C_OUTPUT);
output->sway_output = sway_output; output->sway_output = sway_output;
output->name = strdup(name); output->name = strdup(name);
if (output->name == NULL) { if (output->name == NULL) {
container_destroy(output); free_swayc(output);
return NULL; return NULL;
} }
apply_output_config(oc, output); apply_output_config(oc, output);
container_add_child(&root_container, output); add_child(&root_container, output);
// Create workspace // Create workspace
char *ws_name = workspace_next_name(output->name); char *ws_name = workspace_next_name(output->name);
wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); wlr_log(L_DEBUG, "Creating default workspace %s", ws_name);
struct sway_container *ws = container_workspace_create(output, ws_name); swayc_t *ws = new_workspace(output, ws_name);
// Set each seat's focus if not already set // Set each seat's focus if not already set
struct sway_seat *seat = NULL; struct sway_seat *seat = NULL;
wl_list_for_each(seat, &input_manager->seats, link) { wl_list_for_each(seat, &input_manager->seats, link) {
@ -151,14 +185,12 @@ struct sway_container *container_output_create(
return output; return output;
} }
struct sway_container *container_workspace_create( swayc_t *new_workspace(swayc_t *output, const char *name) {
struct sway_container *output, const char *name) { if (!sway_assert(output, "new_workspace called with null output")) {
if (!sway_assert(output,
"container_workspace_create called with null output")) {
return NULL; return NULL;
} }
wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name);
struct sway_container *workspace = container_create(C_WORKSPACE); swayc_t *workspace = new_swayc(C_WORKSPACE);
workspace->x = output->x; workspace->x = output->x;
workspace->y = output->y; workspace->y = output->y;
@ -166,23 +198,21 @@ struct sway_container *container_workspace_create(
workspace->height = output->height; workspace->height = output->height;
workspace->name = !name ? NULL : strdup(name); workspace->name = !name ? NULL : strdup(name);
workspace->prev_layout = L_NONE; workspace->prev_layout = L_NONE;
workspace->layout = container_get_default_layout(output); workspace->layout = default_layout(output);
workspace->workspace_layout = container_get_default_layout(output); workspace->workspace_layout = default_layout(output);
container_add_child(output, workspace); add_child(output, workspace);
container_sort_workspaces(output); sort_workspaces(output);
notify_new_container(workspace); notify_new_container(workspace);
return workspace; return workspace;
} }
struct sway_container *container_view_create(struct sway_container *sibling, swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) {
struct sway_view *sway_view) { if (!sway_assert(sibling, "new_view called with NULL sibling/parent")) {
if (!sway_assert(sibling,
"container_view_create called with NULL sibling/parent")) {
return NULL; return NULL;
} }
const char *title = view_get_title(sway_view); const char *title = view_get_title(sway_view);
struct sway_container *swayc = container_create(C_VIEW); swayc_t *swayc = new_swayc(C_VIEW);
wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s",
swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); swayc, title, sibling, sibling ? sibling->type : 0, sibling->name);
// Setup values // Setup values
@ -193,18 +223,17 @@ struct sway_container *container_view_create(struct sway_container *sibling,
if (sibling->type == C_WORKSPACE) { if (sibling->type == C_WORKSPACE) {
// Case of focused workspace, just create as child of it // Case of focused workspace, just create as child of it
container_add_child(sibling, swayc); add_child(sibling, swayc);
} else { } else {
// Regular case, create as sibling of current container // Regular case, create as sibling of current container
container_add_sibling(sibling, swayc); add_sibling(sibling, swayc);
} }
notify_new_container(swayc); notify_new_container(swayc);
return swayc; return swayc;
} }
struct sway_container *container_output_destroy(struct sway_container *output) { swayc_t *destroy_output(swayc_t *output) {
if (!sway_assert(output, if (!sway_assert(output, "null output passed to destroy_output")) {
"null output passed to container_output_destroy")) {
return NULL; return NULL;
} }
@ -216,13 +245,12 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
int p = root_container.children->items[0] == output; int p = root_container.children->items[0] == output;
// Move workspace from this output to another output // Move workspace from this output to another output
while (output->children->length) { while (output->children->length) {
struct sway_container *child = output->children->items[0]; swayc_t *child = output->children->items[0];
container_remove_child(child); remove_child(child);
container_add_child(root_container.children->items[p], child); add_child(root_container.children->items[p], child);
} }
container_sort_workspaces(root_container.children->items[p]); sort_workspaces(root_container.children->items[p]);
arrange_windows(root_container.children->items[p], arrange_windows(root_container.children->items[p], -1, -1);
-1, -1);
} }
} }
@ -231,18 +259,18 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
wl_list_remove(&output->sway_output->mode.link); wl_list_remove(&output->sway_output->mode.link);
wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name);
container_destroy(output); free_swayc(output);
return &root_container; return &root_container;
} }
struct sway_container *container_view_destroy(struct sway_container *view) { swayc_t *destroy_view(swayc_t *view) {
if (!view) { if (!view) {
return NULL; return NULL;
} }
wlr_log(L_DEBUG, "Destroying view '%s'", view->name); wlr_log(L_DEBUG, "Destroying view '%s'", view->name);
struct sway_container *parent = view->parent; swayc_t *parent = view->parent;
container_destroy(view); free_swayc(view);
// TODO WLR: Destroy empty containers // TODO WLR: Destroy empty containers
/* /*
@ -253,55 +281,7 @@ struct sway_container *container_view_destroy(struct sway_container *view) {
return parent; return parent;
} }
struct sway_container *container_set_layout(struct sway_container *container, swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
enum sway_container_layout layout) {
if (container->type == C_WORKSPACE) {
container->workspace_layout = layout;
if (layout == L_HORIZ || layout == L_VERT) {
container->layout = layout;
}
} else {
container->layout = layout;
}
return container;
}
void container_descendents(struct sway_container *root,
enum sway_container_type type,
void (*func)(struct sway_container *item, void *data), void *data) {
for (int i = 0; i < root->children->length; ++i) {
struct sway_container *item = root->children->items[i];
if (item->type == type) {
func(item, data);
}
if (item->children && item->children->length) {
container_descendents(item, type, func, data);
}
}
}
struct sway_container *container_find(struct sway_container *container,
bool (*test)(struct sway_container *view, void *data), void *data) {
if (!container->children) {
return NULL;
}
// TODO: floating windows
for (int i = 0; i < container->children->length; ++i) {
struct sway_container *child = container->children->items[i];
if (test(child, data)) {
return child;
} else {
struct sway_container *res = container_find(child, test, data);
if (res) {
return res;
}
}
}
return NULL;
}
struct sway_container *container_parent(struct sway_container *container,
enum sway_container_type type) {
if (!sway_assert(container, "container is NULL")) { if (!sway_assert(container, "container is NULL")) {
return NULL; return NULL;
} }
@ -314,8 +294,7 @@ struct sway_container *container_parent(struct sway_container *container,
return container; return container;
} }
struct sway_container *container_at(struct sway_container *parent, swayc_t *swayc_at(swayc_t *parent, double lx, double ly,
double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) { struct wlr_surface **surface, double *sx, double *sy) {
list_t *queue = get_bfs_queue(); list_t *queue = get_bfs_queue();
if (!queue) { if (!queue) {
@ -324,13 +303,13 @@ struct sway_container *container_at(struct sway_container *parent,
list_add(queue, parent); list_add(queue, parent);
struct sway_container *swayc = NULL; swayc_t *swayc = NULL;
while (queue->length) { while (queue->length) {
swayc = queue->items[0]; swayc = queue->items[0];
list_del(queue, 0); list_del(queue, 0);
if (swayc->type == C_VIEW) { if (swayc->type == C_VIEW) {
struct sway_view *sview = swayc->sway_view; struct sway_view *sview = swayc->sway_view;
struct sway_container *soutput = container_parent(swayc, C_OUTPUT); swayc_t *soutput = swayc_parent_by_type(swayc, C_OUTPUT);
struct wlr_box *output_box = struct wlr_box *output_box =
wlr_output_layout_get_box( wlr_output_layout_get_box(
root_container.sway_root->output_layout, root_container.sway_root->output_layout,
@ -400,8 +379,30 @@ struct sway_container *container_at(struct sway_container *parent,
return NULL; return NULL;
} }
void container_for_each_descendent(struct sway_container *con, void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
void (*f)(struct sway_container *con, void *data), void *data) { if (container) {
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);
}
}
// TODO
/*
if (container->floating) {
for (i = 0; i < container->floating->length; ++i) {
swayc_t *child = container->floating->items[i];
container_map(child, f, data);
}
}
*/
f(container, data);
}
}
void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
void *data) {
list_t *queue = get_bfs_queue(); list_t *queue = get_bfs_queue();
if (!queue) { if (!queue) {
return; return;
@ -414,7 +415,7 @@ void container_for_each_descendent(struct sway_container *con,
list_add(queue, con); list_add(queue, con);
struct sway_container *current = NULL; swayc_t *current = NULL;
while (queue->length) { while (queue->length) {
current = queue->items[0]; current = queue->items[0];
list_del(queue, 0); list_del(queue, 0);
@ -423,3 +424,15 @@ void container_for_each_descendent(struct sway_container *con,
list_cat(queue, current->children); list_cat(queue, current->children);
} }
} }
swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) {
if (container->type == C_WORKSPACE) {
container->workspace_layout = layout;
if (layout == L_HORIZ || layout == L_VERT) {
container->layout = layout;
}
} else {
container->layout = layout;
}
return container;
}

@ -6,26 +6,24 @@
#include <string.h> #include <string.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/tree/view.h" #include "sway/view.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
struct sway_container root_container; swayc_t root_container;
static void output_layout_change_notify(struct wl_listener *listener, static void output_layout_change_notify(struct wl_listener *listener, void *data) {
void *data) {
struct wlr_box *layout_box = wlr_output_layout_get_box( struct wlr_box *layout_box = wlr_output_layout_get_box(
root_container.sway_root->output_layout, NULL); root_container.sway_root->output_layout, NULL);
root_container.width = layout_box->width; root_container.width = layout_box->width;
root_container.height = layout_box->height; root_container.height = layout_box->height;
for (int i = 0 ; i < root_container.children->length; ++i) { for (int i = 0 ; i < root_container.children->length; ++i) {
struct sway_container *output_container = swayc_t *output_container = root_container.children->items[i];
root_container.children->items[i];
if (output_container->type != C_OUTPUT) { if (output_container->type != C_OUTPUT) {
continue; continue;
} }
@ -45,7 +43,7 @@ static void output_layout_change_notify(struct wl_listener *listener,
arrange_windows(&root_container, -1, -1); arrange_windows(&root_container, -1, -1);
} }
void layout_init(void) { void init_layout(void) {
root_container.id = 0; // normally assigned in new_swayc() root_container.id = 0; // normally assigned in new_swayc()
root_container.type = C_ROOT; root_container.type = C_ROOT;
root_container.layout = L_NONE; root_container.layout = L_NONE;
@ -64,9 +62,9 @@ void layout_init(void) {
&root_container.sway_root->output_layout_change); &root_container.sway_root->output_layout_change);
} }
static int index_child(const struct sway_container *child) { static int index_child(const swayc_t *child) {
// TODO handle floating // TODO handle floating
struct sway_container *parent = child->parent; swayc_t *parent = child->parent;
int i, len; int i, len;
len = parent->children->length; len = parent->children->length;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
@ -81,18 +79,16 @@ static int index_child(const struct sway_container *child) {
return i; return i;
} }
struct sway_container *container_add_sibling(struct sway_container *fixed, swayc_t *add_sibling(swayc_t *fixed, swayc_t *active) {
struct sway_container *active) {
// TODO handle floating // TODO handle floating
struct sway_container *parent = fixed->parent; swayc_t *parent = fixed->parent;
int i = index_child(fixed); int i = index_child(fixed);
list_insert(parent->children, i + 1, active); list_insert(parent->children, i + 1, active);
active->parent = parent; active->parent = parent;
return active->parent; return active->parent;
} }
void container_add_child(struct sway_container *parent, void add_child(swayc_t *parent, swayc_t *child) {
struct sway_container *child) {
wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
child, child->type, child->width, child->height, child, child->type, child->width, child->height,
parent, parent->type, parent->width, parent->height); parent, parent->type, parent->width, parent->height);
@ -100,17 +96,15 @@ void container_add_child(struct sway_container *parent,
child->parent = parent; child->parent = parent;
// set focus for this container // set focus for this container
/* TODO WLR /* TODO WLR
if (parent->type == C_WORKSPACE && child->type == C_VIEW && if (parent->type == C_WORKSPACE && child->type == C_VIEW && (parent->workspace_layout == L_TABBED || parent->workspace_layout == L_STACKED)) {
(parent->workspace_layout == L_TABBED || parent->workspace_layout ==
L_STACKED)) {
child = new_container(child, parent->workspace_layout); child = new_container(child, parent->workspace_layout);
} }
*/ */
} }
struct sway_container *container_remove_child(struct sway_container *child) { swayc_t *remove_child(swayc_t *child) {
int i; int i;
struct sway_container *parent = child->parent; swayc_t *parent = child->parent;
for (i = 0; i < parent->children->length; ++i) { for (i = 0; i < parent->children->length; ++i) {
if (parent->children->items[i] == child) { if (parent->children->items[i] == child) {
list_del(parent->children, i); list_del(parent->children, i);
@ -121,8 +115,7 @@ struct sway_container *container_remove_child(struct sway_container *child) {
return parent; return parent;
} }
enum sway_container_layout container_get_default_layout( enum swayc_layouts default_layout(swayc_t *output) {
struct sway_container *output) {
/* TODO WLR /* TODO WLR
if (config->default_layout != L_NONE) { if (config->default_layout != L_NONE) {
//return config->default_layout; //return config->default_layout;
@ -136,8 +129,8 @@ enum sway_container_layout container_get_default_layout(
} }
static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
struct sway_container *a = *(void **)_a; swayc_t *a = *(void **)_a;
struct sway_container *b = *(void **)_b; swayc_t *b = *(void **)_b;
int retval = 0; int retval = 0;
if (isdigit(a->name[0]) && isdigit(b->name[0])) { if (isdigit(a->name[0]) && isdigit(b->name[0])) {
@ -153,22 +146,21 @@ static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
return retval; return retval;
} }
void container_sort_workspaces(struct sway_container *output) { void sort_workspaces(swayc_t *output) {
list_stable_sort(output->children, sort_workspace_cmp_qsort); list_stable_sort(output->children, sort_workspace_cmp_qsort);
} }
static void apply_horiz_layout(struct sway_container *container, const double x, static void apply_horiz_layout(swayc_t *container, const double x,
const double y, const double width, const double y, const double width,
const double height, const int start, const double height, const int start,
const int end); const int end);
static void apply_vert_layout(struct sway_container *container, const double x, static void apply_vert_layout(swayc_t *container, const double x,
const double y, const double width, const double y, const double width,
const double height, const int start, const double height, const int start,
const int end); const int end);
void arrange_windows(struct sway_container *container, void arrange_windows(swayc_t *container, double width, double height) {
double width, double height) {
int i; int i;
if (width == -1 || height == -1) { if (width == -1 || height == -1) {
width = container->width; width = container->width;
@ -189,7 +181,7 @@ void arrange_windows(struct sway_container *container,
case C_ROOT: case C_ROOT:
// TODO: wlr_output_layout probably // TODO: wlr_output_layout probably
for (i = 0; i < container->children->length; ++i) { for (i = 0; i < container->children->length; ++i) {
struct sway_container *output = container->children->items[i]; swayc_t *output = container->children->items[i];
wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f", wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f",
output->name, output->x, output->y); output->name, output->x, output->y);
arrange_windows(output, -1, -1); arrange_windows(output, -1, -1);
@ -205,14 +197,13 @@ void arrange_windows(struct sway_container *container,
} }
// arrange all workspaces: // arrange all workspaces:
for (i = 0; i < container->children->length; ++i) { for (i = 0; i < container->children->length; ++i) {
struct sway_container *child = container->children->items[i]; swayc_t *child = container->children->items[i];
arrange_windows(child, -1, -1); arrange_windows(child, -1, -1);
} }
return; return;
case C_WORKSPACE: case C_WORKSPACE:
{ {
struct sway_container *output = swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
container_parent(container, C_OUTPUT);
struct wlr_box *area = &output->sway_output->usable_area; struct wlr_box *area = &output->sway_output->usable_area;
wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
area->width, area->height, area->x, area->y); area->width, area->height, area->x, area->y);
@ -261,15 +252,14 @@ void arrange_windows(struct sway_container *container,
} }
} }
static void apply_horiz_layout(struct sway_container *container, static void apply_horiz_layout(swayc_t *container,
const double x, const double y, const double x, const double y,
const double width, const double height, const double width, const double height,
const int start, const int end) { const int start, const int end) {
double scale = 0; double scale = 0;
// Calculate total width // Calculate total width
for (int i = start; i < end; ++i) { for (int i = start; i < end; ++i) {
double *old_width = double *old_width = &((swayc_t *)container->children->items[i])->width;
&((struct sway_container *)container->children->items[i])->width;
if (*old_width <= 0) { if (*old_width <= 0) {
if (end - start > 1) { if (end - start > 1) {
*old_width = width / (end - start - 1); *old_width = width / (end - start - 1);
@ -286,7 +276,7 @@ static void apply_horiz_layout(struct sway_container *container,
if (scale > 0.1) { if (scale > 0.1) {
wlr_log(L_DEBUG, "Arranging %p horizontally", container); wlr_log(L_DEBUG, "Arranging %p horizontally", container);
for (int i = start; i < end; ++i) { for (int i = start; i < end; ++i) {
struct sway_container *child = container->children->items[i]; swayc_t *child = container->children->items[i];
wlr_log(L_DEBUG, wlr_log(L_DEBUG,
"Calculating arrangement for %p:%d (will scale %f by %f)", "Calculating arrangement for %p:%d (will scale %f by %f)",
child, child->type, width, scale); child, child->type, width, scale);
@ -311,7 +301,7 @@ static void apply_horiz_layout(struct sway_container *container,
} }
} }
void apply_vert_layout(struct sway_container *container, void apply_vert_layout(swayc_t *container,
const double x, const double y, const double x, const double y,
const double width, const double height, const int start, const double width, const double height, const int start,
const int end) { const int end) {
@ -319,8 +309,7 @@ void apply_vert_layout(struct sway_container *container,
double scale = 0; double scale = 0;
// Calculate total height // Calculate total height
for (i = start; i < end; ++i) { for (i = start; i < end; ++i) {
double *old_height = double *old_height = &((swayc_t *)container->children->items[i])->height;
&((struct sway_container *)container->children->items[i])->height;
if (*old_height <= 0) { if (*old_height <= 0) {
if (end - start > 1) { if (end - start > 1) {
*old_height = height / (end - start - 1); *old_height = height / (end - start - 1);
@ -337,7 +326,7 @@ void apply_vert_layout(struct sway_container *container,
if (scale > 0.1) { if (scale > 0.1) {
wlr_log(L_DEBUG, "Arranging %p vertically", container); wlr_log(L_DEBUG, "Arranging %p vertically", container);
for (i = start; i < end; ++i) { for (i = start; i < end; ++i) {
struct sway_container *child = container->children->items[i]; swayc_t *child = container->children->items[i];
wlr_log(L_DEBUG, wlr_log(L_DEBUG,
"Calculating arrangement for %p:%d (will scale %f by %f)", "Calculating arrangement for %p:%d (will scale %f by %f)",
child, child->type, height, scale); child, child->type, height, scale);
@ -365,16 +354,15 @@ void apply_vert_layout(struct sway_container *container,
/** /**
* Get swayc in the direction of newly entered output. * Get swayc in the direction of newly entered output.
*/ */
static struct sway_container *get_swayc_in_output_direction( static swayc_t *get_swayc_in_output_direction(swayc_t *output,
struct sway_container *output, enum movement_direction dir, enum movement_direction dir, struct sway_seat *seat) {
struct sway_seat *seat) {
if (!output) { if (!output) {
return NULL; return NULL;
} }
struct sway_container *ws = sway_seat_get_focus_inactive(seat, output); swayc_t *ws = sway_seat_get_focus_inactive(seat, output);
if (ws->type != C_WORKSPACE) { if (ws->type != C_WORKSPACE) {
ws = container_parent(ws, C_WORKSPACE); ws = swayc_parent_by_type(ws, C_WORKSPACE);
} }
if (ws == NULL) { if (ws == NULL) {
@ -392,15 +380,13 @@ static struct sway_container *get_swayc_in_output_direction(
return ws->children->items[0]; return ws->children->items[0];
case MOVE_UP: case MOVE_UP:
case MOVE_DOWN: { case MOVE_DOWN: {
struct sway_container *focused = swayc_t *focused = sway_seat_get_focus_inactive(seat, ws);
sway_seat_get_focus_inactive(seat, ws);
if (focused && focused->parent) { if (focused && focused->parent) {
struct sway_container *parent = focused->parent; swayc_t *parent = focused->parent;
if (parent->layout == L_VERT) { if (parent->layout == L_VERT) {
if (dir == MOVE_UP) { if (dir == MOVE_UP) {
// get child furthest down on new output // get child furthest down on new output
int idx = parent->children->length - 1; return parent->children->items[parent->children->length-1];
return parent->children->items[idx];
} else if (dir == MOVE_DOWN) { } else if (dir == MOVE_DOWN) {
// get child furthest up on new output // get child furthest up on new output
return parent->children->items[0]; return parent->children->items[0];
@ -418,14 +404,13 @@ static struct sway_container *get_swayc_in_output_direction(
return ws; return ws;
} }
static void get_layout_center_position(struct sway_container *container, static void get_layout_center_position(swayc_t *container, int *x, int *y) {
int *x, int *y) {
// FIXME view coords are inconsistently referred to in layout/output systems // FIXME view coords are inconsistently referred to in layout/output systems
if (container->type == C_OUTPUT) { if (container->type == C_OUTPUT) {
*x = container->x + container->width/2; *x = container->x + container->width/2;
*y = container->y + container->height/2; *y = container->y + container->height/2;
} else { } else {
struct sway_container *output = container_parent(container, C_OUTPUT); swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
if (container->type == C_WORKSPACE) { if (container->type == C_WORKSPACE) {
// Workspace coordinates are actually wrong/arbitrary, but should // Workspace coordinates are actually wrong/arbitrary, but should
// be same as output. // be same as output.
@ -438,8 +423,7 @@ static void get_layout_center_position(struct sway_container *container,
} }
} }
static bool sway_dir_to_wlr(enum movement_direction dir, static bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
enum wlr_direction *out) {
switch (dir) { switch (dir) {
case MOVE_UP: case MOVE_UP:
*out = WLR_DIRECTION_UP; *out = WLR_DIRECTION_UP;
@ -460,12 +444,12 @@ static bool sway_dir_to_wlr(enum movement_direction dir,
return true; return true;
} }
static struct sway_container *sway_output_from_wlr(struct wlr_output *output) { static swayc_t *sway_output_from_wlr(struct wlr_output *output) {
if (output == NULL) { if (output == NULL) {
return NULL; return NULL;
} }
for (int i = 0; i < root_container.children->length; ++i) { for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *o = root_container.children->items[i]; swayc_t *o = root_container.children->items[i];
if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) { if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) {
return o; return o;
} }
@ -473,14 +457,13 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
return NULL; return NULL;
} }
static struct sway_container *get_swayc_in_direction_under( static swayc_t *get_swayc_in_direction_under(swayc_t *container,
struct sway_container *container, enum movement_direction dir, enum movement_direction dir, struct sway_seat *seat, swayc_t *limit) {
struct sway_seat *seat, struct sway_container *limit) {
if (dir == MOVE_CHILD) { if (dir == MOVE_CHILD) {
return sway_seat_get_focus_inactive(seat, container); return sway_seat_get_focus_inactive(seat, container);
} }
struct sway_container *parent = container->parent; swayc_t *parent = container->parent;
if (dir == MOVE_PARENT) { if (dir == MOVE_PARENT) {
if (parent->type == C_OUTPUT) { if (parent->type == C_OUTPUT) {
return NULL; return NULL;
@ -513,10 +496,9 @@ static struct sway_container *get_swayc_in_direction_under(
/* /*
if (container->type == C_VIEW && swayc_is_fullscreen(container)) { if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
container = container_parent(container, C_OUTPUT); container = swayc_parent_by_type(container, C_OUTPUT);
get_layout_center_position(container, &abs_pos); get_layout_center_position(container, &abs_pos);
struct sway_container *output = swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
swayc_adjacent_output(container, dir, &abs_pos, true);
return get_swayc_in_output_direction(output, dir); return get_swayc_in_output_direction(output, dir);
} }
if (container->type == C_WORKSPACE && container->fullscreen) { if (container->type == C_WORKSPACE && container->fullscreen) {
@ -525,7 +507,7 @@ static struct sway_container *get_swayc_in_direction_under(
} }
*/ */
struct sway_container *wrap_candidate = NULL; swayc_t *wrap_candidate = NULL;
while (true) { while (true) {
// Test if we can even make a difference here // Test if we can even make a difference here
bool can_move = false; bool can_move = false;
@ -539,19 +521,16 @@ static struct sway_container *get_swayc_in_direction_under(
} }
int lx, ly; int lx, ly;
get_layout_center_position(container, &lx, &ly); get_layout_center_position(container, &lx, &ly);
struct wlr_output_layout *layout = struct wlr_output_layout *layout = root_container.sway_root->output_layout;
root_container.sway_root->output_layout;
struct wlr_output *wlr_adjacent = struct wlr_output *wlr_adjacent =
wlr_output_layout_adjacent_output(layout, wlr_dir, wlr_output_layout_adjacent_output(layout, wlr_dir,
container->sway_output->wlr_output, lx, ly); container->sway_output->wlr_output, lx, ly);
struct sway_container *adjacent = swayc_t *adjacent = sway_output_from_wlr(wlr_adjacent);
sway_output_from_wlr(wlr_adjacent);
if (!adjacent || adjacent == container) { if (!adjacent || adjacent == container) {
return wrap_candidate; return wrap_candidate;
} }
struct sway_container *next = swayc_t *next = get_swayc_in_output_direction(adjacent, dir, seat);
get_swayc_in_output_direction(adjacent, dir, seat);
if (next == NULL) { if (next == NULL) {
return NULL; return NULL;
} }
@ -591,9 +570,8 @@ static struct sway_container *get_swayc_in_direction_under(
} }
} }
} else { } else {
wlr_log(L_DEBUG, wlr_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__,
"cont %d-%p dir %i sibling %d: %p", idx, idx, container, dir, desired, parent->children->items[desired]);
container, dir, desired, parent->children->items[desired]);
return parent->children->items[desired]; return parent->children->items[desired];
} }
} }
@ -609,8 +587,7 @@ static struct sway_container *get_swayc_in_direction_under(
} }
} }
struct sway_container *container_get_in_direction( swayc_t *get_swayc_in_direction(swayc_t *container, struct sway_seat *seat,
struct sway_container *container, struct sway_seat *seat,
enum movement_direction dir) { enum movement_direction dir) {
return get_swayc_in_direction_under(container, dir, seat, NULL); return get_swayc_in_direction_under(container, dir, seat, NULL);
} }

@ -1,8 +1,8 @@
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/tree/layout.h" #include "sway/layout.h"
#include "sway/tree/view.h" #include "sway/view.h"
const char *view_get_title(struct sway_view *view) { const char *view_get_title(struct sway_view *view) {
if (view->iface.get_prop) { if (view->iface.get_prop) {
@ -45,7 +45,6 @@ void view_set_size(struct sway_view *view, int width, int height) {
} }
} }
// TODO make view coordinates in layout coordinates
void view_set_position(struct sway_view *view, double ox, double oy) { void view_set_position(struct sway_view *view, double ox, double oy) {
if (view->iface.set_position) { if (view->iface.set_position) {
struct wlr_box box = { struct wlr_box box = {

@ -3,10 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <strings.h> #include <strings.h>
#include "sway/tree/container.h" #include "sway/container.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/workspace.h" #include "sway/workspace.h"
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
@ -17,7 +17,7 @@ struct workspace_by_number_data {
const char *name; const char *name;
}; };
void next_name_map(struct sway_container *ws, void *data) { void next_name_map(swayc_t *ws, void *data) {
int *count = data; int *count = data;
++count; ++count;
} }
@ -37,7 +37,7 @@ char *workspace_next_name(const char *output_name) {
return name; return name;
} }
static bool _workspace_by_number(struct sway_container *view, void *data) { static bool _workspace_by_number(swayc_t *view, void *data) {
if (view->type != C_WORKSPACE) { if (view->type != C_WORKSPACE) {
return false; return false;
} }
@ -46,28 +46,27 @@ static bool _workspace_by_number(struct sway_container *view, void *data) {
return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0;
} }
struct sway_container *workspace_by_number(const char* name) { swayc_t *workspace_by_number(const char* name) {
struct workspace_by_number_data wbnd = {0, "1234567890", name}; struct workspace_by_number_data wbnd = {0, "1234567890", name};
wbnd.len = strspn(name, wbnd.cset); wbnd.len = strspn(name, wbnd.cset);
if (wbnd.len <= 0) { if (wbnd.len <= 0) {
return NULL; return NULL;
} }
return container_find(&root_container, return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd);
_workspace_by_number, (void *) &wbnd);
} }
static bool _workspace_by_name(struct sway_container *view, void *data) { static bool _workspace_by_name(swayc_t *view, void *data) {
return (view->type == C_WORKSPACE) && return (view->type == C_WORKSPACE) &&
(strcasecmp(view->name, (char *) data) == 0); (strcasecmp(view->name, (char *) data) == 0);
} }
struct sway_container *workspace_by_name(const char *name) { swayc_t *workspace_by_name(const char *name) {
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *current_workspace = NULL, *current_output = NULL; swayc_t *current_workspace = NULL, *current_output = NULL;
struct sway_container *focus = sway_seat_get_focus(seat); swayc_t *focus = sway_seat_get_focus(seat);
if (focus) { if (focus) {
current_workspace = container_parent(focus, C_WORKSPACE); current_workspace = swayc_parent_by_type(focus, C_WORKSPACE);
current_output = container_parent(focus, C_OUTPUT); current_output = swayc_parent_by_type(focus, C_OUTPUT);
} }
if (strcmp(name, "prev") == 0) { if (strcmp(name, "prev") == 0) {
return workspace_prev(current_workspace); return workspace_prev(current_workspace);
@ -80,13 +79,12 @@ struct sway_container *workspace_by_name(const char *name) {
} else if (strcmp(name, "current") == 0) { } else if (strcmp(name, "current") == 0) {
return current_workspace; return current_workspace;
} else { } else {
return container_find(&root_container, _workspace_by_name, return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
(void *)name);
} }
} }
struct sway_container *workspace_create(const char *name) { swayc_t *workspace_create(const char *name) {
struct sway_container *parent; swayc_t *parent;
// Search for workspace<->output pair // Search for workspace<->output pair
int i, e = config->workspace_outputs->length; int i, e = config->workspace_outputs->length;
for (i = 0; i < e; ++i) { for (i = 0; i < e; ++i) {
@ -97,7 +95,7 @@ struct sway_container *workspace_create(const char *name) {
for (i = 0; i < e; ++i) { for (i = 0; i < e; ++i) {
parent = root_container.children->items[i]; parent = root_container.children->items[i];
if (strcmp(parent->name, wso->output) == 0) { if (strcmp(parent->name, wso->output) == 0) {
return container_workspace_create(parent, name); return new_workspace(parent, name);
} }
} }
break; break;
@ -105,11 +103,10 @@ struct sway_container *workspace_create(const char *name) {
} }
// Otherwise create a new one // Otherwise create a new one
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
sway_seat_get_focus_inactive(seat, &root_container);
parent = focus; parent = focus;
parent = container_parent(parent, C_OUTPUT); parent = swayc_parent_by_type(parent, C_OUTPUT);
return container_workspace_create(parent, name); return new_workspace(parent, name);
} }
/** /**
@ -117,18 +114,17 @@ struct sway_container *workspace_create(const char *name) {
* the end and beginning. If next is false, the previous workspace is returned, * the end and beginning. If next is false, the previous workspace is returned,
* otherwise the next one is returned. * otherwise the next one is returned.
*/ */
struct sway_container *workspace_output_prev_next_impl( swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) {
struct sway_container *output, bool next) {
if (!sway_assert(output->type == C_OUTPUT, if (!sway_assert(output->type == C_OUTPUT,
"Argument must be an output, is %d", output->type)) { "Argument must be an output, is %d", output->type)) {
return NULL; return NULL;
} }
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); swayc_t *focus = sway_seat_get_focus_inactive(seat, output);
struct sway_container *workspace = (focus->type == C_WORKSPACE ? swayc_t *workspace = (focus->type == C_WORKSPACE ?
focus : focus :
container_parent(focus, C_WORKSPACE)); swayc_parent_by_type(focus, C_WORKSPACE));
int i; int i;
for (i = 0; i < output->children->length; i++) { for (i = 0; i < output->children->length; i++) {
@ -138,8 +134,7 @@ struct sway_container *workspace_output_prev_next_impl(
} }
} }
// Doesn't happen, at worst the for loop returns the previously active // Doesn't happen, at worst the for loop returns the previously active workspace
// workspace
return NULL; return NULL;
} }
@ -149,14 +144,13 @@ struct sway_container *workspace_output_prev_next_impl(
* next is false, the previous workspace is returned, otherwise the next one is * next is false, the previous workspace is returned, otherwise the next one is
* returned. * returned.
*/ */
struct sway_container *workspace_prev_next_impl( swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) {
struct sway_container *workspace, bool next) {
if (!sway_assert(workspace->type == C_WORKSPACE, if (!sway_assert(workspace->type == C_WORKSPACE,
"Argument must be a workspace, is %d", workspace->type)) { "Argument must be a workspace, is %d", workspace->type)) {
return NULL; return NULL;
} }
struct sway_container *current_output = workspace->parent; swayc_t *current_output = workspace->parent;
int offset = next ? 1 : -1; int offset = next ? 1 : -1;
int start = next ? 0 : 1; int start = next ? 0 : 1;
int end; int end;
@ -172,57 +166,54 @@ struct sway_container *workspace_prev_next_impl(
} }
} }
// Given workspace is the first/last on the output, jump to the // Given workspace is the first/last on the output, jump to the previous/next output
// previous/next output
int num_outputs = root_container.children->length; int num_outputs = root_container.children->length;
for (i = 0; i < num_outputs; i++) { for (i = 0; i < num_outputs; i++) {
if (root_container.children->items[i] == current_output) { if (root_container.children->items[i] == current_output) {
struct sway_container *next_output = root_container.children->items[ swayc_t *next_output = root_container.children->items[
wrap(i + offset, num_outputs)]; wrap(i + offset, num_outputs)];
return workspace_output_prev_next_impl(next_output, next); return workspace_output_prev_next_impl(next_output, next);
} }
} }
// Doesn't happen, at worst the for loop returns the previously active // Doesn't happen, at worst the for loop returns the previously active workspace on the active output
// workspace on the active output
return NULL; return NULL;
} }
struct sway_container *workspace_output_next(struct sway_container *current) { swayc_t *workspace_output_next(swayc_t *current) {
return workspace_output_prev_next_impl(current, true); return workspace_output_prev_next_impl(current, true);
} }
struct sway_container *workspace_next(struct sway_container *current) { swayc_t *workspace_next(swayc_t *current) {
return workspace_prev_next_impl(current, true); return workspace_prev_next_impl(current, true);
} }
struct sway_container *workspace_output_prev(struct sway_container *current) { swayc_t *workspace_output_prev(swayc_t *current) {
return workspace_output_prev_next_impl(current, false); return workspace_output_prev_next_impl(current, false);
} }
struct sway_container *workspace_prev(struct sway_container *current) { swayc_t *workspace_prev(swayc_t *current) {
return workspace_prev_next_impl(current, false); return workspace_prev_next_impl(current, false);
} }
bool workspace_switch(struct sway_container *workspace) { bool workspace_switch(swayc_t *workspace) {
if (!workspace) { if (!workspace) {
return false; return false;
} }
struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
sway_seat_get_focus_inactive(seat, &root_container);
if (!seat || !focus) { if (!seat || !focus) {
return false; return false;
} }
struct sway_container *active_ws = focus; swayc_t *active_ws = focus;
if (active_ws->type != C_WORKSPACE) { if (active_ws->type != C_WORKSPACE) {
container_parent(focus, C_WORKSPACE); swayc_parent_by_type(focus, C_WORKSPACE);
} }
if (config->auto_back_and_forth if (config->auto_back_and_forth
&& active_ws == workspace && active_ws == workspace
&& prev_workspace_name) { && prev_workspace_name) {
struct sway_container *new_ws = workspace_by_name(prev_workspace_name); swayc_t *new_ws = workspace_by_name(prev_workspace_name);
workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
} }
@ -239,14 +230,13 @@ bool workspace_switch(struct sway_container *workspace) {
// TODO: Deal with sticky containers // TODO: Deal with sticky containers
wlr_log(L_DEBUG, "Switching to workspace %p:%s", wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
workspace, workspace->name); swayc_t *next = sway_seat_get_focus_inactive(seat, workspace);
struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace);
if (next == NULL) { if (next == NULL) {
next = workspace; next = workspace;
} }
sway_seat_set_focus(seat, next); sway_seat_set_focus(seat, next);
struct sway_container *output = container_parent(workspace, C_OUTPUT); swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
arrange_windows(output, -1, -1); arrange_windows(output, -1, -1);
return true; return true;
} }

@ -352,7 +352,7 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) {
} }
// add bar to the output // add bar to the output
struct output *bar_output = container_output_create(name); struct output *bar_output = new_output(name);
bar_output->idx = i; bar_output->idx = i;
list_add(bar->outputs, bar_output); list_add(bar->outputs, bar_output);
} }

Loading…
Cancel
Save