mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 08:51:27 +00:00
This commit is contained in:
commit
af872be2cf
|
@ -22,6 +22,12 @@ struct sway_mode {
|
||||||
list_t *bindings;
|
list_t *bindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct output_config {
|
||||||
|
char *name;
|
||||||
|
int width, height;
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
struct workspace_output {
|
struct workspace_output {
|
||||||
char *output;
|
char *output;
|
||||||
char *workspace;
|
char *workspace;
|
||||||
|
@ -32,6 +38,7 @@ struct sway_config {
|
||||||
list_t *modes;
|
list_t *modes;
|
||||||
list_t *cmd_queue;
|
list_t *cmd_queue;
|
||||||
list_t *workspace_outputs;
|
list_t *workspace_outputs;
|
||||||
|
list_t *output_configs;
|
||||||
struct sway_mode *current_mode;
|
struct sway_mode *current_mode;
|
||||||
uint32_t floating_mod;
|
uint32_t floating_mod;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <wlc/wlc.h>
|
#include <wlc/wlc.h>
|
||||||
|
|
||||||
extern struct wlc_interface interface;
|
extern struct wlc_interface interface;
|
||||||
|
extern struct wlc_origin mouse_origin;
|
||||||
extern uint32_t keys_pressed[32];
|
extern uint32_t keys_pressed[32];
|
||||||
|
|
||||||
// set focus to current pointer location and return focused container
|
// set focus to current pointer location and return focused container
|
||||||
|
|
|
@ -37,13 +37,19 @@ extern struct pointer_state {
|
||||||
struct pointer_tiling {
|
struct pointer_tiling {
|
||||||
bool resize;
|
bool resize;
|
||||||
swayc_t *init_view;
|
swayc_t *init_view;
|
||||||
struct wlc_origin *lock_pos;
|
struct wlc_origin lock_pos;
|
||||||
} tiling;
|
} tiling;
|
||||||
struct pointer_lock {
|
struct pointer_lock {
|
||||||
|
// Lock movement for certain edges
|
||||||
bool left;
|
bool left;
|
||||||
bool right;
|
bool right;
|
||||||
bool top;
|
bool top;
|
||||||
bool bottom;
|
bool bottom;
|
||||||
|
// Lock movement in certain directions
|
||||||
|
bool temp_left;
|
||||||
|
bool temp_right;
|
||||||
|
bool temp_up;
|
||||||
|
bool temp_down;
|
||||||
} lock;
|
} lock;
|
||||||
} pointer_state;
|
} pointer_state;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
extern swayc_t root_container;
|
extern swayc_t root_container;
|
||||||
|
|
||||||
|
extern int min_sane_w;
|
||||||
|
extern int min_sane_h;
|
||||||
|
|
||||||
void init_layout(void);
|
void init_layout(void);
|
||||||
|
|
||||||
void add_child(swayc_t *parent, swayc_t *child);
|
void add_child(swayc_t *parent, swayc_t *child);
|
||||||
|
@ -19,17 +22,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);
|
||||||
|
|
8
include/resize.h
Normal file
8
include/resize.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _SWAY_RESIZE_H
|
||||||
|
#define _SWAY_RESIZE_H
|
||||||
|
|
||||||
|
bool mouse_resize_tiled(struct wlc_origin prev_pos);
|
||||||
|
bool resize_floating(struct wlc_origin prev_pos);
|
||||||
|
bool resize_tiled(int amount, bool use_width);
|
||||||
|
|
||||||
|
#endif
|
|
@ -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();
|
||||||
|
|
68
sway.5.txt
68
sway.5.txt
|
@ -41,6 +41,11 @@ Commands
|
||||||
**floating** toggle::
|
**floating** toggle::
|
||||||
Toggles the "floating" status of the focused view.
|
Toggles the "floating" status of the focused view.
|
||||||
|
|
||||||
|
**floating_modifier** <modifier>::
|
||||||
|
When the _modifier_ key is held down, you may use left click to drag floating
|
||||||
|
windows, and right click to resize them. Unlike i3, this modifier may also be
|
||||||
|
used to resize and move windows that are tiled.
|
||||||
|
|
||||||
**focus** <direction>::
|
**focus** <direction>::
|
||||||
Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The
|
Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The
|
||||||
directional focus commands will move the focus in that direction. The parent
|
directional focus commands will move the focus in that direction. The parent
|
||||||
|
@ -55,34 +60,6 @@ Commands
|
||||||
If set to _yes_, the currently focused view will change as you move your
|
If set to _yes_, the currently focused view will change as you move your
|
||||||
mouse around the screen to the view that ends up underneath your mouse.
|
mouse around the screen to the view that ends up underneath your mouse.
|
||||||
|
|
||||||
**kill**::
|
|
||||||
Closes the currently focused view.
|
|
||||||
|
|
||||||
**layout** <mode>::
|
|
||||||
Sets the layout mode of the focused container. _mode_ can be one of _splith_,
|
|
||||||
_splitv_, or _toggle split_.
|
|
||||||
|
|
||||||
**reload**::
|
|
||||||
Reloads the sway config file without restarting sway.
|
|
||||||
|
|
||||||
**set** <name> <value>::
|
|
||||||
Creates a substitution for _value_ that can be used with $_name_ in other
|
|
||||||
commands.
|
|
||||||
|
|
||||||
**split** <vertical|horizontal>::
|
|
||||||
Splits the current container, vertically or horiziontally. The letters "h" and
|
|
||||||
"v" can be used instead of the full words "vertical" or "horizontal".
|
|
||||||
|
|
||||||
**splith**::
|
|
||||||
Equivalent to **split horizontal**.
|
|
||||||
|
|
||||||
**splitv**::
|
|
||||||
Equivalent to **split vertical**.
|
|
||||||
|
|
||||||
**floating_modifier** <modifier>::
|
|
||||||
When the _modifier_ key is held down, you may use left click to drag floating
|
|
||||||
windows, and right click to resize them.
|
|
||||||
|
|
||||||
**fullscreen**::
|
**fullscreen**::
|
||||||
Toggles fullscreen status for the focused view.
|
Toggles fullscreen status for the focused view.
|
||||||
|
|
||||||
|
@ -93,6 +70,41 @@ Commands
|
||||||
Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects
|
Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects
|
||||||
spacing between views and the latter affects the space around each output.
|
spacing between views and the latter affects the space around each output.
|
||||||
|
|
||||||
|
**kill**::
|
||||||
|
Closes the currently focused view.
|
||||||
|
|
||||||
|
**layout** <mode>::
|
||||||
|
Sets the layout mode of the focused container. _mode_ can be one of _splith_,
|
||||||
|
_splitv_, or _toggle split_.
|
||||||
|
|
||||||
|
**move** <left|right|up|down>::
|
||||||
|
Moves the focused container _left_, _right_, _up_, or _down_.
|
||||||
|
|
||||||
|
**output** <name> <resolution|res WIDTHxHEIGHT> <position|pos X,Y>::
|
||||||
|
Configures the specified output. It will use the given resolution and be
|
||||||
|
arranged at the given position in the layout tree. You may omit either of
|
||||||
|
these parameters if you only want to set one of them.
|
||||||
|
|
||||||
|
**reload**::
|
||||||
|
Reloads the sway config file without restarting sway.
|
||||||
|
|
||||||
|
**resize** <shrink|grow> <width|height> <amount>::
|
||||||
|
Resizes the currently focused container or view by _amount_. _amount_ can be
|
||||||
|
specified as "n px" or "n ppt" or "n px or n ppt".
|
||||||
|
|
||||||
|
**set** <name> <value>::
|
||||||
|
Creates a substitution for _value_ that can be used with $_name_ in other
|
||||||
|
commands.
|
||||||
|
|
||||||
|
**split** <vertical|v|horizontal|h>::
|
||||||
|
Splits the current container, vertically or horiziontally.
|
||||||
|
|
||||||
|
**splith**::
|
||||||
|
Equivalent to **split horizontal**.
|
||||||
|
|
||||||
|
**splitv**::
|
||||||
|
Equivalent to **split vertical**.
|
||||||
|
|
||||||
**workspace** <name>::
|
**workspace** <name>::
|
||||||
Switches to the specified workspace.
|
Switches to the specified workspace.
|
||||||
|
|
||||||
|
|
250
sway/commands.c
250
sway/commands.c
|
@ -16,6 +16,7 @@
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "sway.h"
|
#include "sway.h"
|
||||||
|
#include "resize.h"
|
||||||
|
|
||||||
struct modifier_key {
|
struct modifier_key {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -208,16 +209,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 +229,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 +245,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 +294,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,6 +364,66 @@ static bool cmd_move(struct sway_config *config, int argc, char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cmd_output(struct sway_config *config, int argc, char **argv) {
|
||||||
|
if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct output_config *output = calloc(1, sizeof(struct output_config));
|
||||||
|
output->x = output->y = output->width = output->height = -1;
|
||||||
|
output->name = strdup(argv[0]);
|
||||||
|
|
||||||
|
// TODO: atoi doesn't handle invalid numbers
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
if (strcasecmp(argv[i], "resolution") == 0 || strcasecmp(argv[i], "res") == 0) {
|
||||||
|
char *res = argv[++i];
|
||||||
|
char *x = strchr(res, 'x');
|
||||||
|
int width = -1, height = -1;
|
||||||
|
if (x != NULL) {
|
||||||
|
// Format is 1234x4321
|
||||||
|
*x = '\0';
|
||||||
|
width = atoi(res);
|
||||||
|
height = atoi(x + 1);
|
||||||
|
*x = 'x';
|
||||||
|
} else {
|
||||||
|
// Format is 1234 4321
|
||||||
|
width = atoi(res);
|
||||||
|
res = argv[++i];
|
||||||
|
height = atoi(res);
|
||||||
|
}
|
||||||
|
output->width = width;
|
||||||
|
output->height = height;
|
||||||
|
} else if (strcasecmp(argv[i], "position") == 0 || strcasecmp(argv[i], "pos") == 0) {
|
||||||
|
char *res = argv[++i];
|
||||||
|
char *c = strchr(res, ',');
|
||||||
|
int x = -1, y = -1;
|
||||||
|
if (c != NULL) {
|
||||||
|
// Format is 1234,4321
|
||||||
|
*c = '\0';
|
||||||
|
x = atoi(res);
|
||||||
|
y = atoi(c + 1);
|
||||||
|
*c = ',';
|
||||||
|
} else {
|
||||||
|
// Format is 1234 4321
|
||||||
|
x = atoi(res);
|
||||||
|
res = argv[++i];
|
||||||
|
y = atoi(res);
|
||||||
|
}
|
||||||
|
output->x = x;
|
||||||
|
output->y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add(config->output_configs, output);
|
||||||
|
|
||||||
|
sway_log(L_DEBUG, "Configured output %s to %d x %d @ %d, %d",
|
||||||
|
output->name, output->width, output->height, output->x, output->y);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool cmd_gaps(struct sway_config *config, int argc, char **argv) {
|
static bool cmd_gaps(struct sway_config *config, int argc, char **argv) {
|
||||||
if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) {
|
if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -452,147 +514,21 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) {
|
if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[0], "shrink") == 0) {
|
if (strcmp(argv[0], "shrink") == 0) {
|
||||||
amount *= -1;
|
amount *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *parent = get_focused_view(active_workspace);
|
|
||||||
swayc_t *focused = parent;
|
|
||||||
swayc_t *sibling;
|
|
||||||
if (!parent) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Find the closest parent container which has siblings of the proper layout.
|
|
||||||
// Then apply the resize to all of them.
|
|
||||||
int i;
|
|
||||||
if (strcmp(argv[1], "width") == 0) {
|
if (strcmp(argv[1], "width") == 0) {
|
||||||
int lnumber = 0;
|
return resize_tiled(amount, true);
|
||||||
int rnumber = 0;
|
|
||||||
while (parent->parent) {
|
|
||||||
if (parent->parent->layout == L_HORIZ) {
|
|
||||||
for (i = 0; i < parent->parent->children->length; i++) {
|
|
||||||
sibling = parent->parent->children->items[i];
|
|
||||||
if (sibling->x != focused->x) {
|
|
||||||
if (sibling->x < parent->x) {
|
|
||||||
lnumber++;
|
|
||||||
} else if (sibling->x > parent->x) {
|
|
||||||
rnumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rnumber || lnumber) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
if (parent == &root_container) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber);
|
|
||||||
//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
|
|
||||||
for (i = 0; i < parent->parent->children->length; i++) {
|
|
||||||
sibling = parent->parent->children->items[i];
|
|
||||||
if (sibling->x != focused->x) {
|
|
||||||
if (sibling->x < parent->x) {
|
|
||||||
double pixels = -1 * amount;
|
|
||||||
pixels /= lnumber;
|
|
||||||
if (rnumber) {
|
|
||||||
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
} else {
|
|
||||||
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
}
|
|
||||||
} else if (sibling->x > parent->x) {
|
|
||||||
double pixels = -1 * amount;
|
|
||||||
pixels /= rnumber;
|
|
||||||
if (lnumber) {
|
|
||||||
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
} else {
|
|
||||||
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (rnumber != 0 && lnumber != 0) {
|
|
||||||
double pixels = amount;
|
|
||||||
pixels /= 2;
|
|
||||||
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
} else if (rnumber) {
|
|
||||||
recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
} else if (lnumber) {
|
|
||||||
recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Recursive resize does not handle positions, let arrange_windows
|
|
||||||
// take care of that.
|
|
||||||
arrange_windows(active_workspace, -1, -1);
|
|
||||||
return true;
|
|
||||||
} else if (strcmp(argv[1], "height") == 0) {
|
} else if (strcmp(argv[1], "height") == 0) {
|
||||||
int tnumber = 0;
|
return resize_tiled(amount, false);
|
||||||
int bnumber = 0;
|
|
||||||
while (parent->parent) {
|
|
||||||
if (parent->parent->layout == L_VERT) {
|
|
||||||
for (i = 0; i < parent->parent->children->length; i++) {
|
|
||||||
sibling = parent->parent->children->items[i];
|
|
||||||
if (sibling->y != focused->y) {
|
|
||||||
if (sibling->y < parent->y) {
|
|
||||||
bnumber++;
|
|
||||||
} else if (sibling->y > parent->y) {
|
|
||||||
tnumber++;
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
if (bnumber || tnumber) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
if (parent == &root_container) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber);
|
|
||||||
//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
|
|
||||||
for (i = 0; i < parent->parent->children->length; i++) {
|
|
||||||
sibling = parent->parent->children->items[i];
|
|
||||||
if (sibling->y != focused->y) {
|
|
||||||
if (sibling->y < parent->y) {
|
|
||||||
double pixels = -1 * amount;
|
|
||||||
pixels /= bnumber;
|
|
||||||
if (tnumber) {
|
|
||||||
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
} else {
|
|
||||||
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
}
|
|
||||||
} else if (sibling->x > parent->x) {
|
|
||||||
double pixels = -1 * amount;
|
|
||||||
pixels /= tnumber;
|
|
||||||
if (bnumber) {
|
|
||||||
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP);
|
|
||||||
} else {
|
|
||||||
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (bnumber != 0 && tnumber != 0) {
|
|
||||||
double pixels = amount/2;
|
|
||||||
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP);
|
|
||||||
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
} else if (tnumber) {
|
|
||||||
recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP);
|
|
||||||
} else if (bnumber) {
|
|
||||||
recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arrange_windows(active_workspace, -1, -1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cmd_set(struct sway_config *config, int argc, char **argv) {
|
static bool cmd_set(struct sway_config *config, int argc, char **argv) {
|
||||||
|
@ -616,8 +552,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 +572,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 +619,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 +660,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]);
|
||||||
}
|
}
|
||||||
|
@ -758,6 +697,7 @@ static struct cmd_handler handlers[] = {
|
||||||
{ "layout", cmd_layout },
|
{ "layout", cmd_layout },
|
||||||
{ "log_colors", cmd_log_colors },
|
{ "log_colors", cmd_log_colors },
|
||||||
{ "move", cmd_move},
|
{ "move", cmd_move},
|
||||||
|
{ "output", cmd_output},
|
||||||
{ "reload", cmd_reload },
|
{ "reload", cmd_reload },
|
||||||
{ "resize", cmd_resize },
|
{ "resize", cmd_resize },
|
||||||
{ "set", cmd_set },
|
{ "set", cmd_set },
|
||||||
|
|
|
@ -22,6 +22,7 @@ void config_defaults(struct sway_config *config) {
|
||||||
config->modes = create_list();
|
config->modes = create_list();
|
||||||
config->cmd_queue = create_list();
|
config->cmd_queue = create_list();
|
||||||
config->workspace_outputs = create_list();
|
config->workspace_outputs = create_list();
|
||||||
|
config->output_configs = create_list();
|
||||||
config->current_mode = malloc(sizeof(struct sway_mode));
|
config->current_mode = malloc(sizeof(struct sway_mode));
|
||||||
config->current_mode->name = NULL;
|
config->current_mode->name = NULL;
|
||||||
config->current_mode->bindings = create_list();
|
config->current_mode->bindings = create_list();
|
||||||
|
@ -60,6 +61,7 @@ void free_config(struct sway_config *config) {
|
||||||
free(sym->value);
|
free(sym->value);
|
||||||
}
|
}
|
||||||
free_flat_list(config->symbols);
|
free_flat_list(config->symbols);
|
||||||
|
free_flat_list(config->output_configs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *search_paths[] = {
|
static const char *search_paths[] = {
|
||||||
|
|
210
sway/container.c
210
sway/container.c
|
@ -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,34 +54,65 @@ 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);
|
||||||
sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
|
sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
|
||||||
|
|
||||||
|
struct output_config *oc = NULL;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < config->output_configs->length; ++i) {
|
||||||
|
oc = config->output_configs->items[i];
|
||||||
|
if (strcasecmp(name, oc->name) == 0) {
|
||||||
|
sway_log(L_DEBUG, "Matched output config for %s", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
swayc_t *output = new_swayc(C_OUTPUT);
|
swayc_t *output = new_swayc(C_OUTPUT);
|
||||||
|
if (oc && oc->width != -1 && oc->height != -1) {
|
||||||
|
output->width = oc->width;
|
||||||
|
output->height = oc->height;
|
||||||
|
struct wlc_size new_size = { .w = oc->width, .h = oc->height };
|
||||||
|
wlc_output_set_resolution(handle, &new_size);
|
||||||
|
} else {
|
||||||
output->width = size->w;
|
output->width = size->w;
|
||||||
output->height = size->h;
|
output->height = size->h;
|
||||||
|
}
|
||||||
output->handle = handle;
|
output->handle = handle;
|
||||||
output->name = name ? strdup(name) : NULL;
|
output->name = name ? strdup(name) : NULL;
|
||||||
output->gaps = config->gaps_outer + config->gaps_inner / 2;
|
output->gaps = config->gaps_outer + config->gaps_inner / 2;
|
||||||
|
|
||||||
|
// Find position for it
|
||||||
|
if (oc && oc->x != -1 && oc->y != -1) {
|
||||||
|
sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y);
|
||||||
|
output->x = oc->x;
|
||||||
|
output->y = oc->y;
|
||||||
|
} else {
|
||||||
|
int x = 0;
|
||||||
|
for (i = 0; i < root_container.children->length; ++i) {
|
||||||
|
swayc_t *c = root_container.children->items[i];
|
||||||
|
if (c->type == C_OUTPUT) {
|
||||||
|
if (c->width + c->x > x) {
|
||||||
|
x = c->width + c->x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output->x = x;
|
||||||
|
}
|
||||||
|
|
||||||
add_child(&root_container, output);
|
add_child(&root_container, output);
|
||||||
|
|
||||||
// Create workspace
|
// Create workspace
|
||||||
char *ws_name = NULL;
|
char *ws_name = NULL;
|
||||||
if (name) {
|
if (name) {
|
||||||
int i;
|
|
||||||
for (i = 0; i < config->workspace_outputs->length; ++i) {
|
for (i = 0; i < config->workspace_outputs->length; ++i) {
|
||||||
struct workspace_output *wso = config->workspace_outputs->items[i];
|
struct workspace_output *wso = config->workspace_outputs->items[i];
|
||||||
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 +156,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 +236,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 +252,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 +263,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;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +299,8 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace->children->length == 0) {
|
// Do not destroy if there are children
|
||||||
|
if (workspace->children->length == 0 && workspace->floating->length == 0) {
|
||||||
sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
|
sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
|
||||||
swayc_t *parent = workspace->parent;
|
swayc_t *parent = workspace->parent;
|
||||||
free_swayc(workspace);
|
free_swayc(workspace);
|
||||||
|
@ -306,33 +339,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 +359,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,15 +368,115 @@ 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) {
|
||||||
int i;
|
int i;
|
||||||
|
if (container->children) {
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
swayc_t *child = container->children->items[i];
|
||||||
f(child, data);
|
f(child, data);
|
||||||
container_map(child, f, data);
|
container_map(child, f, data);
|
||||||
}
|
}
|
||||||
if (container->type == C_WORKSPACE) {
|
}
|
||||||
|
if (container->floating) {
|
||||||
for (i = 0; i < container->floating->length; ++i) {
|
for (i = 0; i < container->floating->length; ++i) {
|
||||||
swayc_t *child = container->floating->items[i];
|
swayc_t *child = container->floating->items[i];
|
||||||
f(child, data);
|
f(child, data);
|
||||||
|
|
47
sway/focus.c
47
sway/focus.c
|
@ -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
|
||||||
|
@ -36,10 +34,8 @@ static void update_focus(swayc_t *c) {
|
||||||
mask = 2;
|
mask = 2;
|
||||||
container_map(c, set_view_visibility, &mask);
|
container_map(c, set_view_visibility, &mask);
|
||||||
wlc_output_set_mask(parent->handle, 2);
|
wlc_output_set_mask(parent->handle, 2);
|
||||||
c->parent->focused = c;
|
|
||||||
destroy_workspace(ws);
|
destroy_workspace(ws);
|
||||||
}
|
}
|
||||||
active_workspace = c;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -54,8 +50,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 +64,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 +80,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 +100,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 +129,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 +172,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;
|
||||||
}
|
}
|
||||||
|
|
266
sway/handlers.c
266
sway/handlers.c
|
@ -15,8 +15,9 @@
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
#include "input_state.h"
|
#include "input_state.h"
|
||||||
|
#include "resize.h"
|
||||||
|
|
||||||
static struct wlc_origin mouse_origin;
|
struct wlc_origin mouse_origin;
|
||||||
|
|
||||||
static bool pointer_test(swayc_t *view, void *_origin) {
|
static bool pointer_test(swayc_t *view, void *_origin) {
|
||||||
const struct wlc_origin *origin = _origin;
|
const struct wlc_origin *origin = _origin;
|
||||||
|
@ -86,7 +87,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 +105,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 +113,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 +121,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 +139,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 +196,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 +230,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 +246,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
|
||||||
|
@ -340,198 +339,17 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
mouse_origin = *origin;
|
mouse_origin = *origin;
|
||||||
bool changed_floating = false;
|
bool changed_floating = false;
|
||||||
bool changed_tiling = false;
|
bool changed_tiling = false;
|
||||||
int min_sane_w = 100;
|
if (!swayc_active_workspace()) {
|
||||||
int min_sane_h = 60;
|
|
||||||
if (!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
|
||||||
swayc_t *view = container_under_pointer();
|
swayc_t *view = container_under_pointer();
|
||||||
uint32_t edge = 0;
|
|
||||||
if (pointer_state.floating.drag && view) {
|
if (pointer_state.floating.drag && view) {
|
||||||
if (view->is_floating) {
|
if (view->is_floating) {
|
||||||
int dx = mouse_origin.x - prev_pos.x;
|
int dx = mouse_origin.x - prev_pos.x;
|
||||||
int dy = mouse_origin.y - prev_pos.y;
|
int dy = mouse_origin.y - prev_pos.y;
|
||||||
view->x += dx;
|
view->x += dx;
|
||||||
view->y += dy;
|
view->y += dy;
|
||||||
changed_floating = true;
|
|
||||||
}
|
|
||||||
} else if (pointer_state.floating.resize && view) {
|
|
||||||
if (view->is_floating) {
|
|
||||||
int dx = mouse_origin.x - prev_pos.x;
|
|
||||||
int dy = mouse_origin.y - prev_pos.y;
|
|
||||||
|
|
||||||
// Move and resize the view based on the dx/dy and mouse position
|
|
||||||
int midway_x = view->x + view->width/2;
|
|
||||||
int midway_y = view->y + view->height/2;
|
|
||||||
if (dx < 0) {
|
|
||||||
if (!pointer_state.lock.right) {
|
|
||||||
if (view->width > min_sane_w) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->width += dx;
|
|
||||||
edge += WLC_RESIZE_EDGE_RIGHT;
|
|
||||||
}
|
|
||||||
} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->x += dx;
|
|
||||||
view->width -= dx;
|
|
||||||
edge += WLC_RESIZE_EDGE_LEFT;
|
|
||||||
}
|
|
||||||
} else if (dx > 0) {
|
|
||||||
if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->width += dx;
|
|
||||||
edge += WLC_RESIZE_EDGE_RIGHT;
|
|
||||||
} else if (!pointer_state.lock.left) {
|
|
||||||
if (view->width > min_sane_w) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->x += dx;
|
|
||||||
view->width -= dx;
|
|
||||||
edge += WLC_RESIZE_EDGE_LEFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dy < 0) {
|
|
||||||
if (!pointer_state.lock.bottom) {
|
|
||||||
if (view->height > min_sane_h) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->height += dy;
|
|
||||||
edge += WLC_RESIZE_EDGE_BOTTOM;
|
|
||||||
}
|
|
||||||
} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->y += dy;
|
|
||||||
view->height -= dy;
|
|
||||||
edge += WLC_RESIZE_EDGE_TOP;
|
|
||||||
}
|
|
||||||
} else if (dy > 0) {
|
|
||||||
if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->height += dy;
|
|
||||||
edge += WLC_RESIZE_EDGE_BOTTOM;
|
|
||||||
} else if (!pointer_state.lock.top) {
|
|
||||||
if (view->height > min_sane_h) {
|
|
||||||
changed_floating = true;
|
|
||||||
view->y += dy;
|
|
||||||
view->height -= dy;
|
|
||||||
edge += WLC_RESIZE_EDGE_TOP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (pointer_state.tiling.resize && view) {
|
|
||||||
if (view != pointer_state.tiling.init_view) {
|
|
||||||
// Quit out of the resize
|
|
||||||
//pointer_state.tiling.init_view = NULL;
|
|
||||||
}
|
|
||||||
if (!view->is_floating && view == pointer_state.tiling.init_view) {
|
|
||||||
// Handle layout resizes -- Find the biggest parent container then apply resizes to that
|
|
||||||
// and its bordering siblings
|
|
||||||
swayc_t *parent = view;
|
|
||||||
double dx = mouse_origin.x - prev_pos.x;
|
|
||||||
double dy = mouse_origin.y - prev_pos.y;
|
|
||||||
if (!pointer_state.lock.bottom) {
|
|
||||||
while (parent->type != C_WORKSPACE) {
|
|
||||||
// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
|
|
||||||
// way of doing this.
|
|
||||||
if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
|
|
||||||
parent = parent->parent;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
|
|
||||||
sway_log(L_DEBUG, "Top is locked, found biggest valid parent at: %p", parent);
|
|
||||||
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
|
|
||||||
if (sibling) {
|
|
||||||
sway_log(L_DEBUG, "Found sibling at: %p", sibling);
|
|
||||||
if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
|
|
||||||
recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
|
|
||||||
changed_tiling = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!pointer_state.lock.top) {
|
|
||||||
while (parent->type != C_WORKSPACE) {
|
|
||||||
if (fabs(parent->parent->y - view->y) <= 1) {
|
|
||||||
parent = parent->parent;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
|
|
||||||
sway_log(L_DEBUG, "Bot is locked, found biggest valid parent at: %p", parent);
|
|
||||||
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
|
|
||||||
if (sibling) {
|
|
||||||
sway_log(L_DEBUG, "Found sibling at: %p", sibling);
|
|
||||||
if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
|
|
||||||
recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
|
|
||||||
recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
|
|
||||||
changed_tiling = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = view;
|
|
||||||
if (!pointer_state.lock.right) {
|
|
||||||
while (parent->type != C_WORKSPACE) {
|
|
||||||
if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
|
|
||||||
parent = parent->parent;
|
|
||||||
} else {
|
|
||||||
sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
|
|
||||||
sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent);
|
|
||||||
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
|
|
||||||
if (sibling) {
|
|
||||||
sway_log(L_DEBUG, "Found sibling at: %p", sibling);
|
|
||||||
if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
|
|
||||||
recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
changed_tiling = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!pointer_state.lock.left) {
|
|
||||||
while (parent->type != C_WORKSPACE) {
|
|
||||||
if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
|
|
||||||
parent = parent->parent;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
|
|
||||||
sway_log(L_DEBUG, "Right is locked, found biggest valid parent at: %p", parent);
|
|
||||||
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
|
|
||||||
if (sibling) {
|
|
||||||
sway_log(L_DEBUG, "Found sibling at: %p", sibling);
|
|
||||||
if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
|
|
||||||
recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
|
|
||||||
recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
|
|
||||||
changed_tiling = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arrange_windows(active_workspace, -1, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config->focus_follows_mouse && prev_handle != handle) {
|
|
||||||
// Dont change focus if fullscreen
|
|
||||||
swayc_t *focused = get_focused_view(view);
|
|
||||||
if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)
|
|
||||||
&& !(pointer_state.l_held || pointer_state.r_held)) {
|
|
||||||
set_focused_container(container_under_pointer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev_handle = handle;
|
|
||||||
prev_pos = mouse_origin;
|
|
||||||
if (changed_floating) {
|
|
||||||
struct wlc_geometry geometry = {
|
struct wlc_geometry geometry = {
|
||||||
.origin = {
|
.origin = {
|
||||||
.x = view->x,
|
.x = view->x,
|
||||||
|
@ -542,10 +360,56 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
.h = view->height
|
.h = view->height
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
wlc_view_set_geometry(view->handle, edge, &geometry);
|
wlc_view_set_geometry(view->handle, 0, &geometry);
|
||||||
return true;
|
changed_floating = true;
|
||||||
|
} else {
|
||||||
|
swayc_t *init_view = pointer_state.tiling.init_view;
|
||||||
|
if (view != init_view && view->type == C_VIEW) {
|
||||||
|
changed_tiling = true;
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < view->parent->children->length; i++) {
|
||||||
|
if (view->parent->children->items[i] == view) {
|
||||||
|
for (j = 0; j < init_view->parent->children->length; j++) {
|
||||||
|
if (init_view->parent->children->items[j] == init_view) {
|
||||||
|
double temp_w = view->width;
|
||||||
|
double temp_h = view->height;
|
||||||
|
view->width = init_view->width;
|
||||||
|
view->height = init_view->height;
|
||||||
|
init_view->width = temp_w;
|
||||||
|
init_view->height = temp_h;
|
||||||
|
|
||||||
|
init_view->parent->children->items[j] = view;
|
||||||
|
view->parent->children->items[i] = init_view;
|
||||||
|
|
||||||
|
swayc_t *temp = view->parent;
|
||||||
|
view->parent = init_view->parent;
|
||||||
|
init_view->parent = temp;
|
||||||
|
|
||||||
|
arrange_windows(&root_container, -1, -1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (changed_tiling) {
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pointer_state.floating.resize && view) {
|
||||||
|
changed_floating = resize_floating(prev_pos);
|
||||||
|
} else if (pointer_state.tiling.resize && view) {
|
||||||
|
changed_tiling = mouse_resize_tiled(prev_pos);
|
||||||
|
}
|
||||||
|
if (config->focus_follows_mouse && prev_handle != handle) {
|
||||||
|
// Dont change focus if fullscreen
|
||||||
|
swayc_t *focused = get_focused_view(view);
|
||||||
|
if (!swayc_is_fullscreen(focused)
|
||||||
|
&& !(pointer_state.l_held || pointer_state.r_held)) {
|
||||||
|
set_focused_container(container_under_pointer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_handle = handle;
|
||||||
|
prev_pos = mouse_origin;
|
||||||
|
if (changed_tiling || changed_floating) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -556,7 +420,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) {
|
||||||
|
@ -596,8 +460,13 @@ 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.floating.drag = pointer_state.l_held;
|
||||||
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 {
|
||||||
|
@ -605,13 +474,14 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
|
||||||
if (button == M_LEFT_CLICK) {
|
if (button == M_LEFT_CLICK) {
|
||||||
pointer_state.l_held = false;
|
pointer_state.l_held = false;
|
||||||
pointer_state.floating.drag = false;
|
pointer_state.floating.drag = false;
|
||||||
|
pointer_state.tiling.init_view = NULL;
|
||||||
}
|
}
|
||||||
if (button == M_RIGHT_CLICK) {
|
if (button == M_RIGHT_CLICK) {
|
||||||
pointer_state.r_held = false;
|
pointer_state.r_held = false;
|
||||||
pointer_state.floating.resize = false;
|
pointer_state.floating.resize = false;
|
||||||
pointer_state.tiling.resize = false;
|
pointer_state.tiling.resize = false;
|
||||||
pointer_state.tiling.init_view = NULL;
|
pointer_state.tiling.init_view = NULL;
|
||||||
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
|
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void release_key(keycode key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}};
|
struct pointer_state pointer_state;
|
||||||
|
|
||||||
static struct wlc_geometry saved_floating;
|
static struct wlc_geometry saved_floating;
|
||||||
|
|
||||||
|
@ -69,6 +69,6 @@ void reset_floating(swayc_t *view) {
|
||||||
view->height = saved_floating.size.h;
|
view->height = saved_floating.size.h;
|
||||||
arrange_windows(view->parent, -1, -1);
|
arrange_windows(view->parent, -1, -1);
|
||||||
}
|
}
|
||||||
pointer_state.floating = (struct pointer_floating){0,0};
|
pointer_state.floating = (struct pointer_floating){0, 0};
|
||||||
pointer_state.lock = (struct pointer_lock){0,0,0,0};
|
pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
}
|
}
|
||||||
|
|
116
sway/layout.c
116
sway/layout.c
|
@ -10,6 +10,8 @@
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
|
|
||||||
swayc_t root_container;
|
swayc_t root_container;
|
||||||
|
int min_sane_h = 60;
|
||||||
|
int min_sane_w = 100;
|
||||||
|
|
||||||
void init_layout(void) {
|
void init_layout(void) {
|
||||||
root_container.type = C_ROOT;
|
root_container.type = C_ROOT;
|
||||||
|
@ -35,7 +37,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 +48,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 +73,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 +102,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;
|
||||||
}
|
}
|
||||||
|
@ -167,21 +169,14 @@ void arrange_windows(swayc_t *container, double width, double height) {
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
swayc_t *child = container->children->items[i];
|
||||||
sway_log(L_DEBUG, "Arranging output at %d", x);
|
sway_log(L_DEBUG, "Arranging output at %d", x);
|
||||||
child->x = x;
|
|
||||||
child->y = y;
|
|
||||||
arrange_windows(child, -1, -1);
|
arrange_windows(child, -1, -1);
|
||||||
// Removed for now because wlc works with relative positions
|
x += child->width;
|
||||||
// Addition can be reconsidered once wlc positions are changed
|
|
||||||
// x += child->width;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case C_OUTPUT:
|
case C_OUTPUT:
|
||||||
container->width = width;
|
container->width = width;
|
||||||
container->height = height;
|
container->height = height;
|
||||||
// These lines make x/y negative and result in stuff glitching out
|
x = 0, y = 0;
|
||||||
// Their addition can be reconsidered once wlc positions are changed
|
|
||||||
// x -= container->x;
|
|
||||||
// y -= container->y;
|
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
swayc_t *child = container->children->items[i];
|
||||||
child->x = x + container->gaps;
|
child->x = x + container->gaps;
|
||||||
|
@ -204,7 +199,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 +298,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 +313,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 +323,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;
|
||||||
|
@ -372,8 +338,63 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
|
||||||
// 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;
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
int i;
|
||||||
|
if (parent->type == C_ROOT) {
|
||||||
|
// Find the next output
|
||||||
|
int target = -1, max_x = 0, max_y = 0, self = -1;
|
||||||
|
sway_log(L_DEBUG, "Moving between outputs");
|
||||||
|
|
||||||
|
for (i = 0; i < parent->children->length; ++i) {
|
||||||
|
swayc_t *next = parent->children->items[i];
|
||||||
|
if (next == container) {
|
||||||
|
self = i;
|
||||||
|
sway_log(L_DEBUG, "self is %p %d", next, self);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (next->type == C_OUTPUT) {
|
||||||
|
sway_log(L_DEBUG, "Testing with %p %d (dir %d)", next, i, dir);
|
||||||
|
// Check if it's more extreme
|
||||||
|
if (dir == MOVE_RIGHT) {
|
||||||
|
if (container->x + container->width <= next->x) {
|
||||||
|
if (target == -1 || next->x < max_x) {
|
||||||
|
target = i;
|
||||||
|
max_x = next->x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dir == MOVE_LEFT) {
|
||||||
|
if (container->x >= next->x + next->width) {
|
||||||
|
if (target == -1 || max_x < next->x) {
|
||||||
|
target = i;
|
||||||
|
max_x = next->x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dir == MOVE_DOWN) {
|
||||||
|
if (container->y + container->height <= next->y) {
|
||||||
|
if (target == -1 || next->y < max_y) {
|
||||||
|
target = i;
|
||||||
|
max_y = next->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dir == MOVE_UP) {
|
||||||
|
if (container->y >= next->y + next->height) {
|
||||||
|
if (target == -1 || max_y < next->y) {
|
||||||
|
target = i;
|
||||||
|
max_y = next->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == -1) {
|
||||||
|
can_move = false;
|
||||||
|
} else {
|
||||||
|
can_move = true;
|
||||||
|
diff = target - self;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
||||||
if (parent->layout == L_HORIZ || parent->type == C_ROOT) {
|
if (parent->layout == L_HORIZ) {
|
||||||
can_move = true;
|
can_move = true;
|
||||||
diff = dir == MOVE_LEFT ? -1 : 1;
|
diff = dir == MOVE_LEFT ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
@ -383,8 +404,9 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
|
||||||
diff = dir == MOVE_UP ? -1 : 1;
|
diff = dir == MOVE_UP ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (can_move) {
|
if (can_move) {
|
||||||
int i;
|
|
||||||
for (i = 0; i < parent->children->length; ++i) {
|
for (i = 0; i < parent->children->length; ++i) {
|
||||||
swayc_t *child = parent->children->items[i];
|
swayc_t *child = parent->children->items[i];
|
||||||
if (child == container) {
|
if (child == container) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
13
sway/main.c
13
sway/main.c
|
@ -38,12 +38,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
setenv("WLC_DIM", "0", 0);
|
setenv("WLC_DIM", "0", 0);
|
||||||
|
|
||||||
FILE *devnull = fopen("/dev/null", "w");
|
|
||||||
if (devnull) {
|
|
||||||
// NOTE: Does not work, see wlc issue #54
|
|
||||||
wlc_set_log_file(devnull);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Changing code earlier than this point requires detailed review */
|
/* Changing code earlier than this point requires detailed review */
|
||||||
if (!wlc_init(&interface, argc, argv)) {
|
if (!wlc_init(&interface, argc, argv)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -85,9 +79,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
init_log(L_DEBUG);
|
init_log(L_DEBUG);
|
||||||
wlc_set_log_file(stderr);
|
|
||||||
fclose(devnull);
|
|
||||||
devnull = NULL;
|
|
||||||
} else if (verbose || validate) {
|
} else if (verbose || validate) {
|
||||||
init_log(L_INFO);
|
init_log(L_INFO);
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,10 +105,6 @@ int main(int argc, char **argv) {
|
||||||
wlc_run();
|
wlc_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devnull) {
|
|
||||||
fclose(devnull);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc_terminate();
|
ipc_terminate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
491
sway/resize.c
Normal file
491
sway/resize.c
Normal file
|
@ -0,0 +1,491 @@
|
||||||
|
#include <wlc/wlc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "layout.h"
|
||||||
|
#include "focus.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "input_state.h"
|
||||||
|
#include "handlers.h"
|
||||||
|
|
||||||
|
bool mouse_resize_tiled(struct wlc_origin prev_pos) {
|
||||||
|
swayc_t *view = container_under_pointer();
|
||||||
|
bool valid = true;
|
||||||
|
bool changed_tiling = false;
|
||||||
|
double dx = mouse_origin.x - prev_pos.x;
|
||||||
|
double dy = mouse_origin.y - prev_pos.y;
|
||||||
|
if (view != pointer_state.tiling.init_view) {
|
||||||
|
changed_tiling = true;
|
||||||
|
valid = false;
|
||||||
|
if (view->type != C_WORKSPACE) {
|
||||||
|
if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) {
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
|
||||||
|
pointer_state.lock.temp_left = true;
|
||||||
|
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) {
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
|
||||||
|
pointer_state.lock.temp_right = true;
|
||||||
|
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) {
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
|
||||||
|
pointer_state.lock.temp_up = true;
|
||||||
|
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) {
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
|
||||||
|
pointer_state.lock.temp_down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
|
||||||
|
changed_tiling = true;
|
||||||
|
valid = false;
|
||||||
|
} else if (dx > 0 && pointer_state.lock.temp_left) {
|
||||||
|
pointer_state.lock.temp_left = false;
|
||||||
|
pointer_state.tiling.lock_pos.x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
|
||||||
|
changed_tiling = true;
|
||||||
|
valid = false;
|
||||||
|
} else if (dx < 0 && pointer_state.lock.temp_right) {
|
||||||
|
pointer_state.lock.temp_right = false;
|
||||||
|
pointer_state.tiling.lock_pos.x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
|
||||||
|
changed_tiling = true;
|
||||||
|
valid = false;
|
||||||
|
} else if (dy > 0 && pointer_state.lock.temp_up) {
|
||||||
|
pointer_state.lock.temp_up = false;
|
||||||
|
pointer_state.tiling.lock_pos.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
|
||||||
|
changed_tiling = true;
|
||||||
|
valid = false;
|
||||||
|
} else if (dy < 0 && pointer_state.lock.temp_down) {
|
||||||
|
pointer_state.lock.temp_down = false;
|
||||||
|
pointer_state.tiling.lock_pos.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!view->is_floating && valid) {
|
||||||
|
// Handle layout resizes -- Find the biggest parent container then apply resizes to that
|
||||||
|
// and its bordering siblings
|
||||||
|
swayc_t *parent = view;
|
||||||
|
if (!pointer_state.lock.bottom) {
|
||||||
|
while (parent->type != C_WORKSPACE) {
|
||||||
|
// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
|
||||||
|
// way of doing this.
|
||||||
|
if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
|
||||||
|
parent = parent->parent;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
|
||||||
|
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
|
||||||
|
if (sibling) {
|
||||||
|
if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
|
||||||
|
recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
|
||||||
|
changed_tiling = true;
|
||||||
|
} else {
|
||||||
|
if (parent->height < min_sane_h) {
|
||||||
|
//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
|
||||||
|
pointer_state.lock.temp_up = true;
|
||||||
|
} else if (sibling->height < min_sane_h) {
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
|
||||||
|
pointer_state.lock.temp_down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!pointer_state.lock.top) {
|
||||||
|
while (parent->type != C_WORKSPACE) {
|
||||||
|
if (fabs(parent->parent->y - view->y) <= 1) {
|
||||||
|
parent = parent->parent;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
|
||||||
|
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
|
||||||
|
if (sibling) {
|
||||||
|
if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
|
||||||
|
recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
|
||||||
|
recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
changed_tiling = true;
|
||||||
|
} else {
|
||||||
|
if (parent->height < min_sane_h) {
|
||||||
|
//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
|
||||||
|
pointer_state.lock.temp_down = true;
|
||||||
|
} else if (sibling->height < min_sane_h) {
|
||||||
|
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
|
||||||
|
pointer_state.lock.temp_up = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = view;
|
||||||
|
if (!pointer_state.lock.right) {
|
||||||
|
while (parent->type != C_WORKSPACE) {
|
||||||
|
if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
|
||||||
|
parent = parent->parent;
|
||||||
|
} else {
|
||||||
|
sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
|
||||||
|
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
|
||||||
|
if (sibling) {
|
||||||
|
if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
|
||||||
|
recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
changed_tiling = true;
|
||||||
|
} else {
|
||||||
|
if (parent->width < min_sane_w) {
|
||||||
|
pointer_state.lock.temp_left = true;
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
|
||||||
|
} else if (sibling->width < min_sane_w) {
|
||||||
|
pointer_state.lock.temp_right = true;
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!pointer_state.lock.left) {
|
||||||
|
while (parent->type != C_WORKSPACE) {
|
||||||
|
if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
|
||||||
|
parent = parent->parent;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
|
||||||
|
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
|
||||||
|
if (sibling) {
|
||||||
|
if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
|
||||||
|
recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
changed_tiling = true;
|
||||||
|
} else {
|
||||||
|
if (parent->width < min_sane_w) {
|
||||||
|
pointer_state.lock.temp_right = true;
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
|
||||||
|
} else if (sibling->width < min_sane_w) {
|
||||||
|
pointer_state.lock.temp_left = true;
|
||||||
|
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arrange_windows(swayc_active_workspace(), -1, -1);
|
||||||
|
}
|
||||||
|
return changed_tiling;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resize_floating(struct wlc_origin prev_pos) {
|
||||||
|
bool changed = false;
|
||||||
|
swayc_t *view = container_under_pointer();
|
||||||
|
uint32_t edge = 0;
|
||||||
|
int dx = mouse_origin.x - prev_pos.x;
|
||||||
|
int dy = mouse_origin.y - prev_pos.y;
|
||||||
|
|
||||||
|
// Move and resize the view based on the dx/dy and mouse position
|
||||||
|
int midway_x = view->x + view->width/2;
|
||||||
|
int midway_y = view->y + view->height/2;
|
||||||
|
if (dx < 0) {
|
||||||
|
if (!pointer_state.lock.right) {
|
||||||
|
if (view->width > min_sane_w) {
|
||||||
|
changed = true;
|
||||||
|
view->width += dx;
|
||||||
|
edge += WLC_RESIZE_EDGE_RIGHT;
|
||||||
|
}
|
||||||
|
} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
|
||||||
|
changed = true;
|
||||||
|
view->x += dx;
|
||||||
|
view->width -= dx;
|
||||||
|
edge += WLC_RESIZE_EDGE_LEFT;
|
||||||
|
}
|
||||||
|
} else if (dx > 0) {
|
||||||
|
if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
|
||||||
|
changed = true;
|
||||||
|
view->width += dx;
|
||||||
|
edge += WLC_RESIZE_EDGE_RIGHT;
|
||||||
|
} else if (!pointer_state.lock.left) {
|
||||||
|
if (view->width > min_sane_w) {
|
||||||
|
changed = true;
|
||||||
|
view->x += dx;
|
||||||
|
view->width -= dx;
|
||||||
|
edge += WLC_RESIZE_EDGE_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dy < 0) {
|
||||||
|
if (!pointer_state.lock.bottom) {
|
||||||
|
if (view->height > min_sane_h) {
|
||||||
|
changed = true;
|
||||||
|
view->height += dy;
|
||||||
|
edge += WLC_RESIZE_EDGE_BOTTOM;
|
||||||
|
}
|
||||||
|
} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
|
||||||
|
changed = true;
|
||||||
|
view->y += dy;
|
||||||
|
view->height -= dy;
|
||||||
|
edge += WLC_RESIZE_EDGE_TOP;
|
||||||
|
}
|
||||||
|
} else if (dy > 0) {
|
||||||
|
if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
|
||||||
|
changed = true;
|
||||||
|
view->height += dy;
|
||||||
|
edge += WLC_RESIZE_EDGE_BOTTOM;
|
||||||
|
} else if (!pointer_state.lock.top) {
|
||||||
|
if (view->height > min_sane_h) {
|
||||||
|
changed = true;
|
||||||
|
view->y += dy;
|
||||||
|
view->height -= dy;
|
||||||
|
edge += WLC_RESIZE_EDGE_TOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
struct wlc_geometry geometry = {
|
||||||
|
.origin = {
|
||||||
|
.x = view->x,
|
||||||
|
.y = view->y
|
||||||
|
},
|
||||||
|
.size = {
|
||||||
|
.w = view->width,
|
||||||
|
.h = view->height
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wlc_view_set_geometry(view->handle, edge, &geometry);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resize_tiled(int amount, bool use_width) {
|
||||||
|
swayc_t *parent = get_focused_view(swayc_active_workspace());
|
||||||
|
swayc_t *focused = parent;
|
||||||
|
swayc_t *sibling;
|
||||||
|
if (!parent) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Find the closest parent container which has siblings of the proper layout.
|
||||||
|
// Then apply the resize to all of them.
|
||||||
|
int i;
|
||||||
|
if (use_width) {
|
||||||
|
int lnumber = 0;
|
||||||
|
int rnumber = 0;
|
||||||
|
while (parent->parent) {
|
||||||
|
if (parent->parent->layout == L_HORIZ) {
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->x != focused->x) {
|
||||||
|
if (sibling->x < parent->x) {
|
||||||
|
lnumber++;
|
||||||
|
} else if (sibling->x > parent->x) {
|
||||||
|
rnumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rnumber || lnumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent = parent->parent;
|
||||||
|
}
|
||||||
|
if (parent == &root_container) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber);
|
||||||
|
//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
|
||||||
|
bool valid = true;
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->x != focused->x) {
|
||||||
|
if (sibling->x < parent->x) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= lnumber;
|
||||||
|
if (rnumber) {
|
||||||
|
if ((sibling->width + pixels/2) < min_sane_w) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((sibling->width + pixels) < min_sane_w) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sibling->x > parent->x) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= rnumber;
|
||||||
|
if (lnumber) {
|
||||||
|
if ((sibling->width + pixels/2) < min_sane_w) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((sibling->width + pixels) < min_sane_w) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
double pixels = amount;
|
||||||
|
if (parent->width + pixels < min_sane_w) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (valid) {
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->x != focused->x) {
|
||||||
|
if (sibling->x < parent->x) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= lnumber;
|
||||||
|
if (rnumber) {
|
||||||
|
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
} else {
|
||||||
|
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
}
|
||||||
|
} else if (sibling->x > parent->x) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= rnumber;
|
||||||
|
if (lnumber) {
|
||||||
|
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
} else {
|
||||||
|
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rnumber != 0 && lnumber != 0) {
|
||||||
|
double pixels = amount;
|
||||||
|
pixels /= 2;
|
||||||
|
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
} else if (rnumber) {
|
||||||
|
recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT);
|
||||||
|
} else if (lnumber) {
|
||||||
|
recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recursive resize does not handle positions, let arrange_windows
|
||||||
|
// take care of that.
|
||||||
|
arrange_windows(swayc_active_workspace(), -1, -1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
int tnumber = 0;
|
||||||
|
int bnumber = 0;
|
||||||
|
while (parent->parent) {
|
||||||
|
if (parent->parent->layout == L_VERT) {
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->y != focused->y) {
|
||||||
|
if (sibling->y < parent->y) {
|
||||||
|
bnumber++;
|
||||||
|
} else if (sibling->y > parent->y) {
|
||||||
|
tnumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bnumber || tnumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent = parent->parent;
|
||||||
|
}
|
||||||
|
if (parent == &root_container) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber);
|
||||||
|
//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
|
||||||
|
bool valid = true;
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->y != focused->y) {
|
||||||
|
if (sibling->y < parent->y) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= bnumber;
|
||||||
|
if (tnumber) {
|
||||||
|
if ((sibling->height + pixels/2) < min_sane_h) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((sibling->height + pixels) < min_sane_h) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sibling->y > parent->y) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= tnumber;
|
||||||
|
if (bnumber) {
|
||||||
|
if ((sibling->height + pixels/2) < min_sane_h) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((sibling->height + pixels) < min_sane_h) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
double pixels = amount;
|
||||||
|
if (parent->height + pixels < min_sane_h) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (valid) {
|
||||||
|
for (i = 0; i < parent->parent->children->length; i++) {
|
||||||
|
sibling = parent->parent->children->items[i];
|
||||||
|
if (sibling->y != focused->y) {
|
||||||
|
if (sibling->y < parent->y) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= bnumber;
|
||||||
|
if (tnumber) {
|
||||||
|
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
} else {
|
||||||
|
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
}
|
||||||
|
} else if (sibling->x > parent->x) {
|
||||||
|
double pixels = -1 * amount;
|
||||||
|
pixels /= tnumber;
|
||||||
|
if (bnumber) {
|
||||||
|
recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP);
|
||||||
|
} else {
|
||||||
|
recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bnumber != 0 && tnumber != 0) {
|
||||||
|
double pixels = amount/2;
|
||||||
|
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP);
|
||||||
|
recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
} else if (tnumber) {
|
||||||
|
recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP);
|
||||||
|
} else if (bnumber) {
|
||||||
|
recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arrange_windows(swayc_active_workspace(), -1, -1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue