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

Diff for /src/usr.bin/tmux/window.c between version 1.108 and 1.109

version 1.108, 2014/04/17 14:45:49 version 1.109, 2014/05/08 06:03:30
Line 56 
Line 56 
 struct window_pane_tree all_window_panes;  struct window_pane_tree all_window_panes;
 u_int   next_window_pane_id;  u_int   next_window_pane_id;
 u_int   next_window_id;  u_int   next_window_id;
   u_int   next_active_point;
   
 struct window_pane *window_pane_active_set(struct window_pane *,  
             struct window_pane *);  
 void    window_pane_active_lost(struct window_pane *, struct window_pane *);  
   
 void    window_pane_timer_callback(int, short, void *);  void    window_pane_timer_callback(int, short, void *);
 void    window_pane_read_callback(struct bufferevent *, void *);  void    window_pane_read_callback(struct bufferevent *, void *);
 void    window_pane_error_callback(struct bufferevent *, short, void *);  void    window_pane_error_callback(struct bufferevent *, short, void *);
   
   struct window_pane *window_pane_choose_best(struct window_pane_list *);
   
 RB_GENERATE(winlinks, winlink, entry, winlink_cmp);  RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
   
 int  int
Line 387 
Line 386 
         w->sy = sy;          w->sy = sy;
 }  }
   
 /*  
  * Restore previously active pane when changing from wp to nextwp. The intended  
  * pane is in nextwp and it returns the previously focused pane.  
  */  
 struct window_pane *  
 window_pane_active_set(struct window_pane *wp, struct window_pane *nextwp)  
 {  
         struct layout_cell      *lc;  
         struct window_pane      *lastwp;  
   
         /* Target pane's parent must not be an ancestor of source pane. */  
         for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {  
                 if (lc == nextwp->layout_cell->parent)  
                         return (nextwp);  
         }  
   
         /*  
          * Previously active pane, if any, must not be the same as the source  
          * pane.  
          */  
         lc = nextwp->layout_cell->parent;  
         if (lc != NULL && lc->lastwp != NULL) {  
                 lastwp = lc->lastwp;  
                 if (lastwp != wp && window_pane_visible(lastwp))  
                         return (lastwp);  
         }  
         return (nextwp);  
 }  
   
 /* Remember previously active pane when changing from wp to nextwp. */  
 void  void
 window_pane_active_lost(struct window_pane *wp, struct window_pane *nextwp)  
 {  
         struct layout_cell      *lc, *lc2, *lcparent;  
   
         /* Get the parent cell. */  
         lcparent = nextwp->layout_cell->parent;  
         if (lcparent == NULL)  
                 return;  
   
         /* Save the target pane in its parent. */  
         lcparent->lastwp = nextwp;  
   
         /*  
          * Save the source pane in all of its parents up to, but not including,  
          * the common ancestor of itself and the target panes.  
          */  
         if (wp == NULL)  
                 return;  
         for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {  
                 for (lc2 = lcparent; lc2 != NULL; lc2 = lc2->parent) {  
                         if (lc == lc2)  
                                 return;  
                 }  
                 lc->lastwp = wp;  
         }  
 }  
   
 void  
 window_set_active_pane(struct window *w, struct window_pane *wp)  window_set_active_pane(struct window *w, struct window_pane *wp)
 {  {
         if (wp == w->active)          if (wp == w->active)
                 return;                  return;
         w->last = w->active;          w->last = w->active;
         w->active = wp;          w->active = wp;
         window_pane_active_lost(w->last, wp);  
         while (!window_pane_visible(w->active)) {          while (!window_pane_visible(w->active)) {
                 w->active = TAILQ_PREV(w->active, window_panes, entry);                  w->active = TAILQ_PREV(w->active, window_panes, entry);
                 if (w->active == NULL)                  if (w->active == NULL)
Line 460 
Line 400 
                 if (w->active == wp)                  if (w->active == wp)
                         return;                          return;
         }          }
           w->active->active_point = next_active_point++;
 }  }
   
 struct window_pane *  struct window_pane *
Line 771 
Line 712 
 void  void
 window_pane_destroy(struct window_pane *wp)  window_pane_destroy(struct window_pane *wp)
 {  {
         struct window_pane      *wp2;  
   
         /* Forget removed pane in all layout cells that remember it. */  
         RB_FOREACH(wp2, window_pane_tree, &all_window_panes) {  
                 if (wp2->layout_cell != NULL &&  
                     wp2->layout_cell->parent != NULL &&  
                     wp2->layout_cell->parent->lastwp == wp)  
                         wp2->layout_cell->parent->lastwp = NULL;  
         }  
   
         window_pane_reset_mode(wp);          window_pane_reset_mode(wp);
   
         if (event_initialized(&wp->changes_timer))          if (event_initialized(&wp->changes_timer))
Line 1187 
Line 1118 
         return (msg);          return (msg);
 }  }
   
 /* Find the pane directly above another. */  /* Get MRU pane from a list. */
 struct window_pane *  struct window_pane *
   window_pane_choose_best(struct window_pane_list *list)
   {
           struct window_pane      *next, *best;
           u_int                    i;
   
           if (ARRAY_LENGTH(list) == 0)
                   return (NULL);
   
           best = ARRAY_FIRST(list);
           for (i = 1; i < ARRAY_LENGTH(list); i++) {
                   next = ARRAY_ITEM(list, i);
                   if (next->active_point > best->active_point)
                           best = next;
           }
           return (best);
   }
   
   /*
    * Find the pane directly above another. We build a list of those adjacent to
    * top edge and then choose the best.
    */
   struct window_pane *
 window_pane_find_up(struct window_pane *wp)  window_pane_find_up(struct window_pane *wp)
 {  {
         struct window_pane     *wp2;          struct window_pane      *next, *best;
         u_int                   left, top;          u_int                    edge, left, right, end;
           struct window_pane_list  list;
           int                      found;
   
         if (wp == NULL || !window_pane_visible(wp))          if (wp == NULL || !window_pane_visible(wp))
                 return (NULL);                  return (NULL);
           ARRAY_INIT(&list);
   
         top = wp->yoff;          edge = wp->yoff;
         if (top == 0)          if (edge == 0)
                 top = wp->window->sy + 1;                  edge = wp->window->sy + 1;
   
         left = wp->xoff;          left = wp->xoff;
           right = wp->xoff + wp->sx;
   
         TAILQ_FOREACH(wp2, &wp->window->panes, entry) {          TAILQ_FOREACH(next, &wp->window->panes, entry) {
                 if (!window_pane_visible(wp2))                  if (next == wp || !window_pane_visible(next))
                         continue;                          continue;
                 if (wp2->yoff + wp2->sy + 1 != top)                  if (next->yoff + next->sy + 1 != edge)
                         continue;                          continue;
                 if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)                  end = next->xoff + next->sx - 1;
                         return (window_pane_active_set(wp, wp2));  
                   found = 0;
                   if (next->xoff < left && end > right)
                           found = 1;
                   else if (next->xoff >= left && next->xoff <= right)
                           found = 1;
                   else if (end >= left && end <= right)
                           found = 1;
                   if (found)
                           ARRAY_ADD(&list, next);
         }          }
         return (NULL);  
           best = window_pane_choose_best(&list);
           ARRAY_FREE(&list);
           return (best);
 }  }
   
 /* Find the pane directly below another. */  /* Find the pane directly below another. */
 struct window_pane *  struct window_pane *
 window_pane_find_down(struct window_pane *wp)  window_pane_find_down(struct window_pane *wp)
 {  {
         struct window_pane     *wp2;          struct window_pane      *next, *best;
         u_int                   left, bottom;          u_int                    edge, left, right, end;
           struct window_pane_list  list;
           int                      found;
   
         if (wp == NULL || !window_pane_visible(wp))          if (wp == NULL || !window_pane_visible(wp))
                 return (NULL);                  return (NULL);
           ARRAY_INIT(&list);
   
         bottom = wp->yoff + wp->sy + 1;          edge = wp->yoff + wp->sy + 1;
         if (bottom >= wp->window->sy)          if (edge >= wp->window->sy)
                 bottom = 0;                  edge = 0;
   
         left = wp->xoff;          left = wp->xoff;
           right = wp->xoff + wp->sx;
   
         TAILQ_FOREACH(wp2, &wp->window->panes, entry) {          TAILQ_FOREACH(next, &wp->window->panes, entry) {
                 if (!window_pane_visible(wp2))                  if (next == wp || !window_pane_visible(next))
                         continue;                          continue;
                 if (wp2->yoff != bottom)                  if (next->yoff != edge)
                         continue;                          continue;
                 if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)                  end = next->xoff + next->sx - 1;
                         return (window_pane_active_set(wp, wp2));  
                   found = 0;
                   if (next->xoff < left && end > right)
                           found = 1;
                   else if (next->xoff >= left && next->xoff <= right)
                           found = 1;
                   else if (end >= left && end <= right)
                           found = 1;
                   if (found)
                           ARRAY_ADD(&list, next);
         }          }
         return (NULL);  
           best = window_pane_choose_best(&list);
           ARRAY_FREE(&list);
           return (best);
 }  }
   
 /*  /* Find the pane directly to the left of another. */
  * Find the pane directly to the left of another, adjacent to the left side and  
  * containing the top edge.  
  */  
 struct window_pane *  struct window_pane *
 window_pane_find_left(struct window_pane *wp)  window_pane_find_left(struct window_pane *wp)
 {  {
         struct window_pane     *wp2;          struct window_pane      *next, *best;
         u_int                   left, top;          u_int                    edge, top, bottom, end;
           struct window_pane_list  list;
           int                      found;
   
         if (wp == NULL || !window_pane_visible(wp))          if (wp == NULL || !window_pane_visible(wp))
                 return (NULL);                  return (NULL);
           ARRAY_INIT(&list);
   
         left = wp->xoff;          edge = wp->xoff;
         if (left == 0)          if (edge == 0)
                 left = wp->window->sx + 1;                  edge = wp->window->sx + 1;
   
         top = wp->yoff;          top = wp->yoff;
           bottom = wp->yoff + wp->sy;
   
         TAILQ_FOREACH(wp2, &wp->window->panes, entry) {          TAILQ_FOREACH(next, &wp->window->panes, entry) {
                 if (!window_pane_visible(wp2))                  if (next == wp || !window_pane_visible(next))
                         continue;                          continue;
                 if (wp2->xoff + wp2->sx + 1 != left)                  if (next->xoff + next->sx + 1 != edge)
                         continue;                          continue;
                 if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)                  end = next->yoff + next->sy - 1;
                         return (window_pane_active_set(wp, wp2));  
                   found = 0;
                   if (next->yoff < top && end > bottom)
                           found = 1;
                   else if (next->yoff >= top && next->yoff <= bottom)
                           found = 1;
                   else if (end >= top && end <= bottom)
                           found = 1;
                   if (found)
                           ARRAY_ADD(&list, next);
         }          }
         return (NULL);  
           best = window_pane_choose_best(&list);
           ARRAY_FREE(&list);
           return (best);
 }  }
   
 /*  /* Find the pane directly to the right of another. */
  * Find the pane directly to the right of another, that is adjacent to the  
  * right edge and including the top edge.  
  */  
 struct window_pane *  struct window_pane *
 window_pane_find_right(struct window_pane *wp)  window_pane_find_right(struct window_pane *wp)
 {  {
         struct window_pane     *wp2;          struct window_pane      *next, *best;
         u_int                   right, top;          u_int                    edge, top, bottom, end;
           struct window_pane_list  list;
           int                      found;
   
         if (wp == NULL || !window_pane_visible(wp))          if (wp == NULL || !window_pane_visible(wp))
                 return (NULL);                  return (NULL);
           ARRAY_INIT(&list);
   
         right = wp->xoff + wp->sx + 1;          edge = wp->xoff + wp->sx + 1;
         if (right >= wp->window->sx)          if (edge >= wp->window->sx)
                 right = 0;                  edge = 0;
   
         top = wp->yoff;          top = wp->yoff;
           bottom = wp->yoff + wp->sy;
   
         TAILQ_FOREACH(wp2, &wp->window->panes, entry) {          TAILQ_FOREACH(next, &wp->window->panes, entry) {
                 if (!window_pane_visible(wp2))                  if (next == wp || !window_pane_visible(next))
                         continue;                          continue;
                 if (wp2->xoff != right)                  if (next->xoff != edge)
                         continue;                          continue;
                 if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)                  end = next->yoff + next->sy - 1;
                         return (window_pane_active_set(wp, wp2));  
                   found = 0;
                   if (next->yoff < top && end > bottom)
                           found = 1;
                   else if (next->yoff >= top && next->yoff <= bottom)
                           found = 1;
                   else if (end >= top && end <= bottom)
                           found = 1;
                   if (found)
                           ARRAY_ADD(&list, next);
         }          }
         return (NULL);  
           best = window_pane_choose_best(&list);
           ARRAY_FREE(&list);
           return (best);
 }  }
   
 /* Clear alert flags for a winlink */  /* Clear alert flags for a winlink */

Legend:
Removed from v.1.108  
changed lines
  Added in v.1.109