Merge remote-tracking branch 'taiyu-len/master'

This commit is contained in:
Drew DeVault 2015-08-21 17:00:00 -04:00
commit 39041d07b5
10 changed files with 224 additions and 175 deletions

View file

@ -81,13 +81,22 @@ swayc_t *destroy_view(swayc_t *view);
// Container Lookup // Container Lookup
swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types); swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts); swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
swayc_t *swayc_by_handle(wlc_handle handle);
swayc_t *swayc_active_output(void);
swayc_t *swayc_active_workspace(void);
swayc_t *swayc_active_workspace_for(swayc_t *view);
// Container information
bool swayc_is_fullscreen(swayc_t *view);
// Mapping functions
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *); void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
// Mappings // Mappings
void set_view_visibility(swayc_t *view, void *data); void set_view_visibility(swayc_t *view, void *data);
void reset_gaps(swayc_t *view, void *data); void reset_gaps(swayc_t *view, void *data);

View file

@ -19,17 +19,10 @@ swayc_t *remove_child(swayc_t *child);
void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction); void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction);
// Layout // Layout
void arrange_windows(swayc_t *container, double width, double height); void arrange_windows(swayc_t *container, double width, double height);
// Focus
void unfocus_all(swayc_t *container);
void focus_view(swayc_t *view);
void focus_view_for(swayc_t *ancestor, swayc_t *container);
swayc_t *get_focused_container(swayc_t *parent); swayc_t *get_focused_container(swayc_t *parent);
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge); void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge);

View file

@ -5,11 +5,9 @@
#include "list.h" #include "list.h"
#include "layout.h" #include "layout.h"
extern swayc_t *active_workspace;
char *workspace_next_name(void); char *workspace_next_name(void);
swayc_t *workspace_create(const char*); swayc_t *workspace_create(const char*);
swayc_t *workspace_find_by_name(const char*); swayc_t *workspace_by_name(const char*);
void workspace_switch(swayc_t*); void workspace_switch(swayc_t*);
void workspace_output_next(); void workspace_output_next();
void workspace_next(); void workspace_next();

View file

@ -208,16 +208,16 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
destroy_container(remove_child(view)); destroy_container(remove_child(view));
// and move it into workspace floating // and move it into workspace floating
add_floating(active_workspace,view); add_floating(swayc_active_workspace(),view);
view->x = (active_workspace->width - view->width)/2; view->x = (swayc_active_workspace()->width - view->width)/2;
view->y = (active_workspace->height - view->height)/2; view->y = (swayc_active_workspace()->height - view->height)/2;
if (view->desired_width != -1) { if (view->desired_width != -1) {
view->width = view->desired_width; view->width = view->desired_width;
} }
if (view->desired_height != -1) { if (view->desired_height != -1) {
view->height = view->desired_height; view->height = view->desired_height;
} }
arrange_windows(active_workspace, -1, -1); arrange_windows(swayc_active_workspace(), -1, -1);
} else { } else {
// Delete the view from the floating list and unset its is_floating flag // Delete the view from the floating list and unset its is_floating flag
// Using length-1 as the index is safe because the view must be the currently // Using length-1 as the index is safe because the view must be the currently
@ -228,7 +228,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
swayc_t *focused = container_under_pointer(); swayc_t *focused = container_under_pointer();
// If focused is null, it's because the currently focused container is a workspace // If focused is null, it's because the currently focused container is a workspace
if (focused == NULL) { if (focused == NULL) {
focused = active_workspace; focused = swayc_active_workspace();
} }
set_focused_container(focused); set_focused_container(focused);
@ -244,7 +244,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
} }
// Refocus on the view once its been put back into the layout // Refocus on the view once its been put back into the layout
view->width = view->height = 0; view->width = view->height = 0;
arrange_windows(active_workspace, -1, -1); arrange_windows(swayc_active_workspace(), -1, -1);
} }
set_focused_container(view); set_focused_container(view);
} }
@ -293,37 +293,38 @@ static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
return move_focus(MOVE_PARENT); return move_focus(MOVE_PARENT);
} else if (strcasecmp(argv[0], "mode_toggle") == 0) { } else if (strcasecmp(argv[0], "mode_toggle") == 0) {
int i; int i;
swayc_t *focused = get_focused_view(active_workspace); swayc_t *workspace = swayc_active_workspace();
swayc_t *focused = get_focused_view(workspace);
if (focused->is_floating) { if (focused->is_floating) {
if (active_workspace->children->length > 0) { if (workspace->children->length > 0) {
for (i = 0;i < active_workspace->floating->length; i++) { for (i = 0;i < workspace->floating->length; i++) {
if (active_workspace->floating->items[i] == focused) { if (workspace->floating->items[i] == focused) {
floating_toggled_index = i; floating_toggled_index = i;
break; break;
} }
} }
if (active_workspace->children->length > tiled_toggled_index) { if (workspace->children->length > tiled_toggled_index) {
set_focused_container(get_focused_view(active_workspace->children->items[tiled_toggled_index])); set_focused_container(get_focused_view(workspace->children->items[tiled_toggled_index]));
} else { } else {
set_focused_container(get_focused_view(active_workspace->children->items[0])); set_focused_container(get_focused_view(workspace->children->items[0]));
tiled_toggled_index = 0; tiled_toggled_index = 0;
} }
} }
} else { } else {
if (active_workspace->floating->length > 0) { if (workspace->floating->length > 0) {
for (i = 0;i < active_workspace->children->length; i++) { for (i = 0;i < workspace->children->length; i++) {
if (active_workspace->children->items[i] == focused) { if (workspace->children->items[i] == focused) {
tiled_toggled_index = i; tiled_toggled_index = i;
break; break;
} }
} }
if (active_workspace->floating->length > floating_toggled_index) { if (workspace->floating->length > floating_toggled_index) {
swayc_t *floating = active_workspace->floating->items[floating_toggled_index]; swayc_t *floating = workspace->floating->items[floating_toggled_index];
set_focused_container(get_focused_view(floating)); set_focused_container(get_focused_view(floating));
} else { } else {
swayc_t *floating = active_workspace->floating->items[active_workspace->floating->length - 1]; swayc_t *floating = workspace->floating->items[workspace->floating->length - 1];
set_focused_container(get_focused_view(floating)); set_focused_container(get_focused_view(floating));
tiled_toggled_index = active_workspace->floating->length - 1; tiled_toggled_index = workspace->floating->length - 1;
} }
} }
} }
@ -459,7 +460,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
amount *= -1; amount *= -1;
} }
swayc_t *parent = get_focused_view(active_workspace); swayc_t *parent = get_focused_view(swayc_active_workspace());
swayc_t *focused = parent; swayc_t *focused = parent;
swayc_t *sibling; swayc_t *sibling;
if (!parent) { if (!parent) {
@ -529,7 +530,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
} }
// Recursive resize does not handle positions, let arrange_windows // Recursive resize does not handle positions, let arrange_windows
// take care of that. // take care of that.
arrange_windows(active_workspace, -1, -1); arrange_windows(swayc_active_workspace(), -1, -1);
return true; return true;
} else if (strcmp(argv[1], "height") == 0) { } else if (strcmp(argv[1], "height") == 0) {
int tnumber = 0; int tnumber = 0;
@ -589,7 +590,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
} }
} }
} }
arrange_windows(active_workspace, -1, -1); arrange_windows(swayc_active_workspace(), -1, -1);
return true; return true;
} }
return true; return true;
@ -616,8 +617,12 @@ static bool _do_split(struct sway_config *config, int argc, char **argv, int lay
} }
swayc_t *focused = get_focused_container(&root_container); swayc_t *focused = get_focused_container(&root_container);
if (focused->type == C_WORKSPACE && focused->children->length <= 1) { // Case of floating window, dont split
if (focused->is_floating) {
return true;
}
/* Case that focus is on an workspace with 0/1 children.change its layout */ /* Case that focus is on an workspace with 0/1 children.change its layout */
if (focused->type == C_WORKSPACE && focused->children->length <= 1) {
sway_log(L_DEBUG, "changing workspace layout"); sway_log(L_DEBUG, "changing workspace layout");
focused->layout = layout; focused->layout = layout;
} else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) { } else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) {
@ -632,7 +637,6 @@ static bool _do_split(struct sway_config *config, int argc, char **argv, int lay
set_focused_container(focused); set_focused_container(focused);
arrange_windows(parent, -1, -1); arrange_windows(parent, -1, -1);
} }
return true; return true;
} }
@ -680,7 +684,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
} }
swayc_t *container = get_focused_view(&root_container); swayc_t *container = get_focused_view(&root_container);
bool current = (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) > 0; bool current = swayc_is_fullscreen(container);
wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current); wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current);
// Resize workspace if going from fullscreen -> notfullscreen // Resize workspace if going from fullscreen -> notfullscreen
// otherwise just resize container // otherwise just resize container
@ -721,7 +725,7 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
return true; return true;
} }
swayc_t *workspace = workspace_find_by_name(argv[0]); swayc_t *workspace = workspace_by_name(argv[0]);
if (!workspace) { if (!workspace) {
workspace = workspace_create(argv[0]); workspace = workspace_create(argv[0]);
} }

View file

@ -26,14 +26,11 @@ static void free_swayc(swayc_t *cont) {
if (!ASSERT_NONNULL(cont)) { if (!ASSERT_NONNULL(cont)) {
return; return;
} }
// TODO does not properly handle containers with children,
// TODO but functions that call this usually check for that
if (cont->children) { if (cont->children) {
if (cont->children->length) { // remove children until there are no more, free_swayc calls
int i; // remove_child, which removes child from this container
for (i = 0; i < cont->children->length; ++i) { while (cont->children->length) {
free_swayc(cont->children->items[i]); free_swayc(cont->children->items[0]);
}
} }
list_free(cont->children); list_free(cont->children);
} }
@ -57,10 +54,6 @@ static void free_swayc(swayc_t *cont) {
// New containers // New containers
static bool workspace_test(swayc_t *view, void *name) {
return strcasecmp(view->name, (char *)name) == 0;
}
swayc_t *new_output(wlc_handle handle) { swayc_t *new_output(wlc_handle handle) {
const struct wlc_size* size = wlc_output_get_resolution(handle); const struct wlc_size* size = wlc_output_get_resolution(handle);
const char *name = wlc_output_get_name(handle); const char *name = wlc_output_get_name(handle);
@ -84,7 +77,7 @@ swayc_t *new_output(wlc_handle handle) {
if (strcasecmp(wso->output, name) == 0) { if (strcasecmp(wso->output, name) == 0) {
sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output); sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output);
// Check if any other workspaces are using this name // Check if any other workspaces are using this name
if (find_container(&root_container, workspace_test, wso->workspace)) { if (workspace_by_name(wso->workspace)) {
sway_log(L_DEBUG, "But it's already taken"); sway_log(L_DEBUG, "But it's already taken");
break; break;
} }
@ -128,7 +121,8 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
} }
swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
if (!ASSERT_NONNULL(child)) { if (!ASSERT_NONNULL(child)
&& !sway_assert(!child->is_floating, "cannot create container around floating window")) {
return NULL; return NULL;
} }
swayc_t *cont = new_swayc(C_CONTAINER); swayc_t *cont = new_swayc(C_CONTAINER);
@ -207,6 +201,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
} }
swayc_t *new_floating_view(wlc_handle handle) { swayc_t *new_floating_view(wlc_handle handle) {
if (swayc_active_workspace() == NULL) {
return NULL;
}
const char *title = wlc_view_get_title(handle); const char *title = wlc_view_get_title(handle);
swayc_t *view = new_swayc(C_VIEW); swayc_t *view = new_swayc(C_VIEW);
sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view", sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view",
@ -220,8 +217,8 @@ swayc_t *new_floating_view(wlc_handle handle) {
const struct wlc_geometry* geometry = wlc_view_get_geometry(handle); const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
// give it requested geometry, but place in center // give it requested geometry, but place in center
view->x = (active_workspace->width - geometry->size.w) / 2; view->x = (swayc_active_workspace()->width - geometry->size.w) / 2;
view->y = (active_workspace->height- geometry->size.h) / 2; view->y = (swayc_active_workspace()->height- geometry->size.h) / 2;
view->width = geometry->size.w; view->width = geometry->size.w;
view->height = geometry->size.h; view->height = geometry->size.h;
@ -231,10 +228,10 @@ swayc_t *new_floating_view(wlc_handle handle) {
view->is_floating = true; view->is_floating = true;
// Case of focused workspace, just create as child of it // Case of focused workspace, just create as child of it
list_add(active_workspace->floating, view); list_add(swayc_active_workspace()->floating, view);
view->parent = active_workspace; view->parent = swayc_active_workspace();
if (active_workspace->focused == NULL) { if (swayc_active_workspace()->focused == NULL) {
set_focused_container_for(active_workspace, view); set_focused_container_for(swayc_active_workspace(), view);
} }
return view; return view;
} }
@ -306,33 +303,8 @@ swayc_t *destroy_view(swayc_t *view) {
// Container lookup // Container lookup
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
if (!ASSERT_NONNULL(container)) {
return NULL;
}
if (!sway_assert(type < C_TYPES && type >= C_ROOT, "%s: invalid type", __func__)) {
return NULL;
}
do {
container = container->parent;
} while(container && container->type != type);
return container;
}
swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) { swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
if (!ASSERT_NONNULL(container)) {
return NULL;
}
if (!sway_assert(layout < L_LAYOUTS && layout >= L_NONE, "%s: invalid layout", __func__)) {
return NULL;
}
do {
container = container->parent;
} while (container && container->layout != layout);
return container;
}
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
if (!container->children) { if (!container->children) {
return NULL; return NULL;
} }
@ -351,7 +323,7 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
if (test(child, data)) { if (test(child, data)) {
return child; return child;
} else { } else {
swayc_t *res = find_container(child, test, data); swayc_t *res = swayc_by_test(child, test, data);
if (res) { if (res) {
return res; return res;
} }
@ -360,6 +332,104 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
return NULL; return NULL;
} }
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
if (!ASSERT_NONNULL(container)) {
return NULL;
}
if (!sway_assert(type < C_TYPES && type >= C_ROOT, "%s: invalid type", __func__)) {
return NULL;
}
do {
container = container->parent;
} while (container && container->type != type);
return container;
}
swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
if (!ASSERT_NONNULL(container)) {
return NULL;
}
if (!sway_assert(layout < L_LAYOUTS && layout >= L_NONE, "%s: invalid layout", __func__)) {
return NULL;
}
do {
container = container->parent;
} while (container && container->layout != layout);
return container;
}
static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) {
if (!parent || !parent->children) {
return NULL;
}
int i, len;
swayc_t **child;
if (parent->type == C_WORKSPACE) {
len = parent->floating->length;
child = (swayc_t **)parent->floating->items;
for (i = 0; i < len; ++i, ++child) {
if ((*child)->handle == handle) {
return *child;
}
}
}
len = parent->children->length;
child = (swayc_t**)parent->children->items;
for (i = 0; i < len; ++i, ++child) {
if ((*child)->handle == handle) {
return *child;
} else {
swayc_t *res;
if ((res = _swayc_by_handle_helper(handle, *child))) {
return res;
}
}
}
return NULL;
}
swayc_t *swayc_by_handle(wlc_handle handle) {
return _swayc_by_handle_helper(handle, &root_container);
}
swayc_t *swayc_active_output(void) {
return root_container.focused;
}
swayc_t *swayc_active_workspace(void) {
return root_container.focused ? root_container.focused->focused : NULL;
}
swayc_t *swayc_active_workspace_for(swayc_t *cont) {
if (!cont) {
return NULL;
}
switch (cont->type) {
case C_ROOT:
cont = cont->focused;
/* Fallthrough */
case C_OUTPUT:
cont = cont->focused;
/* Fallthrough */
case C_WORKSPACE:
return cont;
default:
return swayc_parent_by_type(cont, C_WORKSPACE);
}
}
// Container information
bool swayc_is_fullscreen(swayc_t *view) {
return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN);
}
// Mapping
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
if (container && container->children && container->children->length) { if (container && container->children && container->children->length) {
int i; int i;

View file

@ -21,8 +21,6 @@ static void update_focus(swayc_t *c) {
// Case where output changes // Case where output changes
case C_OUTPUT: case C_OUTPUT:
wlc_output_focus(c->handle); wlc_output_focus(c->handle);
// Set new workspace to the outputs focused workspace
active_workspace = c->focused;
break; break;
// Case where workspace changes // Case where workspace changes
@ -39,7 +37,6 @@ static void update_focus(swayc_t *c) {
c->parent->focused = c; c->parent->focused = c;
destroy_workspace(ws); destroy_workspace(ws);
} }
active_workspace = c;
break; break;
default: default:
@ -54,8 +51,8 @@ static void update_focus(swayc_t *c) {
} }
bool move_focus(enum movement_direction direction) { bool move_focus(enum movement_direction direction) {
swayc_t *view = get_swayc_in_direction( swayc_t *view = get_focused_container(&root_container);
get_focused_container(&root_container), direction); view = get_swayc_in_direction(view, direction);
if (view) { if (view) {
if (direction == MOVE_PARENT) { if (direction == MOVE_PARENT) {
set_focused_container(view); set_focused_container(view);
@ -68,13 +65,12 @@ bool move_focus(enum movement_direction direction) {
} }
swayc_t *get_focused_container(swayc_t *parent) { swayc_t *get_focused_container(swayc_t *parent) {
while (parent && !parent->is_focused) { if (!parent) {
parent = parent->focused; return swayc_active_workspace();
} }
// just incase // get focusde container
if (parent == NULL) { while (!parent->is_focused && parent->focused) {
sway_log(L_DEBUG, "get_focused_container unable to find container"); parent = parent->focused;
return active_workspace;
} }
return parent; return parent;
} }
@ -85,9 +81,13 @@ void set_focused_container(swayc_t *c) {
} }
sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle); sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle);
// Find previous focused view, and the new focused view, if they are the same return // Get workspace for c, get that workspaces current focused container.
swayc_t *focused = get_focused_view(&root_container); swayc_t *workspace = swayc_active_workspace_for(c);
swayc_t *workspace = active_workspace; swayc_t *focused = get_focused_view(workspace);
// if the workspace we are changing focus to has a fullscreen view return
if (swayc_is_fullscreen(focused) && focused != c) {
return;
}
// update container focus from here to root, making necessary changes along // update container focus from here to root, making necessary changes along
// the way // the way
@ -101,13 +101,6 @@ void set_focused_container(swayc_t *c) {
p->is_focused = false; p->is_focused = false;
} }
// if the workspace is the same, and previous focus is fullscreen, dont
// change focus
if (workspace == active_workspace
&& wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) {
return;
}
// get new focused view and set focus to it. // get new focused view and set focus to it.
p = get_focused_view(c); p = get_focused_view(c);
if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) {
@ -137,6 +130,15 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) {
return; return;
} }
} }
// Get workspace for c, get that workspaces current focused container.
swayc_t *workspace = swayc_active_workspace_for(c);
swayc_t *focused = get_focused_view(workspace);
// if the workspace we are changing focus to has a fullscreen view return
if (swayc_is_fullscreen(focused) && c != focused) {
return;
}
// Check if we changing a parent container that will see chnage // Check if we changing a parent container that will see chnage
bool effective = true; bool effective = true;
while (find != &root_container) { while (find != &root_container) {
@ -171,7 +173,7 @@ swayc_t *get_focused_view(swayc_t *parent) {
parent = parent->focused; parent = parent->focused;
} }
if (parent == NULL) { if (parent == NULL) {
return active_workspace; return swayc_active_workspace_for(parent);
} }
return parent; return parent;
} }

View file

@ -86,7 +86,7 @@ static bool handle_output_created(wlc_handle output) {
swayc_t *op = new_output(output); swayc_t *op = new_output(output);
// Switch to workspace if we need to // Switch to workspace if we need to
if (active_workspace == NULL) { if (swayc_active_workspace() == NULL) {
swayc_t *ws = op->children->items[0]; swayc_t *ws = op->children->items[0];
workspace_switch(ws); workspace_switch(ws);
} }
@ -104,9 +104,7 @@ static void handle_output_destroyed(wlc_handle output) {
if (i < list->length) { if (i < list->length) {
destroy_output(list->items[i]); destroy_output(list->items[i]);
} }
if (list->length == 0) { if (list->length > 0) {
active_workspace = NULL;
} else {
// switch to other outputs active workspace // switch to other outputs active workspace
workspace_switch(((swayc_t *)root_container.children->items[0])->focused); workspace_switch(((swayc_t *)root_container.children->items[0])->focused);
} }
@ -114,7 +112,7 @@ static void handle_output_destroyed(wlc_handle output) {
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h); sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
swayc_t *c = get_swayc_for_handle(output, &root_container); swayc_t *c = swayc_by_handle(output);
if (!c) return; if (!c) return;
c->width = to->w; c->width = to->w;
c->height = to->h; c->height = to->h;
@ -122,7 +120,7 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
} }
static void handle_output_focused(wlc_handle output, bool focus) { static void handle_output_focused(wlc_handle output, bool focus) {
swayc_t *c = get_swayc_for_handle(output, &root_container); swayc_t *c = swayc_by_handle(output);
// if for some reason this output doesnt exist, create it. // if for some reason this output doesnt exist, create it.
if (!c) { if (!c) {
handle_output_created(output); handle_output_created(output);
@ -140,7 +138,7 @@ static bool handle_view_created(wlc_handle handle) {
// Get parent container, to add view in // Get parent container, to add view in
if (parent) { if (parent) {
focused = get_swayc_for_handle(parent, &root_container); focused = swayc_by_handle(parent);
} }
if (!focused || focused->type == C_OUTPUT) { if (!focused || focused->type == C_OUTPUT) {
focused = get_focused_container(&root_container); focused = get_focused_container(&root_container);
@ -197,7 +195,7 @@ static bool handle_view_created(wlc_handle handle) {
static void handle_view_destroyed(wlc_handle handle) { static void handle_view_destroyed(wlc_handle handle) {
sway_log(L_DEBUG, "Destroying window %lu", handle); sway_log(L_DEBUG, "Destroying window %lu", handle);
swayc_t *view = get_swayc_for_handle(handle, &root_container); swayc_t *view = swayc_by_handle(handle);
switch (wlc_view_get_type(handle)) { switch (wlc_view_get_type(handle)) {
// regular view created regularly // regular view created regularly
@ -231,7 +229,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
// If the view is floating, then apply the geometry. // If the view is floating, then apply the geometry.
// Otherwise save the desired width/height for the view. // Otherwise save the desired width/height for the view.
// This will not do anything for the time being as WLC improperly sends geometry requests // This will not do anything for the time being as WLC improperly sends geometry requests
swayc_t *view = get_swayc_for_handle(handle, &root_container); swayc_t *view = swayc_by_handle(handle);
if (view) { if (view) {
view->desired_width = geometry->size.w; view->desired_width = geometry->size.w;
view->desired_height = geometry->size.h; view->desired_height = geometry->size.h;
@ -247,7 +245,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
} }
static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
swayc_t *c = get_swayc_for_handle(view, &root_container); swayc_t *c = swayc_by_handle(view);
switch (state) { switch (state) {
case WLC_BIT_FULLSCREEN: case WLC_BIT_FULLSCREEN:
// i3 just lets it become fullscreen // i3 just lets it become fullscreen
@ -342,7 +340,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
bool changed_tiling = false; bool changed_tiling = false;
int min_sane_w = 100; int min_sane_w = 100;
int min_sane_h = 60; int min_sane_h = 60;
if (!active_workspace) { if (!swayc_active_workspace()) {
return false; return false;
} }
// Do checks to determine if proper keys are being held // Do checks to determine if proper keys are being held
@ -568,13 +566,13 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
} }
} }
} }
arrange_windows(active_workspace, -1, -1); arrange_windows(swayc_active_workspace(), -1, -1);
} }
} }
if (config->focus_follows_mouse && prev_handle != handle) { if (config->focus_follows_mouse && prev_handle != handle) {
// Dont change focus if fullscreen // Dont change focus if fullscreen
swayc_t *focused = get_focused_view(view); swayc_t *focused = get_focused_view(view);
if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) if (!swayc_is_fullscreen(focused)
&& !(pointer_state.l_held || pointer_state.r_held)) { && !(pointer_state.l_held || pointer_state.r_held)) {
set_focused_container(container_under_pointer()); set_focused_container(container_under_pointer());
} }
@ -606,7 +604,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) {
swayc_t *focused = get_focused_container(&root_container); swayc_t *focused = get_focused_container(&root_container);
// dont change focus if fullscreen // dont change focus if fullscreen
if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { if (swayc_is_fullscreen(focused)) {
return false; return false;
} }
if (state == WLC_BUTTON_STATE_PRESSED) { if (state == WLC_BUTTON_STATE_PRESSED) {
@ -646,8 +644,12 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
// Dont want pointer sent to window while dragging or resizing // Dont want pointer sent to window while dragging or resizing
return (pointer_state.floating.drag || pointer_state.floating.resize); return (pointer_state.floating.drag || pointer_state.floating.resize);
} else { } else {
if (modifiers->mods & config->floating_mod) {
pointer_state.tiling.resize = pointer_state.r_held; pointer_state.tiling.resize = pointer_state.r_held;
pointer_state.tiling.init_view = pointer; pointer_state.tiling.init_view = pointer;
// Dont want pointer sent when resizing
return (pointer_state.tiling.resize);
}
} }
return (pointer && pointer != focused); return (pointer && pointer != focused);
} else { } else {

View file

@ -35,7 +35,7 @@ void add_child(swayc_t *parent, swayc_t *child) {
child->parent = parent; child->parent = parent;
// set focus for this container // set focus for this container
if (parent->children->length == 1) { if (parent->children->length == 1) {
set_focused_container_for(parent, child); parent->focused = child;
} }
} }
@ -46,7 +46,7 @@ void add_floating(swayc_t *ws, swayc_t *child) {
child->parent = ws; child->parent = ws;
child->is_floating = true; child->is_floating = true;
if (!ws->focused) { if (!ws->focused) {
set_focused_container_for(ws, child); ws->focused = child;
} }
} }
@ -71,7 +71,7 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
new_child->parent = child->parent; new_child->parent = child->parent;
if (child->parent->focused == child) { if (child->parent->focused == child) {
set_focused_container_for(child->parent, new_child); child->parent->focused = new_child;
} }
child->parent = NULL; child->parent = NULL;
return parent; return parent;
@ -100,7 +100,7 @@ swayc_t *remove_child(swayc_t *child) {
// Set focused to new container // Set focused to new container
if (parent->focused == child) { if (parent->focused == child) {
if (parent->children->length > 0) { if (parent->children->length > 0) {
set_focused_container_for(parent, parent->children->items[i?i-1:0]); parent->focused = parent->children->items[i?i-1:0];
} else { } else {
parent->focused = NULL; parent->focused = NULL;
} }
@ -204,7 +204,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
.h = height - container->gaps .h = height - container->gaps
} }
}; };
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) { if (swayc_is_fullscreen(container)) {
swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT);
geometry.origin.x = 0; geometry.origin.x = 0;
geometry.origin.y = 0; geometry.origin.y = 0;
@ -303,7 +303,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
.h = view->height .h = view->height
} }
}; };
if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) { if (swayc_is_fullscreen(view)) {
swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
geometry.origin.x = 0; geometry.origin.x = 0;
geometry.origin.y = 0; geometry.origin.y = 0;
@ -318,7 +318,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
// have higher indexes // have higher indexes
// This is conditional on there not being a fullscreen view in the workspace // This is conditional on there not being a fullscreen view in the workspace
if (!container->focused if (!container->focused
|| !(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) { || !swayc_is_fullscreen(container->focused)) {
wlc_view_bring_to_front(view->handle); wlc_view_bring_to_front(view->handle);
} }
} }
@ -328,35 +328,6 @@ void arrange_windows(swayc_t *container, double width, double height) {
layout_log(&root_container, 0); layout_log(&root_container, 0);
} }
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
if (parent->children == NULL) {
return NULL;
}
// Search for floating workspaces
int i;
if (parent->type == C_WORKSPACE) {
for (i = 0; i < parent->floating->length; ++i) {
swayc_t *child = parent->floating->items[i];
if (child->handle == handle) {
return child;
}
}
}
for (i = 0; i < parent->children->length; ++i) {
swayc_t *child = parent->children->items[i];
if (child->handle == handle) {
return child;
} else {
swayc_t *res;
if ((res = get_swayc_for_handle(handle, child))) {
return res;
}
}
}
return NULL;
}
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) { swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) {
swayc_t *parent = container->parent; swayc_t *parent = container->parent;

View file

@ -119,8 +119,9 @@ bool sway_assert(bool condition, const char* format, ...) {
/* XXX:DEBUG:XXX */ /* XXX:DEBUG:XXX */
static void container_log(const swayc_t *c) { static void container_log(const swayc_t *c) {
fprintf(stderr, "focus:%c|", fprintf(stderr, "focus:%c|",
c->is_focused ? 'F' : // Focused c == get_focused_view(&root_container) ? 'K':
c == active_workspace ? 'W' : // active workspace c == get_focused_container(&root_container) ? 'F' : // Focused
c == swayc_active_workspace() ? 'W' : // active workspace
c == &root_container ? 'R' : // root c == &root_container ? 'R' : // root
'X');// not any others 'X');// not any others
fprintf(stderr,"(%p)",c); fprintf(stderr,"(%p)",c);

View file

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <wlc/wlc.h> #include <wlc/wlc.h>
#include <string.h>
#include "workspace.h" #include "workspace.h"
#include "layout.h" #include "layout.h"
#include "list.h" #include "list.h"
@ -11,8 +12,6 @@
#include "stringop.h" #include "stringop.h"
#include "focus.h" #include "focus.h"
swayc_t *active_workspace = NULL;
char *workspace_next_name(void) { char *workspace_next_name(void) {
sway_log(L_DEBUG, "Workspace: Generating new name"); sway_log(L_DEBUG, "Workspace: Generating new name");
int i; int i;
@ -48,7 +47,7 @@ char *workspace_next_name(void) {
} }
// Make sure that the workspace doesn't already exist // Make sure that the workspace doesn't already exist
if (workspace_find_by_name(target)) { if (workspace_by_name(target)) {
list_free(args); list_free(args);
continue; continue;
} }
@ -79,22 +78,22 @@ swayc_t *workspace_create(const char* name) {
return new_workspace(parent, name); return new_workspace(parent, name);
} }
bool workspace_by_name(swayc_t *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);
} }
swayc_t *workspace_find_by_name(const char* name) { swayc_t *workspace_by_name(const char* name) {
return find_container(&root_container, workspace_by_name, (void *) name); return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
} }
void workspace_output_next() { void workspace_output_next() {
// Get the index of the workspace in the current output, and change the view to index+1 workspace. // Get the index of the workspace in the current output, and change the view to index+1 workspace.
// if we're currently focused on the last workspace in the output, switch to the first // if we're currently focused on the last workspace in the output, switch to the first
swayc_t *current_output = active_workspace->parent; swayc_t *current_output = swayc_active_workspace()->parent;
int i; int i;
for (i = 0; i < current_output->children->length - 1; i++) { for (i = 0; i < current_output->children->length - 1; i++) {
if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
workspace_switch(current_output->children->items[i + 1]); workspace_switch(current_output->children->items[i + 1]);
return; return;
} }
@ -106,10 +105,10 @@ void workspace_next() {
// Get the index of the workspace in the current output, and change the view to index+1 workspace. // Get the index of the workspace in the current output, and change the view to index+1 workspace.
// if we're currently focused on the last workspace in the output, change focus to there // if we're currently focused on the last workspace in the output, change focus to there
// and call workspace_output_next(), as long as another output actually exists // and call workspace_output_next(), as long as another output actually exists
swayc_t *current_output = active_workspace->parent; swayc_t *current_output = swayc_active_workspace()->parent;
int i; int i;
for (i = 0; i < current_output->children->length - 1; i++) { for (i = 0; i < current_output->children->length - 1; i++) {
if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
workspace_switch(current_output->children->items[i + 1]); workspace_switch(current_output->children->items[i + 1]);
return; return;
} }
@ -134,10 +133,10 @@ void workspace_next() {
void workspace_output_prev() { void workspace_output_prev() {
// Get the index of the workspace in the current output, and change the view to index+1 workspace // Get the index of the workspace in the current output, and change the view to index+1 workspace
// if we're currently focused on the first workspace in the output, do nothing and return false // if we're currently focused on the first workspace in the output, do nothing and return false
swayc_t *current_output = active_workspace->parent; swayc_t *current_output = swayc_active_workspace()->parent;
int i; int i;
for (i = 1; i < current_output->children->length; i++) { for (i = 1; i < current_output->children->length; i++) {
if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
workspace_switch(current_output->children->items[i - 1]); workspace_switch(current_output->children->items[i - 1]);
return; return;
} }
@ -150,10 +149,10 @@ void workspace_prev() {
// if we're currently focused on the last workspace in the output, change focus to there // if we're currently focused on the last workspace in the output, change focus to there
// and call workspace_output_next(), as long as another output actually exists // and call workspace_output_next(), as long as another output actually exists
swayc_t *current_output = active_workspace->parent; swayc_t *current_output = swayc_active_workspace()->parent;
int i; int i;
for (i = 1; i < current_output->children->length; i++) { for (i = 1; i < current_output->children->length; i++) {
if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) { if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
workspace_switch(current_output->children->items[i - 1]); workspace_switch(current_output->children->items[i - 1]);
return; return;
} }