mirror of
https://github.com/swaywm/sway.git
synced 2026-05-03 06:46:26 -04:00
commit
9039937c39
22 changed files with 819 additions and 244 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,3 +9,4 @@ bin/
|
||||||
test/
|
test/
|
||||||
build/
|
build/
|
||||||
.lvimrc
|
.lvimrc
|
||||||
|
config-debug
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ struct sway_config {
|
||||||
int gaps_outer;
|
int gaps_outer;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool load_config(void);
|
bool load_config(const char *file);
|
||||||
bool read_config(FILE *file, bool is_active);
|
bool read_config(FILE *file, bool is_active);
|
||||||
char *do_var_replacement(struct sway_config *config, char *str);
|
char *do_var_replacement(struct sway_config *config, char *str);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ enum swayc_types{
|
||||||
C_WORKSPACE,
|
C_WORKSPACE,
|
||||||
C_CONTAINER,
|
C_CONTAINER,
|
||||||
C_VIEW,
|
C_VIEW,
|
||||||
//Keep last
|
// Keep last
|
||||||
C_TYPES,
|
C_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ enum swayc_layouts{
|
||||||
L_STACKED,
|
L_STACKED,
|
||||||
L_TABBED,
|
L_TABBED,
|
||||||
L_FLOATING,
|
L_FLOATING,
|
||||||
//Keep last
|
// Keep last
|
||||||
L_LAYOUTS,
|
L_LAYOUTS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,8 +44,6 @@ struct sway_container {
|
||||||
bool is_floating;
|
bool is_floating;
|
||||||
bool is_focused;
|
bool is_focused;
|
||||||
|
|
||||||
int weight;
|
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
int gaps;
|
int gaps;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#ifndef _SWAY_FOCUS_H
|
#ifndef _SWAY_FOCUS_H
|
||||||
#define _SWAY_FOCUS_H
|
#define _SWAY_FOCUS_H
|
||||||
#include "container.h"
|
|
||||||
|
|
||||||
enum movement_direction {
|
enum movement_direction {
|
||||||
MOVE_LEFT,
|
MOVE_LEFT,
|
||||||
MOVE_RIGHT,
|
MOVE_RIGHT,
|
||||||
|
|
@ -10,6 +8,8 @@ enum movement_direction {
|
||||||
MOVE_PARENT
|
MOVE_PARENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "container.h"
|
||||||
|
|
||||||
// focused_container - the container found by following the `focused` pointer
|
// focused_container - the container found by following the `focused` pointer
|
||||||
// from a given container to a container with `is_focused` boolean set
|
// from a given container to a container with `is_focused` boolean set
|
||||||
// ---
|
// ---
|
||||||
|
|
|
||||||
49
include/input_state.h
Normal file
49
include/input_state.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef _SWAY_KEY_STATE_H
|
||||||
|
#define _SWAY_KEY_STATE_H
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "container.h"
|
||||||
|
|
||||||
|
/* Keyboard state */
|
||||||
|
|
||||||
|
typedef uint32_t keycode;
|
||||||
|
|
||||||
|
// returns true if key has been pressed, otherwise false
|
||||||
|
bool check_key(keycode key);
|
||||||
|
|
||||||
|
// sets a key as pressed
|
||||||
|
void press_key(keycode key);
|
||||||
|
|
||||||
|
// unsets a key as pressed
|
||||||
|
void release_key(keycode key);
|
||||||
|
|
||||||
|
/* Pointer state */
|
||||||
|
|
||||||
|
enum pointer_values {
|
||||||
|
M_LEFT_CLICK = 272,
|
||||||
|
M_RIGHT_CLICK = 273,
|
||||||
|
M_SCROLL_CLICK = 274,
|
||||||
|
M_SCROLL_UP = 275,
|
||||||
|
M_SCROLL_DOWN = 276,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct pointer_state {
|
||||||
|
bool l_held;
|
||||||
|
bool r_held;
|
||||||
|
struct pointer_floating {
|
||||||
|
bool drag;
|
||||||
|
bool resize;
|
||||||
|
} floating;
|
||||||
|
struct pointer_lock {
|
||||||
|
bool left;
|
||||||
|
bool right;
|
||||||
|
bool top;
|
||||||
|
bool bottom;
|
||||||
|
} lock;
|
||||||
|
} pointer_state;
|
||||||
|
|
||||||
|
void start_floating(swayc_t *view);
|
||||||
|
void reset_floating(swayc_t *view);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
18
include/ipc.h
Normal file
18
include/ipc.h
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef _SWAY_IPC_H
|
||||||
|
#define _SWAY_IPC_H
|
||||||
|
|
||||||
|
enum ipc_command_type {
|
||||||
|
IPC_COMMAND = 0,
|
||||||
|
IPC_GET_WORKSPACES = 1,
|
||||||
|
IPC_SUBSCRIBE = 2,
|
||||||
|
IPC_GET_OUTPUTS = 3,
|
||||||
|
IPC_GET_TREE = 4,
|
||||||
|
IPC_GET_MARKS = 5,
|
||||||
|
IPC_GET_BAR_CONFIG = 6,
|
||||||
|
IPC_GET_VERSION = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
void ipc_init(void);
|
||||||
|
void ipc_terminate(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <wlc/wlc.h>
|
#include <wlc/wlc.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
|
#include "focus.h"
|
||||||
|
|
||||||
extern swayc_t root_container;
|
extern swayc_t root_container;
|
||||||
|
|
||||||
|
|
@ -26,5 +27,6 @@ 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_for_handle(wlc_handle handle, swayc_t *parent);
|
||||||
|
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ typedef enum {
|
||||||
void init_log(int verbosity);
|
void init_log(int 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(int verbosity, const char* format, ...) __attribute__((format(printf,2,3)));
|
||||||
|
void sway_log_errno(int 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)));
|
||||||
|
|
||||||
|
|
|
||||||
6
include/sway.h
Normal file
6
include/sway.h
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _SWAY_SWAY_H
|
||||||
|
#define _SWAY_SWAY_H
|
||||||
|
|
||||||
|
void sway_terminate(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
17
sway.5.txt
17
sway.5.txt
|
|
@ -22,11 +22,11 @@ Commands
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**bindsym** <key combo> <command>::
|
**bindsym** <key combo> <command>::
|
||||||
Binds _key combo_ to execute _command_ when pressed. You may use XKB key names
|
Binds _key combo_ to execute _command_ when pressed. You may use XKB key
|
||||||
here (**xev**(1) is a good tool for discovering them). An example bindsym
|
names here (**xev**(1) is a good tool for discovering them). An example
|
||||||
command would be _bindsym Mod1+Shift+f exec firefox_, which would execute
|
bindsym command would be _bindsym Mod1+Shift+f exec firefox_, which would
|
||||||
Firefox if the alt, shift, and F keys are pressed together. Any valid sway
|
execute Firefox if the alt, shift, and F keys are pressed together. Any
|
||||||
command is eligible to be bound to a key combo.
|
valid sway command is eligible to be bound to a key combo.
|
||||||
|
|
||||||
**exec** <shell command>::
|
**exec** <shell command>::
|
||||||
Executes _shell command_ with sh.
|
Executes _shell command_ with sh.
|
||||||
|
|
@ -48,6 +48,9 @@ Commands
|
||||||
container, which is useful, for example, to open a sibling of the parent
|
container, which is useful, for example, to open a sibling of the parent
|
||||||
container, or to move the entire container around.
|
container, or to move the entire container around.
|
||||||
|
|
||||||
|
**focus** mode_toggle::
|
||||||
|
Toggles focus between floating view and tiled view.
|
||||||
|
|
||||||
**focus_follows_mouse** <yes|no>::
|
**focus_follows_mouse** <yes|no>::
|
||||||
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.
|
||||||
|
|
@ -83,10 +86,10 @@ Commands
|
||||||
**fullscreen**::
|
**fullscreen**::
|
||||||
Toggles fullscreen status for the focused view.
|
Toggles fullscreen status for the focused view.
|
||||||
|
|
||||||
**gaps** <amount>**::
|
**gaps** <amount>::
|
||||||
Adds _amount_ pixels between each view, and around each output.
|
Adds _amount_ pixels between each view, and around each output.
|
||||||
|
|
||||||
**gaps** <inner|outer> <amount>**::
|
**gaps** <inner|outer> <amount>::
|
||||||
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
|
#include "sway.h"
|
||||||
|
|
||||||
struct modifier_key {
|
struct modifier_key {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
@ -76,6 +77,18 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bindsym_sort(const void *_lbind, const void *_rbind) {
|
||||||
|
const struct sway_binding *lbind = *(void **)_lbind;
|
||||||
|
const struct sway_binding *rbind = *(void **)_rbind;
|
||||||
|
unsigned int lmod = 0, rmod = 0, i;
|
||||||
|
|
||||||
|
// Count how any modifiers are pressed
|
||||||
|
for (i = 0; i < 8 * sizeof(lbind->modifiers); ++i) {
|
||||||
|
lmod += lbind->modifiers & 1 << i;
|
||||||
|
rmod += rbind->modifiers & 1 << i;
|
||||||
|
}
|
||||||
|
return (rbind->keys->length + rmod) - (lbind->keys->length + lmod);
|
||||||
|
}
|
||||||
|
|
||||||
static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
||||||
if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) {
|
if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) {
|
||||||
|
|
@ -118,7 +131,10 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
|
||||||
list_free(split);
|
list_free(split);
|
||||||
|
|
||||||
// TODO: Check if there are other commands with this key binding
|
// TODO: Check if there are other commands with this key binding
|
||||||
list_add(config->current_mode->bindings, binding);
|
struct sway_mode *mode = config->current_mode;
|
||||||
|
list_add(mode->bindings, binding);
|
||||||
|
qsort(mode->bindings->items, mode->bindings->length,
|
||||||
|
sizeof(mode->bindings->items[0]), bindsym_sort);
|
||||||
|
|
||||||
sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command);
|
sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -171,7 +187,7 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
|
||||||
}
|
}
|
||||||
// Close all views
|
// Close all views
|
||||||
container_map(&root_container, kill_views, NULL);
|
container_map(&root_container, kill_views, NULL);
|
||||||
exit(0);
|
sway_terminate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,10 +204,10 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
|
||||||
}
|
}
|
||||||
// Change from nonfloating to floating
|
// Change from nonfloating to floating
|
||||||
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;
|
||||||
view->y = (active_workspace->height - view->height)/2;
|
view->y = (active_workspace->height - view->height)/2;
|
||||||
|
|
@ -218,21 +234,20 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
|
||||||
|
|
||||||
sway_log(L_DEBUG, "Non-floating focused container is %p", focused);
|
sway_log(L_DEBUG, "Non-floating focused container is %p", focused);
|
||||||
|
|
||||||
//Case of focused workspace, just create as child of it
|
// Case of focused workspace, just create as child of it
|
||||||
if (focused->type == C_WORKSPACE) {
|
if (focused->type == C_WORKSPACE) {
|
||||||
add_child(focused, view);
|
add_child(focused, view);
|
||||||
}
|
}
|
||||||
//Regular case, create as sibling of current container
|
// Regular case, create as sibling of current container
|
||||||
else {
|
else {
|
||||||
add_sibling(focused, view);
|
add_sibling(focused, view);
|
||||||
}
|
}
|
||||||
// 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;
|
||||||
arrange_windows(active_workspace, -1, -1);
|
arrange_windows(active_workspace, -1, -1);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
set_focused_container(view);
|
set_focused_container(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +259,7 @@ static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv)
|
||||||
list_t *split = split_string(argv[0], "+");
|
list_t *split = split_string(argv[0], "+");
|
||||||
config->floating_mod = 0;
|
config->floating_mod = 0;
|
||||||
|
|
||||||
//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 < 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) {
|
||||||
|
|
@ -261,6 +276,8 @@ static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
|
static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
|
||||||
|
static int floating_toggled_index = 0;
|
||||||
|
static int tiled_toggled_index = 0;
|
||||||
if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) {
|
if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +291,44 @@ static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
|
||||||
return move_focus(MOVE_DOWN);
|
return move_focus(MOVE_DOWN);
|
||||||
} else if (strcasecmp(argv[0], "parent") == 0) {
|
} else if (strcasecmp(argv[0], "parent") == 0) {
|
||||||
return move_focus(MOVE_PARENT);
|
return move_focus(MOVE_PARENT);
|
||||||
|
} else if (strcasecmp(argv[0], "mode_toggle") == 0) {
|
||||||
|
int i;
|
||||||
|
swayc_t *focused = get_focused_view(active_workspace);
|
||||||
|
if (focused->is_floating) {
|
||||||
|
if (active_workspace->children->length > 0) {
|
||||||
|
for (i = 0;i < active_workspace->floating->length; i++) {
|
||||||
|
if (active_workspace->floating->items[i] == focused) {
|
||||||
|
floating_toggled_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (active_workspace->children->length > tiled_toggled_index) {
|
||||||
|
set_focused_container(get_focused_view(active_workspace->children->items[tiled_toggled_index]));
|
||||||
|
} else {
|
||||||
|
set_focused_container(get_focused_view(active_workspace->children->items[0]));
|
||||||
|
tiled_toggled_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (active_workspace->floating->length > 0) {
|
||||||
|
for (i = 0;i < active_workspace->children->length; i++) {
|
||||||
|
if (active_workspace->children->items[i] == focused) {
|
||||||
|
tiled_toggled_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (active_workspace->floating->length > floating_toggled_index) {
|
||||||
|
swayc_t *floating = active_workspace->floating->items[floating_toggled_index];
|
||||||
|
set_focused_container(get_focused_view(floating));
|
||||||
|
} else {
|
||||||
|
swayc_t *floating = active_workspace->floating->items[active_workspace->floating->length - 1];
|
||||||
|
set_focused_container(get_focused_view(floating));
|
||||||
|
tiled_toggled_index = active_workspace->floating->length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +415,7 @@ static bool cmd_reload(struct sway_config *config, int argc, char **argv) {
|
||||||
if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)) {
|
if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!load_config()) {
|
if (!load_config(NULL)) { // TODO: Use config given from -c
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
arrange_windows(&root_container, -1, -1);
|
arrange_windows(&root_container, -1, -1);
|
||||||
|
|
@ -455,14 +509,14 @@ 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 = (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) > 0;
|
||||||
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
|
||||||
if (current) {
|
if (current) {
|
||||||
while (container->type != C_WORKSPACE) {
|
while (container->type != C_WORKSPACE) {
|
||||||
container = container->parent;
|
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);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -626,7 +680,7 @@ bool handle_command(struct sway_config *config, char *exec) {
|
||||||
char **argv = split_directive(exec + strlen(handler->command), &argc);
|
char **argv = split_directive(exec + strlen(handler->command), &argc);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
//Perform var subs on all parts of the command
|
// Perform var subs on all parts of the command
|
||||||
for (i = 0; i < argc; ++i) {
|
for (i = 0; i < argc; ++i) {
|
||||||
argv[i] = do_var_replacement(config, argv[i]);
|
argv[i] = do_var_replacement(config, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,10 +144,15 @@ _continue:
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_config(void) {
|
bool load_config(const char *file) {
|
||||||
sway_log(L_INFO, "Loading config");
|
sway_log(L_INFO, "Loading config");
|
||||||
|
|
||||||
char *path = get_config_path();
|
char *path;
|
||||||
|
if (file != NULL) {
|
||||||
|
path = strdup(file);
|
||||||
|
} else {
|
||||||
|
path = get_config_path();
|
||||||
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
sway_log(L_ERROR, "Unable to find a config file!");
|
sway_log(L_ERROR, "Unable to find a config file!");
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ static swayc_t *new_swayc(enum swayc_types type) {
|
||||||
c->handle = -1;
|
c->handle = -1;
|
||||||
c->layout = L_NONE;
|
c->layout = L_NONE;
|
||||||
c->type = type;
|
c->type = type;
|
||||||
c->weight = 1;
|
|
||||||
if (type != C_VIEW) {
|
if (type != C_VIEW) {
|
||||||
c->children = create_list();
|
c->children = create_list();
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +53,7 @@ static void free_swayc(swayc_t *c) {
|
||||||
/* 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);
|
return strcasecmp(view->name, (char *)name) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *new_output(wlc_handle handle) {
|
swayc_t *new_output(wlc_handle handle) {
|
||||||
|
|
@ -67,7 +66,7 @@ swayc_t *new_output(wlc_handle handle) {
|
||||||
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;
|
output->gaps = config->gaps_outer + config->gaps_inner / 2;
|
||||||
|
|
||||||
add_child(&root_container, output);
|
add_child(&root_container, output);
|
||||||
|
|
||||||
|
|
@ -81,8 +80,10 @@ swayc_t *new_output(wlc_handle handle) {
|
||||||
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 (find_container(&root_container, workspace_test, wso->workspace)) {
|
||||||
|
sway_log(L_DEBUG, "But it's already taken");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sway_log(L_DEBUG, "So we're going to use it");
|
||||||
ws_name = strdup(wso->workspace);
|
ws_name = strdup(wso->workspace);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -150,6 +151,7 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
|
||||||
// give them proper layouts
|
// give them proper layouts
|
||||||
cont->layout = workspace->layout;
|
cont->layout = workspace->layout;
|
||||||
workspace->layout = layout;
|
workspace->layout = layout;
|
||||||
|
set_focused_container_for(workspace, get_focused_view(workspace));
|
||||||
} else { // Or is built around container
|
} else { // Or is built around container
|
||||||
swayc_t *parent = replace_child(child, cont);
|
swayc_t *parent = replace_child(child, cont);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
|
@ -169,6 +171,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
|
||||||
view->name = title ? strdup(title) : NULL;
|
view->name = title ? strdup(title) : NULL;
|
||||||
view->visible = true;
|
view->visible = true;
|
||||||
view->is_focused = true;
|
view->is_focused = true;
|
||||||
|
// Setup geometry
|
||||||
|
view->width = 0;
|
||||||
|
view->height = 0;
|
||||||
|
|
||||||
view->gaps = config->gaps_inner;
|
view->gaps = config->gaps_inner;
|
||||||
|
|
||||||
|
|
@ -200,7 +205,7 @@ swayc_t *new_floating_view(wlc_handle handle) {
|
||||||
// Set the geometry of the floating view
|
// Set the geometry of the floating view
|
||||||
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 = (active_workspace->width - geometry->size.w) / 2;
|
||||||
view->y = (active_workspace->height- geometry->size.h) / 2;
|
view->y = (active_workspace->height- geometry->size.h) / 2;
|
||||||
view->width = geometry->size.w;
|
view->width = geometry->size.w;
|
||||||
|
|
|
||||||
78
sway/focus.c
78
sway/focus.c
|
|
@ -3,6 +3,7 @@
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
#include "layout.h"
|
||||||
|
|
||||||
bool locked_container_focus = false;
|
bool locked_container_focus = false;
|
||||||
bool locked_view_focus = false;
|
bool locked_view_focus = false;
|
||||||
|
|
@ -20,6 +21,8 @@ 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
|
||||||
|
|
@ -51,74 +54,17 @@ static void update_focus(swayc_t *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool move_focus(enum movement_direction direction) {
|
bool move_focus(enum movement_direction direction) {
|
||||||
if (locked_container_focus) {
|
swayc_t *view = get_swayc_in_direction(
|
||||||
return false;
|
get_focused_container(&root_container), direction);
|
||||||
}
|
if (view) {
|
||||||
swayc_t *current = get_focused_container(&root_container);
|
if (direction == MOVE_PARENT) {
|
||||||
if (current->type == C_VIEW
|
set_focused_container(view);
|
||||||
&& wlc_view_get_state(current->handle) & WLC_BIT_FULLSCREEN) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
swayc_t *parent = current->parent;
|
|
||||||
|
|
||||||
if (direction == MOVE_PARENT) {
|
|
||||||
if (parent->type == C_OUTPUT) {
|
|
||||||
sway_log(L_DEBUG, "Focus cannot move to parent");
|
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
sway_log(L_DEBUG, "Moving focus from %p:%ld to %p:%ld",
|
set_focused_container(get_focused_view(view));
|
||||||
current, current->handle, parent, parent->handle);
|
|
||||||
set_focused_container(parent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
sway_log(L_DEBUG, "Moving focus away from %p", current);
|
|
||||||
|
|
||||||
// Test if we can even make a difference here
|
|
||||||
bool can_move = false;
|
|
||||||
int diff = 0;
|
|
||||||
if (direction == MOVE_LEFT || direction == MOVE_RIGHT) {
|
|
||||||
if (parent->layout == L_HORIZ || parent->type == C_ROOT) {
|
|
||||||
can_move = true;
|
|
||||||
diff = direction == MOVE_LEFT ? -1 : 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (parent->layout == L_VERT) {
|
|
||||||
can_move = true;
|
|
||||||
diff = direction == MOVE_UP ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no");
|
|
||||||
if (can_move) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < parent->children->length; ++i) {
|
|
||||||
swayc_t *child = parent->children->items[i];
|
|
||||||
if (child == current) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int desired = i + diff;
|
|
||||||
sway_log(L_DEBUG, "Moving from %d to %d", i, desired);
|
|
||||||
if (desired < 0 || desired >= parent->children->length) {
|
|
||||||
can_move = false;
|
|
||||||
} else {
|
|
||||||
swayc_t *newview = parent->children->items[desired];
|
|
||||||
set_focused_container(get_focused_view(newview));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!can_move) {
|
|
||||||
sway_log(L_DEBUG, "Can't move at current level, moving up tree");
|
|
||||||
current = parent;
|
|
||||||
parent = parent->parent;
|
|
||||||
if (!parent) {
|
|
||||||
// Nothing we can do
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *get_focused_container(swayc_t *parent) {
|
swayc_t *get_focused_container(swayc_t *parent) {
|
||||||
|
|
@ -172,7 +118,7 @@ void set_focused_container(swayc_t *c) {
|
||||||
// activate current focus
|
// activate current focus
|
||||||
if (p->type == C_VIEW) {
|
if (p->type == C_VIEW) {
|
||||||
wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true);
|
wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true);
|
||||||
//set focus if view_focus is unlocked
|
// set focus if view_focus is unlocked
|
||||||
if (!locked_view_focus) {
|
if (!locked_view_focus) {
|
||||||
wlc_view_focus(p->handle);
|
wlc_view_focus(p->handle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
176
sway/handlers.c
176
sway/handlers.c
|
|
@ -13,19 +13,10 @@
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
|
#include "input_state.h"
|
||||||
uint32_t keys_pressed[32];
|
|
||||||
int keys_pressed_length = 0;
|
|
||||||
|
|
||||||
|
|
||||||
static struct wlc_origin mouse_origin;
|
static struct wlc_origin mouse_origin;
|
||||||
|
|
||||||
static bool m1_held = false;
|
|
||||||
static bool dragging = false;
|
|
||||||
static bool m2_held = false;
|
|
||||||
static bool resizing = false;
|
|
||||||
static bool lock_left, lock_right, lock_top, lock_bottom = false;
|
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -91,10 +82,12 @@ swayc_t *container_under_pointer(void) {
|
||||||
return lookup;
|
return lookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handles */
|
||||||
|
|
||||||
static bool handle_output_created(wlc_handle output) {
|
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 (active_workspace == NULL) {
|
||||||
swayc_t *ws = op->children->items[0];
|
swayc_t *ws = op->children->items[0];
|
||||||
workspace_switch(ws);
|
workspace_switch(ws);
|
||||||
|
|
@ -116,7 +109,7 @@ static void handle_output_destroyed(wlc_handle output) {
|
||||||
if (list->length == 0) {
|
if (list->length == 0) {
|
||||||
active_workspace = NULL;
|
active_workspace = NULL;
|
||||||
} else {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -154,8 +147,14 @@ static bool handle_view_created(wlc_handle handle) {
|
||||||
if (!focused || focused->type == C_OUTPUT) {
|
if (!focused || focused->type == C_OUTPUT) {
|
||||||
focused = get_focused_container(&root_container);
|
focused = get_focused_container(&root_container);
|
||||||
}
|
}
|
||||||
sway_log(L_DEBUG, "creating view %ld with type %x, state %x, with parent %ld",
|
sway_log(L_DEBUG, "handle:%ld type:%x state:%x parent:%ld "
|
||||||
handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent);
|
"mask:%d (x:%d y:%d w:%d h:%d) title:%s "
|
||||||
|
"class:%s appid:%s",
|
||||||
|
handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent,
|
||||||
|
wlc_view_get_mask(handle), wlc_view_get_geometry(handle)->origin.x,
|
||||||
|
wlc_view_get_geometry(handle)->origin.y,wlc_view_get_geometry(handle)->size.w,
|
||||||
|
wlc_view_get_geometry(handle)->size.h, wlc_view_get_title(handle),
|
||||||
|
wlc_view_get_class(handle), wlc_view_get_app_id(handle));
|
||||||
|
|
||||||
// TODO properly figure out how each window should be handled.
|
// TODO properly figure out how each window should be handled.
|
||||||
switch (wlc_view_get_type(handle)) {
|
switch (wlc_view_get_type(handle)) {
|
||||||
|
|
@ -168,7 +167,7 @@ static bool handle_view_created(wlc_handle handle) {
|
||||||
// Dmenu keeps viewfocus, but others with this flag dont, for now simulate
|
// Dmenu keeps viewfocus, but others with this flag dont, for now simulate
|
||||||
// dmenu
|
// dmenu
|
||||||
case WLC_BIT_OVERRIDE_REDIRECT:
|
case WLC_BIT_OVERRIDE_REDIRECT:
|
||||||
// locked_view_focus = true;
|
// locked_view_focus = true;
|
||||||
wlc_view_focus(handle);
|
wlc_view_focus(handle);
|
||||||
wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
|
wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
|
||||||
wlc_view_bring_to_front(handle);
|
wlc_view_bring_to_front(handle);
|
||||||
|
|
@ -218,7 +217,7 @@ static void handle_view_destroyed(wlc_handle handle) {
|
||||||
// DMENU has this flag, and takes view_focus, but other things with this
|
// DMENU has this flag, and takes view_focus, but other things with this
|
||||||
// flag dont
|
// flag dont
|
||||||
case WLC_BIT_OVERRIDE_REDIRECT:
|
case WLC_BIT_OVERRIDE_REDIRECT:
|
||||||
// locked_view_focus = false;
|
// locked_view_focus = false;
|
||||||
break;
|
break;
|
||||||
case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
|
case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
|
||||||
locked_container_focus = false;
|
locked_container_focus = false;
|
||||||
|
|
@ -233,7 +232,7 @@ static void handle_view_focus(wlc_handle view, bool focus) {
|
||||||
|
|
||||||
static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) {
|
static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) {
|
||||||
sway_log(L_DEBUG, "geometry request %d x %d : %d x %d",
|
sway_log(L_DEBUG, "geometry request %d x %d : %d x %d",
|
||||||
geometry->origin.x, geometry->origin.y, geometry->size.w,geometry->size.h);
|
geometry->origin.x, geometry->origin.y, geometry->size.w, geometry->size.h);
|
||||||
// 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
|
||||||
|
|
@ -253,14 +252,13 @@ 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 = NULL;
|
swayc_t *c = get_swayc_for_handle(view, &root_container);
|
||||||
switch(state) {
|
switch (state) {
|
||||||
case WLC_BIT_FULLSCREEN:
|
case WLC_BIT_FULLSCREEN:
|
||||||
// i3 just lets it become fullscreen
|
// i3 just lets it become fullscreen
|
||||||
wlc_view_set_state(view, state, toggle);
|
wlc_view_set_state(view, state, toggle);
|
||||||
c = get_swayc_for_handle(view, &root_container);
|
|
||||||
sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d",view,c->name,toggle);
|
|
||||||
if (c) {
|
if (c) {
|
||||||
|
sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d", view, c->name, toggle);
|
||||||
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) {
|
||||||
|
|
@ -276,7 +274,9 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s
|
||||||
case WLC_BIT_MAXIMIZED:
|
case WLC_BIT_MAXIMIZED:
|
||||||
case WLC_BIT_RESIZING:
|
case WLC_BIT_RESIZING:
|
||||||
case WLC_BIT_MOVING:
|
case WLC_BIT_MOVING:
|
||||||
|
break;
|
||||||
case WLC_BIT_ACTIVATED:
|
case WLC_BIT_ACTIVATED:
|
||||||
|
sway_log(L_DEBUG, "View %p requested to be activated", c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -285,30 +285,38 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s
|
||||||
|
|
||||||
static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
||||||
uint32_t key, uint32_t sym, enum wlc_key_state state) {
|
uint32_t key, uint32_t sym, enum wlc_key_state state) {
|
||||||
enum { QSIZE = 32 };
|
|
||||||
if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) {
|
if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool cmd_success = false;
|
|
||||||
|
// Revert floating container back to original position on keypress
|
||||||
|
if (state == WLC_KEY_STATE_PRESSED &&
|
||||||
|
(pointer_state.floating.drag || pointer_state.floating.resize)) {
|
||||||
|
reset_floating(get_focused_view(&root_container));
|
||||||
|
}
|
||||||
|
|
||||||
struct sway_mode *mode = config->current_mode;
|
struct sway_mode *mode = config->current_mode;
|
||||||
|
|
||||||
|
if (sym < 70000 /* bullshit made up number */) {
|
||||||
|
if (!isalnum(sym) && sym != ' ' && sym != XKB_KEY_Escape && sym != XKB_KEY_Tab) {
|
||||||
|
// God fucking dammit
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lowercase if necessary
|
// Lowercase if necessary
|
||||||
sym = tolower(sym);
|
sym = tolower(sym);
|
||||||
|
|
||||||
// Find key, if it has been pressed
|
|
||||||
int mid = 0;
|
|
||||||
while (mid < keys_pressed_length && keys_pressed[mid] != sym) {
|
|
||||||
++mid;
|
|
||||||
}
|
|
||||||
//Add or remove key depending on state
|
|
||||||
if (state == WLC_KEY_STATE_PRESSED && mid == keys_pressed_length && keys_pressed_length + 1 < QSIZE) {
|
|
||||||
keys_pressed[keys_pressed_length++] = sym;
|
|
||||||
} else if (state == WLC_KEY_STATE_RELEASED && mid < keys_pressed_length) {
|
|
||||||
memmove(keys_pressed + mid, keys_pressed + mid + 1, sizeof*keys_pressed * (--keys_pressed_length - mid));
|
|
||||||
keys_pressed[keys_pressed_length] = 0;
|
|
||||||
}
|
|
||||||
// TODO: reminder to check conflicts with mod+q+a versus mod+q
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (state == WLC_KEY_STATE_PRESSED) {
|
||||||
|
press_key(sym);
|
||||||
|
} else { // WLC_KEY_STATE_RELEASED
|
||||||
|
release_key(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: reminder to check conflicts with mod+q+a versus mod+q
|
||||||
for (i = 0; i < mode->bindings->length; ++i) {
|
for (i = 0; i < mode->bindings->length; ++i) {
|
||||||
struct sway_binding *binding = mode->bindings->items[i];
|
struct sway_binding *binding = mode->bindings->items[i];
|
||||||
|
|
||||||
|
|
@ -316,40 +324,22 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
|
||||||
bool match;
|
bool match;
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < binding->keys->length; ++j) {
|
for (j = 0; j < binding->keys->length; ++j) {
|
||||||
match = false;
|
|
||||||
xkb_keysym_t *key = binding->keys->items[j];
|
xkb_keysym_t *key = binding->keys->items[j];
|
||||||
uint8_t k;
|
if ((match = check_key(*key)) == false) {
|
||||||
for (k = 0; k < keys_pressed_length; ++k) {
|
|
||||||
if (keys_pressed[k] == *key) {
|
|
||||||
match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match == false) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
// Remove matched keys from keys_pressed
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < binding->keys->length; ++j) {
|
|
||||||
uint8_t k;
|
|
||||||
for (k = 0; k < keys_pressed_length; ++k) {
|
|
||||||
memmove(keys_pressed + k, keys_pressed + k + 1, sizeof*keys_pressed * (--keys_pressed_length - k));
|
|
||||||
keys_pressed[keys_pressed_length] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state == WLC_KEY_STATE_PRESSED) {
|
if (state == WLC_KEY_STATE_PRESSED) {
|
||||||
cmd_success = handle_command(config, binding->command);
|
handle_command(config, binding->command);
|
||||||
|
return true;
|
||||||
} else if (state == WLC_KEY_STATE_RELEASED) {
|
} else if (state == WLC_KEY_STATE_RELEASED) {
|
||||||
// TODO: --released
|
// TODO: --released
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cmd_success;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
|
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
|
||||||
|
|
@ -363,7 +353,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
// 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 = get_focused_view(active_workspace);
|
||||||
uint32_t edge = 0;
|
uint32_t edge = 0;
|
||||||
if (dragging && 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;
|
||||||
|
|
@ -371,7 +361,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
view->y += dy;
|
view->y += dy;
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
}
|
}
|
||||||
} else if (resizing && view) {
|
} else if (pointer_state.floating.resize && 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;
|
||||||
|
|
@ -382,24 +372,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
int midway_x = view->x + view->width/2;
|
int midway_x = view->x + view->width/2;
|
||||||
int midway_y = view->y + view->height/2;
|
int midway_y = view->y + view->height/2;
|
||||||
if (dx < 0) {
|
if (dx < 0) {
|
||||||
if (!lock_right) {
|
if (!pointer_state.lock.right) {
|
||||||
if (view->width > min_sane_w) {
|
if (view->width > min_sane_w) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->width += dx;
|
view->width += dx;
|
||||||
edge += WLC_RESIZE_EDGE_RIGHT;
|
edge += WLC_RESIZE_EDGE_RIGHT;
|
||||||
}
|
}
|
||||||
} else if (mouse_origin.x < midway_x && !lock_left) {
|
} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->x += dx;
|
view->x += dx;
|
||||||
view->width -= dx;
|
view->width -= dx;
|
||||||
edge += WLC_RESIZE_EDGE_LEFT;
|
edge += WLC_RESIZE_EDGE_LEFT;
|
||||||
}
|
}
|
||||||
} else if (dx > 0){
|
} else if (dx > 0) {
|
||||||
if (mouse_origin.x > midway_x && !lock_right) {
|
if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->width += dx;
|
view->width += dx;
|
||||||
edge += WLC_RESIZE_EDGE_RIGHT;
|
edge += WLC_RESIZE_EDGE_RIGHT;
|
||||||
} else if (!lock_left) {
|
} else if (!pointer_state.lock.left) {
|
||||||
if (view->width > min_sane_w) {
|
if (view->width > min_sane_w) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->x += dx;
|
view->x += dx;
|
||||||
|
|
@ -410,24 +400,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dy < 0) {
|
if (dy < 0) {
|
||||||
if (!lock_bottom) {
|
if (!pointer_state.lock.bottom) {
|
||||||
if (view->height > min_sane_h) {
|
if (view->height > min_sane_h) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->height += dy;
|
view->height += dy;
|
||||||
edge += WLC_RESIZE_EDGE_BOTTOM;
|
edge += WLC_RESIZE_EDGE_BOTTOM;
|
||||||
}
|
}
|
||||||
} else if (mouse_origin.y < midway_y && !lock_top) {
|
} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->y += dy;
|
view->y += dy;
|
||||||
view->height -= dy;
|
view->height -= dy;
|
||||||
edge += WLC_RESIZE_EDGE_TOP;
|
edge += WLC_RESIZE_EDGE_TOP;
|
||||||
}
|
}
|
||||||
} else if (dy > 0) {
|
} else if (dy > 0) {
|
||||||
if (mouse_origin.y > midway_y && !lock_bottom) {
|
if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->height += dy;
|
view->height += dy;
|
||||||
edge += WLC_RESIZE_EDGE_BOTTOM;
|
edge += WLC_RESIZE_EDGE_BOTTOM;
|
||||||
} else if (!lock_top) {
|
} else if (!pointer_state.lock.top) {
|
||||||
if (view->height > min_sane_h) {
|
if (view->height > min_sane_h) {
|
||||||
changed_floating = true;
|
changed_floating = true;
|
||||||
view->y += dy;
|
view->y += dy;
|
||||||
|
|
@ -439,9 +429,10 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config->focus_follows_mouse && prev_handle != handle) {
|
if (config->focus_follows_mouse && prev_handle != handle) {
|
||||||
//Dont change focus if fullscreen
|
// Dont change focus if fullscreen
|
||||||
swayc_t *focused = get_focused_view(view);
|
swayc_t *focused = get_focused_view(view);
|
||||||
if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) && !(m1_held || m2_held)) {
|
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());
|
set_focused_container(container_under_pointer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -464,20 +455,21 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
||||||
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 (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (state == WLC_BUTTON_STATE_PRESSED) {
|
if (state == WLC_BUTTON_STATE_PRESSED) {
|
||||||
sway_log(L_DEBUG, "Mouse button %u pressed", button);
|
sway_log(L_DEBUG, "Mouse button %u pressed", button);
|
||||||
if (button == 272) {
|
if (button == M_LEFT_CLICK) {
|
||||||
m1_held = true;
|
pointer_state.l_held = true;
|
||||||
}
|
}
|
||||||
if (button == 273) {
|
if (button == M_RIGHT_CLICK) {
|
||||||
m2_held = true;
|
pointer_state.r_held = true;
|
||||||
}
|
}
|
||||||
swayc_t *pointer = container_under_pointer();
|
swayc_t *pointer = container_under_pointer();
|
||||||
set_focused_container(pointer);
|
set_focused_container(pointer);
|
||||||
|
|
@ -492,29 +484,31 @@ 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) {
|
||||||
dragging = m1_held;
|
|
||||||
resizing = m2_held;
|
|
||||||
int midway_x = pointer->x + pointer->width/2;
|
int midway_x = pointer->x + pointer->width/2;
|
||||||
int midway_y = pointer->y + pointer->height/2;
|
int midway_y = pointer->y + pointer->height/2;
|
||||||
lock_bottom = origin->y < midway_y;
|
|
||||||
lock_top = !lock_bottom;
|
pointer_state.floating.drag = pointer_state.l_held;
|
||||||
lock_right = origin->x < midway_x;
|
pointer_state.floating.resize = pointer_state.r_held;
|
||||||
lock_left = !lock_right;
|
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);
|
||||||
}
|
}
|
||||||
//Dont want pointer sent to window while dragging or resizing
|
// Dont want pointer sent to window while dragging or resizing
|
||||||
return (dragging || resizing);
|
return (pointer_state.floating.drag || pointer_state.floating.resize);
|
||||||
}
|
}
|
||||||
return (pointer && pointer != focused);
|
return (pointer && pointer != focused);
|
||||||
} else {
|
} else {
|
||||||
sway_log(L_DEBUG, "Mouse button %u released", button);
|
sway_log(L_DEBUG, "Mouse button %u released", button);
|
||||||
if (button == 272) {
|
if (button == M_LEFT_CLICK) {
|
||||||
m1_held = false;
|
pointer_state.l_held = false;
|
||||||
dragging = false;
|
pointer_state.floating.drag = false;
|
||||||
}
|
}
|
||||||
if (button == 273) {
|
if (button == M_RIGHT_CLICK) {
|
||||||
m2_held = false;
|
pointer_state.r_held = false;
|
||||||
resizing = false;
|
pointer_state.floating.resize = false;
|
||||||
lock_top = lock_bottom = lock_left = lock_right = false;
|
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
68
sway/input_state.c
Normal file
68
sway/input_state.c
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "input_state.h"
|
||||||
|
|
||||||
|
#define KEY_STATE_MAX_LENGTH 64
|
||||||
|
|
||||||
|
static keycode key_state_array[KEY_STATE_MAX_LENGTH];
|
||||||
|
|
||||||
|
static uint8_t find_key(keycode key) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
|
||||||
|
if (key_state_array[i] == key) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_key(keycode key) {
|
||||||
|
return find_key(key) < KEY_STATE_MAX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void press_key(keycode key) {
|
||||||
|
// Check if key exists
|
||||||
|
if (!check_key(key)) {
|
||||||
|
// Check that we dont exceed buffer length
|
||||||
|
int insert = find_key(0);
|
||||||
|
if (insert < KEY_STATE_MAX_LENGTH) {
|
||||||
|
key_state_array[insert] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_key(keycode key) {
|
||||||
|
uint8_t index = find_key(key);
|
||||||
|
if (index < KEY_STATE_MAX_LENGTH) {
|
||||||
|
// shift it over and remove key
|
||||||
|
key_state_array[index] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}};
|
||||||
|
|
||||||
|
static struct wlc_geometry saved_floating;
|
||||||
|
|
||||||
|
void start_floating(swayc_t *view) {
|
||||||
|
if (view->is_floating) {
|
||||||
|
saved_floating.origin.x = view->x;
|
||||||
|
saved_floating.origin.y = view->y;
|
||||||
|
saved_floating.size.w = view->width;
|
||||||
|
saved_floating.size.h = view->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_floating(swayc_t *view) {
|
||||||
|
if (view->is_floating) {
|
||||||
|
view->x = saved_floating.origin.x;
|
||||||
|
view->y = saved_floating.origin.y;
|
||||||
|
view->width = saved_floating.size.w;
|
||||||
|
view->height = saved_floating.size.h;
|
||||||
|
arrange_windows(view->parent, -1, -1);
|
||||||
|
}
|
||||||
|
pointer_state.floating = (struct pointer_floating){0,0};
|
||||||
|
pointer_state.lock = (struct pointer_lock){0,0,0,0};
|
||||||
|
}
|
||||||
|
|
||||||
229
sway/ipc.c
Normal file
229
sway/ipc.c
Normal file
|
|
@ -0,0 +1,229 @@
|
||||||
|
// See https://i3wm.org/docs/ipc.html for protocol information
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <wlc/wlc.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stropts.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
|
static int ipc_socket = -1;
|
||||||
|
static struct wlc_event_source *ipc_event_source = NULL;
|
||||||
|
static struct sockaddr_un ipc_sockaddr = {
|
||||||
|
.sun_family = AF_UNIX,
|
||||||
|
.sun_path = "/tmp/sway-ipc.sock"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
|
||||||
|
|
||||||
|
struct ipc_client {
|
||||||
|
struct wlc_event_source *event_source;
|
||||||
|
int fd;
|
||||||
|
uint32_t payload_length;
|
||||||
|
enum ipc_command_type current_command;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ipc_handle_connection(int fd, uint32_t mask, void *data);
|
||||||
|
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
|
||||||
|
void ipc_client_disconnect(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);
|
||||||
|
|
||||||
|
void ipc_init(void) {
|
||||||
|
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||||
|
if (ipc_socket == -1) {
|
||||||
|
sway_abort("Unable to create IPC socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("SWAYSOCK") != NULL) {
|
||||||
|
strncpy(ipc_sockaddr.sun_path, getenv("SWAYSOCK"), sizeof(ipc_sockaddr.sun_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(ipc_sockaddr.sun_path);
|
||||||
|
if (bind(ipc_socket, (struct sockaddr *)&ipc_sockaddr, sizeof(ipc_sockaddr)) == -1) {
|
||||||
|
sway_abort("Unable to bind IPC socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(ipc_socket, 3) == -1) {
|
||||||
|
sway_abort("Unable to listen on IPC socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set i3 IPC socket path so that i3-msg works out of the box
|
||||||
|
setenv("I3SOCK", ipc_sockaddr.sun_path, 1);
|
||||||
|
|
||||||
|
ipc_event_source = wlc_event_loop_add_fd(ipc_socket, WLC_EVENT_READABLE, ipc_handle_connection, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_terminate(void) {
|
||||||
|
if (ipc_event_source) {
|
||||||
|
wlc_event_source_remove(ipc_event_source);
|
||||||
|
}
|
||||||
|
close(ipc_socket);
|
||||||
|
unlink(ipc_sockaddr.sun_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
||||||
|
(void) fd; (void) data;
|
||||||
|
sway_log(L_DEBUG, "Event on IPC listening socket");
|
||||||
|
assert(mask == WLC_EVENT_READABLE);
|
||||||
|
|
||||||
|
int client_fd = accept(ipc_socket, NULL, NULL);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to accept IPC client connection");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
if ((flags=fcntl(client_fd, F_GETFD)) == -1 || fcntl(client_fd, F_SETFD, flags|FD_CLOEXEC) == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to set CLOEXEC on IPC client socket");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipc_client* client = malloc(sizeof(struct ipc_client));
|
||||||
|
client->payload_length = 0;
|
||||||
|
client->fd = client_fd;
|
||||||
|
client->event_source = wlc_event_loop_add_fd(client_fd, WLC_EVENT_READABLE, ipc_client_handle_readable, client);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int ipc_header_size = sizeof(ipc_magic)+8;
|
||||||
|
|
||||||
|
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
|
||||||
|
struct ipc_client *client = data;
|
||||||
|
sway_log(L_DEBUG, "Event on IPC client socket %d", client_fd);
|
||||||
|
|
||||||
|
if (mask & WLC_EVENT_ERROR) {
|
||||||
|
sway_log(L_INFO, "IPC Client socket error, removing client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & WLC_EVENT_HANGUP) {
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_available;
|
||||||
|
ioctl(client_fd, FIONREAD, &read_available);
|
||||||
|
|
||||||
|
// Wait for the rest of the command payload in case the header has already been read
|
||||||
|
if (client->payload_length > 0) {
|
||||||
|
if (read_available >= client->payload_length) {
|
||||||
|
ipc_client_handle_command(client);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sway_log(L_DEBUG, "Too little data to read payload on IPC Client socket, waiting for more (%d < %d)", read_available, client->payload_length);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_available < ipc_header_size) {
|
||||||
|
sway_log(L_DEBUG, "Too little data to read header on IPC Client socket, waiting for more (%d < %d)", read_available, ipc_header_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[ipc_header_size];
|
||||||
|
ssize_t received = recv(client_fd, buf, ipc_header_size, 0);
|
||||||
|
if (received == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to receive header from IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(buf, ipc_magic, sizeof(ipc_magic)) != 0) {
|
||||||
|
sway_log(L_DEBUG, "IPC header check failed");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->payload_length = *(uint32_t *)&buf[sizeof(ipc_magic)];
|
||||||
|
client->current_command = (enum ipc_command_type) *(uint32_t *)&buf[sizeof(ipc_magic)+4];
|
||||||
|
|
||||||
|
if (read_available - received >= client->payload_length) {
|
||||||
|
ipc_client_handle_command(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_client_disconnect(struct ipc_client *client)
|
||||||
|
{
|
||||||
|
if (!sway_assert(client != NULL, "client != NULL")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sway_log(L_INFO, "IPC Client %d disconnected", client->fd);
|
||||||
|
wlc_event_source_remove(client->event_source);
|
||||||
|
close(client->fd);
|
||||||
|
free(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
|
if (!sway_assert(client != NULL, "client != NULL")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[client->payload_length + 1];
|
||||||
|
if (client->payload_length > 0)
|
||||||
|
{
|
||||||
|
ssize_t received = recv(client->fd, buf, client->payload_length, 0);
|
||||||
|
if (received == -1)
|
||||||
|
{
|
||||||
|
sway_log_errno(L_INFO, "Unable to receive payload from IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (client->current_command) {
|
||||||
|
case IPC_COMMAND:
|
||||||
|
{
|
||||||
|
buf[client->payload_length] = '\0';
|
||||||
|
bool success = handle_command(config, buf);
|
||||||
|
char reply[64];
|
||||||
|
int length = snprintf(reply, sizeof(reply), "{\"success\":%s}", success ? "true" : "false");
|
||||||
|
ipc_send_reply(client, reply, (uint32_t) length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->payload_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length) {
|
||||||
|
assert(payload);
|
||||||
|
|
||||||
|
char data[ipc_header_size];
|
||||||
|
|
||||||
|
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||||
|
*(uint32_t *)&(data[sizeof(ipc_magic)]) = payload_length;
|
||||||
|
*(uint32_t *)&(data[sizeof(ipc_magic)+4]) = client->current_command;
|
||||||
|
|
||||||
|
if (write(client->fd, data, ipc_header_size) == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to send header to IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(client->fd, payload, payload_length) == -1) {
|
||||||
|
sway_log_errno(L_INFO, "Unable to send payload to IPC client");
|
||||||
|
ipc_client_disconnect(client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
141
sway/layout.c
141
sway/layout.c
|
|
@ -33,8 +33,9 @@ void add_child(swayc_t *parent, swayc_t *child) {
|
||||||
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;
|
||||||
|
// set focus for this container
|
||||||
if (parent->children->length == 1) {
|
if (parent->children->length == 1) {
|
||||||
parent->focused = child;
|
set_focused_container_for(parent, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +46,7 @@ void add_floating(swayc_t *ws, swayc_t *child) {
|
||||||
child->parent = ws;
|
child->parent = ws;
|
||||||
child->is_floating = true;
|
child->is_floating = true;
|
||||||
if (!ws->focused) {
|
if (!ws->focused) {
|
||||||
ws->focused = child;
|
set_focused_container_for(ws, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +71,7 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
|
||||||
new_child->parent = child->parent;
|
new_child->parent = child->parent;
|
||||||
|
|
||||||
if (child->parent->focused == child) {
|
if (child->parent->focused == child) {
|
||||||
child->parent->focused = new_child;
|
set_focused_container_for(child->parent, new_child);
|
||||||
}
|
}
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
return parent;
|
return parent;
|
||||||
|
|
@ -96,7 +97,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]);
|
set_focused_container_for(parent, parent->children->items[i?i-1:0]);
|
||||||
|
|
@ -151,12 +152,12 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
{
|
{
|
||||||
struct wlc_geometry geometry = {
|
struct wlc_geometry geometry = {
|
||||||
.origin = {
|
.origin = {
|
||||||
.x = container->x + container->gaps,
|
.x = container->x + container->gaps / 2,
|
||||||
.y = container->y + container->gaps
|
.y = container->y + container->gaps / 2
|
||||||
},
|
},
|
||||||
.size = {
|
.size = {
|
||||||
.w = width - container->gaps * 2,
|
.w = width - container->gaps,
|
||||||
.h = height - container->gaps * 2
|
.h = height - container->gaps
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
|
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
|
||||||
|
|
@ -185,40 +186,62 @@ void arrange_windows(swayc_t *container, int width, int height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double total_weight = 0;
|
x = y = 0;
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
double scale = 0;
|
||||||
swayc_t *child = container->children->items[i];
|
|
||||||
total_weight += child->weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (container->layout) {
|
switch (container->layout) {
|
||||||
case L_HORIZ:
|
case L_HORIZ:
|
||||||
default:
|
default:
|
||||||
sway_log(L_DEBUG, "Arranging %p horizontally", container);
|
// Calculate total width
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
int *old_width = &((swayc_t *)container->children->items[i])->width;
|
||||||
double percent = child->weight / total_weight;
|
if (*old_width <= 0) {
|
||||||
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will receive %.2f of %d)", child, child->type, percent, width);
|
if (container->children->length > 1) {
|
||||||
child->x = x + container->x;
|
*old_width = width / (container->children->length - 1);
|
||||||
child->y = y + container->y;
|
} else {
|
||||||
int w = width * percent;
|
*old_width = width;
|
||||||
int h = height;
|
}
|
||||||
arrange_windows(child, w, h);
|
}
|
||||||
x += w;
|
scale += *old_width;
|
||||||
|
}
|
||||||
|
// Resize windows
|
||||||
|
if (scale > 0.1) {
|
||||||
|
scale = width / scale;
|
||||||
|
sway_log(L_DEBUG, "Arranging %p horizontally", container);
|
||||||
|
for (i = 0; i < container->children->length; ++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);
|
||||||
|
child->x = x + container->x;
|
||||||
|
child->y = y + container->y;
|
||||||
|
arrange_windows(child, child->width * scale, height);
|
||||||
|
x += child->width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case L_VERT:
|
case L_VERT:
|
||||||
sway_log(L_DEBUG, "Arranging %p vertically", container);
|
// Calculate total height
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
int *old_height = &((swayc_t *)container->children->items[i])->height;
|
||||||
double percent = child->weight / total_weight;
|
if (*old_height <= 0) {
|
||||||
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will receive %.2f of %d)", child, child->type, percent, width);
|
if (container->children->length > 1) {
|
||||||
child->x = x + container->x;
|
*old_height = height / (container->children->length - 1);
|
||||||
child->y = y + container->y;
|
} else {
|
||||||
int w = width;
|
*old_height = height;
|
||||||
int h = height * percent;
|
}
|
||||||
arrange_windows(child, w, h);
|
}
|
||||||
y += h;
|
scale += *old_height;
|
||||||
|
}
|
||||||
|
// Resize
|
||||||
|
if (scale > 0.1) {
|
||||||
|
scale = height / scale;
|
||||||
|
sway_log(L_DEBUG, "Arranging %p vertically", container);
|
||||||
|
for (i = 0; i < container->children->length; ++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);
|
||||||
|
child->x = x + container->x;
|
||||||
|
child->y = y + container->y;
|
||||||
|
arrange_windows(child, width, child->height * scale);
|
||||||
|
y += child->height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -297,3 +320,53 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) {
|
||||||
|
swayc_t *parent = container->parent;
|
||||||
|
|
||||||
|
if (dir == MOVE_PARENT) {
|
||||||
|
if (parent->type == C_OUTPUT) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
// Test if we can even make a difference here
|
||||||
|
bool can_move = false;
|
||||||
|
int diff = 0;
|
||||||
|
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
||||||
|
if (parent->layout == L_HORIZ || parent->type == C_ROOT) {
|
||||||
|
can_move = true;
|
||||||
|
diff = dir == MOVE_LEFT ? -1 : 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (parent->layout == L_VERT) {
|
||||||
|
can_move = true;
|
||||||
|
diff = dir == MOVE_UP ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (can_move) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < parent->children->length; ++i) {
|
||||||
|
swayc_t *child = parent->children->items[i];
|
||||||
|
if (child == container) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int desired = i + diff;
|
||||||
|
if (desired < 0 || desired >= parent->children->length) {
|
||||||
|
can_move = false;
|
||||||
|
} else {
|
||||||
|
return parent->children->items[desired];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!can_move) {
|
||||||
|
container = parent;
|
||||||
|
parent = parent->parent;
|
||||||
|
if (!parent) {
|
||||||
|
// Nothing we can do
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
46
sway/log.c
46
sway/log.c
|
|
@ -1,10 +1,13 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "sway.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int colored = 1;
|
int colored = 1;
|
||||||
int v = 0;
|
int v = 0;
|
||||||
|
|
@ -19,10 +22,10 @@ static const char *verbosity_colors[] = {
|
||||||
void init_log(int verbosity) {
|
void init_log(int 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, flag;
|
int i;
|
||||||
int fd[] = { STDOUT_FILENO, STDIN_FILENO, STDERR_FILENO };
|
int fd[] = { STDOUT_FILENO, STDIN_FILENO, STDERR_FILENO };
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
flag = fcntl(fd[i], F_GETFD);
|
int flag = fcntl(fd[i], F_GETFD);
|
||||||
if (flag != -1) {
|
if (flag != -1) {
|
||||||
fcntl(fd[i], F_SETFD, flag | FD_CLOEXEC);
|
fcntl(fd[i], F_SETFD, flag | FD_CLOEXEC);
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +43,7 @@ void sway_abort(const char *format, ...) {
|
||||||
vfprintf(stderr, format, args);
|
vfprintf(stderr, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
exit(1);
|
sway_terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_log(int verbosity, const char* format, ...) {
|
void sway_log(int verbosity, const char* format, ...) {
|
||||||
|
|
@ -66,6 +69,34 @@ void sway_log(int verbosity, const char* format, ...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sway_log_errno(int verbosity, char* format, ...) {
|
||||||
|
if (verbosity <= v) {
|
||||||
|
int c = verbosity;
|
||||||
|
if (c > sizeof(verbosity_colors) / sizeof(char *)) {
|
||||||
|
c = sizeof(verbosity_colors) / sizeof(char *) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colored) {
|
||||||
|
fprintf(stderr, verbosity_colors[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
fprintf(stderr, ": ");
|
||||||
|
char error[256];
|
||||||
|
strerror_r(errno, error, sizeof(error));
|
||||||
|
fprintf(stderr, error);
|
||||||
|
|
||||||
|
if (colored) {
|
||||||
|
fprintf(stderr, "\x1B[0m");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool sway_assert(bool condition, const char* format, ...) {
|
bool sway_assert(bool condition, const char* format, ...) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -88,10 +119,10 @@ 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->is_focused ? 'F' : // Focused
|
||||||
c == active_workspace ? 'W' : //active workspace
|
c == 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);
|
||||||
fprintf(stderr,"(p:%p)",c->parent);
|
fprintf(stderr,"(p:%p)",c->parent);
|
||||||
fprintf(stderr,"(f:%p)",c->focused);
|
fprintf(stderr,"(f:%p)",c->focused);
|
||||||
|
|
@ -114,7 +145,6 @@ static void container_log(const swayc_t *c) {
|
||||||
fprintf(stderr, "w:%d|h:%d|", c->width, c->height);
|
fprintf(stderr, "w:%d|h:%d|", c->width, c->height);
|
||||||
fprintf(stderr, "x:%d|y:%d|", c->x, c->y);
|
fprintf(stderr, "x:%d|y:%d|", c->x, c->y);
|
||||||
fprintf(stderr, "vis:%c|", c->visible?'t':'f');
|
fprintf(stderr, "vis:%c|", c->visible?'t':'f');
|
||||||
fprintf(stderr, "wgt:%d|", c->weight);
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
100
sway/main.c
100
sway/main.c
|
|
@ -4,31 +4,121 @@
|
||||||
#include <wlc/wlc.h>
|
#include <wlc/wlc.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "sway.h"
|
||||||
|
|
||||||
|
static bool terminate_request = false;
|
||||||
|
|
||||||
|
void sway_terminate(void) {
|
||||||
|
terminate_request = true;
|
||||||
|
wlc_terminate();
|
||||||
|
}
|
||||||
|
|
||||||
static void sigchld_handle(int signal);
|
static void sigchld_handle(int signal);
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
static int verbose = 0, debug = 0, validate = 0;
|
||||||
|
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"config", required_argument, NULL, 'c'},
|
||||||
|
{"validate", no_argument, &validate, 1},
|
||||||
|
{"debug", no_argument, &debug, 1},
|
||||||
|
{"version", no_argument, NULL, 'v'},
|
||||||
|
{"verbose", no_argument, &verbose, 1},
|
||||||
|
{"get-socketpath", no_argument, NULL, 'p'},
|
||||||
|
};
|
||||||
|
|
||||||
/* Signal handling */
|
/* Signal handling */
|
||||||
signal(SIGCHLD, sigchld_handle);
|
signal(SIGCHLD, sigchld_handle);
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_log(L_DEBUG); // TODO: Control this with command line arg
|
char *config_path = NULL;
|
||||||
init_layout();
|
|
||||||
|
|
||||||
if (!load_config()) {
|
int c;
|
||||||
sway_log(L_ERROR, "Error(s) loading config!");
|
while (1) {
|
||||||
|
int option_index = 0;
|
||||||
|
c = getopt_long(argc, argv, "CdvVpc:", long_options, &option_index);
|
||||||
|
if (c == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case 0: // Flag
|
||||||
|
break;
|
||||||
|
case 'c': // config
|
||||||
|
config_path = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'C': // validate
|
||||||
|
validate = 1;
|
||||||
|
break;
|
||||||
|
case 'd': // debug
|
||||||
|
debug = 1;
|
||||||
|
break;
|
||||||
|
case 'v': // version
|
||||||
|
// todo
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case 'V': // verbose
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'p': // --get-socketpath
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlc_run();
|
if (debug) {
|
||||||
|
init_log(L_DEBUG);
|
||||||
|
wlc_set_log_file(stderr);
|
||||||
|
fclose(devnull);
|
||||||
|
devnull = NULL;
|
||||||
|
} else if (verbose || validate) {
|
||||||
|
init_log(L_INFO);
|
||||||
|
} else {
|
||||||
|
init_log(L_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validate) {
|
||||||
|
bool valid = load_config(config_path);
|
||||||
|
return valid ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_layout();
|
||||||
|
|
||||||
|
if (!load_config(config_path)) {
|
||||||
|
sway_log(L_ERROR, "Error(s) loading config!");
|
||||||
|
}
|
||||||
|
if (config_path) {
|
||||||
|
free(config_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc_init();
|
||||||
|
|
||||||
|
if (!terminate_request) {
|
||||||
|
wlc_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devnull) {
|
||||||
|
fclose(devnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc_terminate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,22 @@ char *read_line(FILE *file) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (length == size) {
|
if (length == size) {
|
||||||
string = realloc(string, size *= 2);
|
char *new_string = realloc(string, size *= 2);
|
||||||
if (!string) {
|
if (!new_string) {
|
||||||
|
free(string);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
string = new_string;
|
||||||
}
|
}
|
||||||
string[length++] = c;
|
string[length++] = c;
|
||||||
}
|
}
|
||||||
if (length + 1 == size) {
|
if (length + 1 == size) {
|
||||||
string = realloc(string, length + 1);
|
char *new_string = realloc(string, length + 1);
|
||||||
if (!string) {
|
if (!new_string) {
|
||||||
|
free(string);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
string = new_string;
|
||||||
}
|
}
|
||||||
string[length] = '\0';
|
string[length] = '\0';
|
||||||
return string;
|
return string;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ char *workspace_next_name(void) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//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_find_by_name(target)) {
|
||||||
list_free(args);
|
list_free(args);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -183,7 +183,6 @@ void workspace_switch(swayc_t *workspace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
|
sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
|
||||||
active_workspace = workspace;
|
|
||||||
set_focused_container(get_focused_view(workspace));
|
set_focused_container(get_focused_view(workspace));
|
||||||
arrange_windows(workspace, -1, -1);
|
arrange_windows(workspace, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue