From b7f4607544d51811e986b98c8c3eda7ed7c68b1a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 22 Aug 2015 11:18:55 -0400 Subject: [PATCH] Implement output configuration through config Do not use `output res WIDTHxHEIGHT` yet, wlc has issues with it (cc @Cloudef) --- include/config.h | 7 ++++++ sway.5.txt | 46 ++++++++++++++++++++++-------------- sway/commands.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ sway/config.c | 2 ++ sway/container.c | 25 ++++++++++++++++---- 5 files changed, 120 insertions(+), 21 deletions(-) diff --git a/include/config.h b/include/config.h index c23c3509..c896b423 100644 --- a/include/config.h +++ b/include/config.h @@ -22,6 +22,12 @@ struct sway_mode { list_t *bindings; }; +struct output_config { + char *name; + int width, height; + int x, y; +}; + struct workspace_output { char *output; char *workspace; @@ -32,6 +38,7 @@ struct sway_config { list_t *modes; list_t *cmd_queue; list_t *workspace_outputs; + list_t *output_configs; struct sway_mode *current_mode; uint32_t floating_mod; diff --git a/sway.5.txt b/sway.5.txt index 5bccbd12..e0052ee1 100644 --- a/sway.5.txt +++ b/sway.5.txt @@ -41,6 +41,11 @@ Commands **floating** toggle:: Toggles the "floating" status of the focused view. +**floating_modifier** :: + When the _modifier_ key is held down, you may use left click to drag floating + windows, and right click to resize them. Unlike i3, this modifier may also be + used to resize and move windows that are tiled. + **focus** :: Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The directional focus commands will move the focus in that direction. The parent @@ -55,6 +60,16 @@ Commands If set to _yes_, the currently focused view will change as you move your mouse around the screen to the view that ends up underneath your mouse. +**fullscreen**:: + Toggles fullscreen status for the focused view. + +**gaps** :: + Adds _amount_ pixels between each view, and around each output. + +**gaps** :: + Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects + spacing between views and the latter affects the space around each output. + **kill**:: Closes the currently focused view. @@ -62,16 +77,27 @@ Commands Sets the layout mode of the focused container. _mode_ can be one of _splith_, _splitv_, or _toggle split_. +**move** :: + Moves the focused container _left_, _right_, _up_, or _down_. + +**output** :: + Configures the specified output. It will use the given resolution and be + arranged at the given position in the layout tree. You may omit either of + these parameters if you only want to set one of them. + **reload**:: Reloads the sway config file without restarting sway. +**resize** :: + Resizes the currently focused container or view by _amount_. _amount_ can be + specified as "n px" or "n ppt" or "n px or n ppt". + **set** :: Creates a substitution for _value_ that can be used with $_name_ in other commands. -**split** :: - Splits the current container, vertically or horiziontally. The letters "h" and - "v" can be used instead of the full words "vertical" or "horizontal". +**split** :: + Splits the current container, vertically or horiziontally. **splith**:: Equivalent to **split horizontal**. @@ -79,20 +105,6 @@ Commands **splitv**:: Equivalent to **split vertical**. -**floating_modifier** :: - When the _modifier_ key is held down, you may use left click to drag floating - windows, and right click to resize them. - -**fullscreen**:: - Toggles fullscreen status for the focused view. - -**gaps** :: - Adds _amount_ pixels between each view, and around each output. - -**gaps** :: - Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects - spacing between views and the latter affects the space around each output. - **workspace** :: Switches to the specified workspace. diff --git a/sway/commands.c b/sway/commands.c index 62794111..5de1fb0c 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -364,6 +364,66 @@ static bool cmd_move(struct sway_config *config, int argc, char **argv) { return true; } +static bool cmd_output(struct sway_config *config, int argc, char **argv) { + if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) { + return false; + } + + struct output_config *output = calloc(1, sizeof(struct output_config)); + output->x = output->y = output->width = output->height = -1; + output->name = strdup(argv[0]); + + // TODO: atoi doesn't handle invalid numbers + + int i; + for (i = 1; i < argc; ++i) { + if (strcasecmp(argv[i], "resolution") == 0 || strcasecmp(argv[i], "res") == 0) { + char *res = argv[++i]; + char *x = strchr(res, 'x'); + int width = -1, height = -1; + if (x != NULL) { + // Format is 1234x4321 + *x = '\0'; + width = atoi(res); + height = atoi(x + 1); + *x = 'x'; + } else { + // Format is 1234 4321 + width = atoi(res); + res = argv[++i]; + height = atoi(res); + } + output->width = width; + output->height = height; + } else if (strcasecmp(argv[i], "position") == 0 || strcasecmp(argv[i], "pos") == 0) { + char *res = argv[++i]; + char *c = strchr(res, ','); + int x = -1, y = -1; + if (c != NULL) { + // Format is 1234,4321 + *c = '\0'; + x = atoi(res); + y = atoi(c + 1); + *c = ','; + } else { + // Format is 1234 4321 + x = atoi(res); + res = argv[++i]; + y = atoi(res); + } + output->x = x; + output->y = y; + } + } + + list_add(config->output_configs, output); + + sway_log(L_DEBUG, "Configured output %s to %d x %d @ %d, %d", + output->name, output->width, output->height, output->x, output->y); + + return true; +} + static bool cmd_gaps(struct sway_config *config, int argc, char **argv) { if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) { return false; @@ -637,6 +697,7 @@ static struct cmd_handler handlers[] = { { "layout", cmd_layout }, { "log_colors", cmd_log_colors }, { "move", cmd_move}, + { "output", cmd_output}, { "reload", cmd_reload }, { "resize", cmd_resize }, { "set", cmd_set }, diff --git a/sway/config.c b/sway/config.c index 1ebd95ff..fcd60de7 100644 --- a/sway/config.c +++ b/sway/config.c @@ -22,6 +22,7 @@ void config_defaults(struct sway_config *config) { config->modes = create_list(); config->cmd_queue = create_list(); config->workspace_outputs = create_list(); + config->output_configs = create_list(); config->current_mode = malloc(sizeof(struct sway_mode)); config->current_mode->name = NULL; config->current_mode->bindings = create_list(); @@ -60,6 +61,7 @@ void free_config(struct sway_config *config) { free(sym->value); } free_flat_list(config->symbols); + free_flat_list(config->output_configs); } static const char *search_paths[] = { diff --git a/sway/container.c b/sway/container.c index 62ff1c4a..7f6fcbc6 100644 --- a/sway/container.c +++ b/sway/container.c @@ -55,13 +55,31 @@ static void free_swayc(swayc_t *cont) { // New containers swayc_t *new_output(wlc_handle handle) { - const struct wlc_size* size = wlc_output_get_resolution(handle); + const struct wlc_size *size = wlc_output_get_resolution(handle); const char *name = wlc_output_get_name(handle); sway_log(L_DEBUG, "Added output %lu:%s", handle, name); + struct output_config *oc ; + int i; + for (i = 0; i < config->output_configs->length; ++i) { + oc = config->output_configs->items[i]; + if (strcasecmp(name, oc->name) == 0) { + sway_log(L_DEBUG, "Matched output config for %s", name); + break; + } + oc = NULL; + } + swayc_t *output = new_swayc(C_OUTPUT); - output->width = size->w; - output->height = size->h; + if (oc && oc->width != -1 && oc->height != -1) { + output->width = oc->width; + output->height = oc->height; + struct wlc_size new_size = { .w = oc->width, .h = oc->width }; + wlc_output_set_resolution(handle, &new_size); + } else { + output->width = size->w; + output->height = size->h; + } output->handle = handle; output->name = name ? strdup(name) : NULL; output->gaps = config->gaps_outer + config->gaps_inner / 2; @@ -71,7 +89,6 @@ swayc_t *new_output(wlc_handle handle) { // Create workspace char *ws_name = NULL; if (name) { - int i; for (i = 0; i < config->workspace_outputs->length; ++i) { struct workspace_output *wso = config->workspace_outputs->items[i]; if (strcasecmp(wso->output, name) == 0) {