]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #3080 from orestisf1993/cmd_move_con_to_workspace
authorIngo Bürk <admin@airblader.de>
Wed, 17 Jan 2018 20:26:09 +0000 (21:26 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Jan 2018 20:26:09 +0000 (21:26 +0100)
 Reduce repetition in cmd_move_con_to_workspace*

1  2 
src/commands.c

diff --combined src/commands.c
index 73164f325a07a7f19bb50fd3028e5ae9c44e2730,02d14daac01392d47baf7cb3cdf6ba05319b1687..899bbb90c8f0854254b4d36b52e0e2a21619e034
          }                                               \
      } while (0)
  
 -/*
 - * Returns true if a is definitely greater than b (using the given epsilon)
 - *
 - */
 -static bool definitelyGreaterThan(float a, float b, float epsilon) {
 -    return (a - b) > ((fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
 -}
 -
  /*
   * Checks whether we switched to a new workspace and returns false in that case,
   * signaling that further workspace switching should be done by the calling function
@@@ -261,14 -269,20 +261,20 @@@ void cmd_criteria_add(I3_CMD, const cha
      match_parse_property(current_match, ctype, cvalue);
  }
  
+ static void move_matches_to_workspace(Con *ws) {
+     owindow *current;
+     TAILQ_FOREACH(current, &owindows, owindows) {
+         DLOG("matching: %p / %s\n", current->con, current->con->name);
+         con_move_to_workspace(current->con, ws, true, false, false);
+     }
+ }
  /*
   * Implementation of 'move [window|container] [to] workspace
   * next|prev|next_on_output|prev_on_output|current'.
   *
   */
  void cmd_move_con_to_workspace(I3_CMD, const char *which) {
-     owindow *current;
      DLOG("which=%s\n", which);
  
      /* We have nothing to move:
          return;
      }
  
-     TAILQ_FOREACH(current, &owindows, owindows) {
-         DLOG("matching: %p / %s\n", current->con, current->con->name);
-         con_move_to_workspace(current->con, ws, true, false, false);
-     }
+     move_matches_to_workspace(ws);
  
      cmd_output->needs_tree_render = true;
      // XXX: default reply for now, make this a better reply
   *
   */
  void cmd_move_con_to_workspace_back_and_forth(I3_CMD) {
-     owindow *current;
-     Con *ws;
-     ws = workspace_back_and_forth_get();
+     Con *ws = workspace_back_and_forth_get();
      if (ws == NULL) {
          yerror("No workspace was previously active.");
          return;
  
      HANDLE_EMPTY_MATCH;
  
-     TAILQ_FOREACH(current, &owindows, owindows) {
-         DLOG("matching: %p / %s\n", current->con, current->con->name);
-         con_move_to_workspace(current->con, ws, true, false, false);
-     }
+     move_matches_to_workspace(ws);
  
      cmd_output->needs_tree_render = true;
      // XXX: default reply for now, make this a better reply
@@@ -350,7 -354,6 +346,6 @@@ void cmd_move_con_to_workspace_name(I3_
      }
  
      const bool no_auto_back_and_forth = (_no_auto_back_and_forth != NULL);
-     owindow *current;
  
      /* We have nothing to move:
       *  when criteria was specified but didn't match any window or
  
      HANDLE_EMPTY_MATCH;
  
-     TAILQ_FOREACH(current, &owindows, owindows) {
-         DLOG("matching: %p / %s\n", current->con, current->con->name);
-         con_move_to_workspace(current->con, ws, true, false, false);
-     }
+     move_matches_to_workspace(ws);
  
      cmd_output->needs_tree_render = true;
      // XXX: default reply for now, make this a better reply
   */
  void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *_no_auto_back_and_forth) {
      const bool no_auto_back_and_forth = (_no_auto_back_and_forth != NULL);
-     owindow *current;
  
      /* We have nothing to move:
       *  when criteria was specified but didn't match any window or
  
      LOG("should move window to workspace %s\n", which);
      /* get the workspace */
-     Con *output, *workspace = NULL;
+     Con *output, *ws = NULL;
  
      long parsed_num = ws_name_to_number(which);
  
      }
  
      TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
-     GREP_FIRST(workspace, output_get_content(output),
+     GREP_FIRST(ws, output_get_content(output),
                 child->num == parsed_num);
  
-     if (!workspace) {
-         workspace = workspace_get(which, NULL);
+     if (!ws) {
+         ws = workspace_get(which, NULL);
      }
  
      if (!no_auto_back_and_forth)
-         workspace = maybe_auto_back_and_forth_workspace(workspace);
+         ws = maybe_auto_back_and_forth_workspace(ws);
  
      HANDLE_EMPTY_MATCH;
  
-     TAILQ_FOREACH(current, &owindows, owindows) {
-         DLOG("matching: %p / %s\n", current->con, current->con->name);
-         con_move_to_workspace(current->con, workspace, true, false, false);
-     }
+     move_matches_to_workspace(ws);
  
      cmd_output->needs_tree_render = true;
      // XXX: default reply for now, make this a better reply
@@@ -503,7 -499,7 +491,7 @@@ static bool cmd_resize_tiling_direction
      else
          search_direction = D_DOWN;
  
 -    bool res = resize_find_tiling_participants(&first, &second, search_direction);
 +    bool res = resize_find_tiling_participants(&first, &second, search_direction, false);
      if (!res) {
          LOG("No second container in this direction found.\n");
          ysuccess(false);
      LOG("default percentage = %f\n", percentage);
  
      /* resize */
 -    LOG("second->percent = %f\n", second->percent);
      LOG("first->percent before = %f\n", first->percent);
 +    LOG("second->percent before = %f\n", second->percent);
      if (first->percent == 0.0)
          first->percent = percentage;
      if (second->percent == 0.0)
      double new_second_percent = second->percent - ((double)ppt / 100.0);
      LOG("new_first_percent = %f\n", new_first_percent);
      LOG("new_second_percent = %f\n", new_second_percent);
 -    /* Ensure that the new percentages are positive and greater than
 -     * 0.05 to have a reasonable minimum size. */
 -    if (definitelyGreaterThan(new_first_percent, 0.05, DBL_EPSILON) &&
 -        definitelyGreaterThan(new_second_percent, 0.05, DBL_EPSILON)) {
 -        first->percent += ((double)ppt / 100.0);
 -        second->percent -= ((double)ppt / 100.0);
 +    /* Ensure that the new percentages are positive. */
 +    if (new_first_percent > 0.0 && new_second_percent > 0.0) {
 +        first->percent = new_first_percent;
 +        second->percent = new_second_percent;
          LOG("first->percent after = %f\n", first->percent);
          LOG("second->percent after = %f\n", second->percent);
      } else {
  
  static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *way, const char *direction, int ppt) {
      LOG("width/height resize\n");
 -    /* get the appropriate current container (skip stacked/tabbed cons) */
 -    while (current->parent->layout == L_STACKED ||
 -           current->parent->layout == L_TABBED)
 -        current = current->parent;
  
 -    /* Then further go up until we find one with the matching orientation. */
 -    orientation_t search_orientation =
 -        (strcmp(direction, "width") == 0 ? HORIZ : VERT);
 -
 -    while (current->type != CT_WORKSPACE &&
 -           current->type != CT_FLOATING_CON &&
 -           (con_orientation(current->parent) != search_orientation || con_num_children(current->parent) == 1))
 -        current = current->parent;
 +    /* get the appropriate current container (skip stacked/tabbed cons) */
 +    Con *dummy = NULL;
 +    direction_t search_direction = (strcmp(direction, "width") == 0 ? D_LEFT : D_DOWN);
 +    bool search_result = resize_find_tiling_participants(&current, &dummy, search_direction, true);
 +    if (search_result == false) {
 +        ysuccess(false);
 +        return false;
 +    }
  
      /* get the default percentage */
      int children = con_num_children(current->parent);
      double percentage = 1.0 / children;
      LOG("default percentage = %f\n", percentage);
  
 -    orientation_t orientation = con_orientation(current->parent);
 -
 -    if ((orientation == HORIZ &&
 -         strcmp(direction, "height") == 0) ||
 -        (orientation == VERT &&
 -         strcmp(direction, "width") == 0)) {
 -        LOG("You cannot resize in that direction. Your focus is in a %s split container currently.\n",
 -            (orientation == HORIZ ? "horizontal" : "vertical"));
 -        ysuccess(false);
 -        return false;
 -    }
 -
 -    if (children == 1) {
 -        LOG("This is the only container, cannot resize.\n");
 -        ysuccess(false);
 -        return false;
 -    }
 -
      /* Ensure all the other children have a percentage set. */
      Con *child;
      TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
      double subtract_percent = ((double)ppt / 100.0) / (children - 1);
      LOG("new_current_percent = %f\n", new_current_percent);
      LOG("subtract_percent = %f\n", subtract_percent);
 -    /* Ensure that the new percentages are positive and greater than
 -     * 0.05 to have a reasonable minimum size. */
 +    /* Ensure that the new percentages are positive. */
      TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
          if (child == current)
              continue;
 -        if (!definitelyGreaterThan(child->percent - subtract_percent, 0.05, DBL_EPSILON)) {
 +        if (child->percent - subtract_percent <= 0.0) {
              LOG("Not resizing, already at minimum size (child %p would end up with a size of %.f\n", child, child->percent - subtract_percent);
              ysuccess(false);
              return false;
          }
      }
 -    if (!definitelyGreaterThan(new_current_percent, 0.05, DBL_EPSILON)) {
 +    if (new_current_percent <= 0.0) {
          LOG("Not resizing, already at minimum size\n");
          ysuccess(false);
          return false;
      }
  
 -    current->percent += ((double)ppt / 100.0);
 +    current->percent = new_current_percent;
      LOG("current->percent after = %f\n", current->percent);
  
      TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
@@@ -648,7 -669,7 +636,7 @@@ void cmd_resize(I3_CMD, const char *way
   */
  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) {
 +    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 (mode_width && strcmp(mode_width, "ppt") == 0) {
 +            if (cwidth == 0) {
 +                cwidth = output->rect.width;
 +            } else if (mode_width && strcmp(mode_width, "ppt") == 0) {
                  cwidth = output->rect.width * ((double)cwidth / 100.0);
              }
 -            if (mode_height && strcmp(mode_height, "ppt") == 0) {
 +            if (cheight == 0) {
 +                cheight = output->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 {
 -            ELOG("Resize failed: %p not a floating container\n", current->con);
 +            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 && strcmp(mode_width, "ppt") == 0) {
 +                /* get the appropriate current container (skip stacked/tabbed cons) */
 +                Con *target = current->con;
 +                Con *dummy;
 +                resize_find_tiling_participants(&target, &dummy, D_LEFT, true);
 +
 +                /* Calculate new size for the target container */
 +                double current_percent = target->percent;
 +                char *action_string;
 +                long adjustment;
 +
 +                if (current_percent > cwidth) {
 +                    action_string = "shrink";
 +                    adjustment = (int)(current_percent * 100) - cwidth;
 +                } else {
 +                    action_string = "grow";
 +                    adjustment = cwidth - (int)(current_percent * 100);
 +                }
 +
 +                /* perform resizing and report failure if not possible */
 +                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
 +                                                    target, action_string, "width", adjustment)) {
 +                    success = false;
 +                }
 +            }
 +
 +            if (cheight > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
 +                /* get the appropriate current container (skip stacked/tabbed cons) */
 +                Con *target = current->con;
 +                Con *dummy;
 +                resize_find_tiling_participants(&target, &dummy, D_DOWN, true);
 +
 +                /* Calculate new size for the target container */
 +                double current_percent = target->percent;
 +                char *action_string;
 +                long adjustment;
 +
 +                if (current_percent > cheight) {
 +                    action_string = "shrink";
 +                    adjustment = (int)(current_percent * 100) - cheight;
 +                } else {
 +                    action_string = "grow";
 +                    adjustment = cheight - (int)(current_percent * 100);
 +                }
 +
 +                /* perform resizing and report failure if not possible */
 +                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
 +                                                    target, action_string, "height", adjustment)) {
 +                    success = false;
 +                }
 +            }
          }
      }
  
      cmd_output->needs_tree_render = true;
 -    // XXX: default reply for now, make this a better reply
 -    ysuccess(true);
 +    ysuccess(success);
  }
  
  /*
@@@ -793,7 -755,6 +781,7 @@@ void cmd_nop(I3_CMD, const char *commen
      LOG("-------------------------------------------------\n");
      LOG("  NOP: %s\n", comment);
      LOG("-------------------------------------------------\n");
 +    ysuccess(true);
  }
  
  /*
@@@ -1288,7 -1249,7 +1276,7 @@@ static void cmd_focus_force_focus(Con *
      if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
          con_disable_fullscreen(fullscreen_on_ws);
      }
 -    con_focus(con);
 +    con_activate(con);
  }
  
  /*
@@@ -1406,12 -1367,12 +1394,12 @@@ void cmd_focus(I3_CMD) 
           * the target workspace, then revert focus. */
          Con *currently_focused = focused;
          cmd_focus_force_focus(current->con);
 -        con_focus(currently_focused);
 +        con_activate(currently_focused);
  
          /* Now switch to the workspace, then focus */
          workspace_show(ws);
          LOG("focusing %p / %s\n", current->con, current->con->name);
 -        con_focus(current->con);
 +        con_activate(current->con);
          count++;
      }
  
@@@ -1523,7 -1484,7 +1511,7 @@@ void cmd_move_direction(I3_CMD, const c
  
      /* the move command should not disturb focus */
      if (focused != initially_focused)
 -        con_focus(initially_focused);
 +        con_activate(initially_focused);
  
      // XXX: default reply for now, make this a better reply
      ysuccess(true);
@@@ -1648,7 -1609,7 +1636,7 @@@ void cmd_open(I3_CMD) 
      LOG("opening new container\n");
      Con *con = tree_open_con(NULL, NULL);
      con->layout = L_SPLITH;
 -    con_focus(con);
 +    con_activate(con);
  
      y(map_open);
      ystr("success");
@@@ -2037,7 -1998,7 +2025,7 @@@ void cmd_rename_workspace(I3_CMD, cons
      }
  
      /* Restore the previous focus since con_attach messes with the focus. */
 -    con_focus(previously_focused);
 +    con_activate(previously_focused);
  
      cmd_output->needs_tree_render = true;
      ysuccess(true);