[BACK]Return to resize.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/resize.c between version 1.41 and 1.42

version 1.41, 2020/06/05 07:33:57 version 1.42, 2020/10/05 10:00:51
Line 92 
Line 92 
         return (0);          return (0);
 }  }
   
 void  static u_int
 default_window_size(struct client *c, struct session *s, struct window *w,  clients_with_window(struct window *w)
     u_int *sx, u_int *sy, u_int *xpixel, u_int *ypixel, int type)  
 {  {
         struct client   *loop;          struct client   *loop;
         u_int            cx, cy, n;          u_int            n = 0;
         const char      *value;  
   
         if (type == -1)          TAILQ_FOREACH(loop, &clients, entry) {
                 type = options_get_number(global_w_options, "window-size");                  if (ignore_client_size(loop) || !session_has(loop->session, w))
         switch (type) {                          continue;
         case WINDOW_SIZE_LARGEST:                  if (++n > 1)
                           break;
           }
           return (n);
   }
   
   static int
   clients_calculate_size(int type, int current, struct session *s,
       struct window *w, int (*skip_client)(struct client *, int, int,
       struct session *, struct window *), u_int *sx, u_int *sy, u_int *xpixel,
       u_int *ypixel)
   {
           struct client   *loop;
           u_int            cx, cy, n = 0;
   
           /* Manual windows do not have their size changed based on a client. */
           if (type == WINDOW_SIZE_MANUAL)
                   return (0);
   
           /*
            * Start comparing with 0 for largest and UINT_MAX for smallest or
            * latest.
            */
           if (type == WINDOW_SIZE_LARGEST)
                 *sx = *sy = 0;                  *sx = *sy = 0;
                 *xpixel = *ypixel = 0;          else
                 TAILQ_FOREACH(loop, &clients, entry) {                  *sx = *sy = UINT_MAX;
                         if (ignore_client_size(loop))          *xpixel = *ypixel = 0;
                                 continue;  
                         if (w != NULL && !session_has(loop->session, w))  
                                 continue;  
                         if (w == NULL && loop->session != s)  
                                 continue;  
   
                         cx = loop->tty.sx;          /*
                         cy = loop->tty.sy - status_line_size(loop);           * For latest, count the number of clients with this window. We only
            * care if there is more than one.
            */
           if (type == WINDOW_SIZE_LATEST)
                   n = clients_with_window(w);
   
           /* Loop over the clients and work out the size. */
           TAILQ_FOREACH(loop, &clients, entry) {
                   if (ignore_client_size(loop))
                           continue;
                   if (skip_client(loop, type, current, s, w))
                           continue;
   
                   /*
                    * If there are multiple clients attached, only accept the
                    * latest client; otherwise let the only client be chosen as
                    * for smallest.
                    */
                   if (type == WINDOW_SIZE_LATEST && n > 1 && loop != w->latest)
                           continue;
   
                   /* Work out this client's size. */
                   cx = loop->tty.sx;
                   cy = loop->tty.sy - status_line_size(loop);
   
                   /*
                    * If it is larger or smaller than the best so far, update the
                    * new size.
                    */
                   if (type == WINDOW_SIZE_LARGEST) {
                         if (cx > *sx)                          if (cx > *sx)
                                 *sx = cx;                                  *sx = cx;
                         if (cy > *sy)                          if (cy > *sy)
                                 *sy = cy;                                  *sy = cy;
                   } else {
                         if (loop->tty.xpixel > *xpixel &&  
                             loop->tty.ypixel > *ypixel) {  
                                 *xpixel = loop->tty.xpixel;  
                                 *ypixel = loop->tty.ypixel;  
                         }  
                 }  
                 if (*sx == 0 || *sy == 0)  
                         goto manual;  
                 break;  
         case WINDOW_SIZE_SMALLEST:  
                 *sx = *sy = UINT_MAX;  
                 *xpixel = *ypixel = 0;  
                 TAILQ_FOREACH(loop, &clients, entry) {  
                         if (ignore_client_size(loop))  
                                 continue;  
                         if (w != NULL && !session_has(loop->session, w))  
                                 continue;  
                         if (w == NULL && loop->session != s)  
                                 continue;  
   
                         cx = loop->tty.sx;  
                         cy = loop->tty.sy - status_line_size(loop);  
   
                         if (cx < *sx)                          if (cx < *sx)
                                 *sx = cx;                                  *sx = cx;
                         if (cy < *sy)                          if (cy < *sy)
                                 *sy = cy;                                  *sy = cy;
   
                         if (loop->tty.xpixel > *xpixel &&  
                             loop->tty.ypixel > *ypixel) {  
                                 *xpixel = loop->tty.xpixel;  
                                 *ypixel = loop->tty.ypixel;  
                         }  
                 }                  }
                 if (*sx == UINT_MAX || *sy == UINT_MAX)                  if (loop->tty.xpixel > *xpixel && loop->tty.ypixel > *ypixel) {
                         goto manual;                          *xpixel = loop->tty.xpixel;
                 break;                          *ypixel = loop->tty.ypixel;
         case WINDOW_SIZE_LATEST:                  }
           }
   
           /* Return whether a suitable size was found. */
           if (type == WINDOW_SIZE_LARGEST)
                   return (*sx != 0 && *sy != 0);
           return (*sx != UINT_MAX && *sy != UINT_MAX);
   }
   
   static int
   default_window_size_skip_client (struct client *loop, int type,
       __unused int current, struct session *s, struct window *w)
   {
           /*
            * Latest checks separately, so do not check here. Otherwise only
            * include clients where the session contains the window or where the
            * session is the given session.
            */
           if (type == WINDOW_SIZE_LATEST)
                   return (0);
           if (w != NULL && !session_has(loop->session, w))
                   return (1);
           if (w == NULL && loop->session != s)
                   return (1);
           return (0);
   }
   
   void
   default_window_size(struct client *c, struct session *s, struct window *w,
           u_int *sx, u_int *sy, u_int *xpixel, u_int *ypixel, int type)
   {
           const char      *value;
   
           /* Get type if not provided. */
           if (type == -1)
                   type = options_get_number(global_w_options, "window-size");
   
           /*
            * Latest clients can use the given client if suitable. If there is no
            * client and no window, use the default size as for manual type.
            */
           if (type == WINDOW_SIZE_LATEST) {
                 if (c != NULL && !ignore_client_size(c)) {                  if (c != NULL && !ignore_client_size(c)) {
                         *sx = c->tty.sx;                          *sx = c->tty.sx;
                         *sy = c->tty.sy - status_line_size(c);                          *sy = c->tty.sy - status_line_size(c);
                         *xpixel = c->tty.xpixel;                          *xpixel = c->tty.xpixel;
                         *ypixel = c->tty.ypixel;                          *ypixel = c->tty.ypixel;
                 } else {                          goto done;
                         if (w == NULL)  
                                 goto manual;  
                         n = 0;  
                         TAILQ_FOREACH(loop, &clients, entry) {  
                                 if (!ignore_client_size(loop) &&  
                                     session_has(loop->session, w)) {  
                                         if (++n > 1)  
                                                 break;  
                                 }  
                         }  
                         *sx = *sy = UINT_MAX;  
                         *xpixel = *ypixel = 0;  
                         TAILQ_FOREACH(loop, &clients, entry) {  
                                 if (ignore_client_size(loop))  
                                         continue;  
                                 if (n > 1 && loop != w->latest)  
                                         continue;  
                                 s = loop->session;  
   
                                 cx = loop->tty.sx;  
                                 cy = loop->tty.sy - status_line_size(loop);  
   
                                 if (cx < *sx)  
                                         *sx = cx;  
                                 if (cy < *sy)  
                                         *sy = cy;  
   
                                 if (loop->tty.xpixel > *xpixel &&  
                                     loop->tty.ypixel > *ypixel) {  
                                         *xpixel = loop->tty.xpixel;  
                                         *ypixel = loop->tty.ypixel;  
                                 }  
                         }  
                         if (*sx == UINT_MAX || *sy == UINT_MAX)  
                                 goto manual;  
                 }                  }
                 break;                  if (w == NULL)
         case WINDOW_SIZE_MANUAL:                          type = WINDOW_SIZE_MANUAL;
                 goto manual;  
         }          }
         goto done;  
   
 manual:          /*
         value = options_get_string(s->options, "default-size");           * Look for a client to base the size on. If none exists (or the type
         if (sscanf(value, "%ux%u", sx, sy) != 2) {           * is manual), use the default-size option.
                 *sx = 80;           */
                 *sy = 24;          if (!clients_calculate_size(type, 0, s, w,
               default_window_size_skip_client, sx, sy, xpixel, ypixel)) {
                   value = options_get_string(s->options, "default-size");
                   if (sscanf(value, "%ux%u", sx, sy) != 2) {
                           *sx = 80;
                           *sy = 24;
                   }
         }          }
   
 done:  done:
           /* Make sure the limits are enforced. */
         if (*sx < WINDOW_MINIMUM)          if (*sx < WINDOW_MINIMUM)
                 *sx = WINDOW_MINIMUM;                  *sx = WINDOW_MINIMUM;
         if (*sx > WINDOW_MAXIMUM)          if (*sx > WINDOW_MAXIMUM)
Line 226 
Line 252 
                 *sy = WINDOW_MAXIMUM;                  *sy = WINDOW_MAXIMUM;
 }  }
   
   static int
   recalculate_size_skip_client(struct client *loop, __unused int type,
       int current, __unused struct session *s, struct window *w)
   {
           /*
            * If the current flag is set, then skip any client where this window
            * is not the current window - this is used for aggressive-resize.
            * Otherwise skip any session that doesn't contain the window.
            */
           if (current)
                   return (loop->session->curw->window != w);
           return (session_has(loop->session, w) == 0);
   }
   
 void  void
 recalculate_size(struct window *w, int now)  recalculate_size(struct window *w, int now)
 {  {
         struct session  *s;          u_int   sx, sy, xpixel = 0, ypixel = 0;
         struct client   *c;          int     type, current, changed;
         u_int            sx, sy, cx, cy, xpixel = 0, ypixel = 0, n;  
         int              type, current, has, changed;  
   
           /*
            * Do not attempt to resize windows which have no pane, they must be on
            * the way to destruction.
            */
         if (w->active == NULL)          if (w->active == NULL)
                 return;                  return;
         log_debug("%s: @%u is %u,%u", __func__, w->id, w->sx, w->sy);          log_debug("%s: @%u is %u,%u", __func__, w->id, w->sx, w->sy);
   
           /*
            * Type is manual, smallest, largest, latest. Current is the
            * aggressive-resize option (do not resize based on clients where the
            * window is not the current window).
            */
         type = options_get_number(w->options, "window-size");          type = options_get_number(w->options, "window-size");
         current = options_get_number(w->options, "aggressive-resize");          current = options_get_number(w->options, "aggressive-resize");
   
         changed = 1;          /* Look for a suitable client and get the new size. */
         switch (type) {          changed = clients_calculate_size(type, current, NULL, w,
         case WINDOW_SIZE_LARGEST:              recalculate_size_skip_client, &sx, &sy, &xpixel, &ypixel);
                 sx = sy = 0;  
                 TAILQ_FOREACH(c, &clients, entry) {  
                         if (ignore_client_size(c))  
                                 continue;  
                         s = c->session;  
   
                         if (current)          /*
                                 has = (s->curw->window == w);           * Make sure the size has actually changed. If the window has already
                         else           * got a resize scheduled, then use the new size; otherwise the old.
                                 has = session_has(s, w);           */
                         if (!has)  
                                 continue;  
   
                         cx = c->tty.sx;  
                         cy = c->tty.sy - status_line_size(c);  
   
                         if (cx > sx)  
                                 sx = cx;  
                         if (cy > sy)  
                                 sy = cy;  
   
                         if (c->tty.xpixel > xpixel && c->tty.ypixel > ypixel) {  
                                 xpixel = c->tty.xpixel;  
                                 ypixel = c->tty.ypixel;  
                         }  
                 }  
                 if (sx == 0 || sy == 0)  
                         changed = 0;  
                 break;  
         case WINDOW_SIZE_SMALLEST:  
                 sx = sy = UINT_MAX;  
                 TAILQ_FOREACH(c, &clients, entry) {  
                         if (ignore_client_size(c))  
                                 continue;  
                         s = c->session;  
   
                         if (current)  
                                 has = (s->curw->window == w);  
                         else  
                                 has = session_has(s, w);  
                         if (!has)  
                                 continue;  
   
                         cx = c->tty.sx;  
                         cy = c->tty.sy - status_line_size(c);  
   
                         if (cx < sx)  
                                 sx = cx;  
                         if (cy < sy)  
                                 sy = cy;  
   
                         if (c->tty.xpixel > xpixel && c->tty.ypixel > ypixel) {  
                                 xpixel = c->tty.xpixel;  
                                 ypixel = c->tty.ypixel;  
                         }  
                 }  
                 if (sx == UINT_MAX || sy == UINT_MAX)  
                         changed = 0;  
                 break;  
         case WINDOW_SIZE_LATEST:  
                 n = 0;  
                 TAILQ_FOREACH(c, &clients, entry) {  
                         if (!ignore_client_size(c) &&  
                             session_has(c->session, w)) {  
                                 if (++n > 1)  
                                         break;  
                         }  
                 }  
                 sx = sy = UINT_MAX;  
                 TAILQ_FOREACH(c, &clients, entry) {  
                         if (ignore_client_size(c))  
                                 continue;  
                         if (n > 1 && c != w->latest)  
                                 continue;  
                         s = c->session;  
   
                         if (current)  
                                 has = (s->curw->window == w);  
                         else  
                                 has = session_has(s, w);  
                         if (!has)  
                                 continue;  
   
                         cx = c->tty.sx;  
                         cy = c->tty.sy - status_line_size(c);  
   
                         if (cx < sx)  
                                 sx = cx;  
                         if (cy < sy)  
                                 sy = cy;  
   
                         if (c->tty.xpixel > xpixel && c->tty.ypixel > ypixel) {  
                                 xpixel = c->tty.xpixel;  
                                 ypixel = c->tty.ypixel;  
                         }  
                 }  
                 if (sx == UINT_MAX || sy == UINT_MAX)  
                         changed = 0;  
                 break;  
         case WINDOW_SIZE_MANUAL:  
                 changed = 0;  
                 break;  
         }  
         if (w->flags & WINDOW_RESIZE) {          if (w->flags & WINDOW_RESIZE) {
                 if (!now && changed && w->new_sx == sx && w->new_sy == sy)                  if (!now && changed && w->new_sx == sx && w->new_sy == sy)
                         changed = 0;                          changed = 0;
Line 355 
Line 304 
                         changed = 0;                          changed = 0;
         }          }
   
           /*
            * If the size hasn't changed, update the window offset but not the
            * size.
            */
         if (!changed) {          if (!changed) {
                 tty_update_window_offset(w);                  tty_update_window_offset(w);
                 return;                  return;
         }          }
   
           /*
            * If the now flag is set or if the window is sized manually, change
            * the size immediately. Otherwise set the flag and it will be done
            * later.
            */
         log_debug("%s: @%u new size %u,%u", __func__, w->id, sx, sy);          log_debug("%s: @%u new size %u,%u", __func__, w->id, sx, sy);
         if (now || type == WINDOW_SIZE_MANUAL)          if (now || type == WINDOW_SIZE_MANUAL)
                 resize_window(w, sx, sy, xpixel, ypixel);                  resize_window(w, sx, sy, xpixel, ypixel);

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42