Merge branch 'master' into pid-workspaces
This commit is contained in:
commit
f4b882475e
|
@ -107,7 +107,7 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
|
||||
int desired_output = atoi(argv[1]);
|
||||
sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length);
|
||||
sway_log(WLR_INFO, "Using output %d of %d", desired_output, registry->outputs->length);
|
||||
int i;
|
||||
struct output_state *output = registry->outputs->items[desired_output];
|
||||
struct window *window = window_setup(registry, 100, 100, false);
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
Use `sway_log(importance, fmt, ...)` to log. The following importances are
|
||||
available:
|
||||
|
||||
* `L_DEBUG`: Debug messages, only shows with `sway -d`
|
||||
* `L_INFO`: Informational messages
|
||||
* `L_ERROR`: Error messages
|
||||
* `WLR_DEBUG`: Debug messages, only shows with `sway -d`
|
||||
* `WLR_INFO`: Informational messages
|
||||
* `WLR_ERROR`: Error messages
|
||||
|
||||
`sway_log` is a macro that calls `_sway_log` with the current filename and line
|
||||
number, which are written into the log with your message.
|
||||
|
|
|
@ -18,7 +18,7 @@ enum background_mode parse_background_mode(const char *mode) {
|
|||
} else if (strcmp(mode, "solid_color") == 0) {
|
||||
return BACKGROUND_MODE_SOLID_COLOR;
|
||||
}
|
||||
wlr_log(L_ERROR, "Unsupported background mode: %s", mode);
|
||||
wlr_log(WLR_ERROR, "Unsupported background mode: %s", mode);
|
||||
return BACKGROUND_MODE_INVALID;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ cairo_surface_t *load_background_image(const char *path) {
|
|||
GError *err = NULL;
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
|
||||
if (!pixbuf) {
|
||||
wlr_log(L_ERROR, "Failed to load background image (%s).",
|
||||
wlr_log(WLR_ERROR, "Failed to load background image (%s).",
|
||||
err->message);
|
||||
return false;
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ cairo_surface_t *load_background_image(const char *path) {
|
|||
image = cairo_image_surface_create_from_png(path);
|
||||
#endif //HAVE_GDK_PIXBUF
|
||||
if (!image) {
|
||||
wlr_log(L_ERROR, "Failed to read background image.");
|
||||
wlr_log(WLR_ERROR, "Failed to read background image.");
|
||||
return NULL;
|
||||
}
|
||||
if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
|
||||
wlr_log(L_ERROR, "Failed to read background image: %s."
|
||||
wlr_log(WLR_ERROR, "Failed to read background image: %s."
|
||||
#ifndef HAVE_GDK_PIXBUF
|
||||
"\nSway was compiled without gdk_pixbuf support, so only"
|
||||
"\nPNG images can be loaded. This is the likely cause."
|
||||
|
|
|
@ -97,7 +97,7 @@ struct ipc_response *ipc_recv_response(int socketfd) {
|
|||
error_2:
|
||||
free(response);
|
||||
error_1:
|
||||
wlr_log(L_ERROR, "Unable to allocate memory for IPC response");
|
||||
wlr_log(WLR_ERROR, "Unable to allocate memory for IPC response");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
|
||||
list_t *create_list(void) {
|
||||
list_t *list = malloc(sizeof(list_t));
|
||||
|
@ -82,6 +83,20 @@ void list_swap(list_t *list, int src, int dest) {
|
|||
list->items[dest] = tmp;
|
||||
}
|
||||
|
||||
void list_move_to_end(list_t *list, void *item) {
|
||||
int i;
|
||||
for (i = 0; i < list->length; ++i) {
|
||||
if (list->items[i] == item) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sway_assert(i < list->length, "Item not found in list")) {
|
||||
return;
|
||||
}
|
||||
list_del(list, i);
|
||||
list_add(list, item);
|
||||
}
|
||||
|
||||
static void list_rotate(list_t *list, int from, int to) {
|
||||
void *tmp = list->items[to];
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ void sway_terminate(int code);
|
|||
void _sway_abort(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
_wlr_vlog(L_ERROR, format, args);
|
||||
_wlr_vlog(WLR_ERROR, format, args);
|
||||
va_end(args);
|
||||
sway_terminate(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ bool _sway_assert(bool condition, const char *format, ...) {
|
|||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
_wlr_vlog(L_ERROR, format, args);
|
||||
_wlr_vlog(WLR_ERROR, format, args);
|
||||
va_end(args);
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -81,7 +81,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
|
|||
pango_layout_set_markup(layout, buf, -1);
|
||||
free(buf);
|
||||
} else {
|
||||
wlr_log(L_ERROR, "pango_parse_markup '%s' -> error %s", text,
|
||||
wlr_log(WLR_ERROR, "pango_parse_markup '%s' -> error %s", text,
|
||||
error->message);
|
||||
g_error_free(error);
|
||||
markup = false; // fallback to plain text
|
||||
|
|
|
@ -9,7 +9,7 @@ char *read_line(FILE *file) {
|
|||
char *string = malloc(size);
|
||||
char lastChar = '\0';
|
||||
if (!string) {
|
||||
wlr_log(L_ERROR, "Unable to allocate memory for read_line");
|
||||
wlr_log(WLR_ERROR, "Unable to allocate memory for read_line");
|
||||
return NULL;
|
||||
}
|
||||
while (1) {
|
||||
|
@ -30,7 +30,7 @@ char *read_line(FILE *file) {
|
|||
char *new_string = realloc(string, size *= 2);
|
||||
if (!new_string) {
|
||||
free(string);
|
||||
wlr_log(L_ERROR, "Unable to allocate memory for read_line");
|
||||
wlr_log(WLR_ERROR, "Unable to allocate memory for read_line");
|
||||
return NULL;
|
||||
}
|
||||
string = new_string;
|
||||
|
|
|
@ -92,7 +92,7 @@ static const struct {
|
|||
|
||||
int utf8_size(const char *s) {
|
||||
uint8_t c = (uint8_t)*s;
|
||||
for (size_t i = 0; i < sizeof(sizes) / 2; ++i) {
|
||||
for (size_t i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) {
|
||||
if ((c & sizes[i].mask) == sizes[i].result) {
|
||||
return sizes[i].octets;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ pid_t get_parent_pid(pid_t child) {
|
|||
token = strtok(NULL, sep); // parent pid
|
||||
parent = strtol(token, NULL, 10);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
fclose(stat);
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ uint32_t parse_color(const char *color) {
|
|||
|
||||
int len = strlen(color);
|
||||
if (len != 6 && len != 8) {
|
||||
wlr_log(L_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
|
||||
wlr_log(WLR_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
uint32_t res = (uint32_t)strtoul(color, NULL, 16);
|
||||
|
|
|
@ -22,7 +22,6 @@ types=(
|
|||
'get_marks'
|
||||
'get_bar_config'
|
||||
'get_version'
|
||||
'get_clipboard'
|
||||
)
|
||||
|
||||
_arguments -s \
|
||||
|
|
|
@ -13,11 +13,12 @@ enum ipc_command_type {
|
|||
IPC_GET_MARKS = 5,
|
||||
IPC_GET_BAR_CONFIG = 6,
|
||||
IPC_GET_VERSION = 7,
|
||||
IPC_GET_BINDING_MODES = 8,
|
||||
IPC_GET_CONFIG = 9,
|
||||
|
||||
// sway-specific command types
|
||||
IPC_GET_INPUTS = 100,
|
||||
IPC_GET_CLIPBOARD = 101,
|
||||
IPC_GET_SEATS = 102,
|
||||
IPC_GET_SEATS = 101,
|
||||
|
||||
// Events sent from sway to clients. Events have the highest bits set.
|
||||
IPC_EVENT_WORKSPACE = ((1<<31) | 0),
|
||||
|
|
|
@ -24,4 +24,6 @@ int list_seq_find(list_t *list, int compare(const void *item, const void *cmp_to
|
|||
void list_stable_sort(list_t *list, int compare(const void *a, const void *b));
|
||||
// swap two elements in a list
|
||||
void list_swap(list_t *list, int src, int dest);
|
||||
// move item to end of list
|
||||
void list_move_to_end(list_t *list, void *item);
|
||||
#endif
|
||||
|
|
|
@ -3,13 +3,19 @@
|
|||
#include <stdbool.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
|
||||
#else
|
||||
#define ATTRIB_PRINTF(start, end)
|
||||
#endif
|
||||
|
||||
void _sway_abort(const char *filename, ...) ATTRIB_PRINTF(1, 2);
|
||||
#define sway_abort(FMT, ...) \
|
||||
_sway_abort("[%s:%d] " FMT, wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
|
||||
_sway_abort("[%s:%d] " FMT, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
|
||||
|
||||
bool _sway_assert(bool condition, const char* format, ...) ATTRIB_PRINTF(2, 3);
|
||||
#define sway_assert(COND, FMT, ...) \
|
||||
_sway_assert(COND, "[%s:%d] %s:" FMT, wlr_strip_path(__FILE__), __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
|
||||
_sway_assert(COND, "[%s:%d] %s:" FMT, _wlr_strip_path(__FILE__), __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
|
||||
|
||||
void error_handler(int sig);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ void free_cmd_results(struct cmd_results *results);
|
|||
*
|
||||
* Free the JSON string later on.
|
||||
*/
|
||||
const char *cmd_results_to_json(struct cmd_results *results);
|
||||
char *cmd_results_to_json(struct cmd_results *results);
|
||||
|
||||
struct cmd_results *add_color(const char *name,
|
||||
char *buffer, const char *color);
|
||||
|
@ -95,7 +95,6 @@ sway_cmd cmd_client_unfocused;
|
|||
sway_cmd cmd_client_urgent;
|
||||
sway_cmd cmd_client_placeholder;
|
||||
sway_cmd cmd_client_background;
|
||||
sway_cmd cmd_clipboard;
|
||||
sway_cmd cmd_commands;
|
||||
sway_cmd cmd_debuglog;
|
||||
sway_cmd cmd_default_border;
|
||||
|
@ -107,13 +106,14 @@ sway_cmd cmd_exit;
|
|||
sway_cmd cmd_floating;
|
||||
sway_cmd cmd_floating_maximum_size;
|
||||
sway_cmd cmd_floating_minimum_size;
|
||||
sway_cmd cmd_floating_mod;
|
||||
sway_cmd cmd_floating_modifier;
|
||||
sway_cmd cmd_floating_scroll;
|
||||
sway_cmd cmd_focus;
|
||||
sway_cmd cmd_focus_follows_mouse;
|
||||
sway_cmd cmd_focus_wrapping;
|
||||
sway_cmd cmd_font;
|
||||
sway_cmd cmd_for_window;
|
||||
sway_cmd cmd_force_display_urgency_hint;
|
||||
sway_cmd cmd_force_focus_wrapping;
|
||||
sway_cmd cmd_fullscreen;
|
||||
sway_cmd cmd_gaps;
|
||||
|
@ -153,6 +153,7 @@ sway_cmd cmd_swaybg_command;
|
|||
sway_cmd cmd_swap;
|
||||
sway_cmd cmd_title_format;
|
||||
sway_cmd cmd_unmark;
|
||||
sway_cmd cmd_urgent;
|
||||
sway_cmd cmd_workspace;
|
||||
sway_cmd cmd_ws_auto_back_and_forth;
|
||||
sway_cmd cmd_workspace_layout;
|
||||
|
@ -208,8 +209,10 @@ sway_cmd input_cmd_natural_scroll;
|
|||
sway_cmd input_cmd_pointer_accel;
|
||||
sway_cmd input_cmd_repeat_delay;
|
||||
sway_cmd input_cmd_repeat_rate;
|
||||
sway_cmd input_cmd_scroll_button;
|
||||
sway_cmd input_cmd_scroll_method;
|
||||
sway_cmd input_cmd_tap;
|
||||
sway_cmd input_cmd_tap_button_map;
|
||||
sway_cmd input_cmd_xkb_layout;
|
||||
sway_cmd input_cmd_xkb_model;
|
||||
sway_cmd input_cmd_xkb_options;
|
||||
|
|
|
@ -49,6 +49,7 @@ struct sway_mode {
|
|||
char *name;
|
||||
list_t *keysym_bindings;
|
||||
list_t *keycode_bindings;
|
||||
bool pango;
|
||||
};
|
||||
|
||||
struct input_config_mapped_from_region {
|
||||
|
@ -73,9 +74,11 @@ struct input_config {
|
|||
float pointer_accel;
|
||||
int repeat_delay;
|
||||
int repeat_rate;
|
||||
int scroll_button;
|
||||
int scroll_method;
|
||||
int send_events;
|
||||
int tap;
|
||||
int tap_button_map;
|
||||
|
||||
char *xkb_layout;
|
||||
char *xkb_model;
|
||||
|
@ -263,11 +266,10 @@ enum ipc_feature {
|
|||
IPC_FEATURE_EVENT_WINDOW = 2048,
|
||||
IPC_FEATURE_EVENT_BINDING = 4096,
|
||||
IPC_FEATURE_EVENT_INPUT = 8192,
|
||||
IPC_FEATURE_GET_CLIPBOARD = 16384,
|
||||
IPC_FEATURE_GET_SEATS = 32768,
|
||||
IPC_FEATURE_GET_SEATS = 16384,
|
||||
|
||||
IPC_FEATURE_ALL_COMMANDS =
|
||||
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384 | 32768,
|
||||
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384,
|
||||
IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
|
||||
|
||||
IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
|
||||
|
@ -314,6 +316,7 @@ struct sway_config {
|
|||
char *font;
|
||||
size_t font_height;
|
||||
bool pango_markup;
|
||||
size_t urgent_timeout;
|
||||
|
||||
// Flags
|
||||
bool focus_follows_mouse;
|
||||
|
@ -332,6 +335,7 @@ struct sway_config {
|
|||
int gaps_outer;
|
||||
|
||||
list_t *config_chain;
|
||||
const char *current_config_path;
|
||||
const char *current_config;
|
||||
|
||||
enum sway_container_border border;
|
||||
|
@ -447,8 +451,14 @@ void merge_output_config(struct output_config *dst, struct output_config *src);
|
|||
void apply_output_config(struct output_config *oc,
|
||||
struct sway_container *output);
|
||||
|
||||
struct output_config *store_output_config(struct output_config *oc);
|
||||
|
||||
void apply_output_config_to_outputs(struct output_config *oc);
|
||||
|
||||
void free_output_config(struct output_config *oc);
|
||||
|
||||
void create_default_output_configs(void);
|
||||
|
||||
int workspace_output_cmp_workspace(const void *a, const void *b);
|
||||
|
||||
int sway_binding_cmp(const void *a, const void *b);
|
||||
|
@ -484,7 +494,4 @@ void config_update_font_height(bool recalculate);
|
|||
/* Global config singleton. */
|
||||
extern struct sway_config *config;
|
||||
|
||||
/* Config file currently being read */
|
||||
extern const char *current_config_path;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@ enum criteria_type {
|
|||
CT_COMMAND = 1 << 0,
|
||||
CT_ASSIGN_OUTPUT = 1 << 1,
|
||||
CT_ASSIGN_WORKSPACE = 1 << 2,
|
||||
CT_NO_FOCUS = 1 << 3,
|
||||
};
|
||||
|
||||
struct criteria {
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
#ifndef SWAY_DEBUG_H
|
||||
#define SWAY_DEBUG_H
|
||||
|
||||
// Tree
|
||||
extern bool enable_debug_tree;
|
||||
void update_debug_tree();
|
||||
|
||||
// Damage
|
||||
extern const char *damage_debug;
|
||||
|
||||
// Transactions
|
||||
extern int txn_timeout_ms;
|
||||
extern bool txn_debug;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
#include <wlr/types/wlr_surface.h>
|
||||
|
||||
struct sway_container;
|
||||
|
||||
void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly,
|
||||
bool whole);
|
||||
|
||||
void desktop_damage_whole_container(struct sway_container *con);
|
||||
|
|
28
include/sway/desktop/idle_inhibit_v1.h
Normal file
28
include/sway/desktop/idle_inhibit_v1.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
||||
#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_idle.h>
|
||||
#include "sway/server.h"
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 {
|
||||
struct wlr_idle_inhibit_manager_v1 *wlr_manager;
|
||||
struct wl_listener new_idle_inhibitor_v1;
|
||||
struct wl_list inhibitors;
|
||||
|
||||
struct wlr_idle *idle;
|
||||
};
|
||||
|
||||
struct sway_idle_inhibitor_v1 {
|
||||
struct sway_idle_inhibit_manager_v1 *manager;
|
||||
struct sway_view *view;
|
||||
|
||||
struct wl_list link;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
void idle_inhibit_v1_check_active(
|
||||
struct sway_idle_inhibit_manager_v1 *manager);
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
||||
struct wl_display *wl_display, struct wlr_idle *idle);
|
||||
#endif
|
|
@ -6,34 +6,25 @@
|
|||
/**
|
||||
* Transactions enable us to perform atomic layout updates.
|
||||
*
|
||||
* When we want to make adjustments to the layout, we create a transaction.
|
||||
* A transaction contains a list of affected containers and their new state.
|
||||
* A transaction contains a list of containers and their new state.
|
||||
* A state might contain a new size, or new border settings, or new parent/child
|
||||
* relationships.
|
||||
*
|
||||
* Calling transaction_commit() makes sway notify of all the affected clients
|
||||
* with their new sizes. We then wait for all the views to respond with their
|
||||
* new surface sizes. When all are ready, or when a timeout has passed, we apply
|
||||
* the updates all at the same time.
|
||||
* Committing a transaction makes sway notify of all the affected clients with
|
||||
* their new sizes. We then wait for all the views to respond with their new
|
||||
* surface sizes. When all are ready, or when a timeout has passed, we apply the
|
||||
* updates all at the same time.
|
||||
*
|
||||
* When we want to make adjustments to the layout, we change the pending state
|
||||
* in containers, mark them as dirty and call transaction_commit_dirty(). This
|
||||
* create and commits a transaction from the dirty containers.
|
||||
*/
|
||||
|
||||
struct sway_transaction;
|
||||
|
||||
/**
|
||||
* Create a new transaction.
|
||||
* Find all dirty containers, create and commit a transaction containing them,
|
||||
* and unmark them as dirty.
|
||||
*/
|
||||
struct sway_transaction *transaction_create(void);
|
||||
|
||||
/**
|
||||
* Add a container's pending state to the transaction.
|
||||
*/
|
||||
void transaction_add_container(struct sway_transaction *transaction,
|
||||
struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Submit a transaction to the client views for configuration.
|
||||
*/
|
||||
void transaction_commit(struct sway_transaction *transaction);
|
||||
void transaction_commit_dirty(void);
|
||||
|
||||
/**
|
||||
* Notify the transaction system that a view is ready for the new layout.
|
||||
|
|
|
@ -11,6 +11,7 @@ struct sway_cursor {
|
|||
} previous;
|
||||
struct wlr_xcursor_manager *xcursor_manager;
|
||||
|
||||
const char *image;
|
||||
struct wl_client *image_client;
|
||||
|
||||
struct wl_listener motion;
|
||||
|
@ -37,4 +38,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
|||
void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec,
|
||||
uint32_t button, enum wlr_button_state state);
|
||||
|
||||
void cursor_set_image(struct sway_cursor *cursor, const char *image,
|
||||
struct wl_client *client);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <wlr/types/wlr_layer_shell.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/util/edges.h>
|
||||
#include "sway/input/input-manager.h"
|
||||
|
||||
struct sway_seat_device {
|
||||
|
@ -52,6 +53,24 @@ struct sway_seat {
|
|||
int32_t touch_id;
|
||||
double touch_x, touch_y;
|
||||
|
||||
// Operations (drag and resize)
|
||||
enum {
|
||||
OP_NONE,
|
||||
OP_MOVE,
|
||||
OP_RESIZE,
|
||||
} operation;
|
||||
|
||||
struct sway_container *op_container;
|
||||
enum wlr_edges op_resize_edge;
|
||||
uint32_t op_button;
|
||||
bool op_resize_preserve_ratio;
|
||||
double op_ref_lx, op_ref_ly; // cursor's x/y at start of op
|
||||
double op_ref_width, op_ref_height; // container's size at start of op
|
||||
double op_ref_con_lx, op_ref_con_ly; // container's x/y at start of op
|
||||
|
||||
uint32_t last_button;
|
||||
uint32_t last_button_serial;
|
||||
|
||||
struct wl_listener focus_destroy;
|
||||
struct wl_listener new_container;
|
||||
struct wl_listener new_drag_icon;
|
||||
|
@ -83,7 +102,7 @@ void seat_set_focus_warp(struct sway_seat *seat,
|
|||
struct sway_container *container, bool warp);
|
||||
|
||||
void seat_set_focus_surface(struct sway_seat *seat,
|
||||
struct wlr_surface *surface);
|
||||
struct wlr_surface *surface, bool unfocus);
|
||||
|
||||
void seat_set_focus_layer(struct sway_seat *seat,
|
||||
struct wlr_layer_surface *layer);
|
||||
|
@ -118,17 +137,6 @@ struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
|
|||
struct sway_container *seat_get_active_child(struct sway_seat *seat,
|
||||
struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Return the immediate child of container which was most recently focused, with
|
||||
* fallback to selecting the child in the parent's `current` (rendered) children
|
||||
* list.
|
||||
*
|
||||
* This is useful for when a tabbed container and its children are destroyed but
|
||||
* still being rendered, and we have to render an appropriate child.
|
||||
*/
|
||||
struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
|
||||
struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Iterate over the focus-inactive children of the container calling the
|
||||
* function on each.
|
||||
|
@ -145,4 +153,15 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface);
|
|||
|
||||
void drag_icon_update_position(struct sway_drag_icon *icon);
|
||||
|
||||
void seat_begin_move(struct sway_seat *seat, struct sway_container *con,
|
||||
uint32_t button);
|
||||
|
||||
void seat_begin_resize(struct sway_seat *seat, struct sway_container *con,
|
||||
uint32_t button, enum wlr_edges edge);
|
||||
|
||||
void seat_end_mouse_operation(struct sway_seat *seat);
|
||||
|
||||
void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
uint32_t button, enum wlr_button_state state);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,14 +9,12 @@ struct sway_server;
|
|||
|
||||
void ipc_init(struct sway_server *server);
|
||||
|
||||
void ipc_terminate(void);
|
||||
|
||||
struct sockaddr_un *ipc_user_sockaddr(void);
|
||||
|
||||
void ipc_event_workspace(struct sway_container *old,
|
||||
struct sway_container *new, const char *change);
|
||||
void ipc_event_window(struct sway_container *window, const char *change);
|
||||
void ipc_event_barconfig_update(struct bar_config *bar);
|
||||
void ipc_event_mode(const char *mode);
|
||||
void ipc_event_mode(const char *mode, bool pango);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,16 @@ struct sway_output {
|
|||
} events;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains a surface's root geometry information. For instance, when rendering
|
||||
* a popup, this will contain the parent view's position and size.
|
||||
*/
|
||||
struct root_geometry {
|
||||
double x, y;
|
||||
int width, height;
|
||||
float rotation;
|
||||
};
|
||||
|
||||
void output_damage_whole(struct sway_output *output);
|
||||
|
||||
void output_damage_surface(struct sway_output *output, double ox, double oy,
|
||||
|
@ -54,4 +64,37 @@ void output_damage_whole_container(struct sway_output *output,
|
|||
struct sway_container *output_by_name(const char *name);
|
||||
|
||||
void output_enable(struct sway_output *output);
|
||||
|
||||
bool output_has_opaque_lockscreen(struct sway_output *output,
|
||||
struct sway_seat *seat);
|
||||
|
||||
struct sway_container *output_get_active_workspace(struct sway_output *output);
|
||||
|
||||
void output_render(struct sway_output *output, struct timespec *when,
|
||||
pixman_region32_t *damage);
|
||||
|
||||
bool output_get_surface_box(struct root_geometry *geo,
|
||||
struct sway_output *output, struct wlr_surface *surface, int sx, int sy,
|
||||
struct wlr_box *surface_box);
|
||||
|
||||
void output_surface_for_each_surface(struct wlr_surface *surface,
|
||||
double ox, double oy, struct root_geometry *geo,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
void output_view_for_each_surface(struct sway_view *view,
|
||||
struct sway_output *output, struct root_geometry *geo,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
void output_layer_for_each_surface(struct wl_list *layer_surfaces,
|
||||
struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_unmanaged_for_each_surface(struct wl_list *unmanaged,
|
||||
struct sway_output *output, struct root_geometry *geo,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
void output_drag_icons_for_each_surface(struct wl_list *drag_icons,
|
||||
struct sway_output *output, struct root_geometry *geo,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
#endif
|
||||
|
|
26
include/sway/scratchpad.h
Normal file
26
include/sway/scratchpad.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _SWAY_SCRATCHPAD_H
|
||||
#define _SWAY_SCRATCHPAD_H
|
||||
|
||||
#include "tree/container.h"
|
||||
|
||||
/**
|
||||
* Move a container to the scratchpad.
|
||||
*/
|
||||
void scratchpad_add_container(struct sway_container *con);
|
||||
|
||||
/**
|
||||
* Remove a container from the scratchpad.
|
||||
*/
|
||||
void scratchpad_remove_container(struct sway_container *con);
|
||||
|
||||
/**
|
||||
* Show or hide the next container on the scratchpad.
|
||||
*/
|
||||
void scratchpad_toggle_auto(void);
|
||||
|
||||
/**
|
||||
* Show or hide a specific container on the scratchpad.
|
||||
*/
|
||||
void scratchpad_toggle_container(struct sway_container *con);
|
||||
|
||||
#endif
|
|
@ -23,12 +23,14 @@ struct sway_server {
|
|||
|
||||
struct wlr_compositor *compositor;
|
||||
struct wlr_data_device_manager *data_device_manager;
|
||||
struct wlr_idle *idle;
|
||||
|
||||
struct sway_input_manager *input;
|
||||
|
||||
struct wl_listener new_output;
|
||||
|
||||
struct wlr_idle *idle;
|
||||
struct sway_idle_inhibit_manager_v1 *idle_inhibit_manager_v1;
|
||||
|
||||
struct wlr_layer_shell *layer_shell;
|
||||
struct wl_listener layer_shell_surface;
|
||||
|
||||
|
@ -45,10 +47,7 @@ struct sway_server {
|
|||
bool debug_txn_timings;
|
||||
|
||||
list_t *transactions;
|
||||
|
||||
// When a view is being destroyed and is waiting for a transaction to
|
||||
// complete it will be stored here.
|
||||
list_t *destroying_containers;
|
||||
list_t *dirty_containers;
|
||||
};
|
||||
|
||||
struct sway_server server;
|
||||
|
@ -57,10 +56,12 @@ struct sway_server server;
|
|||
bool server_privileged_prepare(struct sway_server *server);
|
||||
bool server_init(struct sway_server *server);
|
||||
void server_fini(struct sway_server *server);
|
||||
bool server_start_backend(struct sway_server *server);
|
||||
void server_run(struct sway_server *server);
|
||||
|
||||
void handle_new_output(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
|
||||
void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data);
|
||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data);
|
||||
|
|
|
@ -11,26 +11,8 @@ void remove_gaps(struct sway_container *c);
|
|||
void add_gaps(struct sway_container *c);
|
||||
|
||||
/**
|
||||
* Arrange layout for all the children of the given container, and add them to
|
||||
* the given transaction.
|
||||
*
|
||||
* Use this function if you need to arrange multiple sections of the tree in one
|
||||
* transaction.
|
||||
*
|
||||
* You must set the desired state of the container before calling
|
||||
* arrange_windows, then don't change any state-tracked properties in the
|
||||
* container until you've called transaction_commit.
|
||||
* Arrange layout for all the children of the given container.
|
||||
*/
|
||||
void arrange_windows(struct sway_container *container,
|
||||
struct sway_transaction *transaction);
|
||||
|
||||
/**
|
||||
* Arrange layout for the given container and commit the transaction.
|
||||
*
|
||||
* This function is a wrapper around arrange_windows, and handles creating and
|
||||
* committing the transaction for you. Use this function if you're only doing
|
||||
* one arrange operation.
|
||||
*/
|
||||
void arrange_and_commit(struct sway_container *container);
|
||||
void arrange_windows(struct sway_container *container);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -68,6 +68,9 @@ struct sway_container_state {
|
|||
struct sway_container *parent;
|
||||
list_t *children;
|
||||
|
||||
struct sway_container *focused_inactive_child;
|
||||
bool focused;
|
||||
|
||||
// View properties
|
||||
double view_x, view_y;
|
||||
double view_width, view_height;
|
||||
|
@ -132,6 +135,11 @@ struct sway_container {
|
|||
|
||||
struct sway_container *parent;
|
||||
|
||||
// Indicates that the container is a scratchpad container.
|
||||
// Both hidden and visible scratchpad containers have scratchpad=true.
|
||||
// Hidden scratchpad containers have a NULL parent.
|
||||
bool scratchpad;
|
||||
|
||||
float alpha;
|
||||
|
||||
struct wlr_texture *title_focused;
|
||||
|
@ -144,6 +152,10 @@ struct sway_container {
|
|||
|
||||
bool destroying;
|
||||
|
||||
// If true, indicates that the container has pending state that differs from
|
||||
// the current.
|
||||
bool dirty;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
// Raised after the tree updates, but before arrange_windows
|
||||
|
@ -297,4 +309,30 @@ bool container_is_floating(struct sway_container *container);
|
|||
*/
|
||||
void container_get_box(struct sway_container *container, struct wlr_box *box);
|
||||
|
||||
/**
|
||||
* Move a floating container by the specified amount.
|
||||
*/
|
||||
void container_floating_translate(struct sway_container *con,
|
||||
double x_amount, double y_amount);
|
||||
|
||||
/**
|
||||
* Move a floating container to a new layout-local position.
|
||||
*/
|
||||
void container_floating_move_to(struct sway_container *con,
|
||||
double lx, double ly);
|
||||
|
||||
/**
|
||||
* Mark a container as dirty if it isn't already. Dirty containers will be
|
||||
* included in the next transaction then unmarked as dirty.
|
||||
*/
|
||||
void container_set_dirty(struct sway_container *container);
|
||||
|
||||
bool container_has_urgent_child(struct sway_container *container);
|
||||
|
||||
/**
|
||||
* If the container is involved in a drag or resize operation via a mouse, this
|
||||
* ends the operation.
|
||||
*/
|
||||
void container_end_mouse_operation(struct sway_container *container);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,10 +14,11 @@ enum movement_direction {
|
|||
};
|
||||
|
||||
enum resize_edge {
|
||||
RESIZE_EDGE_LEFT,
|
||||
RESIZE_EDGE_RIGHT,
|
||||
RESIZE_EDGE_TOP,
|
||||
RESIZE_EDGE_BOTTOM,
|
||||
RESIZE_EDGE_NONE = 0,
|
||||
RESIZE_EDGE_LEFT = 1,
|
||||
RESIZE_EDGE_RIGHT = 2,
|
||||
RESIZE_EDGE_TOP = 4,
|
||||
RESIZE_EDGE_BOTTOM = 8,
|
||||
};
|
||||
|
||||
struct sway_container;
|
||||
|
@ -34,6 +35,8 @@ struct sway_root {
|
|||
|
||||
struct wl_list outputs; // sway_output::link
|
||||
|
||||
list_t *scratchpad; // struct sway_container
|
||||
|
||||
struct {
|
||||
struct wl_signal new_container;
|
||||
} events;
|
||||
|
|
|
@ -26,6 +26,8 @@ enum sway_view_prop {
|
|||
};
|
||||
|
||||
struct sway_view_impl {
|
||||
void (*get_constraints)(struct sway_view *view, double *min_width,
|
||||
double *max_width, double *min_height, double *max_height);
|
||||
const char *(*get_string_prop)(struct sway_view *view,
|
||||
enum sway_view_prop prop);
|
||||
uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop);
|
||||
|
@ -35,6 +37,7 @@ struct sway_view_impl {
|
|||
void (*set_tiled)(struct sway_view *view, bool tiled);
|
||||
void (*set_fullscreen)(struct sway_view *view, bool fullscreen);
|
||||
bool (*wants_floating)(struct sway_view *view);
|
||||
bool (*has_client_side_decorations)(struct sway_view *view);
|
||||
void (*for_each_surface)(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
void (*close)(struct sway_view *view);
|
||||
|
@ -68,6 +71,11 @@ struct sway_view {
|
|||
bool border_bottom;
|
||||
bool border_left;
|
||||
bool border_right;
|
||||
bool using_csd;
|
||||
|
||||
struct timespec urgent;
|
||||
bool allow_request_urgent;
|
||||
struct wl_event_source *urgent_timer;
|
||||
|
||||
bool destroying;
|
||||
|
||||
|
@ -102,6 +110,8 @@ struct sway_xdg_shell_v6_view {
|
|||
struct wl_listener request_resize;
|
||||
struct wl_listener request_maximize;
|
||||
struct wl_listener request_fullscreen;
|
||||
struct wl_listener set_title;
|
||||
struct wl_listener set_app_id;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
|
@ -116,6 +126,8 @@ struct sway_xdg_shell_view {
|
|||
struct wl_listener request_resize;
|
||||
struct wl_listener request_maximize;
|
||||
struct wl_listener request_fullscreen;
|
||||
struct wl_listener set_title;
|
||||
struct wl_listener set_app_id;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
|
@ -134,6 +146,7 @@ struct sway_xwayland_view {
|
|||
struct wl_listener set_title;
|
||||
struct wl_listener set_class;
|
||||
struct wl_listener set_window_type;
|
||||
struct wl_listener set_hints;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
|
@ -208,6 +221,9 @@ uint32_t view_get_window_type(struct sway_view *view);
|
|||
|
||||
const char *view_get_shell(struct sway_view *view);
|
||||
|
||||
void view_get_constraints(struct sway_view *view, double *min_width,
|
||||
double *max_width, double *min_height, double *max_height);
|
||||
|
||||
uint32_t view_configure(struct sway_view *view, double lx, double ly, int width,
|
||||
int height);
|
||||
|
||||
|
@ -304,4 +320,8 @@ void view_update_marks_textures(struct sway_view *view);
|
|||
*/
|
||||
bool view_is_visible(struct sway_view *view);
|
||||
|
||||
void view_set_urgent(struct sway_view *view, bool enable);
|
||||
|
||||
bool view_is_urgent(struct sway_view *view);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@ struct sway_workspace {
|
|||
struct sway_view *fullscreen;
|
||||
struct sway_container *floating;
|
||||
list_t *output_priority;
|
||||
bool urgent;
|
||||
};
|
||||
|
||||
extern char *prev_workspace_name;
|
||||
|
@ -47,4 +48,6 @@ struct sway_container *workspace_for_pid(pid_t pid);
|
|||
|
||||
void workspace_record_pid(pid_t pid);
|
||||
|
||||
void workspace_detect_urgent(struct sway_container *workspace);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,11 +16,29 @@ struct swaybar_pointer {
|
|||
int x, y;
|
||||
};
|
||||
|
||||
enum x11_button {
|
||||
NONE,
|
||||
LEFT,
|
||||
MIDDLE,
|
||||
RIGHT,
|
||||
SCROLL_UP,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_LEFT,
|
||||
SCROLL_RIGHT,
|
||||
BACK,
|
||||
FORWARD,
|
||||
};
|
||||
|
||||
enum hotspot_event_handling {
|
||||
HOTSPOT_IGNORE,
|
||||
HOTSPOT_PROCESS,
|
||||
};
|
||||
|
||||
struct swaybar_hotspot {
|
||||
struct wl_list link;
|
||||
int x, y, width, height;
|
||||
void (*callback)(struct swaybar_output *output,
|
||||
int x, int y, uint32_t button, void *data);
|
||||
enum hotspot_event_handling (*callback)(struct swaybar_output *output,
|
||||
int x, int y, enum x11_button button, void *data);
|
||||
void (*destroy)(void *data);
|
||||
void *data;
|
||||
};
|
||||
|
|
|
@ -71,8 +71,10 @@ void status_error(struct status_line *status, const char *text);
|
|||
bool status_handle_readable(struct status_line *status);
|
||||
void status_line_free(struct status_line *status);
|
||||
bool i3bar_handle_readable(struct status_line *status);
|
||||
void i3bar_block_send_click(struct status_line *status,
|
||||
struct i3bar_block *block, int x, int y, uint32_t button);
|
||||
enum hotspot_event_handling i3bar_block_send_click(struct status_line *status,
|
||||
struct i3bar_block *block, int x, int y, enum x11_button button);
|
||||
void i3bar_block_free(struct i3bar_block *block);
|
||||
enum x11_button wl_button_to_x11_button(uint32_t button);
|
||||
enum x11_button wl_axis_to_x11_button(uint32_t axis, wl_fixed_t value);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,10 +19,33 @@ enum auth_state {
|
|||
AUTH_STATE_INVALID,
|
||||
};
|
||||
|
||||
struct swaylock_colorset {
|
||||
uint32_t input;
|
||||
uint32_t cleared;
|
||||
uint32_t verifying;
|
||||
uint32_t wrong;
|
||||
};
|
||||
|
||||
struct swaylock_colors {
|
||||
uint32_t background;
|
||||
uint32_t bs_highlight;
|
||||
uint32_t key_highlight;
|
||||
uint32_t separator;
|
||||
struct swaylock_colorset inside;
|
||||
struct swaylock_colorset line;
|
||||
struct swaylock_colorset ring;
|
||||
struct swaylock_colorset text;
|
||||
};
|
||||
|
||||
struct swaylock_args {
|
||||
uint32_t color;
|
||||
struct swaylock_colors colors;
|
||||
enum background_mode mode;
|
||||
char *font;
|
||||
uint32_t radius;
|
||||
uint32_t thickness;
|
||||
bool ignore_empty;
|
||||
bool show_indicator;
|
||||
bool daemonize;
|
||||
};
|
||||
|
||||
struct swaylock_password {
|
||||
|
|
|
@ -98,12 +98,18 @@ static struct cmd_handler handlers[] = {
|
|||
{ "client.unfocused", cmd_client_unfocused },
|
||||
{ "client.urgent", cmd_client_urgent },
|
||||
{ "default_border", cmd_default_border },
|
||||
{ "default_floating_border", cmd_default_floating_border },
|
||||
{ "exec", cmd_exec },
|
||||
{ "exec_always", cmd_exec_always },
|
||||
{ "floating_maximum_size", cmd_floating_maximum_size },
|
||||
{ "floating_minimum_size", cmd_floating_minimum_size },
|
||||
{ "floating_modifier", cmd_floating_modifier },
|
||||
{ "focus", cmd_focus },
|
||||
{ "focus_follows_mouse", cmd_focus_follows_mouse },
|
||||
{ "focus_wrapping", cmd_focus_wrapping },
|
||||
{ "font", cmd_font },
|
||||
{ "for_window", cmd_for_window },
|
||||
{ "force_display_urgency_hint", cmd_force_display_urgency_hint },
|
||||
{ "force_focus_wrapping", cmd_force_focus_wrapping },
|
||||
{ "fullscreen", cmd_fullscreen },
|
||||
{ "gaps", cmd_gaps },
|
||||
|
@ -112,6 +118,7 @@ static struct cmd_handler handlers[] = {
|
|||
{ "input", cmd_input },
|
||||
{ "mode", cmd_mode },
|
||||
{ "mouse_warping", cmd_mouse_warping },
|
||||
{ "no_focus", cmd_no_focus },
|
||||
{ "output", cmd_output },
|
||||
{ "seat", cmd_seat },
|
||||
{ "set", cmd_set },
|
||||
|
@ -133,7 +140,6 @@ static struct cmd_handler command_handlers[] = {
|
|||
{ "border", cmd_border },
|
||||
{ "exit", cmd_exit },
|
||||
{ "floating", cmd_floating },
|
||||
{ "focus", cmd_focus },
|
||||
{ "fullscreen", cmd_fullscreen },
|
||||
{ "kill", cmd_kill },
|
||||
{ "layout", cmd_layout },
|
||||
|
@ -143,6 +149,7 @@ static struct cmd_handler command_handlers[] = {
|
|||
{ "reload", cmd_reload },
|
||||
{ "rename", cmd_rename },
|
||||
{ "resize", cmd_resize },
|
||||
{ "scratchpad", cmd_scratchpad },
|
||||
{ "split", cmd_split },
|
||||
{ "splith", cmd_splith },
|
||||
{ "splitt", cmd_splitt },
|
||||
|
@ -151,6 +158,7 @@ static struct cmd_handler command_handlers[] = {
|
|||
{ "swap", cmd_swap },
|
||||
{ "title_format", cmd_title_format },
|
||||
{ "unmark", cmd_unmark },
|
||||
{ "urgent", cmd_urgent },
|
||||
};
|
||||
|
||||
static int handler_compare(const void *_a, const void *_b) {
|
||||
|
@ -163,7 +171,7 @@ struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers,
|
|||
int handlers_size) {
|
||||
struct cmd_handler d = { .command=line };
|
||||
struct cmd_handler *res = NULL;
|
||||
wlr_log(L_DEBUG, "find_handler(%s)", line);
|
||||
wlr_log(WLR_DEBUG, "find_handler(%s)", line);
|
||||
|
||||
bool config_loading = config->reading || !config->active;
|
||||
|
||||
|
@ -248,10 +256,10 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
|
|||
cmd = argsep(&cmdlist, ",");
|
||||
cmd += strspn(cmd, whitespace);
|
||||
if (strcmp(cmd, "") == 0) {
|
||||
wlr_log(L_INFO, "Ignoring empty command.");
|
||||
wlr_log(WLR_INFO, "Ignoring empty command.");
|
||||
continue;
|
||||
}
|
||||
wlr_log(L_INFO, "Handling command '%s'", cmd);
|
||||
wlr_log(WLR_INFO, "Handling command '%s'", cmd);
|
||||
//TODO better handling of argv
|
||||
int argc;
|
||||
char **argv = split_args(cmd, &argc);
|
||||
|
@ -319,7 +327,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
|
|||
} while(head);
|
||||
cleanup:
|
||||
free(exec);
|
||||
free(views);
|
||||
list_free(views);
|
||||
if (!results) {
|
||||
results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
@ -355,7 +363,7 @@ struct cmd_results *config_command(char *exec) {
|
|||
results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
wlr_log(L_INFO, "handling config command '%s'", exec);
|
||||
wlr_log(WLR_INFO, "handling config command '%s'", exec);
|
||||
struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
|
||||
if (!handler) {
|
||||
char *input = argv[0] ? argv[0] : "(empty)";
|
||||
|
@ -388,7 +396,7 @@ cleanup:
|
|||
struct cmd_results *config_subcommand(char **argv, int argc,
|
||||
struct cmd_handler *handlers, size_t handlers_size) {
|
||||
char *command = join_args(argv, argc);
|
||||
wlr_log(L_DEBUG, "Subcommand: %s", command);
|
||||
wlr_log(WLR_DEBUG, "Subcommand: %s", command);
|
||||
free(command);
|
||||
|
||||
struct cmd_handler *handler = find_handler(argv[0], handlers,
|
||||
|
@ -428,8 +436,7 @@ struct cmd_results *config_commands_command(char *exec) {
|
|||
|
||||
struct cmd_handler *handler = find_handler(cmd, NULL, 0);
|
||||
if (!handler && strcmp(cmd, "*") != 0) {
|
||||
char *input = cmd ? cmd : "(empty)";
|
||||
results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
|
||||
results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -471,14 +478,16 @@ struct cmd_results *config_commands_command(char *exec) {
|
|||
}
|
||||
if (!policy) {
|
||||
policy = alloc_command_policy(cmd);
|
||||
sway_assert(policy, "Unable to allocate security policy");
|
||||
if (policy) {
|
||||
list_add(config->command_policies, policy);
|
||||
if (!sway_assert(policy, "Unable to allocate security policy")) {
|
||||
results = cmd_results_new(CMD_INVALID, cmd,
|
||||
"Unable to allocate memory");
|
||||
goto cleanup;
|
||||
}
|
||||
list_add(config->command_policies, policy);
|
||||
}
|
||||
policy->context = context;
|
||||
|
||||
wlr_log(L_INFO, "Set command policy for %s to %d",
|
||||
wlr_log(WLR_INFO, "Set command policy for %s to %d",
|
||||
policy->command, policy->context);
|
||||
|
||||
results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
@ -492,7 +501,7 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
|
|||
const char *input, const char *format, ...) {
|
||||
struct cmd_results *results = malloc(sizeof(struct cmd_results));
|
||||
if (!results) {
|
||||
wlr_log(L_ERROR, "Unable to allocate command results");
|
||||
wlr_log(WLR_ERROR, "Unable to allocate command results");
|
||||
return NULL;
|
||||
}
|
||||
results->status = status;
|
||||
|
@ -526,7 +535,7 @@ void free_cmd_results(struct cmd_results *results) {
|
|||
free(results);
|
||||
}
|
||||
|
||||
const char *cmd_results_to_json(struct cmd_results *results) {
|
||||
char *cmd_results_to_json(struct cmd_results *results) {
|
||||
json_object *result_array = json_object_new_array();
|
||||
json_object *root = json_object_new_object();
|
||||
json_object_object_add(root, "success",
|
||||
|
@ -541,9 +550,9 @@ const char *cmd_results_to_json(struct cmd_results *results) {
|
|||
}
|
||||
json_object_array_add(result_array, root);
|
||||
const char *json = json_object_to_json_string(result_array);
|
||||
free(result_array);
|
||||
free(root);
|
||||
return json;
|
||||
char *res = strdup(json);
|
||||
json_object_put(result_array);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
|
|||
|
||||
if (strncmp(*argv, "→", strlen("→")) == 0) {
|
||||
if (argc < 3) {
|
||||
free(criteria);
|
||||
return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
|
||||
}
|
||||
++argv;
|
||||
|
@ -44,7 +45,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
|
|||
criteria->target = join_args(argv, target_len);
|
||||
|
||||
list_add(config->criteria, criteria);
|
||||
wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,
|
||||
wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,
|
||||
criteria->target);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -63,13 +63,13 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
|
|||
for (int i = 0; i < config->bars->length; ++i) {
|
||||
struct bar_config *item = config->bars->items[i];
|
||||
if (strcmp(item->id, argv[0]) == 0) {
|
||||
wlr_log(L_DEBUG, "Selecting bar: %s", argv[0]);
|
||||
wlr_log(WLR_DEBUG, "Selecting bar: %s", argv[0]);
|
||||
bar = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bar) {
|
||||
wlr_log(L_DEBUG, "Creating bar: %s", argv[0]);
|
||||
wlr_log(WLR_DEBUG, "Creating bar: %s", argv[0]);
|
||||
bar = default_bar_config();
|
||||
if (!bar) {
|
||||
return cmd_results_new(CMD_FAILURE, "bar",
|
||||
|
@ -108,7 +108,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
|
|||
|
||||
// Set current bar
|
||||
config->current_bar = bar;
|
||||
wlr_log(L_DEBUG, "Creating bar %s", bar->id);
|
||||
wlr_log(WLR_DEBUG, "Creating bar %s", bar->id);
|
||||
}
|
||||
|
||||
return config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers));
|
||||
|
|
|
@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) {
|
|||
}
|
||||
if (strcasecmp("yes", argv[0]) == 0) {
|
||||
config->current_bar->binding_mode_indicator = true;
|
||||
wlr_log(L_DEBUG, "Enabling binding mode indicator on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Enabling binding mode indicator on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else if (strcasecmp("no", argv[0]) == 0) {
|
||||
config->current_bar->binding_mode_indicator = false;
|
||||
wlr_log(L_DEBUG, "Disabling binding mode indicator on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Disabling binding mode indicator on bar: %s",
|
||||
config->current_bar->id);
|
||||
}
|
||||
return cmd_results_new(CMD_INVALID, "binding_mode_indicator",
|
||||
|
|
|
@ -14,8 +14,8 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) {
|
|||
}
|
||||
char *font = join_args(argv, argc);
|
||||
free(config->current_bar->font);
|
||||
config->current_bar->font = strdup(font);
|
||||
wlr_log(L_DEBUG, "Settings font '%s' for bar: %s",
|
||||
config->current_bar->font = font;
|
||||
wlr_log(WLR_DEBUG, "Settings font '%s' for bar: %s",
|
||||
config->current_bar->font, config->current_bar->id);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_height(int argc, char **argv) {
|
|||
"Invalid height value: %s", argv[0]);
|
||||
}
|
||||
config->current_bar->height = height;
|
||||
wlr_log(L_DEBUG, "Setting bar height to %d on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Setting bar height to %d on bar: %s",
|
||||
height, config->current_bar->id);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar,
|
|||
if (!config->reading) {
|
||||
ipc_event_barconfig_update(bar);
|
||||
}
|
||||
wlr_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Setting hidden_state: '%s' for bar: %s",
|
||||
bar->hidden_state, bar->id);
|
||||
}
|
||||
// free old mode
|
||||
|
|
|
@ -24,7 +24,7 @@ struct cmd_results *bar_cmd_id(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name);
|
||||
wlr_log(WLR_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name);
|
||||
|
||||
// free old bar id
|
||||
free(config->current_bar->id);
|
||||
|
|
|
@ -28,7 +28,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
|
|||
if (!config->reading) {
|
||||
ipc_event_barconfig_update(bar);
|
||||
}
|
||||
wlr_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
|
||||
wlr_log(WLR_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
|
||||
}
|
||||
|
||||
// free old mode
|
||||
|
|
|
@ -22,14 +22,15 @@ struct cmd_results *bar_cmd_modifier(int argc, char **argv) {
|
|||
mod |= tmp_mod;
|
||||
continue;
|
||||
} else {
|
||||
free_flat_list(split);
|
||||
return cmd_results_new(CMD_INVALID, "modifier",
|
||||
error = cmd_results_new(CMD_INVALID, "modifier",
|
||||
"Unknown modifier '%s'", split->items[i]);
|
||||
free_flat_list(split);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
free_flat_list(split);
|
||||
config->current_bar->modifier = mod;
|
||||
wlr_log(L_DEBUG,
|
||||
wlr_log(WLR_DEBUG,
|
||||
"Show/Hide the bar when pressing '%s' in hide mode.", argv[0]);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) {
|
|||
|
||||
if (add_output) {
|
||||
list_add(outputs, strdup(output));
|
||||
wlr_log(L_DEBUG, "Adding bar: '%s' to output '%s'",
|
||||
wlr_log(WLR_DEBUG, "Adding bar: '%s' to output '%s'",
|
||||
config->current_bar->id, output);
|
||||
}
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) {
|
|||
}
|
||||
if (strcasecmp("enabled", argv[0]) == 0) {
|
||||
config->current_bar->pango_markup = true;
|
||||
wlr_log(L_DEBUG, "Enabling pango markup for bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Enabling pango markup for bar: %s",
|
||||
config->current_bar->id);
|
||||
} else if (strcasecmp("disabled", argv[0]) == 0) {
|
||||
config->current_bar->pango_markup = false;
|
||||
wlr_log(L_DEBUG, "Disabling pango markup for bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Disabling pango markup for bar: %s",
|
||||
config->current_bar->id);
|
||||
} else {
|
||||
error = cmd_results_new(CMD_INVALID, "pango_markup",
|
||||
|
|
|
@ -15,8 +15,9 @@ struct cmd_results *bar_cmd_position(int argc, char **argv) {
|
|||
char *valid[] = { "top", "bottom", "left", "right" };
|
||||
for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) {
|
||||
if (strcasecmp(valid[i], argv[0]) == 0) {
|
||||
wlr_log(L_DEBUG, "Setting bar position '%s' for bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Setting bar position '%s' for bar: %s",
|
||||
argv[0], config->current_bar->id);
|
||||
free(config->current_bar->position);
|
||||
config->current_bar->position = strdup(argv[0]);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) {
|
|||
}
|
||||
free(config->current_bar->separator_symbol);
|
||||
config->current_bar->separator_symbol = strdup(argv[0]);
|
||||
wlr_log(L_DEBUG, "Settings separator_symbol '%s' for bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Settings separator_symbol '%s' for bar: %s",
|
||||
config->current_bar->separator_symbol, config->current_bar->id);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) {
|
|||
}
|
||||
free(config->current_bar->status_command);
|
||||
config->current_bar->status_command = join_args(argv, argc);
|
||||
wlr_log(L_DEBUG, "Feeding bar with status command: %s",
|
||||
wlr_log(WLR_DEBUG, "Feeding bar with status command: %s",
|
||||
config->current_bar->status_command);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) {
|
|||
}
|
||||
if (strcasecmp("yes", argv[0]) == 0) {
|
||||
config->current_bar->strip_workspace_numbers = true;
|
||||
wlr_log(L_DEBUG, "Stripping workspace numbers on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Stripping workspace numbers on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else if (strcasecmp("no", argv[0]) == 0) {
|
||||
config->current_bar->strip_workspace_numbers = false;
|
||||
wlr_log(L_DEBUG, "Enabling workspace numbers on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Enabling workspace numbers on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
|
|
|
@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) {
|
|||
}
|
||||
free(config->current_bar->swaybar_command);
|
||||
config->current_bar->swaybar_command = join_args(argv, argc);
|
||||
wlr_log(L_DEBUG, "Using custom swaybar command: %s",
|
||||
wlr_log(WLR_DEBUG, "Using custom swaybar command: %s",
|
||||
config->current_bar->swaybar_command);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) {
|
|||
}
|
||||
if (strcasecmp("yes", argv[0]) == 0) {
|
||||
config->current_bar->workspace_buttons = true;
|
||||
wlr_log(L_DEBUG, "Enabling workspace buttons on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Enabling workspace buttons on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else if (strcasecmp("no", argv[0]) == 0) {
|
||||
config->current_bar->workspace_buttons = false;
|
||||
wlr_log(L_DEBUG, "Disabling workspace buttons on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Disabling workspace buttons on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "workspace_buttons",
|
||||
|
|
|
@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) {
|
|||
}
|
||||
if (strcasecmp("yes", argv[0]) == 0) {
|
||||
config->current_bar->wrap_scroll = true;
|
||||
wlr_log(L_DEBUG, "Enabling wrap scroll on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Enabling wrap scroll on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else if (strcasecmp("no", argv[0]) == 0) {
|
||||
config->current_bar->wrap_scroll = false;
|
||||
wlr_log(L_DEBUG, "Disabling wrap scroll on bar: %s",
|
||||
wlr_log(WLR_DEBUG, "Disabling wrap scroll on bar: %s",
|
||||
config->current_bar->id);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
|
|
|
@ -184,7 +184,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
for (int i = 0; i < mode_bindings->length; ++i) {
|
||||
struct sway_binding *config_binding = mode_bindings->items[i];
|
||||
if (binding_key_compare(binding, config_binding)) {
|
||||
wlr_log(L_DEBUG, "overwriting old binding with command '%s'",
|
||||
wlr_log(WLR_DEBUG, "overwriting old binding with command '%s'",
|
||||
config_binding->command);
|
||||
free_sway_binding(config_binding);
|
||||
mode_bindings->items[i] = binding;
|
||||
|
@ -196,7 +196,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
list_add(mode_bindings, binding);
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "%s - Bound %s to command %s",
|
||||
wlr_log(WLR_DEBUG, "%s - Bound %s to command %s",
|
||||
bindtype, argv[0], binding->command);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct cmd_results *cmd_border(int argc, char **argv) {
|
|||
container_set_geometry_from_floating_view(view->swayc);
|
||||
}
|
||||
|
||||
arrange_and_commit(view->swayc);
|
||||
arrange_windows(view->swayc);
|
||||
|
||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||
if (seat->cursor) {
|
||||
|
|
29
sway/commands/default_floating_border.c
Normal file
29
sway/commands/default_floating_border.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "log.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/tree/container.h"
|
||||
|
||||
struct cmd_results *cmd_default_floating_border(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "default_floating_border",
|
||||
EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "none") == 0) {
|
||||
config->floating_border = B_NONE;
|
||||
} else if (strcmp(argv[0], "normal") == 0) {
|
||||
config->floating_border = B_NORMAL;
|
||||
} else if (strcmp(argv[0], "pixel") == 0) {
|
||||
config->floating_border = B_PIXEL;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "default_floating_border",
|
||||
"Expected 'default_floating_border <none|normal|pixel>' "
|
||||
"or 'default_floating_border <normal|pixel> <px>'");
|
||||
}
|
||||
if (argc == 2) {
|
||||
config->floating_border_thickness = atoi(argv[1]);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -8,7 +8,7 @@ struct cmd_results *cmd_exec(int argc, char **argv) {
|
|||
if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL);
|
||||
if (config->reloading) {
|
||||
char *args = join_args(argv, argc);
|
||||
wlr_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args);
|
||||
wlr_log(WLR_DEBUG, "Ignoring 'exec %s' due to reload", args);
|
||||
free(args);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
|
|||
|
||||
char *tmp = NULL;
|
||||
if (strcmp((char*)*argv, "--no-startup-id") == 0) {
|
||||
wlr_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored.");
|
||||
wlr_log(WLR_INFO, "exec switch '--no-startup-id' not supported, ignored.");
|
||||
if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) {
|
||||
return error;
|
||||
}
|
||||
|
@ -35,50 +35,49 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
|
|||
strncpy(cmd, tmp, sizeof(cmd) - 1);
|
||||
cmd[sizeof(cmd) - 1] = 0;
|
||||
free(tmp);
|
||||
wlr_log(L_DEBUG, "Executing %s", cmd);
|
||||
wlr_log(WLR_DEBUG, "Executing %s", cmd);
|
||||
|
||||
int fd[2];
|
||||
if (pipe(fd) != 0) {
|
||||
wlr_log(L_ERROR, "Unable to create pipe for fork");
|
||||
wlr_log(WLR_ERROR, "Unable to create pipe for fork");
|
||||
}
|
||||
|
||||
pid_t pid;
|
||||
pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space
|
||||
if (!child) {
|
||||
return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid");
|
||||
}
|
||||
pid_t pid, child;
|
||||
// Fork process
|
||||
if ((pid = fork()) == 0) {
|
||||
// Fork child process again
|
||||
setsid();
|
||||
if ((*child = fork()) == 0) {
|
||||
execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
|
||||
// Not reached
|
||||
}
|
||||
close(fd[0]);
|
||||
if ((child = fork()) == 0) {
|
||||
close(fd[1]);
|
||||
execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
|
||||
_exit(0);
|
||||
}
|
||||
ssize_t s = 0;
|
||||
while ((size_t)s < sizeof(pid_t)) {
|
||||
s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s);
|
||||
s += write(fd[1], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
|
||||
}
|
||||
close(fd[1]);
|
||||
_exit(0); // Close child process
|
||||
} else if (pid < 0) {
|
||||
free(child);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed");
|
||||
}
|
||||
close(fd[1]); // close write
|
||||
ssize_t s = 0;
|
||||
while ((size_t)s < sizeof(pid_t)) {
|
||||
s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s);
|
||||
s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
|
||||
}
|
||||
close(fd[0]);
|
||||
// cleanup child process
|
||||
waitpid(pid, NULL, 0);
|
||||
if (*child > 0) {
|
||||
wlr_log(L_DEBUG, "Child process created with pid %d", *child);
|
||||
workspace_record_pid(*child);
|
||||
if (child > 0) {
|
||||
wlr_log(WLR_DEBUG, "Child process created with pid %d", child);
|
||||
workspace_record_pid(child);
|
||||
} else {
|
||||
free(child);
|
||||
return cmd_results_new(CMD_FAILURE, "exec_always",
|
||||
"Second fork() failed");
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -37,7 +37,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
|
|||
container_set_floating(container, wants_floating);
|
||||
|
||||
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||
arrange_and_commit(workspace);
|
||||
arrange_windows(workspace);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
53
sway/commands/floating_minmax_size.c
Normal file
53
sway/commands/floating_minmax_size.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
||||
static const char* min_usage =
|
||||
"Expected 'floating_minimum_size <width> x <height>'";
|
||||
|
||||
static const char* max_usage =
|
||||
"Expected 'floating_maximum_size <width> x <height>'";
|
||||
|
||||
static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
|
||||
const char *usage, int *config_width, int *config_height) {
|
||||
struct cmd_results *error;
|
||||
if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 3))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *err;
|
||||
int width = (int)strtol(argv[0], &err, 10);
|
||||
if (*err) {
|
||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "x") != 0) {
|
||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
||||
}
|
||||
|
||||
int height = (int)strtol(argv[2], &err, 10);
|
||||
if (*err) {
|
||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
||||
}
|
||||
|
||||
*config_width = width;
|
||||
*config_height = height;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_floating_minimum_size(int argc, char **argv) {
|
||||
return handle_command(argc, argv, "floating_minimum_size", min_usage,
|
||||
&config->floating_minimum_width, &config->floating_minimum_height);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) {
|
||||
return handle_command(argc, argv, "floating_maximum_size", max_usage,
|
||||
&config->floating_maximum_width, &config->floating_maximum_height);
|
||||
}
|
20
sway/commands/floating_modifier.c
Normal file
20
sway/commands/floating_modifier.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "util.h"
|
||||
|
||||
struct cmd_results *cmd_floating_modifier(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
uint32_t mod = get_modifier_mask_by_name(argv[0]);
|
||||
if (!mod) {
|
||||
return cmd_results_new(CMD_INVALID, "floating_modifier",
|
||||
"Invalid modifier");
|
||||
}
|
||||
|
||||
config->floating_mod = mod;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
#include <strings.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "log.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "stringop.h"
|
||||
|
||||
static bool parse_movement_direction(const char *name,
|
||||
enum movement_direction *out) {
|
||||
|
@ -27,7 +31,55 @@ static bool parse_movement_direction(const char *name,
|
|||
return true;
|
||||
}
|
||||
|
||||
static struct cmd_results *focus_mode(struct sway_container *con,
|
||||
struct sway_seat *seat, bool floating) {
|
||||
struct sway_container *ws = con->type == C_WORKSPACE ?
|
||||
con : container_parent(con, C_WORKSPACE);
|
||||
struct sway_container *new_focus = ws;
|
||||
if (floating) {
|
||||
new_focus = ws->sway_workspace->floating;
|
||||
if (new_focus->children->length == 0) {
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
}
|
||||
seat_set_focus(seat, seat_get_active_child(seat, new_focus));
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct cmd_results *focus_output(struct sway_container *con,
|
||||
struct sway_seat *seat, int argc, char **argv) {
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "focus",
|
||||
"Expected 'focus output <direction|name>'");
|
||||
}
|
||||
char *identifier = join_args(argv, argc);
|
||||
struct sway_container *output = output_by_name(identifier);
|
||||
|
||||
if (!output) {
|
||||
enum movement_direction direction;
|
||||
if (!parse_movement_direction(identifier, &direction) ||
|
||||
direction == MOVE_PARENT || direction == MOVE_CHILD) {
|
||||
free(identifier);
|
||||
return cmd_results_new(CMD_INVALID, "focus",
|
||||
"There is no output with that name");
|
||||
}
|
||||
struct sway_container *focus = seat_get_focus(seat);
|
||||
focus = container_parent(focus, C_OUTPUT);
|
||||
output = container_get_in_direction(focus, seat, direction);
|
||||
}
|
||||
|
||||
free(identifier);
|
||||
if (output) {
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, output));
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_focus(int argc, char **argv) {
|
||||
if (config->reading || !config->active) {
|
||||
return cmd_results_new(CMD_DEFER, NULL, NULL);
|
||||
}
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
if (con->type < C_WORKSPACE) {
|
||||
|
@ -40,11 +92,24 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
// TODO mode_toggle
|
||||
if (strcmp(argv[0], "floating") == 0) {
|
||||
return focus_mode(con, seat, true);
|
||||
} else if (strcmp(argv[0], "tiling") == 0) {
|
||||
return focus_mode(con, seat, false);
|
||||
} else if (strcmp(argv[0], "mode_toggle") == 0) {
|
||||
return focus_mode(con, seat, !container_is_floating(con));
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "output") == 0) {
|
||||
argc--; argv++;
|
||||
return focus_output(con, seat, argc, argv);
|
||||
}
|
||||
|
||||
enum movement_direction direction = 0;
|
||||
if (!parse_movement_direction(argv[0], &direction)) {
|
||||
return cmd_results_new(CMD_INVALID, "focus",
|
||||
"Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
|
||||
"Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' "
|
||||
"or 'focus output <direction|name>'");
|
||||
}
|
||||
|
||||
struct sway_container *next_focus = container_get_in_direction(
|
||||
|
|
|
@ -24,7 +24,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) {
|
|||
criteria->cmdlist = join_args(argv + 1, argc - 1);
|
||||
|
||||
list_add(config->criteria, criteria);
|
||||
wlr_log(L_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist);
|
||||
wlr_log(WLR_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
23
sway/commands/force_display_urgency_hint.c
Normal file
23
sway/commands/force_display_urgency_hint.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
||||
struct cmd_results *cmd_force_display_urgency_hint(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "force_display_urgency_hint",
|
||||
EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *err;
|
||||
int timeout = (int)strtol(argv[0], &err, 10);
|
||||
if (*err) {
|
||||
if (strcmp(err, "ms") != 0) {
|
||||
return cmd_results_new(CMD_INVALID, "force_display_urgency_hint",
|
||||
"Expected 'force_display_urgency_hint <timeout> ms'");
|
||||
}
|
||||
}
|
||||
|
||||
config->urgent_timeout = timeout > 0 ? timeout : 0;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -34,7 +34,7 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
|
|||
view_set_fullscreen(view, wants_fullscreen);
|
||||
|
||||
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||
arrange_and_commit(workspace->parent);
|
||||
arrange_windows(workspace->parent);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "gaps",
|
||||
"gaps edge_gaps on|off|toggle");
|
||||
}
|
||||
arrange_and_commit(&root_container);
|
||||
arrange_windows(&root_container);
|
||||
} else {
|
||||
int amount_idx = 0; // the current index in argv
|
||||
enum gaps_op op = GAPS_OP_SET;
|
||||
|
@ -124,7 +124,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
if (amount_idx == 0) { // gaps <amount>
|
||||
config->gaps_inner = val;
|
||||
config->gaps_outer = val;
|
||||
arrange_and_commit(&root_container);
|
||||
arrange_windows(&root_container);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
// Other variants. The middle-length variant (gaps inner|outer <amount>)
|
||||
|
@ -155,7 +155,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
} else {
|
||||
config->gaps_outer = total;
|
||||
}
|
||||
arrange_and_commit(&root_container);
|
||||
arrange_windows(&root_container);
|
||||
} else {
|
||||
struct sway_container *c =
|
||||
config->handler_context.current_container;
|
||||
|
@ -169,7 +169,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
c->gaps_outer = total;
|
||||
}
|
||||
|
||||
arrange_and_commit(c->parent ? c->parent : &root_container);
|
||||
arrange_windows(c->parent ? c->parent : &root_container);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@ static struct cmd_handler input_handlers[] = {
|
|||
{ "pointer_accel", input_cmd_pointer_accel },
|
||||
{ "repeat_delay", input_cmd_repeat_delay },
|
||||
{ "repeat_rate", input_cmd_repeat_rate },
|
||||
{ "scroll_button", input_cmd_scroll_button },
|
||||
{ "scroll_method", input_cmd_scroll_method },
|
||||
{ "tap", input_cmd_tap },
|
||||
{ "tap_button_map", input_cmd_tap_button_map },
|
||||
{ "xkb_layout", input_cmd_xkb_layout },
|
||||
{ "xkb_model", input_cmd_xkb_model },
|
||||
{ "xkb_options", input_cmd_xkb_options },
|
||||
|
@ -35,7 +37,7 @@ struct cmd_results *cmd_input(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "entering input block: %s", argv[0]);
|
||||
wlr_log(WLR_DEBUG, "entering input block: %s", argv[0]);
|
||||
|
||||
config->handler_context.input_config = new_input_config(argv[0]);
|
||||
if (!config->handler_context.input_config) {
|
||||
|
|
|
@ -23,6 +23,7 @@ struct cmd_results *input_cmd_accel_profile(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "flat") == 0) {
|
||||
new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "accel_profile",
|
||||
"Expected 'accel_profile <adaptive|flat>'");
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ struct cmd_results *input_cmd_click_method(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "clickfinger") == 0) {
|
||||
new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "click_method",
|
||||
"Expected 'click_method <none|button_areas|clickfinger'");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "disabled") == 0) {
|
||||
new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "drag_lock",
|
||||
"Expected 'drag_lock <enabled|disabled>'");
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ struct cmd_results *input_cmd_dwt(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "disabled") == 0) {
|
||||
new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "dwt",
|
||||
"Expected 'dwt <enabled|disabled>'");
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_FAILURE, "events",
|
||||
"No input device defined.");
|
||||
}
|
||||
wlr_log(L_DEBUG, "events for device: %s",
|
||||
wlr_log(WLR_DEBUG, "events for device: %s",
|
||||
current_input_config->identifier);
|
||||
struct input_config *new_config =
|
||||
new_input_config(current_input_config->identifier);
|
||||
|
@ -29,6 +29,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) {
|
|||
new_config->send_events =
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "events",
|
||||
"Expected 'events <enabled|disabled|disabled_on_external_mouse>'");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct cmd_results *input_cmd_left_handed(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "disabled") == 0) {
|
||||
new_config->left_handed = 0;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "left_handed",
|
||||
"Expected 'left_handed <enabled|disabled>'");
|
||||
}
|
||||
|
|
|
@ -54,20 +54,28 @@ struct cmd_results *input_cmd_map_from_region(int argc, char **argv) {
|
|||
bool mm1, mm2;
|
||||
if (!parse_coords(argv[0], &new_config->mapped_from_region->x1,
|
||||
&new_config->mapped_from_region->y1, &mm1)) {
|
||||
free(new_config->mapped_from_region);
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_FAILURE, "map_from_region",
|
||||
"Invalid top-left coordinates");
|
||||
}
|
||||
if (!parse_coords(argv[1], &new_config->mapped_from_region->x2,
|
||||
&new_config->mapped_from_region->y2, &mm2)) {
|
||||
free(new_config->mapped_from_region);
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_FAILURE, "map_from_region",
|
||||
"Invalid bottom-right coordinates");
|
||||
}
|
||||
if (new_config->mapped_from_region->x1 > new_config->mapped_from_region->x2 ||
|
||||
new_config->mapped_from_region->y1 > new_config->mapped_from_region->y2) {
|
||||
free(new_config->mapped_from_region);
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_FAILURE, "map_from_region",
|
||||
"Invalid rectangle");
|
||||
}
|
||||
if (mm1 != mm2) {
|
||||
free(new_config->mapped_from_region);
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_FAILURE, "map_from_region",
|
||||
"Both coordinates must be in the same unit");
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) {
|
|||
new_config->middle_emulation =
|
||||
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "middle_emulation",
|
||||
"Expected 'middle_emulation <enabled|disabled>'");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "disabled") == 0) {
|
||||
new_config->natural_scroll = 0;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "natural_scroll",
|
||||
"Expected 'natural_scroll <enabled|disabled>'");
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) {
|
|||
|
||||
float pointer_accel = atof(argv[0]);
|
||||
if (pointer_accel < -1 || pointer_accel > 1) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "pointer_accel",
|
||||
"Input out of range [-1, 1]");
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ struct cmd_results *input_cmd_repeat_delay(int argc, char **argv) {
|
|||
|
||||
int repeat_delay = atoi(argv[0]);
|
||||
if (repeat_delay < 0) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "repeat_delay",
|
||||
"Repeat delay cannot be negative");
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ struct cmd_results *input_cmd_repeat_rate(int argc, char **argv) {
|
|||
|
||||
int repeat_rate = atoi(argv[0]);
|
||||
if (repeat_rate < 0) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "repeat_rate",
|
||||
"Repeat rate cannot be negative");
|
||||
}
|
||||
|
|
44
sway/commands/input/scroll_button.c
Normal file
44
sway/commands/input/scroll_button.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
||||
struct cmd_results *input_cmd_scroll_button(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "scroll_button", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct input_config *current_input_config =
|
||||
config->handler_context.input_config;
|
||||
if (!current_input_config) {
|
||||
return cmd_results_new(CMD_FAILURE, "scroll_button",
|
||||
"No input device defined.");
|
||||
}
|
||||
struct input_config *new_config =
|
||||
new_input_config(current_input_config->identifier);
|
||||
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
int scroll_button = strtol(*argv, &endptr, 10);
|
||||
if (endptr == *argv && scroll_button == 0) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "scroll_button",
|
||||
"Scroll button identifier must be an integer.");
|
||||
}
|
||||
if (errno == ERANGE) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "scroll_button",
|
||||
"Scroll button identifier out of range.");
|
||||
}
|
||||
if (scroll_button < 0) {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "scroll_button",
|
||||
"Scroll button identifier cannot be negative.");
|
||||
}
|
||||
new_config->scroll_button = scroll_button;
|
||||
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -27,6 +27,7 @@ struct cmd_results *input_cmd_scroll_method(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "on_button_down") == 0) {
|
||||
new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "scroll_method",
|
||||
"Expected 'scroll_method <none|two_finger|edge|on_button_down>'");
|
||||
}
|
||||
|
|
|
@ -23,11 +23,12 @@ struct cmd_results *input_cmd_tap(int argc, char **argv) {
|
|||
} else if (strcasecmp(argv[0], "disabled") == 0) {
|
||||
new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "tap",
|
||||
"Expected 'tap <enabled|disabled>'");
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "apply-tap for device: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-tap for device: %s",
|
||||
current_input_config->identifier);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
33
sway/commands/input/tap_button_map.c
Normal file
33
sway/commands/input/tap_button_map.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
||||
struct cmd_results *input_cmd_tap_button_map(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "tap_button_map", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct input_config *current_input_config =
|
||||
config->handler_context.input_config;
|
||||
if (!current_input_config) {
|
||||
return cmd_results_new(CMD_FAILURE, "tap_button_map",
|
||||
"No input device defined.");
|
||||
}
|
||||
struct input_config *new_config =
|
||||
new_input_config(current_input_config->identifier);
|
||||
|
||||
if (strcasecmp(argv[0], "lrm") == 0) {
|
||||
new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||
} else if (strcasecmp(argv[0], "lmr") == 0) {
|
||||
new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LMR;
|
||||
} else {
|
||||
free_input_config(new_config);
|
||||
return cmd_results_new(CMD_INVALID, "tap_button_map",
|
||||
"Expected 'tap_button_map <lrm|lmr>'");
|
||||
}
|
||||
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_layout(int argc, char **argv) {
|
|||
|
||||
new_config->xkb_layout = strdup(argv[0]);
|
||||
|
||||
wlr_log(L_DEBUG, "apply-xkb_layout for device: %s layout: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-xkb_layout for device: %s layout: %s",
|
||||
current_input_config->identifier, new_config->xkb_layout);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_model(int argc, char **argv) {
|
|||
|
||||
new_config->xkb_model = strdup(argv[0]);
|
||||
|
||||
wlr_log(L_DEBUG, "apply-xkb_model for device: %s model: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-xkb_model for device: %s model: %s",
|
||||
current_input_config->identifier, new_config->xkb_model);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_options(int argc, char **argv) {
|
|||
|
||||
new_config->xkb_options = strdup(argv[0]);
|
||||
|
||||
wlr_log(L_DEBUG, "apply-xkb_options for device: %s options: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-xkb_options for device: %s options: %s",
|
||||
current_input_config->identifier, new_config->xkb_options);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_rules(int argc, char **argv) {
|
|||
|
||||
new_config->xkb_rules = strdup(argv[0]);
|
||||
|
||||
wlr_log(L_DEBUG, "apply-xkb_rules for device: %s rules: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-xkb_rules for device: %s rules: %s",
|
||||
current_input_config->identifier, new_config->xkb_rules);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_variant(int argc, char **argv) {
|
|||
|
||||
new_config->xkb_variant = strdup(argv[0]);
|
||||
|
||||
wlr_log(L_DEBUG, "apply-xkb_variant for device: %s variant: %s",
|
||||
wlr_log(WLR_DEBUG, "apply-xkb_variant for device: %s variant: %s",
|
||||
current_input_config->identifier, new_config->xkb_variant);
|
||||
apply_input_config(new_config);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -49,7 +49,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
|
|||
}
|
||||
|
||||
container_notify_subtree_changed(parent);
|
||||
arrange_and_commit(parent);
|
||||
arrange_windows(parent);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,17 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
|
|||
"mode", "Can only be used in config file.");
|
||||
}
|
||||
|
||||
const char *mode_name = argv[0];
|
||||
bool pango = strcmp(*argv, "--pango_markup") == 0;
|
||||
if (pango) {
|
||||
argc--; argv++;
|
||||
if (argc == 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "mode",
|
||||
"Mode name is missing");
|
||||
}
|
||||
}
|
||||
|
||||
char *mode_name = *argv;
|
||||
strip_quotes(mode_name);
|
||||
struct sway_mode *mode = NULL;
|
||||
// Find mode
|
||||
for (int i = 0; i < config->modes->length; ++i) {
|
||||
|
@ -46,6 +56,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
|
|||
mode->name = strdup(mode_name);
|
||||
mode->keysym_bindings = create_list();
|
||||
mode->keycode_bindings = create_list();
|
||||
mode->pango = pango;
|
||||
list_add(config->modes, mode);
|
||||
}
|
||||
if (!mode) {
|
||||
|
@ -54,13 +65,15 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
if ((config->reading && argc > 1) || (!config->reading && argc == 1)) {
|
||||
wlr_log(L_DEBUG, "Switching to mode `%s'",mode->name);
|
||||
wlr_log(WLR_DEBUG, "Switching to mode `%s' (pango=%d)",
|
||||
mode->name, mode->pango);
|
||||
}
|
||||
// Set current mode
|
||||
config->current_mode = mode;
|
||||
if (argc == 1) {
|
||||
// trigger IPC mode event
|
||||
ipc_event_mode(config->current_mode->name);
|
||||
ipc_event_mode(config->current_mode->name,
|
||||
config->current_mode->pango);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
#define _XOPEN_SOURCE 500
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/scratchpad.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/layout.h"
|
||||
|
@ -103,10 +105,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
// TODO: Ideally we would arrange the surviving parent after reaping,
|
||||
// but container_reap_empty does not return it, so we arrange the
|
||||
// workspace instead.
|
||||
struct sway_transaction *txn = transaction_create();
|
||||
arrange_windows(old_ws, txn);
|
||||
arrange_windows(destination->parent, txn);
|
||||
transaction_commit(txn);
|
||||
arrange_windows(old_ws);
|
||||
arrange_windows(destination->parent);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
} else if (strcasecmp(argv[1], "to") == 0
|
||||
|
@ -142,10 +142,8 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
|
|||
// TODO: Ideally we would arrange the surviving parent after reaping,
|
||||
// but container_reap_empty does not return it, so we arrange the
|
||||
// workspace instead.
|
||||
struct sway_transaction *txn = transaction_create();
|
||||
arrange_windows(old_ws, txn);
|
||||
arrange_windows(focus->parent, txn);
|
||||
transaction_commit(txn);
|
||||
arrange_windows(old_ws);
|
||||
arrange_windows(focus->parent);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
@ -175,20 +173,56 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current,
|
|||
}
|
||||
container_move_to(current, destination);
|
||||
|
||||
struct sway_transaction *txn = transaction_create();
|
||||
arrange_windows(source, txn);
|
||||
arrange_windows(destination, txn);
|
||||
transaction_commit(txn);
|
||||
arrange_windows(source);
|
||||
arrange_windows(destination);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct cmd_results *move_in_direction(struct sway_container *container,
|
||||
enum movement_direction direction, int move_amt) {
|
||||
enum movement_direction direction, int argc, char **argv) {
|
||||
int move_amt = 10;
|
||||
if (argc > 1) {
|
||||
char *inv;
|
||||
move_amt = (int)strtol(argv[1], &inv, 10);
|
||||
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Invalid distance specified");
|
||||
}
|
||||
}
|
||||
|
||||
if (container->type == C_WORKSPACE) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Cannot move workspaces in a direction");
|
||||
}
|
||||
if (container_is_floating(container)) {
|
||||
if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Cannot move fullscreen floating container");
|
||||
}
|
||||
double lx = container->x;
|
||||
double ly = container->y;
|
||||
switch (direction) {
|
||||
case MOVE_LEFT:
|
||||
lx -= move_amt;
|
||||
break;
|
||||
case MOVE_RIGHT:
|
||||
lx += move_amt;
|
||||
break;
|
||||
case MOVE_UP:
|
||||
ly -= move_amt;
|
||||
break;
|
||||
case MOVE_DOWN:
|
||||
ly += move_amt;
|
||||
break;
|
||||
case MOVE_PARENT:
|
||||
case MOVE_CHILD:
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Cannot move floating container to parent or child");
|
||||
}
|
||||
container_floating_move_to(container, lx, ly);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
// For simplicity, we'll arrange the entire workspace. The reason for this
|
||||
// is moving the container might reap the old parent, and container_move
|
||||
// does not return a surviving parent.
|
||||
|
@ -198,54 +232,112 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
|
|||
container_move(container, direction, move_amt);
|
||||
struct sway_container *new_ws = container_parent(container, C_WORKSPACE);
|
||||
|
||||
struct sway_transaction *txn = transaction_create();
|
||||
arrange_windows(old_ws, txn);
|
||||
arrange_windows(old_ws);
|
||||
if (new_ws != old_ws) {
|
||||
arrange_windows(new_ws, txn);
|
||||
arrange_windows(new_ws);
|
||||
}
|
||||
transaction_commit(txn);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
static const char* expected_position_syntax =
|
||||
"Expected 'move [absolute] position <x> <y>' or "
|
||||
"'move [absolute] position mouse'";
|
||||
|
||||
static struct cmd_results *move_to_position(struct sway_container *container,
|
||||
int argc, char **argv) {
|
||||
if (!container_is_floating(container)) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Only floating containers "
|
||||
"can be moved to an absolute position");
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
|
||||
}
|
||||
if (strcmp(argv[0], "absolute") == 0) {
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
|
||||
}
|
||||
if (strcmp(argv[0], "position") == 0) {
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
|
||||
}
|
||||
if (strcmp(argv[0], "mouse") == 0) {
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
if (!seat->cursor) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", "No cursor device");
|
||||
}
|
||||
double lx = seat->cursor->cursor->x - container->width / 2;
|
||||
double ly = seat->cursor->cursor->y - container->height / 2;
|
||||
container_floating_move_to(container, lx, ly);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
if (argc != 2) {
|
||||
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
|
||||
}
|
||||
double lx, ly;
|
||||
char *inv;
|
||||
lx = (double)strtol(argv[0], &inv, 10);
|
||||
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Invalid position specified");
|
||||
}
|
||||
ly = (double)strtol(argv[1], &inv, 10);
|
||||
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Invalid position specified");
|
||||
}
|
||||
container_floating_move_to(container, lx, ly);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct cmd_results *move_to_scratchpad(struct sway_container *con) {
|
||||
if (con->type != C_CONTAINER && con->type != C_VIEW) {
|
||||
return cmd_results_new(CMD_INVALID, "move",
|
||||
"Only views and containers can be moved to the scratchpad");
|
||||
}
|
||||
if (con->scratchpad) {
|
||||
return cmd_results_new(CMD_INVALID, "move",
|
||||
"Container is already in the scratchpad");
|
||||
}
|
||||
scratchpad_add_container(con);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_move(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
int move_amt = 10;
|
||||
if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
|
||||
if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) {
|
||||
char *inv;
|
||||
move_amt = (int)strtol(argv[1], &inv, 10);
|
||||
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
|
||||
return cmd_results_new(CMD_FAILURE, "move",
|
||||
"Invalid distance specified");
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasecmp(argv[0], "left") == 0) {
|
||||
return move_in_direction(current, MOVE_LEFT, move_amt);
|
||||
return move_in_direction(current, MOVE_LEFT, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "right") == 0) {
|
||||
return move_in_direction(current, MOVE_RIGHT, move_amt);
|
||||
return move_in_direction(current, MOVE_RIGHT, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "up") == 0) {
|
||||
return move_in_direction(current, MOVE_UP, move_amt);
|
||||
return move_in_direction(current, MOVE_UP, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "down") == 0) {
|
||||
return move_in_direction(current, MOVE_DOWN, move_amt);
|
||||
return move_in_direction(current, MOVE_DOWN, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "container") == 0
|
||||
|| strcasecmp(argv[0], "window") == 0) {
|
||||
return cmd_move_container(current, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "workspace") == 0) {
|
||||
return cmd_move_workspace(current, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "scratchpad") == 0
|
||||
|| (strcasecmp(argv[0], "to") == 0
|
||||
|| (strcasecmp(argv[0], "to") == 0 && argc == 2
|
||||
&& strcasecmp(argv[1], "scratchpad") == 0)) {
|
||||
// TODO: scratchpad
|
||||
return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
|
||||
return move_to_scratchpad(current);
|
||||
} else if (strcasecmp(argv[0], "position") == 0) {
|
||||
// TODO: floating
|
||||
return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
|
||||
return move_to_position(current, argc, argv);
|
||||
} else if (strcasecmp(argv[0], "absolute") == 0) {
|
||||
return move_to_position(current, argc, argv);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "move", expected_syntax);
|
||||
}
|
||||
|
|
26
sway/commands/no_focus.c
Normal file
26
sway/commands/no_focus.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#define _XOPEN_SOURCE 500
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/criteria.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
||||
struct cmd_results *cmd_no_focus(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "no_focus", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *err_str = NULL;
|
||||
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
||||
if (!criteria) {
|
||||
error = cmd_results_new(CMD_INVALID, "no_focus", err_str);
|
||||
free(err_str);
|
||||
return error;
|
||||
}
|
||||
|
||||
criteria->type = CT_NO_FOCUS;
|
||||
list_add(config->criteria, criteria);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
|
@ -29,7 +29,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
|
|||
|
||||
struct output_config *output = new_output_config(argv[0]);
|
||||
if (!output) {
|
||||
wlr_log(L_ERROR, "Failed to allocate output config");
|
||||
wlr_log(WLR_ERROR, "Failed to allocate output config");
|
||||
return NULL;
|
||||
}
|
||||
argc--; argv++;
|
||||
|
@ -60,53 +60,13 @@ struct cmd_results *cmd_output(int argc, char **argv) {
|
|||
config->handler_context.leftovers.argc = 0;
|
||||
config->handler_context.leftovers.argv = NULL;
|
||||
|
||||
int i = list_seq_find(config->output_configs, output_name_cmp, output->name);
|
||||
if (i >= 0) {
|
||||
// Merge existing config
|
||||
struct output_config *current = config->output_configs->items[i];
|
||||
merge_output_config(current, output);
|
||||
free_output_config(output);
|
||||
output = current;
|
||||
} else {
|
||||
list_add(config->output_configs, output);
|
||||
}
|
||||
output = store_output_config(output);
|
||||
|
||||
wlr_log(L_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||
"position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)",
|
||||
output->name, output->enabled, output->width, output->height,
|
||||
output->refresh_rate, output->x, output->y, output->scale,
|
||||
output->transform, output->background, output->background_option, output->dpms_state);
|
||||
|
||||
// Try to find the output container and apply configuration now. If
|
||||
// this is during startup then there will be no container and config
|
||||
// will be applied during normal "new output" event from wlroots.
|
||||
char identifier[128];
|
||||
bool all = strcmp(output->name, "*") == 0;
|
||||
struct sway_output *sway_output;
|
||||
wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) {
|
||||
output_get_identifier(identifier, sizeof(identifier), sway_output);
|
||||
wlr_log(L_DEBUG, "Checking identifier %s", identifier);
|
||||
if (all || strcmp(sway_output->wlr_output->name, output->name) == 0
|
||||
|| strcmp(identifier, output->name) == 0) {
|
||||
if (!sway_output->swayc) {
|
||||
if (!output->enabled) {
|
||||
if (!all) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
output_enable(sway_output);
|
||||
}
|
||||
|
||||
apply_output_config(output, sway_output->swayc);
|
||||
|
||||
if (!all) {
|
||||
// Stop looking if the output config isn't applicable to all
|
||||
// outputs
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If reloading, the output configs will be applied after reading the
|
||||
// entire config and before the deferred commands so that an auto generated
|
||||
// workspace name is not given to re-enabled outputs.
|
||||
if (!config->reloading) {
|
||||
apply_output_config_to_outputs(output);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
@ -72,7 +72,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
src = strdup(p.we_wordv[0]);
|
||||
wordfree(&p);
|
||||
if (!src) {
|
||||
wlr_log(L_ERROR, "Failed to duplicate string");
|
||||
wlr_log(WLR_ERROR, "Failed to duplicate string");
|
||||
return cmd_results_new(CMD_FAILURE, "output",
|
||||
"Unable to allocate resource");
|
||||
}
|
||||
|
@ -80,9 +80,10 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
if (config->reading && *src != '/') {
|
||||
// src file is inside configuration dir
|
||||
|
||||
char *conf = strdup(config->current_config);
|
||||
char *conf = strdup(config->current_config_path);
|
||||
if (!conf) {
|
||||
wlr_log(L_ERROR, "Failed to duplicate string");
|
||||
wlr_log(WLR_ERROR, "Failed to duplicate string");
|
||||
free(src);
|
||||
return cmd_results_new(CMD_FAILURE, "output",
|
||||
"Unable to allocate resources");
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
if (!src) {
|
||||
free(rel_path);
|
||||
free(conf);
|
||||
wlr_log(L_ERROR, "Unable to allocate memory");
|
||||
wlr_log(WLR_ERROR, "Unable to allocate memory");
|
||||
return cmd_results_new(CMD_FAILURE, "output",
|
||||
"Unable to allocate resources");
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) {
|
|||
}
|
||||
} else {
|
||||
// Format is 1234 4321
|
||||
argc--; argv++;
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "output",
|
||||
"Missing mode argument (height).");
|
||||
}
|
||||
argc--; argv++;
|
||||
output->height = strtol(*argv, &end, 10);
|
||||
if (*end) {
|
||||
return cmd_results_new(CMD_INVALID, "output",
|
||||
|
|
|
@ -27,11 +27,11 @@ struct cmd_results *output_cmd_position(int argc, char **argv) {
|
|||
}
|
||||
} else {
|
||||
// Format is 1234 4321 (legacy)
|
||||
argc--; argv++;
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "output",
|
||||
"Missing position argument (y).");
|
||||
}
|
||||
argc--; argv++;
|
||||
config->handler_context.output_config->y = strtol(*argv, &end, 10);
|
||||
if (*end) {
|
||||
return cmd_results_new(CMD_INVALID, "output",
|
||||
|
|
|
@ -7,11 +7,11 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
|
||||
return error;
|
||||
}
|
||||
if (!load_main_config(config->current_config, true)) {
|
||||
if (!load_main_config(config->current_config_path, true)) {
|
||||
return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
|
||||
}
|
||||
|
||||
load_swaybars();
|
||||
arrange_and_commit(&root_container);
|
||||
arrange_windows(&root_container);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
|||
"Workspace already exists");
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
|
||||
wlr_log(WLR_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
|
||||
free(workspace->name);
|
||||
workspace->name = new_name;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -7,6 +8,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "log.h"
|
||||
|
||||
static const int MIN_SANE_W = 100, MIN_SANE_H = 60;
|
||||
|
@ -21,9 +23,18 @@ enum resize_unit {
|
|||
enum resize_axis {
|
||||
RESIZE_AXIS_HORIZONTAL,
|
||||
RESIZE_AXIS_VERTICAL,
|
||||
RESIZE_AXIS_UP,
|
||||
RESIZE_AXIS_DOWN,
|
||||
RESIZE_AXIS_LEFT,
|
||||
RESIZE_AXIS_RIGHT,
|
||||
RESIZE_AXIS_INVALID,
|
||||
};
|
||||
|
||||
struct resize_amount {
|
||||
int amount;
|
||||
enum resize_unit unit;
|
||||
};
|
||||
|
||||
static enum resize_unit parse_resize_unit(const char *unit) {
|
||||
if (strcasecmp(unit, "px") == 0) {
|
||||
return RESIZE_UNIT_PX;
|
||||
|
@ -37,6 +48,69 @@ static enum resize_unit parse_resize_unit(const char *unit) {
|
|||
return RESIZE_UNIT_INVALID;
|
||||
}
|
||||
|
||||
// Parse arguments such as "10", "10px" or "10 px".
|
||||
// Returns the number of arguments consumed.
|
||||
static int parse_resize_amount(int argc, char **argv,
|
||||
struct resize_amount *amount) {
|
||||
char *err;
|
||||
amount->amount = (int)strtol(argv[0], &err, 10);
|
||||
if (*err) {
|
||||
// e.g. 10px
|
||||
amount->unit = parse_resize_unit(err);
|
||||
return 1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
amount->unit = RESIZE_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
// Try the second argument
|
||||
amount->unit = parse_resize_unit(argv[1]);
|
||||
if (amount->unit == RESIZE_UNIT_INVALID) {
|
||||
amount->unit = RESIZE_UNIT_DEFAULT;
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void calculate_constraints(int *min_width, int *max_width,
|
||||
int *min_height, int *max_height) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
|
||||
if (config->floating_minimum_width == -1) { // no minimum
|
||||
*min_width = 0;
|
||||
} else if (config->floating_minimum_width == 0) { // automatic
|
||||
*min_width = 75;
|
||||
} else {
|
||||
*min_width = config->floating_minimum_width;
|
||||
}
|
||||
|
||||
if (config->floating_minimum_height == -1) { // no minimum
|
||||
*min_height = 0;
|
||||
} else if (config->floating_minimum_height == 0) { // automatic
|
||||
*min_height = 50;
|
||||
} else {
|
||||
*min_height = config->floating_minimum_height;
|
||||
}
|
||||
|
||||
if (config->floating_maximum_width == -1) { // no maximum
|
||||
*max_width = INT_MAX;
|
||||
} else if (config->floating_maximum_width == 0) { // automatic
|
||||
struct sway_container *ws = container_parent(con, C_WORKSPACE);
|
||||
*max_width = ws->width;
|
||||
} else {
|
||||
*max_width = config->floating_maximum_width;
|
||||
}
|
||||
|
||||
if (config->floating_maximum_height == -1) { // no maximum
|
||||
*max_height = INT_MAX;
|
||||
} else if (config->floating_maximum_height == 0) { // automatic
|
||||
struct sway_container *ws = container_parent(con, C_WORKSPACE);
|
||||
*max_height = ws->height;
|
||||
} else {
|
||||
*max_height = config->floating_maximum_height;
|
||||
}
|
||||
}
|
||||
|
||||
static enum resize_axis parse_resize_axis(const char *axis) {
|
||||
if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) {
|
||||
return RESIZE_AXIS_HORIZONTAL;
|
||||
|
@ -44,6 +118,18 @@ static enum resize_axis parse_resize_axis(const char *axis) {
|
|||
if (strcasecmp(axis, "height") == 0 || strcasecmp(axis, "vertical") == 0) {
|
||||
return RESIZE_AXIS_VERTICAL;
|
||||
}
|
||||
if (strcasecmp(axis, "up") == 0) {
|
||||
return RESIZE_AXIS_UP;
|
||||
}
|
||||
if (strcasecmp(axis, "down") == 0) {
|
||||
return RESIZE_AXIS_DOWN;
|
||||
}
|
||||
if (strcasecmp(axis, "left") == 0) {
|
||||
return RESIZE_AXIS_LEFT;
|
||||
}
|
||||
if (strcasecmp(axis, "right") == 0) {
|
||||
return RESIZE_AXIS_RIGHT;
|
||||
}
|
||||
return RESIZE_AXIS_INVALID;
|
||||
}
|
||||
|
||||
|
@ -95,7 +181,7 @@ static void resize_tiled(int amount, enum resize_axis axis) {
|
|||
return;
|
||||
}
|
||||
|
||||
wlr_log(L_DEBUG,
|
||||
wlr_log(WLR_DEBUG,
|
||||
"Found the proper parent: %p. It has %d l conts, and %d r conts",
|
||||
parent->parent, minor_weight, major_weight);
|
||||
|
||||
|
@ -182,32 +268,286 @@ static void resize_tiled(int amount, enum resize_axis axis) {
|
|||
}
|
||||
}
|
||||
|
||||
arrange_and_commit(parent->parent);
|
||||
arrange_windows(parent->parent);
|
||||
}
|
||||
|
||||
static void resize(int amount, enum resize_axis axis, enum resize_unit unit) {
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
if (unit == RESIZE_UNIT_DEFAULT) {
|
||||
// Default for tiling; TODO floating should be px
|
||||
unit = RESIZE_UNIT_PPT;
|
||||
}
|
||||
|
||||
if (unit == RESIZE_UNIT_PPT) {
|
||||
float pct = amount / 100.0f;
|
||||
/**
|
||||
* Implement `resize <grow|shrink>` for a floating container.
|
||||
*/
|
||||
static struct cmd_results *resize_adjust_floating(enum resize_axis axis,
|
||||
struct resize_amount *amount) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
int grow_width = 0, grow_height = 0;
|
||||
switch (axis) {
|
||||
case RESIZE_AXIS_HORIZONTAL:
|
||||
amount = (float)current->width * pct;
|
||||
case RESIZE_AXIS_LEFT:
|
||||
case RESIZE_AXIS_RIGHT:
|
||||
grow_width = amount->amount;
|
||||
break;
|
||||
case RESIZE_AXIS_VERTICAL:
|
||||
amount = (float)current->height * pct;
|
||||
case RESIZE_AXIS_UP:
|
||||
case RESIZE_AXIS_DOWN:
|
||||
grow_height = amount->amount;
|
||||
break;
|
||||
default:
|
||||
sway_assert(0, "invalid resize axis");
|
||||
return;
|
||||
case RESIZE_AXIS_INVALID:
|
||||
return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction");
|
||||
}
|
||||
// Make sure we're not adjusting beyond floating min/max size
|
||||
int min_width, max_width, min_height, max_height;
|
||||
calculate_constraints(&min_width, &max_width, &min_height, &max_height);
|
||||
if (con->width + grow_width < min_width) {
|
||||
grow_width = min_width - con->width;
|
||||
} else if (con->width + grow_width > max_width) {
|
||||
grow_width = max_width - con->width;
|
||||
}
|
||||
if (con->height + grow_height < min_height) {
|
||||
grow_height = min_height - con->height;
|
||||
} else if (con->height + grow_height > max_height) {
|
||||
grow_height = max_height - con->height;
|
||||
}
|
||||
int grow_x = 0, grow_y = 0;
|
||||
switch (axis) {
|
||||
case RESIZE_AXIS_HORIZONTAL:
|
||||
grow_x = -grow_width / 2;
|
||||
break;
|
||||
case RESIZE_AXIS_VERTICAL:
|
||||
grow_y = -grow_height / 2;
|
||||
break;
|
||||
case RESIZE_AXIS_UP:
|
||||
grow_y = -grow_height;
|
||||
break;
|
||||
case RESIZE_AXIS_LEFT:
|
||||
grow_x = -grow_width;
|
||||
break;
|
||||
case RESIZE_AXIS_DOWN:
|
||||
case RESIZE_AXIS_RIGHT:
|
||||
break;
|
||||
case RESIZE_AXIS_INVALID:
|
||||
return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction");
|
||||
}
|
||||
con->x += grow_x;
|
||||
con->y += grow_y;
|
||||
con->width += grow_width;
|
||||
con->height += grow_height;
|
||||
|
||||
if (con->type == C_VIEW) {
|
||||
struct sway_view *view = con->sway_view;
|
||||
view->x += grow_x;
|
||||
view->y += grow_y;
|
||||
view->width += grow_width;
|
||||
view->height += grow_height;
|
||||
}
|
||||
|
||||
arrange_windows(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement `resize <grow|shrink>` for a tiled container.
|
||||
*/
|
||||
static struct cmd_results *resize_adjust_tiled(enum resize_axis axis,
|
||||
struct resize_amount *amount) {
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
|
||||
if (amount->unit == RESIZE_UNIT_DEFAULT) {
|
||||
amount->unit = RESIZE_UNIT_PPT;
|
||||
}
|
||||
if (amount->unit == RESIZE_UNIT_PPT) {
|
||||
float pct = amount->amount / 100.0f;
|
||||
// TODO: Make left/right/up/down resize in that direction?
|
||||
switch (axis) {
|
||||
case RESIZE_AXIS_LEFT:
|
||||
case RESIZE_AXIS_RIGHT:
|
||||
case RESIZE_AXIS_HORIZONTAL:
|
||||
amount->amount = (float)current->width * pct;
|
||||
break;
|
||||
case RESIZE_AXIS_UP:
|
||||
case RESIZE_AXIS_DOWN:
|
||||
case RESIZE_AXIS_VERTICAL:
|
||||
amount->amount = (float)current->height * pct;
|
||||
break;
|
||||
case RESIZE_AXIS_INVALID:
|
||||
return cmd_results_new(CMD_INVALID, "resize",
|
||||
"Invalid resize axis/direction");
|
||||
}
|
||||
}
|
||||
|
||||
return resize_tiled(amount, axis);
|
||||
resize_tiled(amount->amount, axis);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement `resize set` for a tiled container.
|
||||
*/
|
||||
static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
||||
struct resize_amount *width, struct resize_amount *height) {
|
||||
return cmd_results_new(CMD_INVALID, "resize",
|
||||
"'resize set' is not implemented for tiled views");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement `resize set` for a floating container.
|
||||
*/
|
||||
static struct cmd_results *resize_set_floating(struct sway_container *con,
|
||||
struct resize_amount *width, struct resize_amount *height) {
|
||||
int min_width, max_width, min_height, max_height;
|
||||
calculate_constraints(&min_width, &max_width, &min_height, &max_height);
|
||||
width->amount = fmax(min_width, fmin(width->amount, max_width));
|
||||
height->amount = fmax(min_height, fmin(height->amount, max_height));
|
||||
int grow_width = width->amount - con->width;
|
||||
int grow_height = height->amount - con->height;
|
||||
con->x -= grow_width / 2;
|
||||
con->y -= grow_height / 2;
|
||||
con->width = width->amount;
|
||||
con->height = height->amount;
|
||||
|
||||
if (con->type == C_VIEW) {
|
||||
struct sway_view *view = con->sway_view;
|
||||
view->x -= grow_width / 2;
|
||||
view->y -= grow_height / 2;
|
||||
view->width += grow_width;
|
||||
view->height += grow_height;
|
||||
}
|
||||
|
||||
arrange_windows(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* resize set <args>
|
||||
*
|
||||
* args: <width> [px|ppt] <height> [px|ppt]
|
||||
*/
|
||||
static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
||||
struct cmd_results *error;
|
||||
if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) {
|
||||
return error;
|
||||
}
|
||||
const char *usage = "Expected 'resize set <width> <height>'";
|
||||
|
||||
// Width
|
||||
struct resize_amount width;
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &width);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (width.unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
|
||||
// Height
|
||||
struct resize_amount height;
|
||||
num_consumed_args = parse_resize_amount(argc, argv, &height);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (height.unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
|
||||
// If 0, don't resize that dimension
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
if (width.amount <= 0) {
|
||||
width.amount = con->width;
|
||||
}
|
||||
if (height.amount <= 0) {
|
||||
height.amount = con->height;
|
||||
}
|
||||
|
||||
if (container_is_floating(con)) {
|
||||
return resize_set_floating(con, &width, &height);
|
||||
}
|
||||
return resize_set_tiled(con, &width, &height);
|
||||
}
|
||||
|
||||
/**
|
||||
* resize <grow|shrink> <args>
|
||||
*
|
||||
* args: <direction>
|
||||
* args: <direction> <amount> <unit>
|
||||
* args: <direction> <amount> <unit> or <amount> <other_unit>
|
||||
*/
|
||||
static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
||||
int multiplier) {
|
||||
const char *usage = "Expected 'resize grow|shrink <direction> "
|
||||
"[<amount> px|ppt [or <amount> px|ppt]]'";
|
||||
enum resize_axis axis = parse_resize_axis(*argv);
|
||||
if (axis == RESIZE_AXIS_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
--argc; ++argv;
|
||||
|
||||
// First amount
|
||||
struct resize_amount first_amount;
|
||||
if (argc) {
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &first_amount);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (first_amount.unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
} else {
|
||||
first_amount.amount = 10;
|
||||
first_amount.unit = RESIZE_UNIT_DEFAULT;
|
||||
}
|
||||
|
||||
// "or"
|
||||
if (argc) {
|
||||
if (strcmp(*argv, "or") != 0) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
|
||||
// Second amount
|
||||
struct resize_amount second_amount;
|
||||
if (argc) {
|
||||
int num_consumed_args = parse_resize_amount(argc, argv, &second_amount);
|
||||
argc -= num_consumed_args;
|
||||
argv += num_consumed_args;
|
||||
if (second_amount.unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
} else {
|
||||
second_amount.unit = RESIZE_UNIT_INVALID;
|
||||
}
|
||||
|
||||
first_amount.amount *= multiplier;
|
||||
second_amount.amount *= multiplier;
|
||||
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
if (container_is_floating(con)) {
|
||||
// Floating containers can only resize in px. Choose an amount which
|
||||
// uses px, with fallback to an amount that specified no unit.
|
||||
if (first_amount.unit == RESIZE_UNIT_PX) {
|
||||
return resize_adjust_floating(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_PX) {
|
||||
return resize_adjust_floating(axis, &second_amount);
|
||||
} else if (first_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
return resize_adjust_floating(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
return resize_adjust_floating(axis, &second_amount);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "resize",
|
||||
"Floating containers cannot use ppt measurements");
|
||||
}
|
||||
}
|
||||
|
||||
// For tiling, prefer ppt -> default -> px
|
||||
if (first_amount.unit == RESIZE_UNIT_PPT) {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_PPT) {
|
||||
return resize_adjust_tiled(axis, &second_amount);
|
||||
} else if (first_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
} else if (second_amount.unit == RESIZE_UNIT_DEFAULT) {
|
||||
return resize_adjust_tiled(axis, &second_amount);
|
||||
} else {
|
||||
return resize_adjust_tiled(axis, &first_amount);
|
||||
}
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_resize(int argc, char **argv) {
|
||||
|
@ -226,61 +566,17 @@ struct cmd_results *cmd_resize(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (strcasecmp(argv[0], "set") == 0) {
|
||||
// TODO
|
||||
//return cmd_resize_set(argc - 1, &argv[1]);
|
||||
return cmd_results_new(CMD_INVALID, "resize", "resize set unimplemented");
|
||||
return cmd_resize_set(argc - 1, &argv[1]);
|
||||
}
|
||||
if (strcasecmp(argv[0], "grow") == 0) {
|
||||
return cmd_resize_adjust(argc - 1, &argv[1], 1);
|
||||
}
|
||||
if (strcasecmp(argv[0], "shrink") == 0) {
|
||||
return cmd_resize_adjust(argc - 1, &argv[1], -1);
|
||||
}
|
||||
|
||||
// TODO: resize grow|shrink left|right|up|down
|
||||
|
||||
const char *usage = "Expected 'resize <shrink|grow> "
|
||||
"<width|height> [<amount>] [px|ppt]'";
|
||||
"<width|height|up|down|left|right> [<amount>] [px|ppt]'";
|
||||
|
||||
int multiplier = 0;
|
||||
if (strcasecmp(*argv, "grow") == 0) {
|
||||
multiplier = 1;
|
||||
} else if (strcasecmp(*argv, "shrink") == 0) {
|
||||
multiplier = -1;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
--argc; ++argv;
|
||||
|
||||
enum resize_axis axis = parse_resize_axis(*argv);
|
||||
if (axis == RESIZE_AXIS_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
--argc; ++argv;
|
||||
|
||||
int amount = 10; // Default amount
|
||||
enum resize_unit unit = RESIZE_UNIT_DEFAULT;
|
||||
|
||||
if (argc) {
|
||||
char *err;
|
||||
amount = (int)strtol(*argv, &err, 10);
|
||||
if (*err) {
|
||||
// e.g. `resize grow width 10px`
|
||||
unit = parse_resize_unit(err);
|
||||
if (unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
unit = parse_resize_unit(*argv);
|
||||
if (unit == RESIZE_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
// Provied too many args, the bastard
|
||||
return cmd_results_new(CMD_INVALID, "resize", usage);
|
||||
}
|
||||
|
||||
resize(amount * multiplier, axis, unit);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue