+static bool resize_set_tiling(I3_CMD, Con *target, orientation_t resize_orientation, bool is_ppt, long target_size) {
+ direction_t search_direction;
+ char *mode;
+ if (resize_orientation == HORIZ) {
+ search_direction = D_LEFT;
+ mode = "width";
+ } else {
+ search_direction = D_DOWN;
+ mode = "height";
+ }
+
+ /* Get the appropriate current container (skip stacked/tabbed cons) */
+ Con *dummy;
+ resize_find_tiling_participants(&target, &dummy, search_direction, true);
+
+ /* Calculate new size for the target container */
+ double ppt = 0.0;
+ int px = 0;
+ if (is_ppt) {
+ ppt = (double)target_size / 100.0 - target->percent;
+ } else {
+ px = target_size - (resize_orientation == HORIZ ? target->rect.width : target->rect.height);
+ }
+
+ /* Perform resizing and report failure if not possible */
+ return cmd_resize_tiling_width_height(current_match, cmd_output,
+ target, mode, px, ppt);
+}
+
+/*
+ * Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
+ *
+ */
+void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) {
+ DLOG("resizing to %ld %s x %ld %s\n", cwidth, mode_width, cheight, mode_height);
+ if (cwidth < 0 || cheight < 0) {
+ ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height);
+ return;
+ }
+
+ HANDLE_EMPTY_MATCH;
+
+ owindow *current;
+ bool success = true;
+ TAILQ_FOREACH(current, &owindows, owindows) {
+ Con *floating_con;
+ if ((floating_con = con_inside_floating(current->con))) {
+ Con *output = con_get_output(floating_con);
+ if (cwidth == 0) {
+ cwidth = floating_con->rect.width;
+ } else if (mode_width && strcmp(mode_width, "ppt") == 0) {
+ cwidth = output->rect.width * ((double)cwidth / 100.0);
+ }
+ if (cheight == 0) {
+ cheight = floating_con->rect.height;
+ } else if (mode_height && strcmp(mode_height, "ppt") == 0) {
+ cheight = output->rect.height * ((double)cheight / 100.0);
+ }
+ floating_resize(floating_con, cwidth, cheight);
+ } else {
+ if (current->con->window && current->con->window->dock) {
+ DLOG("This is a dock window. Not resizing (con = %p)\n)", current->con);
+ continue;
+ }
+
+ if (cwidth > 0 && mode_width) {
+ success &= resize_set_tiling(current_match, cmd_output, current->con,
+ HORIZ, strcmp(mode_width, "ppt") == 0, cwidth);
+ }
+ if (cheight > 0 && mode_height) {
+ success &= resize_set_tiling(current_match, cmd_output, current->con,
+ VERT, strcmp(mode_height, "ppt") == 0, cheight);
+ }
+ }
+ }
+
+ cmd_output->needs_tree_render = true;
+ ysuccess(success);
+}
+
+static int border_width_from_style(border_style_t border_style, long border_width, Con *con) {
+ if (border_style == BS_NONE) {
+ return 0;
+ }
+ if (border_width >= 0) {
+ return logical_px(border_width);
+ }
+
+ const bool is_floating = con_inside_floating(con) != NULL;
+ /* Load the configured defaults. */
+ if (is_floating && border_style == config.default_floating_border) {
+ return config.default_floating_border_width;
+ } else if (!is_floating && border_style == config.default_border) {
+ return config.default_border_width;
+ } else {
+ /* Use some hardcoded values. */
+ return logical_px(border_style == BS_NORMAL ? 2 : 1);
+ }
+}
+