     (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)) ))

   (when-let [cur-tabset (or ts (ctx/->obj :tabset))]
     (object/add-tags obj [:tabset.tab])
     (object/update! cur-tabset [:objs] conj obj)
     (object/merge! obj {::tabset cur-tabset})
     (add-watch (subatom obj [:dirty]) :tabs (fn [_ _ _ cur]
                                               (object/raise cur-tabset :tab.updated)

              (map #(dom/attr % :pos) children))
        prev-active (:active-obj @multi)]
    (object/merge! multi {:objs (mapv (:objs @multi) ser)
                          :active-obj nil
                          :no-redraw false})
    (active! prev-active)
    ))

