     (active! obj)))
 
 (defn objs-list [multi objs]
-  (let [item (crate/html
+  (let [labels (for [[idx o] (map vector (range) objs)
+                     :when @o]
+                 (object/create ::tab-label multi o idx))
+        item (crate/html
               [:ul
-               (for [[idx o] (map vector (range) objs)
-                     :when @o]
-                 (object/->content (object/create ::tab-label multi o idx)))])]
-    (js/sortable item (js-obj "axis" "x" "distance" 10  "scroll" false "opacity" 0.9 "connectWith" ".list"))
+               (map object/->content labels)
+               ])]
+    (doseq [old (:labels @multi)]
+      (object/destroy! old))
+    ;;TODO: this is an unbelievably awful hack to get around looping infinitely trying to draw the
+    ;;labels.
+    (object/merge! multi {:labels labels :no-redraw true})
+    (js/sortable item (js-obj "axis" "x" "distance" 10  "scroll" false "opacity" 0.9 "connectwith" ".list"))
     (dom/on item "contextmenu" (fn [e]
                                  (object/raise multi :menu! e)))
     (dom/on item "moved" (fn [e] (move-tab multi (.-opts e)) ))

(defn active! [obj]
  (when (and obj
             (::tabset @obj))
    (object/merge! (::tabset @obj) {:active-obj obj})
    (object/raise obj :show)
    (ensure-visible (->index obj) (::tabset @obj))))


(defui tabset-ui [this]
  [:div.tabset {:style {:width (bound (subatom this :width) ->perc)}}
   [:div.list
    (bound this #(when-not (:no-redraw %)
                   (objs-list this (:objs %))))]
   [:div.items
    (map-bound (partial tabbed-item (subatom this :active-obj)) this {:path [:objs]})]
   (vertical-grip this)]
