mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -04:00
commit
d93d416849
20 changed files with 709 additions and 123 deletions
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.5)
|
||||||
project(sway C)
|
project(sway C)
|
||||||
set(CMAKE_C_FLAGS "-g")
|
set(CMAKE_C_FLAGS "-g")
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/")
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/")
|
||||||
add_definitions("-Wall")
|
add_definitions("-Wall -Wextra -Wno-unused-parameter")
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake)
|
||||||
|
|
||||||
find_package(XKBCommon REQUIRED)
|
find_package(XKBCommon REQUIRED)
|
||||||
|
|
@ -69,3 +69,11 @@ INSTALL(
|
||||||
FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sway.5
|
FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sway.5
|
||||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man5
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
INSTALL(
|
||||||
|
FILES ${PROJECT_SOURCE_DIR}/sway.desktop
|
||||||
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/wayland-sessions/)
|
||||||
|
|
||||||
|
INSTALL(
|
||||||
|
FILES ${PROJECT_SOURCE_DIR}/sway-xorg.desktop
|
||||||
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/xsessions/)
|
||||||
|
|
|
||||||
2
config
2
config
|
|
@ -22,7 +22,7 @@ set $menu dmenu_run
|
||||||
# Basics:
|
# Basics:
|
||||||
#
|
#
|
||||||
# start a terminal
|
# start a terminal
|
||||||
bindsym $mod+Return exec urxvt
|
bindsym $mod+Return exec $term
|
||||||
|
|
||||||
# kill focused window
|
# kill focused window
|
||||||
bindsym $mod+Shift+q kill
|
bindsym $mod+Shift+q kill
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ enum swayc_types{
|
||||||
C_TYPES,
|
C_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum swayc_layouts{
|
enum swayc_layouts{
|
||||||
L_NONE,
|
L_NONE,
|
||||||
L_HORIZ,
|
L_HORIZ,
|
||||||
|
|
@ -33,12 +34,12 @@ struct sway_container {
|
||||||
enum swayc_layouts layout;
|
enum swayc_layouts layout;
|
||||||
|
|
||||||
// Not including borders or margins
|
// Not including borders or margins
|
||||||
int width, height;
|
double width, height;
|
||||||
|
|
||||||
// Used for setting floating geometry
|
// Used for setting floating geometry
|
||||||
int desired_width, desired_height;
|
int desired_width, desired_height;
|
||||||
|
|
||||||
int x, y;
|
double x, y;
|
||||||
|
|
||||||
bool visible;
|
bool visible;
|
||||||
bool is_floating;
|
bool is_floating;
|
||||||
|
|
@ -55,6 +56,7 @@ struct sway_container {
|
||||||
struct sway_container *focused;
|
struct sway_container *focused;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Container Creation
|
||||||
|
|
||||||
swayc_t *new_output(wlc_handle handle);
|
swayc_t *new_output(wlc_handle handle);
|
||||||
swayc_t *new_workspace(swayc_t *output, const char *name);
|
swayc_t *new_workspace(swayc_t *output, const char *name);
|
||||||
|
|
@ -65,16 +67,27 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
|
||||||
// Creates view as a new floating view which is in the active workspace
|
// Creates view as a new floating view which is in the active workspace
|
||||||
swayc_t *new_floating_view(wlc_handle handle);
|
swayc_t *new_floating_view(wlc_handle handle);
|
||||||
|
|
||||||
|
// Container Destroying
|
||||||
|
|
||||||
swayc_t *destroy_output(swayc_t *output);
|
swayc_t *destroy_output(swayc_t *output);
|
||||||
// Destroys workspace if empty and returns parent pointer, else returns NULL
|
// Destroys workspace if empty and returns parent pointer, else returns NULL
|
||||||
swayc_t *destroy_workspace(swayc_t *workspace);
|
swayc_t *destroy_workspace(swayc_t *workspace);
|
||||||
|
// Destroyes container and all parent container if they are empty, returns
|
||||||
|
// topmost non-empty parent. returns NULL otherwise
|
||||||
swayc_t *destroy_container(swayc_t *container);
|
swayc_t *destroy_container(swayc_t *container);
|
||||||
|
// Destroys view and all empty parent containers. return topmost non-empty
|
||||||
|
// parent
|
||||||
swayc_t *destroy_view(swayc_t *view);
|
swayc_t *destroy_view(swayc_t *view);
|
||||||
|
|
||||||
|
// Container Lookup
|
||||||
|
|
||||||
|
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 *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
|
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);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ extern struct pointer_state {
|
||||||
bool drag;
|
bool drag;
|
||||||
bool resize;
|
bool resize;
|
||||||
} floating;
|
} floating;
|
||||||
|
struct pointer_tiling {
|
||||||
|
bool resize;
|
||||||
|
swayc_t *init_view;
|
||||||
|
struct wlc_origin *lock_pos;
|
||||||
|
} tiling;
|
||||||
struct pointer_lock {
|
struct pointer_lock {
|
||||||
bool left;
|
bool left;
|
||||||
bool right;
|
bool right;
|
||||||
|
|
@ -44,6 +49,7 @@ extern struct pointer_state {
|
||||||
|
|
||||||
void start_floating(swayc_t *view);
|
void start_floating(swayc_t *view);
|
||||||
void reset_floating(swayc_t *view);
|
void reset_floating(swayc_t *view);
|
||||||
|
void input_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
#define _SWAY_IPC_H
|
#define _SWAY_IPC_H
|
||||||
|
|
||||||
enum ipc_command_type {
|
enum ipc_command_type {
|
||||||
IPC_COMMAND = 0,
|
IPC_COMMAND = 0,
|
||||||
IPC_GET_WORKSPACES = 1,
|
IPC_GET_WORKSPACES = 1,
|
||||||
IPC_SUBSCRIBE = 2,
|
IPC_SUBSCRIBE = 2,
|
||||||
IPC_GET_OUTPUTS = 3,
|
IPC_GET_OUTPUTS = 3,
|
||||||
IPC_GET_TREE = 4,
|
IPC_GET_TREE = 4,
|
||||||
IPC_GET_MARKS = 5,
|
IPC_GET_MARKS = 5,
|
||||||
IPC_GET_BAR_CONFIG = 6,
|
IPC_GET_BAR_CONFIG = 6,
|
||||||
IPC_GET_VERSION = 7,
|
IPC_GET_VERSION = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ipc_init(void);
|
void ipc_init(void);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,11 @@ swayc_t *add_sibling(swayc_t *sibling, swayc_t *child);
|
||||||
swayc_t *replace_child(swayc_t *child, swayc_t *new_child);
|
swayc_t *replace_child(swayc_t *child, swayc_t *new_child);
|
||||||
swayc_t *remove_child(swayc_t *child);
|
swayc_t *remove_child(swayc_t *child);
|
||||||
|
|
||||||
|
void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction);
|
||||||
|
|
||||||
|
|
||||||
// Layout
|
// Layout
|
||||||
void arrange_windows(swayc_t *container, int width, int height);
|
void arrange_windows(swayc_t *container, double width, double height);
|
||||||
|
|
||||||
// Focus
|
// Focus
|
||||||
void unfocus_all(swayc_t *container);
|
void unfocus_all(swayc_t *container);
|
||||||
|
|
@ -29,4 +32,6 @@ swayc_t *get_focused_container(swayc_t *parent);
|
||||||
swayc_t *get_swayc_for_handle(wlc_handle handle, 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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ typedef enum {
|
||||||
L_DEBUG = 3,
|
L_DEBUG = 3,
|
||||||
} log_importance_t;
|
} log_importance_t;
|
||||||
|
|
||||||
void init_log(int verbosity);
|
void init_log(log_importance_t verbosity);
|
||||||
void sway_log_colors(int mode);
|
void sway_log_colors(int mode);
|
||||||
void sway_log(int verbosity, const char* format, ...) __attribute__((format(printf,2,3)));
|
void sway_log(log_importance_t verbosity, const char* format, ...) __attribute__((format(printf,2,3)));
|
||||||
void sway_log_errno(int verbosity, char* format, ...) __attribute__((format(printf,2,3)));
|
void sway_log_errno(log_importance_t verbosity, char* format, ...) __attribute__((format(printf,2,3)));
|
||||||
void sway_abort(const char* format, ...) __attribute__((format(printf,1,2)));
|
void sway_abort(const char* format, ...) __attribute__((format(printf,1,2)));
|
||||||
bool sway_assert(bool condition, const char* format, ...) __attribute__((format(printf,2,3)));
|
bool sway_assert(bool condition, const char* format, ...) __attribute__((format(printf,2,3)));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,6 @@ char *code_strchr(const char *string, char delimiter);
|
||||||
char *code_strstr(const char *haystack, const char *needle);
|
char *code_strstr(const char *haystack, const char *needle);
|
||||||
int unescape_string(char *string);
|
int unescape_string(char *string);
|
||||||
char *join_args(char **argv, int argc);
|
char *join_args(char **argv, int argc);
|
||||||
|
char *join_list(list_t *list, char *separator);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
5
sway-xorg.desktop
Normal file
5
sway-xorg.desktop
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Sway (Xorg)
|
||||||
|
Comment=SirCmpwn's Wayland window manager
|
||||||
|
Exec=sway
|
||||||
|
Type=Application
|
||||||
5
sway.desktop
Normal file
5
sway.desktop
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Sway
|
||||||
|
Comment=SirCmpwn's Wayland window manager
|
||||||
|
Exec=sway
|
||||||
|
Type=Application
|
||||||
187
sway/commands.c
187
sway/commands.c
|
|
@ -106,7 +106,7 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
||||||
// Check for a modifier key
|
// Check for a modifier key
|
||||||
int j;
|
int j;
|
||||||
bool is_mod = false;
|
bool is_mod = false;
|
||||||
for (j = 0; j < sizeof(modifiers) / sizeof(struct modifier_key); ++j) {
|
for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) {
|
||||||
if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
|
if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
|
||||||
binding->modifiers |= modifiers[j].mod;
|
binding->modifiers |= modifiers[j].mod;
|
||||||
is_mod = true;
|
is_mod = true;
|
||||||
|
|
@ -206,7 +206,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
|
||||||
if (!view->is_floating) {
|
if (!view->is_floating) {
|
||||||
// Remove view from its current location
|
// Remove view from its current location
|
||||||
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(active_workspace,view);
|
||||||
view->x = (active_workspace->width - view->width)/2;
|
view->x = (active_workspace->width - view->width)/2;
|
||||||
|
|
@ -261,7 +261,7 @@ static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv)
|
||||||
|
|
||||||
// set modifer keys
|
// set modifer keys
|
||||||
for (i = 0; i < split->length; ++i) {
|
for (i = 0; i < split->length; ++i) {
|
||||||
for (j = 0; j < sizeof(modifiers) / sizeof(struct modifier_key); ++j) {
|
for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) {
|
||||||
if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
|
if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
|
||||||
config->floating_mod |= modifiers[j].mod;
|
config->floating_mod |= modifiers[j].mod;
|
||||||
}
|
}
|
||||||
|
|
@ -341,6 +341,27 @@ static bool cmd_focus_follows_mouse(struct sway_config *config, int argc, char *
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cmd_move(struct sway_config *config, int argc, char **argv) {
|
||||||
|
if (!checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
swayc_t *view = get_focused_container(&root_container);
|
||||||
|
|
||||||
|
if (strcasecmp(argv[0], "left") == 0) {
|
||||||
|
move_container(view,&root_container,MOVE_LEFT);
|
||||||
|
} else if (strcasecmp(argv[0], "right") == 0) {
|
||||||
|
move_container(view,&root_container,MOVE_RIGHT);
|
||||||
|
} else if (strcasecmp(argv[0], "up") == 0) {
|
||||||
|
move_container(view,&root_container,MOVE_UP);
|
||||||
|
} else if (strcasecmp(argv[0], "down") == 0) {
|
||||||
|
move_container(view,&root_container,MOVE_DOWN);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
@ -390,7 +411,6 @@ static bool cmd_layout(struct sway_config *config, int argc, char **argv) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
swayc_t *parent = get_focused_container(&root_container);
|
swayc_t *parent = get_focused_container(&root_container);
|
||||||
|
|
||||||
while (parent->type == C_VIEW) {
|
while (parent->type == C_VIEW) {
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
}
|
}
|
||||||
|
|
@ -422,6 +442,159 @@ static bool cmd_reload(struct sway_config *config, int argc, char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
|
||||||
|
if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char *end;
|
||||||
|
int amount = (int)strtol(argv[2], &end, 10);
|
||||||
|
if (errno == ERANGE || amount == 0) {
|
||||||
|
errno = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(argv[0], "shrink") == 0) {
|
||||||
|
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) {
|
||||||
|
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
|
||||||
|
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) {
|
||||||
|
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
|
||||||
|
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) {
|
||||||
if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) {
|
if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -512,9 +685,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
|
||||||
// Resize workspace if going from fullscreen -> notfullscreen
|
// Resize workspace if going from fullscreen -> notfullscreen
|
||||||
// otherwise just resize container
|
// otherwise just resize container
|
||||||
if (current) {
|
if (current) {
|
||||||
while (container->type != C_WORKSPACE) {
|
container = swayc_parent_by_type(container, C_WORKSPACE);
|
||||||
container = container->parent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Only resize container when going into fullscreen
|
// Only resize container when going into fullscreen
|
||||||
arrange_windows(container, -1, -1);
|
arrange_windows(container, -1, -1);
|
||||||
|
|
@ -586,7 +757,9 @@ static struct cmd_handler handlers[] = {
|
||||||
{ "kill", cmd_kill },
|
{ "kill", cmd_kill },
|
||||||
{ "layout", cmd_layout },
|
{ "layout", cmd_layout },
|
||||||
{ "log_colors", cmd_log_colors },
|
{ "log_colors", cmd_log_colors },
|
||||||
|
{ "move", cmd_move},
|
||||||
{ "reload", cmd_reload },
|
{ "reload", cmd_reload },
|
||||||
|
{ "resize", cmd_resize },
|
||||||
{ "set", cmd_set },
|
{ "set", cmd_set },
|
||||||
{ "split", cmd_split },
|
{ "split", cmd_split },
|
||||||
{ "splith", cmd_splith },
|
{ "splith", cmd_splith },
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "input_state.h"
|
||||||
|
|
||||||
struct sway_config *config;
|
struct sway_config *config;
|
||||||
|
|
||||||
|
|
@ -106,7 +107,7 @@ static char *get_config_path() {
|
||||||
|
|
||||||
char *test = NULL;
|
char *test = NULL;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < sizeof(search_paths) / sizeof(char *); ++i) {
|
for (i = 0; i < (int)(sizeof(search_paths) / sizeof(char *)); ++i) {
|
||||||
test = strdup(search_paths[i]);
|
test = strdup(search_paths[i]);
|
||||||
test = do_var_replacement(temp_config, test);
|
test = do_var_replacement(temp_config, test);
|
||||||
sway_log(L_DEBUG, "Checking for config at %s", test);
|
sway_log(L_DEBUG, "Checking for config at %s", test);
|
||||||
|
|
@ -147,6 +148,8 @@ _continue:
|
||||||
bool load_config(const char *file) {
|
bool load_config(const char *file) {
|
||||||
sway_log(L_INFO, "Loading config");
|
sway_log(L_INFO, "Loading config");
|
||||||
|
|
||||||
|
input_init();
|
||||||
|
|
||||||
char *path;
|
char *path;
|
||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
path = strdup(file);
|
path = strdup(file);
|
||||||
|
|
|
||||||
138
sway/container.c
138
sway/container.c
|
|
@ -8,6 +8,8 @@
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#define ASSERT_NONNULL(PTR) \
|
||||||
|
sway_assert (PTR, "%s: " #PTR "must be non-null", __func__)
|
||||||
|
|
||||||
static swayc_t *new_swayc(enum swayc_types type) {
|
static swayc_t *new_swayc(enum swayc_types type) {
|
||||||
swayc_t *c = calloc(1, sizeof(swayc_t));
|
swayc_t *c = calloc(1, sizeof(swayc_t));
|
||||||
|
|
@ -20,37 +22,40 @@ static swayc_t *new_swayc(enum swayc_types type) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_swayc(swayc_t *c) {
|
static void free_swayc(swayc_t *cont) {
|
||||||
|
if (!ASSERT_NONNULL(cont)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO does not properly handle containers with children,
|
// TODO does not properly handle containers with children,
|
||||||
// TODO but functions that call this usually check for that
|
// TODO but functions that call this usually check for that
|
||||||
if (c->children) {
|
if (cont->children) {
|
||||||
if (c->children->length) {
|
if (cont->children->length) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < c->children->length; ++i) {
|
for (i = 0; i < cont->children->length; ++i) {
|
||||||
free_swayc(c->children->items[i]);
|
free_swayc(cont->children->items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_free(c->children);
|
list_free(cont->children);
|
||||||
}
|
}
|
||||||
if (c->floating) {
|
if (cont->floating) {
|
||||||
if (c->floating->length) {
|
if (cont->floating->length) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < c->floating->length; ++i) {
|
for (i = 0; i < cont->floating->length; ++i) {
|
||||||
free_swayc(c->floating->items[i]);
|
free_swayc(cont->floating->items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_free(c->floating);
|
list_free(cont->floating);
|
||||||
}
|
}
|
||||||
if (c->parent) {
|
if (cont->parent) {
|
||||||
remove_child(c);
|
remove_child(cont);
|
||||||
}
|
}
|
||||||
if (c->name) {
|
if (cont->name) {
|
||||||
free(c->name);
|
free(cont->name);
|
||||||
}
|
}
|
||||||
free(c);
|
free(cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New containers */
|
// New containers
|
||||||
|
|
||||||
static bool workspace_test(swayc_t *view, void *name) {
|
static bool workspace_test(swayc_t *view, void *name) {
|
||||||
return strcasecmp(view->name, (char *)name) == 0;
|
return strcasecmp(view->name, (char *)name) == 0;
|
||||||
|
|
@ -103,6 +108,9 @@ swayc_t *new_output(wlc_handle handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *new_workspace(swayc_t *output, const char *name) {
|
swayc_t *new_workspace(swayc_t *output, const char *name) {
|
||||||
|
if (!ASSERT_NONNULL(output)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
|
sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
|
||||||
swayc_t *workspace = new_swayc(C_WORKSPACE);
|
swayc_t *workspace = new_swayc(C_WORKSPACE);
|
||||||
|
|
||||||
|
|
@ -120,6 +128,9 @@ 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)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
swayc_t *cont = new_swayc(C_CONTAINER);
|
swayc_t *cont = new_swayc(C_CONTAINER);
|
||||||
|
|
||||||
sway_log(L_DEBUG, "creating container %p around %p", cont, child);
|
sway_log(L_DEBUG, "creating container %p around %p", cont, child);
|
||||||
|
|
@ -162,6 +173,9 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
|
swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
|
||||||
|
if (!ASSERT_NONNULL(sibling)) {
|
||||||
|
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:%s to container %p %d",
|
sway_log(L_DEBUG, "Adding new view %lu:%s to container %p %d",
|
||||||
|
|
@ -172,14 +186,14 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
|
||||||
view->visible = true;
|
view->visible = true;
|
||||||
view->is_focused = true;
|
view->is_focused = true;
|
||||||
// Setup geometry
|
// Setup geometry
|
||||||
|
const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
|
||||||
view->width = 0;
|
view->width = 0;
|
||||||
view->height = 0;
|
view->height = 0;
|
||||||
|
view->desired_width = geometry->size.w;
|
||||||
|
view->desired_height = geometry->size.h;
|
||||||
|
|
||||||
view->gaps = config->gaps_inner;
|
view->gaps = config->gaps_inner;
|
||||||
|
|
||||||
view->desired_width = -1;
|
|
||||||
view->desired_height = -1;
|
|
||||||
|
|
||||||
view->is_floating = false;
|
view->is_floating = false;
|
||||||
|
|
||||||
if (sibling->type == C_WORKSPACE) {
|
if (sibling->type == C_WORKSPACE) {
|
||||||
|
|
@ -225,9 +239,12 @@ swayc_t *new_floating_view(wlc_handle handle) {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy container */
|
// Destroy container
|
||||||
|
|
||||||
swayc_t *destroy_output(swayc_t *output) {
|
swayc_t *destroy_output(swayc_t *output) {
|
||||||
|
if (!ASSERT_NONNULL(output)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (output->children->length == 0) {
|
if (output->children->length == 0) {
|
||||||
// TODO move workspaces to other outputs
|
// TODO move workspaces to other outputs
|
||||||
}
|
}
|
||||||
|
|
@ -237,23 +254,21 @@ swayc_t *destroy_output(swayc_t *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *destroy_workspace(swayc_t *workspace) {
|
swayc_t *destroy_workspace(swayc_t *workspace) {
|
||||||
|
if (!ASSERT_NONNULL(workspace)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
// NOTE: This is called from elsewhere without checking children length
|
// NOTE: This is called from elsewhere without checking children length
|
||||||
// TODO move containers to other workspaces?
|
// TODO move containers to other workspaces?
|
||||||
// for now just dont delete
|
// for now just dont delete
|
||||||
|
|
||||||
// Do not destroy this if it's the last workspace on this output
|
// Do not destroy this if it's the last workspace on this output
|
||||||
swayc_t *output = workspace->parent;
|
swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
|
||||||
while (output && output->type != C_OUTPUT) {
|
if (output && output->children->length == 1) {
|
||||||
output = output->parent;
|
return NULL;
|
||||||
}
|
|
||||||
if (output) {
|
|
||||||
if (output->children->length == 1) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace->children->length == 0) {
|
if (workspace->children->length == 0) {
|
||||||
sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", 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);
|
||||||
return parent;
|
return parent;
|
||||||
|
|
@ -262,6 +277,9 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *destroy_container(swayc_t *container) {
|
swayc_t *destroy_container(swayc_t *container) {
|
||||||
|
if (!ASSERT_NONNULL(container)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
while (container->children->length == 0 && container->type == C_CONTAINER) {
|
while (container->children->length == 0 && container->type == C_CONTAINER) {
|
||||||
sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
|
sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
|
||||||
swayc_t *parent = container->parent;
|
swayc_t *parent = container->parent;
|
||||||
|
|
@ -272,8 +290,7 @@ swayc_t *destroy_container(swayc_t *container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *destroy_view(swayc_t *view) {
|
swayc_t *destroy_view(swayc_t *view) {
|
||||||
if (view == NULL) {
|
if (!ASSERT_NONNULL(view)) {
|
||||||
sway_log(L_DEBUG, "Warning: NULL passed into destroy_view");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sway_log(L_DEBUG, "Destroying view '%p'", view);
|
sway_log(L_DEBUG, "Destroying view '%p'", view);
|
||||||
|
|
@ -287,6 +304,34 @@ swayc_t *destroy_view(swayc_t *view) {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
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) {
|
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;
|
||||||
|
|
@ -316,25 +361,27 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
|
||||||
}
|
}
|
||||||
|
|
||||||
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
|
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
|
||||||
if (!container || !container->children || !container->children->length) {
|
if (container && container->children && container->children->length) {
|
||||||
return;
|
int i;
|
||||||
}
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
int i;
|
swayc_t *child = container->children->items[i];
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
|
||||||
swayc_t *child = container->children->items[i];
|
|
||||||
f(child, data);
|
|
||||||
container_map(child, f, data);
|
|
||||||
}
|
|
||||||
if (container->type == C_WORKSPACE) {
|
|
||||||
for (i = 0; i < container->floating->length; ++i) {
|
|
||||||
swayc_t *child = container->floating->items[i];
|
|
||||||
f(child, data);
|
f(child, data);
|
||||||
container_map(child, f, data);
|
container_map(child, f, data);
|
||||||
}
|
}
|
||||||
|
if (container->type == C_WORKSPACE) {
|
||||||
|
for (i = 0; i < container->floating->length; ++i) {
|
||||||
|
swayc_t *child = container->floating->items[i];
|
||||||
|
f(child, data);
|
||||||
|
container_map(child, f, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_view_visibility(swayc_t *view, void *data) {
|
void set_view_visibility(swayc_t *view, void *data) {
|
||||||
|
if (!ASSERT_NONNULL(view)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint32_t *p = data;
|
uint32_t *p = data;
|
||||||
if (view->type == C_VIEW) {
|
if (view->type == C_VIEW) {
|
||||||
wlc_view_set_mask(view->handle, *p);
|
wlc_view_set_mask(view->handle, *p);
|
||||||
|
|
@ -348,6 +395,9 @@ 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) {
|
||||||
|
if (!ASSERT_NONNULL(view)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (view->type == C_OUTPUT) {
|
if (view->type == C_OUTPUT) {
|
||||||
view->gaps = config->gaps_outer;
|
view->gaps = config->gaps_outer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
149
sway/handlers.c
149
sway/handlers.c
|
|
@ -1,6 +1,7 @@
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
#include <wlc/wlc.h>
|
#include <wlc/wlc.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
@ -20,10 +21,7 @@ static 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;
|
||||||
// Determine the output that the view is under
|
// Determine the output that the view is under
|
||||||
swayc_t *parent = view;
|
swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
|
||||||
while (parent->type != C_OUTPUT) {
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
if (origin->x >= view->x && origin->y >= view->y
|
if (origin->x >= view->x && origin->y >= view->y
|
||||||
&& origin->x < view->x + view->width && origin->y < view->y + view->height
|
&& origin->x < view->x + view->width && origin->y < view->y + view->height
|
||||||
&& view->visible && parent == root_container.focused) {
|
&& view->visible && parent == root_container.focused) {
|
||||||
|
|
@ -191,10 +189,7 @@ static bool handle_view_created(wlc_handle handle) {
|
||||||
|
|
||||||
if (newview) {
|
if (newview) {
|
||||||
set_focused_container(newview);
|
set_focused_container(newview);
|
||||||
swayc_t *output = newview->parent;
|
swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
|
||||||
while (output && output->type != C_OUTPUT) {
|
|
||||||
output = output->parent;
|
|
||||||
}
|
|
||||||
arrange_windows(output, -1, -1);
|
arrange_windows(output, -1, -1);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -262,10 +257,7 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s
|
||||||
arrange_windows(c->parent, -1, -1);
|
arrange_windows(c->parent, -1, -1);
|
||||||
// Set it as focused window for that workspace if its going fullscreen
|
// Set it as focused window for that workspace if its going fullscreen
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
swayc_t *ws = c;
|
swayc_t *ws = swayc_parent_by_type(c, C_WORKSPACE);
|
||||||
while (ws->type != C_WORKSPACE) {
|
|
||||||
ws = ws->parent;
|
|
||||||
}
|
|
||||||
// Set ws focus to c
|
// Set ws focus to c
|
||||||
set_focused_container_for(ws, c);
|
set_focused_container_for(ws, c);
|
||||||
}
|
}
|
||||||
|
|
@ -347,11 +339,14 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
static wlc_handle prev_handle = 0;
|
static wlc_handle prev_handle = 0;
|
||||||
mouse_origin = *origin;
|
mouse_origin = *origin;
|
||||||
bool changed_floating = false;
|
bool changed_floating = false;
|
||||||
|
bool changed_tiling = false;
|
||||||
|
int min_sane_w = 100;
|
||||||
|
int min_sane_h = 60;
|
||||||
if (!active_workspace) {
|
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 = get_focused_view(active_workspace);
|
swayc_t *view = container_under_pointer();
|
||||||
uint32_t edge = 0;
|
uint32_t edge = 0;
|
||||||
if (pointer_state.floating.drag && view) {
|
if (pointer_state.floating.drag && view) {
|
||||||
if (view->is_floating) {
|
if (view->is_floating) {
|
||||||
|
|
@ -365,8 +360,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
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;
|
||||||
int min_sane_w = 100;
|
|
||||||
int min_sane_h = 60;
|
|
||||||
|
|
||||||
// Move and resize the view based on the dx/dy and mouse position
|
// Move and resize the view based on the dx/dy and mouse position
|
||||||
int midway_x = view->x + view->width/2;
|
int midway_x = view->x + view->width/2;
|
||||||
|
|
@ -427,6 +420,106 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} 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) {
|
if (config->focus_follows_mouse && prev_handle != handle) {
|
||||||
// Dont change focus if fullscreen
|
// Dont change focus if fullscreen
|
||||||
|
|
@ -452,6 +545,9 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
wlc_view_set_geometry(view->handle, edge, &geometry);
|
wlc_view_set_geometry(view->handle, edge, &geometry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (changed_tiling) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -472,7 +568,16 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
|
||||||
pointer_state.r_held = true;
|
pointer_state.r_held = true;
|
||||||
}
|
}
|
||||||
swayc_t *pointer = container_under_pointer();
|
swayc_t *pointer = container_under_pointer();
|
||||||
set_focused_container(pointer);
|
if (pointer) {
|
||||||
|
set_focused_container(pointer);
|
||||||
|
int midway_x = pointer->x + pointer->width/2;
|
||||||
|
int midway_y = pointer->y + pointer->height/2;
|
||||||
|
pointer_state.lock.bottom = origin->y < midway_y;
|
||||||
|
pointer_state.lock.top = !pointer_state.lock.bottom;
|
||||||
|
pointer_state.lock.right = origin->x < midway_x;
|
||||||
|
pointer_state.lock.left = !pointer_state.lock.right;
|
||||||
|
}
|
||||||
|
|
||||||
if (pointer->is_floating) {
|
if (pointer->is_floating) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < pointer->parent->floating->length; i++) {
|
for (i = 0; i < pointer->parent->floating->length; i++) {
|
||||||
|
|
@ -484,19 +589,15 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
|
||||||
}
|
}
|
||||||
arrange_windows(pointer->parent, -1, -1);
|
arrange_windows(pointer->parent, -1, -1);
|
||||||
if (modifiers->mods & config->floating_mod) {
|
if (modifiers->mods & config->floating_mod) {
|
||||||
int midway_x = pointer->x + pointer->width/2;
|
|
||||||
int midway_y = pointer->y + pointer->height/2;
|
|
||||||
|
|
||||||
pointer_state.floating.drag = pointer_state.l_held;
|
pointer_state.floating.drag = pointer_state.l_held;
|
||||||
pointer_state.floating.resize = pointer_state.r_held;
|
pointer_state.floating.resize = pointer_state.r_held;
|
||||||
pointer_state.lock.bottom = origin->y < midway_y;
|
|
||||||
pointer_state.lock.top = !pointer_state.lock.bottom;
|
|
||||||
pointer_state.lock.right = origin->x < midway_x;
|
|
||||||
pointer_state.lock.left = !pointer_state.lock.right;
|
|
||||||
start_floating(pointer);
|
start_floating(pointer);
|
||||||
}
|
}
|
||||||
// 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 {
|
||||||
|
pointer_state.tiling.resize = pointer_state.r_held;
|
||||||
|
pointer_state.tiling.init_view = pointer;
|
||||||
}
|
}
|
||||||
return (pointer && pointer != focused);
|
return (pointer && pointer != focused);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -508,6 +609,8 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
|
||||||
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.init_view = NULL;
|
||||||
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
|
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@
|
||||||
|
|
||||||
static keycode key_state_array[KEY_STATE_MAX_LENGTH];
|
static keycode key_state_array[KEY_STATE_MAX_LENGTH];
|
||||||
|
|
||||||
|
void input_init(void) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
|
||||||
|
key_state_array[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t find_key(keycode key) {
|
static uint8_t find_key(keycode key) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
|
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
|
||||||
|
|
@ -41,7 +48,7 @@ void release_key(keycode key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}};
|
struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}};
|
||||||
|
|
||||||
static struct wlc_geometry saved_floating;
|
static struct wlc_geometry saved_floating;
|
||||||
|
|
||||||
|
|
@ -65,4 +72,3 @@ void reset_floating(swayc_t *view) {
|
||||||
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};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
100
sway/ipc.c
100
sway/ipc.c
|
|
@ -11,10 +11,13 @@
|
||||||
#include <stropts.h>
|
#include <stropts.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
static int ipc_socket = -1;
|
static int ipc_socket = -1;
|
||||||
static struct wlc_event_source *ipc_event_source = NULL;
|
static struct wlc_event_source *ipc_event_source = NULL;
|
||||||
|
|
@ -37,6 +40,10 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
|
||||||
void ipc_client_disconnect(struct ipc_client *client);
|
void ipc_client_disconnect(struct ipc_client *client);
|
||||||
void ipc_client_handle_command(struct ipc_client *client);
|
void ipc_client_handle_command(struct ipc_client *client);
|
||||||
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
|
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
|
||||||
|
void ipc_get_workspaces_callback(swayc_t *container, void *data);
|
||||||
|
void ipc_get_outputs_callback(swayc_t *container, void *data);
|
||||||
|
|
||||||
|
char *json_list(list_t *items);
|
||||||
|
|
||||||
void ipc_init(void) {
|
void ipc_init(void) {
|
||||||
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||||
|
|
@ -114,11 +121,15 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_available;
|
int read_available;
|
||||||
ioctl(client_fd, FIONREAD, &read_available);
|
if (ioctl(client_fd, FIONREAD, &read_available) == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to read IPC socket buffer size");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the rest of the command payload in case the header has already been read
|
// Wait for the rest of the command payload in case the header has already been read
|
||||||
if (client->payload_length > 0) {
|
if (client->payload_length > 0) {
|
||||||
if (read_available >= client->payload_length) {
|
if ((uint32_t)read_available >= client->payload_length) {
|
||||||
ipc_client_handle_command(client);
|
ipc_client_handle_command(client);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -195,6 +206,26 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
ipc_send_reply(client, reply, (uint32_t) length);
|
ipc_send_reply(client, reply, (uint32_t) length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IPC_GET_WORKSPACES:
|
||||||
|
{
|
||||||
|
list_t *workspaces = create_list();
|
||||||
|
container_map(&root_container, ipc_get_workspaces_callback, workspaces);
|
||||||
|
char *json = json_list(workspaces);
|
||||||
|
free_flat_list(workspaces);
|
||||||
|
ipc_send_reply(client, json, strlen(json));
|
||||||
|
free(json);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IPC_GET_OUTPUTS:
|
||||||
|
{
|
||||||
|
list_t *outputs = create_list();
|
||||||
|
container_map(&root_container, ipc_get_outputs_callback, outputs);
|
||||||
|
char *json = json_list(outputs);
|
||||||
|
free_flat_list(outputs);
|
||||||
|
ipc_send_reply(client, json, strlen(json));
|
||||||
|
free(json);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
|
sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
|
|
@ -227,3 +258,68 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *json_list(list_t *items) {
|
||||||
|
char *json_elements = join_list(items, ",");
|
||||||
|
size_t len = strlen(json_elements);
|
||||||
|
char *json = malloc(len + 3);
|
||||||
|
json[0] = '[';
|
||||||
|
memcpy(json + 1, json_elements, len);
|
||||||
|
json[len+1] = ']';
|
||||||
|
json[len+2] = '\0';
|
||||||
|
free(json_elements);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_get_workspaces_callback(swayc_t *container, void *data) {
|
||||||
|
if (container->type == C_WORKSPACE) {
|
||||||
|
char *json = malloc(512); // Output should usually be around 180 chars
|
||||||
|
int num = isdigit(container->name[0]) ? atoi(container->name) : -1;
|
||||||
|
// TODO: escape the name (quotation marks, unicode)
|
||||||
|
sprintf(json,
|
||||||
|
"{"
|
||||||
|
"\"num\":%d,"
|
||||||
|
"\"name\":\"%s\","
|
||||||
|
"\"visible\":%s,"
|
||||||
|
"\"focused\":%s,"
|
||||||
|
"\"rect\":{"
|
||||||
|
"\"x\":%d,"
|
||||||
|
"\"y\":%d,"
|
||||||
|
"\"width\":%d,"
|
||||||
|
"\"height\":%d"
|
||||||
|
"},"
|
||||||
|
"\"output\":\"%s\","
|
||||||
|
"\"urgent\":%s"
|
||||||
|
"}",
|
||||||
|
num, container->name, container->visible ? "true" : "false", container->is_focused ? "true" : "false",
|
||||||
|
(int)container->x, (int)container->y, (int)container->width, (int)container->height,
|
||||||
|
container->parent->name, "false" // TODO: urgent hint
|
||||||
|
);
|
||||||
|
list_add((list_t *)data, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_get_outputs_callback(swayc_t *container, void *data) {
|
||||||
|
if (container->type == C_OUTPUT) {
|
||||||
|
char *json = malloc(512); // Output should usually be around 130 chars
|
||||||
|
// TODO: escape the name (quotation marks, unicode)
|
||||||
|
sprintf(json,
|
||||||
|
"{"
|
||||||
|
"\"name\":\"%s\","
|
||||||
|
"\"active\":%s,"
|
||||||
|
"\"primary\":%s,"
|
||||||
|
"\"rect\":{"
|
||||||
|
"\"x\":%d,"
|
||||||
|
"\"y\":%d,"
|
||||||
|
"\"width\":%d,"
|
||||||
|
"\"height\":%d"
|
||||||
|
"},"
|
||||||
|
"\"current_workspace\":\"%s\""
|
||||||
|
"}",
|
||||||
|
container->name, "true", "false", // TODO: active, primary
|
||||||
|
(int)container->x, (int)container->y, (int)container->width, (int)container->height,
|
||||||
|
container->focused ? container->focused->name : ""
|
||||||
|
);
|
||||||
|
list_add((list_t *)data, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
106
sway/layout.c
106
sway/layout.c
|
|
@ -29,7 +29,7 @@ static int index_child(swayc_t *parent, swayc_t *child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_child(swayc_t *parent, swayc_t *child) {
|
void add_child(swayc_t *parent, swayc_t *child) {
|
||||||
sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
|
sway_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type,
|
||||||
child->width, child->height, parent, parent->type, parent->width, parent->height);
|
child->width, child->height, parent, parent->type, parent->width, parent->height);
|
||||||
list_add(parent->children, child);
|
list_add(parent->children, child);
|
||||||
child->parent = parent;
|
child->parent = parent;
|
||||||
|
|
@ -40,7 +40,7 @@ void add_child(swayc_t *parent, swayc_t *child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_floating(swayc_t *ws, swayc_t *child) {
|
void add_floating(swayc_t *ws, swayc_t *child) {
|
||||||
sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type,
|
sway_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type,
|
||||||
child->width, child->height, ws, ws->type, ws->width, ws->height);
|
child->width, child->height, ws, ws->type, ws->width, ws->height);
|
||||||
list_add(ws->floating, child);
|
list_add(ws->floating, child);
|
||||||
child->parent = ws;
|
child->parent = ws;
|
||||||
|
|
@ -108,8 +108,52 @@ swayc_t *remove_child(swayc_t *child) {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Implement horizontal movement.
|
||||||
|
//TODO: Implement move to a different workspace.
|
||||||
|
void move_container(swayc_t *container,swayc_t* root,enum movement_direction direction){
|
||||||
|
sway_log(L_DEBUG, "Moved window");
|
||||||
|
swayc_t *temp;
|
||||||
|
int i;
|
||||||
|
int clength = root->children->length;
|
||||||
|
//Rearrange
|
||||||
|
for (i = 0; i < clength; ++i) {
|
||||||
|
swayc_t *child = root->children->items[i];
|
||||||
|
if (child->handle == container->handle){
|
||||||
|
if (clength == 1){
|
||||||
|
//Only one container, meh.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (direction == MOVE_LEFT && i > 0){
|
||||||
|
temp = root->children->items[i-1];
|
||||||
|
root->children->items[i] = temp;
|
||||||
|
root->children->items[i-1] = container;
|
||||||
|
arrange_windows(&root_container,-1,-1);
|
||||||
|
}
|
||||||
|
else if (direction == MOVE_RIGHT && i < clength-1){
|
||||||
|
temp = root->children->items[i+1];
|
||||||
|
root->children->items[i] = temp;
|
||||||
|
root->children->items[i+1] = container;
|
||||||
|
arrange_windows(&root_container,-1,-1);
|
||||||
|
|
||||||
void arrange_windows(swayc_t *container, int width, int height) {
|
}
|
||||||
|
else if (direction == MOVE_UP){
|
||||||
|
sway_log(L_INFO, "Moving up not implemented");
|
||||||
|
}
|
||||||
|
else if (direction == MOVE_DOWN){
|
||||||
|
sway_log(L_INFO, "Moving down not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (child->children != NULL){
|
||||||
|
move_container(container,child,direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void arrange_windows(swayc_t *container, double width, double height) {
|
||||||
int i;
|
int i;
|
||||||
if (width == -1 || height == -1) {
|
if (width == -1 || height == -1) {
|
||||||
sway_log(L_DEBUG, "Arranging layout for %p", container);
|
sway_log(L_DEBUG, "Arranging layout for %p", container);
|
||||||
|
|
@ -144,7 +188,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
child->y = y + container->gaps;
|
child->y = y + container->gaps;
|
||||||
child->width = width - container->gaps * 2;
|
child->width = width - container->gaps * 2;
|
||||||
child->height = height - container->gaps * 2;
|
child->height = height - container->gaps * 2;
|
||||||
sway_log(L_DEBUG, "Arranging workspace #%d at %d, %d", i, child->x, child->y);
|
sway_log(L_DEBUG, "Arranging workspace #%d at %f, %f", i, child->x, child->y);
|
||||||
arrange_windows(child, -1, -1);
|
arrange_windows(child, -1, -1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -161,10 +205,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
|
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
|
||||||
swayc_t *parent = container;
|
swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT);
|
||||||
while (parent->type != C_OUTPUT) {
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
geometry.origin.x = 0;
|
geometry.origin.x = 0;
|
||||||
geometry.origin.y = 0;
|
geometry.origin.y = 0;
|
||||||
geometry.size.w = parent->width;
|
geometry.size.w = parent->width;
|
||||||
|
|
@ -193,7 +234,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
default:
|
default:
|
||||||
// Calculate total width
|
// Calculate total width
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
int *old_width = &((swayc_t *)container->children->items[i])->width;
|
double *old_width = &((swayc_t *)container->children->items[i])->width;
|
||||||
if (*old_width <= 0) {
|
if (*old_width <= 0) {
|
||||||
if (container->children->length > 1) {
|
if (container->children->length > 1) {
|
||||||
*old_width = width / (container->children->length - 1);
|
*old_width = width / (container->children->length - 1);
|
||||||
|
|
@ -209,7 +250,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
sway_log(L_DEBUG, "Arranging %p horizontally", container);
|
sway_log(L_DEBUG, "Arranging %p horizontally", container);
|
||||||
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, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, width, scale);
|
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale);
|
||||||
child->x = x + container->x;
|
child->x = x + container->x;
|
||||||
child->y = y + container->y;
|
child->y = y + container->y;
|
||||||
arrange_windows(child, child->width * scale, height);
|
arrange_windows(child, child->width * scale, height);
|
||||||
|
|
@ -220,7 +261,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
case L_VERT:
|
case L_VERT:
|
||||||
// Calculate total height
|
// Calculate total height
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
int *old_height = &((swayc_t *)container->children->items[i])->height;
|
double *old_height = &((swayc_t *)container->children->items[i])->height;
|
||||||
if (*old_height <= 0) {
|
if (*old_height <= 0) {
|
||||||
if (container->children->length > 1) {
|
if (container->children->length > 1) {
|
||||||
*old_height = height / (container->children->length - 1);
|
*old_height = height / (container->children->length - 1);
|
||||||
|
|
@ -236,7 +277,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
sway_log(L_DEBUG, "Arranging %p vertically", container);
|
sway_log(L_DEBUG, "Arranging %p vertically", container);
|
||||||
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, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, height, scale);
|
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale);
|
||||||
child->x = x + container->x;
|
child->x = x + container->x;
|
||||||
child->y = y + container->y;
|
child->y = y + container->y;
|
||||||
arrange_windows(child, width, child->height * scale);
|
arrange_windows(child, width, child->height * scale);
|
||||||
|
|
@ -263,10 +304,7 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) {
|
if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) {
|
||||||
swayc_t *parent = view;
|
swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
|
||||||
while (parent->type != C_OUTPUT) {
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
geometry.origin.x = 0;
|
geometry.origin.x = 0;
|
||||||
geometry.origin.y = 0;
|
geometry.origin.y = 0;
|
||||||
geometry.size.w = parent->width;
|
geometry.size.w = parent->width;
|
||||||
|
|
@ -370,3 +408,39 @@ 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) {
|
||||||
|
int i;
|
||||||
|
bool layout_match = true;
|
||||||
|
sway_log(L_DEBUG, "Resizing %p with amount: %f", container, amount);
|
||||||
|
if (edge == WLC_RESIZE_EDGE_LEFT || edge == WLC_RESIZE_EDGE_RIGHT) {
|
||||||
|
container->width += amount;
|
||||||
|
layout_match = container->layout == L_HORIZ;
|
||||||
|
} else if (edge == WLC_RESIZE_EDGE_TOP || edge == WLC_RESIZE_EDGE_BOTTOM) {
|
||||||
|
container->height += amount;
|
||||||
|
layout_match = container->layout == L_VERT;
|
||||||
|
}
|
||||||
|
if (container->type == C_VIEW) {
|
||||||
|
struct wlc_geometry geometry = {
|
||||||
|
.origin = {
|
||||||
|
.x = container->x + container->gaps / 2,
|
||||||
|
.y = container->y + container->gaps / 2
|
||||||
|
},
|
||||||
|
.size = {
|
||||||
|
.w = container->width - container->gaps,
|
||||||
|
.h = container->height - container->gaps
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wlc_view_set_geometry(container->handle, edge, &geometry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (layout_match) {
|
||||||
|
for (i = 0; i < container->children->length; i++) {
|
||||||
|
recursive_resize(container->children->items[i], amount/container->children->length, edge);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < container->children->length; i++) {
|
||||||
|
recursive_resize(container->children->items[i], amount, edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
23
sway/log.c
23
sway/log.c
|
|
@ -10,7 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int colored = 1;
|
int colored = 1;
|
||||||
int v = 0;
|
log_importance_t v = L_SILENT;
|
||||||
|
|
||||||
static const char *verbosity_colors[] = {
|
static const char *verbosity_colors[] = {
|
||||||
"", // L_SILENT
|
"", // L_SILENT
|
||||||
|
|
@ -19,7 +19,7 @@ static const char *verbosity_colors[] = {
|
||||||
"\x1B[1;30m", // L_DEBUG
|
"\x1B[1;30m", // L_DEBUG
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_log(int verbosity) {
|
void init_log(log_importance_t verbosity) {
|
||||||
v = verbosity;
|
v = verbosity;
|
||||||
/* set FD_CLOEXEC flag to prevent programs called with exec to write into logs */
|
/* set FD_CLOEXEC flag to prevent programs called with exec to write into logs */
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -46,15 +46,15 @@ void sway_abort(const char *format, ...) {
|
||||||
sway_terminate();
|
sway_terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_log(int verbosity, const char* format, ...) {
|
void sway_log(log_importance_t verbosity, const char* format, ...) {
|
||||||
if (verbosity <= v) {
|
if (verbosity <= v) {
|
||||||
int c = verbosity;
|
unsigned int c = verbosity;
|
||||||
if (c > sizeof(verbosity_colors) / sizeof(char *)) {
|
if (c > sizeof(verbosity_colors) / sizeof(char *)) {
|
||||||
c = sizeof(verbosity_colors) / sizeof(char *) - 1;
|
c = sizeof(verbosity_colors) / sizeof(char *) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colored) {
|
if (colored) {
|
||||||
fprintf(stderr, verbosity_colors[c]);
|
fprintf(stderr, "%s", verbosity_colors[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
@ -69,15 +69,15 @@ void sway_log(int verbosity, const char* format, ...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_log_errno(int verbosity, char* format, ...) {
|
void sway_log_errno(log_importance_t verbosity, char* format, ...) {
|
||||||
if (verbosity <= v) {
|
if (verbosity <= v) {
|
||||||
int c = verbosity;
|
unsigned int c = verbosity;
|
||||||
if (c > sizeof(verbosity_colors) / sizeof(char *)) {
|
if (c > sizeof(verbosity_colors) / sizeof(char *)) {
|
||||||
c = sizeof(verbosity_colors) / sizeof(char *) - 1;
|
c = sizeof(verbosity_colors) / sizeof(char *) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colored) {
|
if (colored) {
|
||||||
fprintf(stderr, verbosity_colors[c]);
|
fprintf(stderr, "%s", verbosity_colors[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
@ -88,7 +88,7 @@ void sway_log_errno(int verbosity, char* format, ...) {
|
||||||
fprintf(stderr, ": ");
|
fprintf(stderr, ": ");
|
||||||
char error[256];
|
char error[256];
|
||||||
strerror_r(errno, error, sizeof(error));
|
strerror_r(errno, error, sizeof(error));
|
||||||
fprintf(stderr, error);
|
fprintf(stderr, "%s", error);
|
||||||
|
|
||||||
if (colored) {
|
if (colored) {
|
||||||
fprintf(stderr, "\x1B[0m");
|
fprintf(stderr, "\x1B[0m");
|
||||||
|
|
@ -142,13 +142,14 @@ static void container_log(const swayc_t *c) {
|
||||||
c->layout == L_STACKED ? "Stacked|":
|
c->layout == L_STACKED ? "Stacked|":
|
||||||
c->layout == L_FLOATING ? "Floating|":
|
c->layout == L_FLOATING ? "Floating|":
|
||||||
"Unknown|");
|
"Unknown|");
|
||||||
fprintf(stderr, "w:%d|h:%d|", c->width, c->height);
|
fprintf(stderr, "w:%f|h:%f|", c->width, c->height);
|
||||||
fprintf(stderr, "x:%d|y:%d|", c->x, c->y);
|
fprintf(stderr, "x:%f|y:%f|", c->x, c->y);
|
||||||
fprintf(stderr, "vis:%c|", c->visible?'t':'f');
|
fprintf(stderr, "vis:%c|", c->visible?'t':'f');
|
||||||
fprintf(stderr, "name:%.16s|", c->name);
|
fprintf(stderr, "name:%.16s|", c->name);
|
||||||
fprintf(stderr, "children:%d\n",c->children?c->children->length:0);
|
fprintf(stderr, "children:%d\n",c->children?c->children->length:0);
|
||||||
}
|
}
|
||||||
void layout_log(const swayc_t *c, int depth) {
|
void layout_log(const swayc_t *c, int depth) {
|
||||||
|
if (L_DEBUG > v) return;
|
||||||
int i, d;
|
int i, d;
|
||||||
int e = c->children ? c->children->length : 0;
|
int e = c->children ? c->children->length : 0;
|
||||||
container_log(c);
|
container_log(c);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
/* Note: This returns 8 characters for trimmed_start per tab character. */
|
/* Note: This returns 8 characters for trimmed_start per tab character. */
|
||||||
char *strip_whitespace(char *_str, int *trimmed_start) {
|
char *strip_whitespace(char *_str, int *trimmed_start) {
|
||||||
|
|
@ -197,3 +198,41 @@ char *join_args(char **argv, int argc) {
|
||||||
res[len - 1] = '\0';
|
res[len - 1] = '\0';
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Join a list of strings, adding separator in between. Separator can be NULL.
|
||||||
|
*/
|
||||||
|
char *join_list(list_t *list, char *separator) {
|
||||||
|
if (!sway_assert(list != NULL, "list != NULL") || list->length == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = 1; // NULL terminator
|
||||||
|
size_t sep_len = 0;
|
||||||
|
if (separator != NULL) {
|
||||||
|
sep_len = strlen(separator);
|
||||||
|
len += (list->length - 1) * sep_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < list->length; i++) {
|
||||||
|
len += strlen(list->items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *res = malloc(len);
|
||||||
|
|
||||||
|
char *p = res + strlen(list->items[0]);
|
||||||
|
strcpy(res, list->items[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < list->length; i++) {
|
||||||
|
if (sep_len) {
|
||||||
|
memcpy(p, separator, sep_len);
|
||||||
|
p += sep_len;
|
||||||
|
}
|
||||||
|
strcpy(p, list->items[i]);
|
||||||
|
p += strlen(list->items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,7 @@ char *workspace_next_name(void) {
|
||||||
|
|
||||||
swayc_t *workspace_create(const char* name) {
|
swayc_t *workspace_create(const char* name) {
|
||||||
swayc_t *parent = get_focused_container(&root_container);
|
swayc_t *parent = get_focused_container(&root_container);
|
||||||
while (parent->type != C_OUTPUT) {
|
parent = swayc_parent_by_type(parent, C_OUTPUT);
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
return new_workspace(parent, name);
|
return new_workspace(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue