Jelajahi Sumber

app: switch user APIs from foo(self: Arc<Self>, ...) to foo(self: &Arc<Self>, ...) due to new rust stable feature

darkfi 11 bulan lalu
induk
melakukan
a9a68782f6

+ 9 - 9
bin/app/src/app/mod.rs

@@ -131,8 +131,8 @@ impl App {
             })
             .await;
 
-        self.sg_root.clone().link(window.clone());
-        self.sg_root.clone().link(setting_root.clone());
+        self.sg_root.link(window.clone());
+        self.sg_root.link(setting_root.clone());
 
         schema::make(&self, window.clone(), &i18n_fish).await;
 
@@ -185,12 +185,12 @@ impl App {
         d!("Starting app epoch={epoch}");
         let mut atom = PropertyAtomicGuard::none();
 
-        let window_node = self.sg_root.clone().lookup_node("/window").unwrap();
+        let window_node = self.sg_root.lookup_node("/window").unwrap();
         let prop = window_node.get_property("screen_size").unwrap();
         // We can only do this once the window has been created in miniquad.
         let (screen_width, screen_height) = miniquad::window::screen_size();
-        prop.clone().set_f32(&mut atom, Role::App, 0, screen_width).unwrap();
-        prop.clone().set_f32(&mut atom, Role::App, 1, screen_height).unwrap();
+        prop.set_f32(&mut atom, Role::App, 0, screen_width).unwrap();
+        prop.set_f32(&mut atom, Role::App, 1, screen_height).unwrap();
 
         drop(atom);
 
@@ -205,7 +205,7 @@ impl App {
     }
 
     pub fn init(&self) {
-        let window_node = self.sg_root.clone().lookup_node("/window").unwrap();
+        let window_node = self.sg_root.lookup_node("/window").unwrap();
         match window_node.pimpl() {
             Pimpl::Window(win) => win.init(),
             _ => panic!("wrong pimpl"),
@@ -213,7 +213,7 @@ impl App {
     }
 
     pub fn stop(&self) {
-        let window_node = self.sg_root.clone().lookup_node("/window").unwrap();
+        let window_node = self.sg_root.lookup_node("/window").unwrap();
         match window_node.pimpl() {
             Pimpl::Window(win) => win.stop(),
             _ => panic!("wrong pimpl"),
@@ -222,14 +222,14 @@ impl App {
 
     async fn trigger_draw(&self) {
         let atom = &mut self.render_api.make_guard();
-        let window_node = self.sg_root.clone().lookup_node("/window").expect("no window attached!");
+        let window_node = self.sg_root.lookup_node("/window").expect("no window attached!");
         match window_node.pimpl() {
             Pimpl::Window(win) => win.draw(atom).await,
             _ => panic!("wrong pimpl"),
         }
     }
     async fn start_procs(&self, event_pub: GraphicsEventPublisherPtr) {
-        let window_node = self.sg_root.clone().lookup_node("/window").unwrap();
+        let window_node = self.sg_root.lookup_node("/window").unwrap();
         match window_node.pimpl() {
             Pimpl::Window(win) => win.clone().start(event_pub, self.ex.clone()).await,
             _ => panic!("wrong pimpl"),

+ 257 - 257
bin/app/src/app/schema/chat.rs

@@ -186,7 +186,7 @@ pub async fn make(
     is_first_time: bool,
 ) {
     let window_scale = PropertyFloat32::wrap(
-        &app.sg_root.clone().lookup_node("/setting/scale").unwrap(),
+        &app.sg_root.lookup_node("/setting/scale").unwrap(),
         Role::Internal,
         "value",
         0,
@@ -213,10 +213,10 @@ pub async fn make(
     // Main view
     let layer_node = create_layer(&(channel.to_string() + "_chat_layer"));
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     layer_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
@@ -225,10 +225,10 @@ pub async fn make(
     // Create the toolbar bg
     let node = create_vector_art("toolbar_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
 
     let (bg_color, sep_color) = match COLOR_SCHEME {
@@ -259,29 +259,29 @@ pub async fn make(
     );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the send button
     let node = create_vector_art("back_btn_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, BACKARROW_Y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 500.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 500.).unwrap();
+    prop.set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
+    prop.set_f32(atom, Role::App, 1, BACKARROW_Y).unwrap();
+    prop.set_f32(atom, Role::App, 2, 500.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 500.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
     let shape = shape::create_back_arrow().scaled(BACKARROW_SCALE);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the back button
     let node = create_button("back_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, EMOJI_BG_W).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, EMOJI_BG_W).unwrap();
+    prop.set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
 
     // Menu doesn't exist yet ;)
     // So look it up in the callback.
@@ -293,10 +293,10 @@ pub async fn make(
         info!(target: "app::chat", "clicked back");
         let atom = &mut render_api.make_guard();
 
-        let editz_node = layer_node2.clone().lookup_node("/content/editz").unwrap();
+        let editz_node = layer_node2.lookup_node("/content/editz").unwrap();
         editz_node.call_method("unfocus", vec![]).await.unwrap();
 
-        let menu_node = sg_root.clone().lookup_node("/window/menu_layer").unwrap();
+        let menu_node = sg_root.lookup_node("/window/menu_layer").unwrap();
         menu_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
 
         chatview_is_visible.set(atom, false);
@@ -313,7 +313,7 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create shortcut to go back as well
     let node = create_shortcut("back_shortcut");
@@ -336,50 +336,50 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_enter);
 
     let node = node.setup(|me| Shortcut::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create some text
     let node = create_text("channel_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CHANNEL_LABEL_Y).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
+    prop.set_f32(atom, Role::App, 1, CHANNEL_LABEL_Y).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE * 1.2).unwrap();
     node.set_property_str(atom, Role::App, "text", &("#".to_string() + channel)).unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the emoji picker
     let mut node = create_emoji_picker("emoji_picker");
     let prop = Property::new("dynamic_h", PropertyType::Float32, PropertySubType::Pixel);
     node.add_property(prop).unwrap();
     let emoji_dynamic_h_prop = node.get_property("dynamic_h").unwrap();
-    //emoji_dynamic_h_prop.clone().set_f32(atom, Role::App, 0, 400.).unwrap();
+    //emoji_dynamic_h_prop.set_f32(atom, Role::App, 0, 400.).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
     let code = cc.compile("h - dynamic_h").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("dynamic_h")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("dynamic_h")).unwrap();
     prop.add_depend(&emoji_dynamic_h_prop, 0, "dynamic_h");
     let emoji_h_prop = PropertyFloat32::wrap(&node, Role::App, "dynamic_h", 0).unwrap();
     //node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
@@ -387,16 +387,16 @@ pub async fn make(
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     let node = node.setup(|me| EmojiPicker::new(me, app.render_api.clone(), emoji_meshes)).await;
     let emoji_picker_node = node.clone();
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the editbox bg
     let node = create_vector_art("emoji_picker_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
     let code = cc.compile("h - dynamic_h").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("dynamic_h")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("dynamic_h")).unwrap();
     prop.add_depend(&emoji_dynamic_h_prop, 0, "dynamic_h");
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
 
@@ -426,33 +426,33 @@ pub async fn make(
     //    [0.41, 0.6, 0.65, 1.],
     //);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Main content view
     let chat_layer_node = layer_node;
     let layer_node = create_layer("content");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     let code = cc.compile("h - emoji_h").unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
     prop.add_depend(&emoji_dynamic_h_prop, 0, "emoji_h");
     layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     layer_node.set_property_u32(atom, Role::App, "priority", 1).unwrap();
     let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    chat_layer_node.clone().link(layer_node.clone());
+    chat_layer_node.link(layer_node.clone());
 
     // ChatView
     let node = create_chatview("chatty");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CHATEDIT_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 1, CHATEDIT_HEIGHT).unwrap();
     let code = cc.compile("w - 30").unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, code).unwrap();
     let code = cc.compile("h - CHATEDIT_HEIGHT - editz_h - 2 * CHATEDIT_BOTTOM_PAD").unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
     let chatview_rect_prop = prop.clone();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
     node.set_property_f32(atom, Role::App, "timestamp_font_size", TIMESTAMP_FONTSIZE).unwrap();
@@ -471,21 +471,21 @@ pub async fn make(
     node.set_property_f32(atom, Role::App, "scroll_resist", 0.9).unwrap();
 
     let prop = node.get_property("timestamp_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.407).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.604).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.647).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.407).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.604).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.647).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
 
     let prop = node.get_property("nick_colors").unwrap();
@@ -503,20 +503,20 @@ pub async fn make(
         1.00, 0.30, 0.00, 1.
     ];
     for c in nick_colors {
-        prop.clone().push_f32(atom, Role::App, c).unwrap();
+        prop.push_f32(atom, Role::App, c).unwrap();
     }
 
     let prop = node.get_property("hi_bg_color").unwrap();
     if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
 
     let tree_name = channel.to_string() + "__chat_tree";
@@ -536,7 +536,7 @@ pub async fn make(
             )
         })
         .await;
-    layer_node.clone().link(chatview_node.clone());
+    layer_node.link(chatview_node.clone());
 
     if is_first_time {
         let chatview = match chatview_node.pimpl() {
@@ -554,12 +554,12 @@ pub async fn make(
     // Create the editbox bg
     let node = create_vector_art("editbox_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
     let code = cc.compile("h - editz_h - 2 * CHATEDIT_BOTTOM_PAD").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     let code = cc.compile("editz_h + 2 * CHATEDIT_BOTTOM_PAD").unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 4).unwrap();
     node.set_property_u32(atom, Role::App, "priority", 2).unwrap();
 
@@ -614,31 +614,31 @@ pub async fn make(
     //    [0.41, 0.6, 0.65, 1.],
     //);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the send button
     let node = create_vector_art("send_btn_bg");
     let prop = node.get_property("rect").unwrap();
     let code = cc.compile("w - SENDARROW_NEG_X").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
     let code = cc.compile("h - SENDARROW_NEG_Y").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 500.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 500.).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, 500.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 500.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 5).unwrap();
     let shape = shape::create_send_arrow().scaled(EMOJI_SCALE);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the emoji button
     let node = create_vector_art("emoji_btn_bg");
     let emoji_btn_is_visible = PropertyBool::wrap(&node, Role::Ignored, "is_visible", 0).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, EMOJI_BTN_X).unwrap();
+    prop.set_f32(atom, Role::App, 0, EMOJI_BTN_X).unwrap();
     let code = cc.compile("h - EMOJI_NEG_Y").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 500.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 500.).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, 500.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 500.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 5).unwrap();
     let color = match COLOR_SCHEME {
         ColorScheme::DarkMode => [0., 1., 1., 1.],
@@ -646,22 +646,22 @@ pub async fn make(
     };
     let shape = shape::create_emoji_selector(color).scaled(EMOJI_SCALE);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the emoji button
     let node = create_vector_art("emoji_close_btn_bg");
     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     let prop = node.get_property("rect").unwrap();
     let emoji_close_is_visible = PropertyBool::wrap(&node, Role::Ignored, "is_visible", 0).unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, EMOJI_BTN_X).unwrap();
+    prop.set_f32(atom, Role::App, 0, EMOJI_BTN_X).unwrap();
     let code = cc.compile("h - EMOJI_NEG_Y").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 500.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 500.).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, 500.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 500.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 5).unwrap();
     let shape = shape::create_close_icon().scaled(EMOJI_CLOSE_SCALE);
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Text edit
     let node = create_chatedit("editz");
@@ -669,54 +669,54 @@ pub async fn make(
     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
 
     let prop = node.get_property("height_range").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_MIN_HEIGHT).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CHATEDIT_MAX_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, CHATEDIT_MIN_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 1, CHATEDIT_MAX_HEIGHT).unwrap();
 
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
+    prop.set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
     let code = cc.compile("parent_h - (rect_h + CHATEDIT_BOTTOM_PAD)").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
     let code = cc.compile("parent_w - CHATEDIT_NEG_W").unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
+    prop.set_expr(atom, Role::App, 2, code).unwrap();
+    prop.set_f32(atom, Role::App, 3, CHATEDIT_HEIGHT).unwrap();
 
     chatview_rect_prop.add_depend(&prop, 3, "editz_h");
     editbox_bg_rect_prop.add_depend(&prop, 3, "editz_h");
 
     let prop = node.get_property("padding").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, TEXTBAR_BASELINE * 0.4).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, TEXTBAR_BASELINE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 0, TEXTBAR_BASELINE * 0.4).unwrap();
+    prop.set_f32(atom, Role::App, 1, TEXTBAR_BASELINE / 2.).unwrap();
 
     node.set_property_f32(atom, Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE * 1.2).unwrap();
     //node.set_property_str(atom, Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     let prop = node.get_property("text_hi_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.44).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.96).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.44).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.96).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     let prop = node.get_property("text_cmd_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.64).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.83).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.64).unwrap();
+    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.83).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     let prop = node.get_property("cursor_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.816).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.627).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.816).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.627).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_ascent", CHATEDIT_CURSOR_ASCENT).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_descent", CHATEDIT_CURSOR_DESCENT).unwrap();
     node.set_property_f32(atom, Role::App, "select_ascent", CHATEDIT_SELECT_ASCENT).unwrap();
@@ -724,27 +724,27 @@ pub async fn make(
     node.set_property_f32(atom, Role::App, "handle_descent", CHATEDIT_HANDLE_DESCENT).unwrap();
     let prop = node.get_property("hi_bg_color").unwrap();
     if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.27).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.22).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.27).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.22).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     let prop = node.get_property("cmd_bg_color").unwrap();
     if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.30).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.25).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.30).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.25).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     node.set_property_u32(atom, Role::App, "z_index", 6).unwrap();
     node.set_property_u32(atom, Role::App, "priority", 3).unwrap();
@@ -775,7 +775,7 @@ pub async fn make(
     let node =
         node.setup(|me| ChatEdit::new(me, window_scale.clone(), app.render_api.clone())).await;
     let chatedit_node = node.clone();
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     let (slot, recvr) = Slot::new("emoji_selected");
     emoji_picker_node.register("emoji_select", slot).unwrap();
@@ -795,13 +795,13 @@ pub async fn make(
     // Create the editbox fg shadow
     let node = create_vector_art("editbox_fg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, EMOJI_BG_W).unwrap();
+    prop.set_f32(atom, Role::App, 0, EMOJI_BG_W).unwrap();
     let code = cc.compile("editz_bg_top_y").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 300.).unwrap();
-    //prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    //prop.clone().set_expr(atom, Role::App, 3, expr::load_var("editz_bg_h")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, 300.).unwrap();
+    //prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    //prop.set_expr(atom, Role::App, 3, expr::load_var("editz_bg_h")).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 4).unwrap();
     prop.add_depend(&editbox_bg_rect_prop, 1, "editz_bg_top_y");
     prop.add_depend(&editbox_bg_rect_prop, 3, "editz_bg_h");
@@ -822,7 +822,7 @@ pub async fn make(
     );
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
     */
 
     // Create the send button
@@ -830,11 +830,11 @@ pub async fn make(
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
     let code = cc.compile("w - SENDBTN_BOX_0").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
     let code = cc.compile("h - SENDBTN_BOX_1").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, SENDBTN_BOX[2]).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SENDBTN_BOX[3]).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, SENDBTN_BOX[2]).unwrap();
+    prop.set_f32(atom, Role::App, 3, SENDBTN_BOX[3]).unwrap();
 
     let editz_text2 = editz_text.clone();
     let channel2 = format!("#{channel}");
@@ -853,7 +853,7 @@ pub async fn make(
             info!(target: "app::chat", "Send '{text}' to channel: {channel}");
             editz_text.set(atom, "");
 
-            let Some(darkirc) = sg_root.clone().lookup_node("/plugin/darkirc") else {
+            let Some(darkirc) = sg_root.lookup_node("/plugin/darkirc") else {
                 error!(target: "app::chat", "DarkIrc plugin has not been loaded");
                 return
             };
@@ -912,7 +912,7 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create shortcut to send as well
     let node = create_shortcut("send_shortcut");
@@ -928,17 +928,17 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_enter);
 
     let node = node.setup(|me| Shortcut::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the emoji button
     let node = create_button("emoji_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, EMOJIBTN_BOX[0]).unwrap();
+    prop.set_f32(atom, Role::App, 0, EMOJIBTN_BOX[0]).unwrap();
     let code = cc.compile("h - EMOJIBTN_BOX_1").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, EMOJIBTN_BOX[2]).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, EMOJIBTN_BOX[3]).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, EMOJIBTN_BOX[2]).unwrap();
+    prop.set_f32(atom, Role::App, 3, EMOJIBTN_BOX[3]).unwrap();
 
     let (slot, recvr) = Slot::new("reqkeyb");
     chatedit_node.register("focus_request", slot).unwrap();
@@ -1011,24 +1011,24 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Commands help hint
     let cmd_layer_node = create_layer("cmd_hint_layer");
     let prop = cmd_layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 5.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 5.).unwrap();
     let code = cc.compile("editz_bg_top_y - CMD_HELP_HEIGHT - CMD_HELP_GAP").unwrap();
     //let code = cc.compile("h - 60 - 80").unwrap();
     //let code = cc.compile("h - 60 - 300").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
     let code = cc.compile("w - 2 * CMD_HELP_GAP").unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CMD_HELP_HEIGHT).unwrap();
+    prop.set_expr(atom, Role::App, 2, code).unwrap();
+    prop.set_f32(atom, Role::App, 3, CMD_HELP_HEIGHT).unwrap();
     prop.add_depend(&editbox_bg_rect_prop, 1, "editz_bg_top_y");
     cmd_layer_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     cmd_layer_node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
     let cmd_layer_node = cmd_layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    layer_node.clone().link(cmd_layer_node.clone());
+    layer_node.link(cmd_layer_node.clone());
 
     let cmd_hint_is_visible =
         PropertyBool::wrap(&cmd_layer_node, Role::App, "is_visible", 0).unwrap();
@@ -1037,10 +1037,10 @@ pub async fn make(
     let node = create_button("nickcmd_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, CMD_HELP_NICK_CMD_WIDTH).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CMD_HELP_HEIGHT).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, CMD_HELP_NICK_CMD_WIDTH).unwrap();
+    prop.set_f32(atom, Role::App, 3, CMD_HELP_HEIGHT).unwrap();
 
     let (slot, recvr) = Slot::new("nickcmd_clicked");
     node.register("click", slot).unwrap();
@@ -1058,15 +1058,15 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    cmd_layer_node.clone().link(node);
+    cmd_layer_node.link(node);
 
     // Create the actionbar bg
     let node = create_vector_art("cmd_hint_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -1101,53 +1101,53 @@ pub async fn make(
     );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    cmd_layer_node.clone().link(node);
+    cmd_layer_node.link(node);
 
     // Create some text
     let node = create_text("cmd_nick_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CMD_HELP_CMD_LABEL_X_INSET).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CMD_HELP_LABEL_Y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 0, CMD_HELP_CMD_LABEL_X_INSET).unwrap();
+    prop.set_f32(atom, Role::App, 1, CMD_HELP_LABEL_Y).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1000.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", CMD_HELP_CMD_FONTSIZE).unwrap();
     node.set_property_str(atom, Role::App, "text", "/nick").unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.64).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.83).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.64).unwrap();
+    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.83).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    cmd_layer_node.clone().link(node);
+    cmd_layer_node.link(node);
 
     // Create some text
     let node = create_text("cmd_nick_desc_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CMD_HELP_NICK_DESC_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CMD_HELP_LABEL_Y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 0, CMD_HELP_NICK_DESC_X).unwrap();
+    prop.set_f32(atom, Role::App, 1, CMD_HELP_LABEL_Y).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1000.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
     node.set_property_str(atom, Role::App, "text", "Change your nickname").unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.94).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.94).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    cmd_layer_node.clone().link(node);
+    cmd_layer_node.link(node);
 
     // Create debug box
     /*
@@ -1156,11 +1156,11 @@ pub async fn make(
     node.add_property(prop).unwrap();
     node.set_property_f32(atom, Role::App, "hoff", 40.).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, EMOJIBTN_BOX[0]).unwrap();
+    prop.set_f32(atom, Role::App, 0, EMOJIBTN_BOX[0]).unwrap();
     let code = cc.compile("h - EMOJIBTN_BOX_1").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, EMOJIBTN_BOX[2]).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, EMOJIBTN_BOX[3]).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, EMOJIBTN_BOX[2]).unwrap();
+    prop.set_f32(atom, Role::App, 3, EMOJIBTN_BOX[3]).unwrap();
     let hoff_prop = node.get_property("hoff").unwrap();
     prop.add_depend(&hoff_prop, 0, "hoff");
     node.set_property_u32(atom, Role::App, "z_index", 6).unwrap();
@@ -1175,37 +1175,37 @@ pub async fn make(
     );
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
     */
 
     // Overlay popup
     let content_layer_node = layer_node.clone();
     let layer_node = create_layer("overlay_layer");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 40.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 40.).unwrap();
     let code = cc.compile("editz_bg_top_y - ACTION_POPUP_Y_OFF").unwrap();
     //let code = cc.compile("h - 60 - 80").unwrap();
     //let code = cc.compile("h - 60 - 300").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     prop.add_depend(&editbox_bg_rect_prop, 1, "editz_bg_top_y");
     layer_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 8).unwrap();
     // Priority higher than chatview but lower than chatedit
     layer_node.set_property_u32(atom, Role::App, "priority", 1).unwrap();
     let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    content_layer_node.clone().link(layer_node.clone());
+    content_layer_node.link(layer_node.clone());
 
     let actions_is_visible = PropertyBool::wrap(&layer_node, Role::App, "is_visible", 0).unwrap();
 
     // Create the actionbar bg
     let node = create_vector_art("actionbar_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -1273,39 +1273,39 @@ pub async fn make(
     );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create some text
     let node = create_text("actions_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, ACTION_LABEL_POS.x).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, ACTION_LABEL_POS.y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, ACTION_LABEL_POS.x).unwrap();
+    prop.set_f32(atom, Role::App, 1, ACTION_LABEL_POS.y).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE * 1.24).unwrap();
     node.set_property_str(atom, Role::App, "text", "copy   paste   select all").unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.94).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.94).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Copy button
     let node = create_button("copy_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, ACTION_COPY_RECT.x).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, ACTION_COPY_RECT.y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_COPY_RECT.w).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_COPY_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, ACTION_COPY_RECT.x).unwrap();
+    prop.set_f32(atom, Role::App, 1, ACTION_COPY_RECT.y).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_COPY_RECT.w).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_COPY_RECT.h).unwrap();
 
     let (slot, recvr) = Slot::new("copy_clicked");
     node.register("click", slot).unwrap();
@@ -1324,16 +1324,16 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Paste button
     let node = create_button("paste_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, ACTION_PASTE_RECT.x).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, ACTION_PASTE_RECT.y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_PASTE_RECT.w).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_PASTE_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, ACTION_PASTE_RECT.x).unwrap();
+    prop.set_f32(atom, Role::App, 1, ACTION_PASTE_RECT.y).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_PASTE_RECT.w).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_PASTE_RECT.h).unwrap();
 
     let (slot, recvr) = Slot::new("paste_clicked");
     node.register("click", slot).unwrap();
@@ -1357,16 +1357,16 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Select all button
     let node = create_button("select_all_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, ACTION_SELECT_ALL_RECT.x).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, ACTION_SELECT_ALL_RECT.y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.w).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, ACTION_SELECT_ALL_RECT.x).unwrap();
+    prop.set_f32(atom, Role::App, 1, ACTION_SELECT_ALL_RECT.y).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.w).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
 
     let (slot, recvr) = Slot::new("select_all_clicked");
     node.register("click", slot).unwrap();
@@ -1378,18 +1378,18 @@ pub async fn make(
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Paste overlay popup
     let layer_node = create_layer("paste_layer");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 40.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 40.).unwrap();
     let code = cc.compile("editz_bg_top_y - ACTION_POPUP_Y_OFF").unwrap();
     //let code = cc.compile("h - 60 - 80").unwrap();
     //let code = cc.compile("h - 60 - 300").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     prop.add_depend(&editbox_bg_rect_prop, 1, "editz_bg_top_y");
     layer_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 8).unwrap();
@@ -1415,10 +1415,10 @@ pub async fn make(
     // Create the paste bg
     let node = create_vector_art("paste_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -1448,42 +1448,42 @@ pub async fn make(
     );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create some text
     let node = create_text("paste_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, ACTION_LABEL_POS.x).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, ACTION_LABEL_POS.y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, ACTION_LABEL_POS.x).unwrap();
+    prop.set_f32(atom, Role::App, 1, ACTION_LABEL_POS.y).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_SELECT_ALL_RECT.rhs()).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_SELECT_ALL_RECT.h).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
     node.set_property_str(atom, Role::App, "text", "paste").unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.94).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.94).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Paste button
     let node = create_button("paste_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, ACTION_PASTE_RECT.w).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, ACTION_PASTE_RECT.h).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, ACTION_PASTE_RECT.w).unwrap();
+    prop.set_f32(atom, Role::App, 3, ACTION_PASTE_RECT.h).unwrap();
 
     let node = node.setup(|me| Button::new(me)).await;
-    layer_node.clone().link(node.clone());
+    layer_node.link(node.clone());
 
     let (slot, recvr) = Slot::new("paste_clicked");
     node.register("click", slot).unwrap();

+ 48 - 48
bin/app/src/app/schema/menu.rs

@@ -63,7 +63,7 @@ use ui_consts::*;
 
 pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     let window_scale = PropertyFloat32::wrap(
-        &app.sg_root.clone().lookup_node("/setting/scale").unwrap(),
+        &app.sg_root.lookup_node("/setting/scale").unwrap(),
         Role::Internal,
         "value",
         0,
@@ -74,10 +74,10 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     // Main view
     let layer_node = create_layer("menu_layer");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
@@ -86,10 +86,10 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     // Channels label bg
     let node = create_vector_art("channels_label_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -121,15 +121,15 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create some text
     let node = create_text("channels_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, CHANNEL_LABEL_Y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
+    prop.set_f32(atom, Role::App, 1, CHANNEL_LABEL_Y).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", CHANNEL_LABEL_FONTSIZE).unwrap();
     node.set_property_bool(atom, Role::App, "use_i18n", true).unwrap();
@@ -138,32 +138,32 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::DarkMode {
-        prop.clone().set_f32(atom, Role::App, 0, 0.65).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.87).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.83).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.65).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.87).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.83).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else if COLOR_SCHEME == ColorScheme::PaperLight {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
         .setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     let mut channel_y = CHANNEL_LABEL_LINESPACE;
 
     for (i, channel) in CHANNELS.iter().enumerate() {
         let node = create_vector_art(&(channel.to_string() + "_channel_label_bg"));
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, channel_y).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, channel_y).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
         let mut shape = VectorShape::new();
@@ -191,7 +191,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         );
 
         let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
 
         // Desktop platforms
         //#[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
@@ -203,10 +203,10 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         // Create some text
         let node = create_text(&(channel.to_string() + "_channel_label"));
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, channel_y + CHANNEL_LABEL_Y).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+        prop.set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
+        prop.set_f32(atom, Role::App, 1, channel_y + CHANNEL_LABEL_Y).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 200.).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
         node.set_property_f32(atom, Role::App, "font_size", CHANNEL_LABEL_FONTSIZE).unwrap();
         node.set_property_str(atom, Role::App, "text", text).unwrap();
@@ -215,15 +215,15 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         let color_prop = node.get_property("text_color").unwrap();
         let set_normal_color = move |atom: &mut PropertyAtomicGuard| {
             if COLOR_SCHEME == ColorScheme::DarkMode {
-                color_prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+                color_prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+                color_prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+                color_prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+                color_prop.set_f32(atom, Role::App, 3, 1.).unwrap();
             } else if COLOR_SCHEME == ColorScheme::PaperLight {
-                color_prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-                color_prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+                color_prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+                color_prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+                color_prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+                color_prop.set_f32(atom, Role::App, 3, 1.).unwrap();
             }
         };
         set_normal_color(atom);
@@ -234,21 +234,21 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
                 Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone())
             })
             .await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
 
         // Create the button
         let node = create_button(&(channel.to_string() + "_channel_btn"));
         node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, channel_y).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, channel_y).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
 
         let (slot, recvr) = Slot::new(channel.to_string() + "_clicked");
         node.register("click", slot).unwrap();
         let chatview_path = "/window/".to_string() + channel + "_chat_layer";
-        let chatview_node = app.sg_root.clone().lookup_node(chatview_path).unwrap();
+        let chatview_node = app.sg_root.lookup_node(chatview_path).unwrap();
         let chatview_is_visible =
             PropertyBool::wrap(&chatview_node, Role::App, "is_visible", 0).unwrap();
         let menu_is_visible = PropertyBool::wrap(&layer_node, Role::App, "is_visible", 0).unwrap();
@@ -271,7 +271,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         app.tasks.lock().unwrap().push(listen_click);
 
         let node = node.setup(|me| Button::new(me)).await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
 
         // Create shortcut
         let channel_id = i + 1;
@@ -293,7 +293,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         app.tasks.lock().unwrap().push(listen_enter);
 
         let node = node.setup(|me| Shortcut::new(me)).await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
 
         channel_y += CHANNEL_LABEL_LINESPACE;
     }

+ 74 - 74
bin/app/src/app/schema/mod.rs

@@ -138,7 +138,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     node.set_property_u32(atom, Role::App, "priority", 10).unwrap();
     let (slot, recvr) = Slot::new("zoom_out_pressed");
     node.register("shortcut", slot).unwrap();
-    let window_scale = app.sg_root.clone().lookup_node("/setting/scale").unwrap();
+    let window_scale = app.sg_root.lookup_node("/setting/scale").unwrap();
     let window_scale2 = window_scale.clone();
     let render_api = app.render_api.clone();
     let listen_zoom = app.ex.spawn(async move {
@@ -159,7 +159,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     });
     app.tasks.lock().unwrap().push(listen_zoom);
     let node = node.setup(|me| Shortcut::new(me)).await;
-    window.clone().link(node);
+    window.link(node);
 
     let node = create_shortcut("zoom_in_shortcut");
     node.set_property_str(atom, Role::App, "key", "ctrl+=").unwrap();
@@ -187,7 +187,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     });
     app.tasks.lock().unwrap().push(listen_zoom);
     let node = node.setup(|me| Shortcut::new(me)).await;
-    window.clone().link(node);
+    window.link(node);
 
     /*
     let node = create_gesture("zoom_gesture");
@@ -215,29 +215,29 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     });
     app.tasks.lock().unwrap().push(listen_zoom);
     let node = node.setup(|me| Gesture::new(me)).await;
-    window.clone().link(node);
+    window.link(node);
     */
 
     if COLOR_SCHEME == ColorScheme::DarkMode {
         // Bg layer
         let layer_node = create_layer("bg_layer");
         let prop = layer_node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
         layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
         layer_node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
         let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-        window.clone().link(layer_node.clone());
+        window.link(layer_node.clone());
 
         // Create a bg image
         let node = create_image("bg_image");
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
 
         // Image aspect ratio
         //let R = 1.78;
@@ -245,8 +245,8 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         cc.add_const_f32("R", r);
 
         let prop = node.get_property("uv").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
         #[rustfmt::skip]
     let code = cc.compile("
         r = w / h;
@@ -256,7 +256,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
             1
         }
     ").unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, code).unwrap();
+        prop.set_expr(atom, Role::App, 2, code).unwrap();
         #[rustfmt::skip]
     let code = cc.compile("
         r = w / h;
@@ -266,20 +266,20 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
             R / r
         }
     ").unwrap();
-        prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+        prop.set_expr(atom, Role::App, 3, code).unwrap();
 
         node.set_property_str(atom, Role::App, "path", BG_PATH).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
         let node = node.setup(|me| Image::new(me, app.render_api.clone())).await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
 
         // Create a bg mesh on top to fade the bg image
         let node = create_vector_art("bg");
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
         //let c = if LIGHTMODE { 1. } else { 0. };
@@ -294,14 +294,14 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
             [c, c, c, 0.3],
         );
         let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-        layer_node.clone().link(node);
+        layer_node.link(node);
     } else if COLOR_SCHEME == ColorScheme::PaperLight {
         let node = create_vector_art("bg");
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
         let c = 1.;
@@ -315,78 +315,78 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
             [c, c, c, 0.3],
         );
         let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-        window.clone().link(node);
+        window.link(node);
     }
 
     let netlayer_node = create_layer("netstatus_layer");
     let prop = netlayer_node.get_property("rect").unwrap();
     let code = cc.compile("w - NETSTATUS_ICON_SIZE").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    //prop.clone().set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
-    //prop.clone().set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1000.).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    //prop.set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
+    //prop.set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1000.).unwrap();
     netlayer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     netlayer_node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     let netlayer_node = netlayer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    window.clone().link(netlayer_node.clone());
+    window.link(netlayer_node.clone());
 
     let node = create_vector_art("net0");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let mut shape = shape::create_netlogo1([1., 0., 0.25, 1.]).scaled(NETLOGO_SCALE);
     shape.join(shape::create_netlogo2([0.27, 0.4, 0.4, 1.]).scaled(NETLOGO_SCALE));
     shape.join(shape::create_netlogo3([0.27, 0.4, 0.4, 1.]).scaled(NETLOGO_SCALE));
     let net0_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    netlayer_node.clone().link(net0_node);
+    netlayer_node.link(net0_node);
 
     let node = create_vector_art("net1");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let mut shape = shape::create_netlogo1([0.49, 0.57, 1., 1.]).scaled(NETLOGO_SCALE);
     shape.join(shape::create_netlogo2([0.49, 0.57, 1., 1.]).scaled(NETLOGO_SCALE));
     shape.join(shape::create_netlogo3([0.27, 0.4, 0.4, 1.]).scaled(NETLOGO_SCALE));
     let net1_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    netlayer_node.clone().link(net1_node);
+    netlayer_node.link(net1_node);
 
     let node = create_vector_art("net2");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let mut shape = shape::create_netlogo1([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE);
     shape.join(shape::create_netlogo2([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE));
     shape.join(shape::create_netlogo3([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE));
     let net2_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    netlayer_node.clone().link(net2_node);
+    netlayer_node.link(net2_node);
 
     let node = create_vector_art("net3");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let mut shape = shape::create_netlogo1([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE);
     shape.join(shape::create_netlogo2([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE));
     shape.join(shape::create_netlogo3([0., 0.94, 1., 1.]).scaled(NETLOGO_SCALE));
     let net3_node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    netlayer_node.clone().link(net3_node);
+    netlayer_node.link(net3_node);
 
     // Navbar Settings Button
 
@@ -395,38 +395,38 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     let settingslayer_node = create_layer("settings_button_layer");
     let prop = settingslayer_node.get_property("rect").unwrap();
     let code = cc.compile("w - NETSTATUS_ICON_SIZE - SETTINGS_ICON_SIZE").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1000.).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1000.).unwrap();
     settingslayer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     settingslayer_node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     let settingslayer_node =
         settingslayer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    window.clone().link(settingslayer_node.clone());
+    window.link(settingslayer_node.clone());
 
     // Background
     let node = create_vector_art("settings_btn_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_f32(atom, Role::App, 1, NETSTATUS_ICON_SIZE / 2.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let shape = shape::create_settings([0., 0.94, 1., 1.]).scaled(20.);
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
-    settingslayer_node.clone().link(node);
+    settingslayer_node.link(node);
 
     // Button
     let node = create_button("settings_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, NETSTATUS_ICON_SIZE).unwrap();
+    prop.set_f32(atom, Role::App, 3, NETSTATUS_ICON_SIZE).unwrap();
 
     let sg_root = app.sg_root.clone();
     let settings = move || {
@@ -450,7 +450,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         //  router currently points to view1 and we call router.goto("./view2")).
         //
         //  2. Support of wildcard in lookups in .get_children() or another method, like this "*_chat_layer".
-        let windows = sg_root.clone().lookup_node("/window").unwrap().get_children();
+        let windows = sg_root.lookup_node("/window").unwrap().get_children();
         let target_substrings = vec!["_chat_layer", "menu_layer", "settings_layer"];
         for node in windows.iter() {
             if target_substrings.iter().any(|&s| node.name.contains(s)) {
@@ -461,7 +461,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         }
 
         // Show settings
-        let settings_node = sg_root.clone().lookup_node("/window/settings_layer").unwrap();
+        let settings_node = sg_root.lookup_node("/window/settings_layer").unwrap();
         settings_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     };
 
@@ -476,7 +476,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-    settingslayer_node.clone().link(node);
+    settingslayer_node.link(node);
     */
 
     let emoji_meshes = emoji_picker::EmojiMeshes::new(
@@ -521,8 +521,8 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     menu::make(app, window.clone(), i18n_fish).await;
 
     // @@@ Debug stuff @@@
-    //let chatview_node = app.sg_root.clone().lookup_node("/window/dev_chat_layer").unwrap();
+    //let chatview_node = app.sg_root.lookup_node("/window/dev_chat_layer").unwrap();
     //chatview_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
-    //let menu_node = app.sg_root.clone().lookup_node("/window/menu_layer").unwrap();
+    //let menu_node = app.sg_root.lookup_node("/window/menu_layer").unwrap();
     //menu_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
 }

+ 172 - 182
bin/app/src/app/schema/settings.rs

@@ -140,7 +140,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
     cc.add_const_f32("SEARCH_PADDING_X", SEARCH_PADDING_X);
     cc.add_const_f32("X_RATIO", 1. / 2.);
     let window_scale = PropertyFloat32::wrap(
-        &app.sg_root.clone().lookup_node("/setting/scale").unwrap(),
+        &app.sg_root.lookup_node("/setting/scale").unwrap(),
         Role::Internal,
         "value",
         0,
@@ -151,25 +151,25 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
     // Main view
     let layer_node = create_layer("settings_layer");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     layer_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     let layer_node =
         layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
-    window.clone().link(layer_node.clone());
+    window.link(layer_node.clone());
 
     let mut setting_y = 0.;
 
     // Create the toolbar bg
     let node = create_vector_art("toolbar_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
 
     let (bg_color, sep_color) = match COLOR_SCHEME {
@@ -201,29 +201,29 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the back button
     let node = create_vector_art("back_btn_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, BACKARROW_Y).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
+    prop.set_f32(atom, Role::App, 1, BACKARROW_Y).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 0.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
     let shape = shape::create_back_arrow().scaled(BACKARROW_SCALE);
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     let node = create_button("back_btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, BACKARROW_BG_W).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, BACKARROW_BG_W).unwrap();
+    prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
 
     let sg_root = app.sg_root.clone();
     let goback = move || {
@@ -231,7 +231,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
         // Disable visilibity of all relevant window nodes
         // This is needed since for example all chats have a different node name.
-        let windows = sg_root.clone().lookup_node("/window").unwrap().get_children();
+        let windows = sg_root.lookup_node("/window").unwrap().get_children();
         let target_substrings = vec!["_chat_layer", "menu_layer", "settings_layer"];
 
         for node in windows.iter() {
@@ -244,7 +244,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         }
 
         // Go back to the dev channel
-        let menu_node = sg_root.clone().lookup_node("/window/dev_chat_layer").unwrap();
+        let menu_node = sg_root.lookup_node("/window/dev_chat_layer").unwrap();
         menu_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     };
 
@@ -259,15 +259,15 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
     app.tasks.lock().unwrap().push(listen_click);
 
     let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-    layer_node.clone().link(node.clone());
+    layer_node.link(node.clone());
 
     // Label: "SETTINGS" title
     let node = create_text("settings_label_fontsize");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, SETTING_TITLE_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 0, SETTING_TITLE_X).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", SETTING_TITLE_BASELINE).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", SETTING_TITLE_FONTSIZE).unwrap();
@@ -286,16 +286,16 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Search Bar Background
     let node = create_vector_art("emoji_picker_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
     let code = cc.compile("100").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("50")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("50")).unwrap();
     //prop.add_depend(&emoji_dynamic_h_prop, 0, "dynamic_h");
     node.set_property_u32(atom, Role::App, "z_index", 4).unwrap();
 
@@ -312,25 +312,25 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Search Bar Input
     let editbox_node = create_editbox("search_input");
     editbox_node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     editbox_node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
     let prop = editbox_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, SEARCH_PADDING_X).unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
+    prop.set_f32(atom, Role::App, 0, SEARCH_PADDING_X).unwrap();
+    prop.set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
     prop.clone()
         .set_expr(atom, Role::App, 2, cc.compile("w - SEARCH_PADDING_X*2").unwrap())
         .unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+    prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
     editbox_node.set_property_f32_vec(atom, Role::App, "text_color", vec![1., 1., 1., 1.]).unwrap();
     let prop = editbox_node.get_property("cursor_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     editbox_node.set_property_f32(atom, Role::App, "cursor_ascent", CURSOR_ASCENT).unwrap();
     editbox_node.set_property_f32(atom, Role::App, "cursor_descent", CURSOR_DESCENT).unwrap();
     editbox_node.set_property_f32(atom, Role::App, "select_ascent", SELECT_ASCENT).unwrap();
@@ -339,8 +339,8 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         .set_property_f32_vec(atom, Role::App, "hi_bg_color", vec![0.5, 0.5, 0.5, 1.])
         .unwrap();
     let prop = editbox_node.get_property("selected").unwrap();
-    prop.clone().set_null(atom, Role::App, 0).unwrap();
-    prop.clone().set_null(atom, Role::App, 1).unwrap();
+    prop.set_null(atom, Role::App, 0).unwrap();
+    prop.set_null(atom, Role::App, 1).unwrap();
     editbox_node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     editbox_node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     editbox_node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
@@ -350,26 +350,26 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
     // Search icon
     let node = create_vector_art("search_icon");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
+    prop.set_f32(atom, Role::App, 0, BACKARROW_X).unwrap();
     prop.clone()
         .set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE + SETTING_LABEL_LINESPACE / 2.)
         .unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 0.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
     let shape = shape::create_logo([1., 1., 1., 1.]).scaled(500.);
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Search placeholder
     let node = create_text("search_label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, SEARCH_PADDING_X).unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 0, SEARCH_PADDING_X).unwrap();
+    prop.set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", 16.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 16.).unwrap();
@@ -388,15 +388,15 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Search settings counter
     let node = create_text("search_count");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+    prop.set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
+    prop.set_expr(atom, Role::App, 1, cc.compile("60 + 20").unwrap()).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", 16.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 16.).unwrap();
@@ -415,18 +415,18 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     let sg_root3 = app.sg_root.clone();
     let search = move || {
         let atom = &mut PropertyAtomicGuard::new();
 
         let path = "/window/settings_layer/search_input";
-        let node = sg_root3.clone().lookup_node(path.to_string()).unwrap();
+        let node = sg_root3.lookup_node(path.to_string()).unwrap();
         let search_string = node.get_property_str("text").unwrap();
 
         let path = "/window/settings_layer/search_label";
-        let search_label_node = sg_root3.clone().lookup_node(path.to_string()).unwrap();
+        let search_label_node = sg_root3.lookup_node(path.to_string()).unwrap();
 
         if search_string.len() > 0 {
             let _ = search_label_node.set_property_f32(atom, Role::App, "font_size", 0.);
@@ -435,7 +435,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         }
 
         let path = "/window/settings_layer/settings";
-        let node = sg_root3.clone().lookup_node(path.to_string()).unwrap();
+        let node = sg_root3.lookup_node(path.to_string()).unwrap();
         let setting_nodes = node.get_children();
         let mut found_nodes = Vec::new();
 
@@ -463,7 +463,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         // Update the counter
         let counter_text = found_nodes.len().to_string();
         let path = "/window/settings_layer/search_count";
-        let node = sg_root3.clone().lookup_node(path.to_string()).unwrap();
+        let node = sg_root3.lookup_node(path.to_string()).unwrap();
         let _ = node.set_property_str(atom, Role::App, "text", &counter_text).unwrap();
     };
 
@@ -489,15 +489,15 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Search background
     let node = create_vector_art("search_bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 60.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, cc.compile("w  * 100").unwrap()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 60.).unwrap();
+    prop.set_expr(atom, Role::App, 2, cc.compile("w  * 100").unwrap()).unwrap();
+    prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -531,14 +531,14 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     let node = create_vector_art("search_bg2");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 60.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, cc.compile("w  * 100").unwrap()).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE / 3.5).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 60.).unwrap();
+    prop.set_expr(atom, Role::App, 2, cc.compile("w  * 100").unwrap()).unwrap();
+    prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE / 3.5).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let mut shape = VectorShape::new();
@@ -573,13 +573,13 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create a BTreeMap to store settings
     let mut settings_map: BTreeMap<String, Arc<Setting>> = BTreeMap::new();
 
     // Get the app settings
-    let app_setting_root = app.sg_root.clone().lookup_node("/setting").unwrap();
+    let app_setting_root = app.sg_root.lookup_node("/setting").unwrap();
     for setting in app_setting_root.get_children().iter() {
         let name = ["app", &setting.name.clone()].join(".");
         settings_map.insert(name.clone(), Arc::new(Setting { name, node: setting.clone() }));
@@ -609,16 +609,16 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
     // Contain a setting
     let settings_layer_node = create_layer("settings");
     let prop = settings_layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, 0.).unwrap();
     settings_layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     settings_layer_node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     let settings_layer_node = settings_layer_node
         .setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone()))
         .await;
-    layer_node.clone().link(settings_layer_node.clone());
+    layer_node.link(settings_layer_node.clone());
 
     // Iterate over the map and process each setting
     for setting in settings_map.values() {
@@ -632,26 +632,26 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         // Contain a setting
         let setting_layer_node = create_layer(&setting_name.to_string());
         let prop = setting_layer_node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, setting_y + 60.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, setting_y + 60.).unwrap();
+        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+        prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
         setting_layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
         setting_layer_node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
         let setting_layer_node = setting_layer_node
             .setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone()))
             .await;
-        settings_layer_node.clone().link(setting_layer_node.clone());
+        settings_layer_node.link(setting_layer_node.clone());
 
         // Background Label
         let node = create_vector_art("key_bg");
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
         prop.clone()
             .set_expr(atom, Role::App, 2, cc.compile("w  * X_RATIO - BORDER_RIGHT_SCALE").unwrap())
             .unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+        prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
         let mut shape = VectorShape::new();
@@ -686,7 +686,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         let node = node
             .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
             .await;
-        setting_layer_node.clone().link(node);
+        setting_layer_node.link(node);
 
         if is_bool {
             // Background Value: Bool FALSE
@@ -700,7 +700,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * X_RATIO - BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 1, 0.).unwrap();
             prop.clone()
                 .set_expr(
                     atom,
@@ -709,7 +709,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * (1-X_RATIO) + BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+            prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
             node.set_property_bool(
                 atom,
@@ -753,7 +753,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             let node = node
                 .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                 .await;
-            setting_layer_node.clone().link(node);
+            setting_layer_node.link(node);
 
             // Background Value: Bool TRUE
             let node = create_vector_art("value_bg_bool_true");
@@ -766,7 +766,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * X_RATIO - BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 1, 0.).unwrap();
             prop.clone()
                 .set_expr(
                     atom,
@@ -775,7 +775,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * (1-X_RATIO) + BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+            prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
             node.set_property_bool(
                 atom,
@@ -819,7 +819,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             let node = node
                 .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                 .await;
-            setting_layer_node.clone().link(node);
+            setting_layer_node.link(node);
         } else {
             // Background Value
             let node = create_vector_art("value_bg");
@@ -832,7 +832,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * X_RATIO - BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 1, 0.).unwrap();
             prop.clone()
                 .set_expr(
                     atom,
@@ -841,7 +841,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                     cc.compile("w * (1-X_RATIO) + BORDER_RIGHT_SCALE").unwrap(),
                 )
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+            prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
             node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
 
@@ -879,16 +879,16 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             let node = node
                 .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                 .await;
-            setting_layer_node.clone().link(node);
+            setting_layer_node.link(node);
         }
 
         // Label Key
         let label_value_node = create_text("key_label");
         let prop = label_value_node.get_property("rect").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, SETTING_LABEL_X).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_expr(atom, Role::App, 2, cc.compile("w * X_RATIO").unwrap()).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 100.).unwrap();
+        prop.set_f32(atom, Role::App, 0, SETTING_LABEL_X).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 2, cc.compile("w * X_RATIO").unwrap()).unwrap();
+        prop.set_f32(atom, Role::App, 3, 100.).unwrap();
         label_value_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
         label_value_node
             .set_property_f32(atom, Role::App, "baseline", SETTING_LABEL_BASELINE)
@@ -919,7 +919,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 )
             })
             .await;
-        setting_layer_node.clone().link(label_value_node);
+        setting_layer_node.link(label_value_node);
 
         // Text edit
         let editbox_node = create_editbox("value_editbox");
@@ -929,11 +929,11 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         prop.clone()
             .set_expr(atom, Role::App, 0, cc.compile("w * X_RATIO + BORDER_RIGHT_SCALE").unwrap())
             .unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
         prop.clone()
             .set_expr(atom, Role::App, 2, cc.compile("w * X_RATIO - BORDER_RIGHT_SCALE").unwrap())
             .unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+        prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
         editbox_node.set_property_f32(atom, Role::App, "baseline", SETTING_LABEL_BASELINE).unwrap();
         editbox_node.set_property_f32(atom, Role::App, "font_size", SETTING_EDIT_FONTSIZE).unwrap();
         editbox_node.set_property_f32(atom, Role::App, "cursor_ascent", CURSOR_ASCENT).unwrap();
@@ -950,8 +950,8 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             .set_property_f32_vec(atom, Role::App, "hi_bg_color", vec![0.5, 0.5, 0.5, 1.])
             .unwrap();
         let prop = editbox_node.get_property("selected").unwrap();
-        prop.clone().set_null(atom, Role::App, 0).unwrap();
-        prop.clone().set_null(atom, Role::App, 1).unwrap();
+        prop.set_null(atom, Role::App, 0).unwrap();
+        prop.set_null(atom, Role::App, 1).unwrap();
         editbox_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
         editbox_node.set_property_bool(atom, Role::App, "is_active", false).unwrap();
         editbox_node.set_property_bool(atom, Role::App, "is_focused", false).unwrap();
@@ -993,7 +993,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 )
             })
             .await;
-        setting_layer_node.clone().link(node);
+        setting_layer_node.link(node);
 
         // Is this setting the one that is currently active
         let cloned_active_setting = active_setting.clone();
@@ -1015,9 +1015,9 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         cc.compile("w * X_RATIO + BORDER_RIGHT_SCALE + 6").unwrap(),
                     )
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
+                prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 3, 0.).unwrap();
                 node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
                 node.set_property_bool(
                     atom,
@@ -1031,7 +1031,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 let node = node
                     .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                     .await;
-                setting_layer_node.clone().link(node);
+                setting_layer_node.link(node);
 
                 // Bool circle: TRUE
                 let node = create_vector_art("bool_icon_bg_true");
@@ -1044,9 +1044,9 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         cc.compile("w * X_RATIO + BORDER_RIGHT_SCALE + 6").unwrap(),
                     )
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
+                prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 3, 0.).unwrap();
                 node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
                 node.set_property_bool(
                     atom,
@@ -1060,7 +1060,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 let node = node
                     .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                     .await;
-                setting_layer_node.clone().link(node);
+                setting_layer_node.link(node);
 
                 // Label showing the setting's current value
                 let value_node = create_text("value_label");
@@ -1073,11 +1073,11 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         cc.compile("w * X_RATIO + BORDER_RIGHT_SCALE + 20 + 6").unwrap(),
                     )
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 1, 0.).unwrap();
                 prop.clone()
                     .set_expr(atom, Role::App, 2, cc.compile("w * X_RATIO").unwrap())
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 100.).unwrap();
+                prop.set_f32(atom, Role::App, 3, 100.).unwrap();
                 value_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
                 value_node
                     .set_property_f32(atom, Role::App, "baseline", SETTING_LABEL_BASELINE)
@@ -1120,7 +1120,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         )
                     })
                     .await;
-                setting_layer_node.clone().link(node);
+                setting_layer_node.link(node);
             } else {
                 // Label showing the setting's current value
                 let value_node = create_text("value_label");
@@ -1133,11 +1133,11 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         cc.compile("w * X_RATIO + BORDER_RIGHT_SCALE").unwrap(),
                     )
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+                prop.set_f32(atom, Role::App, 1, 0.).unwrap();
                 prop.clone()
                     .set_expr(atom, Role::App, 2, cc.compile("w * X_RATIO").unwrap())
                     .unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 100.).unwrap();
+                prop.set_f32(atom, Role::App, 3, 100.).unwrap();
                 value_node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
                 value_node
                     .set_property_f32(atom, Role::App, "baseline", SETTING_LABEL_BASELINE)
@@ -1164,19 +1164,19 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         )
                     })
                     .await;
-                setting_layer_node.clone().link(node);
+                setting_layer_node.link(node);
             }
 
             // A wide button useful to select the current setting
             let node = create_button("selector_btn");
             node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
             let prop = node.get_property("rect").unwrap();
-            prop.clone().set_expr(atom, Role::App, 0, cc.compile("w * X_RATIO").unwrap()).unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
+            prop.set_expr(atom, Role::App, 0, cc.compile("w * X_RATIO").unwrap()).unwrap();
+            prop.set_f32(atom, Role::App, 1, 0.).unwrap();
             prop.clone()
                 .set_expr(atom, Role::App, 2, cc.compile("w * (1-X_RATIO)").unwrap())
                 .unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+            prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
 
             let sg_root2 = app.sg_root.clone();
             let setting_clone2 = setting_clone.clone();
@@ -1187,26 +1187,26 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 let mut lock = cloned_active_setting.lock().unwrap();
 
                 let path = "/window/settings_layer/search_input";
-                let node = sg_root.clone().lookup_node(path).unwrap();
+                let node = sg_root.lookup_node(path).unwrap();
                 //node.set_property_bool(atom, Role::App, "is_active", false).unwrap();
                 node.set_property_bool(atom, Role::App, "is_focused", false).unwrap();
 
                 let was_active = if let Some(s) = lock.as_ref() {
                     let path = format!("/window/settings_layer/settings/{}", &s.name);
-                    let old_node = sg_root.clone().lookup_node(&path).unwrap();
+                    let old_node = sg_root.lookup_node(&path).unwrap();
 
                     let _was_active = s.name == setting_clone2.clone().name;
 
                     // Show the selected setting value label
                     // of the selected setting, if there's one
-                    let node = old_node.clone().lookup_node("/value_label").unwrap();
+                    let node = old_node.lookup_node("/value_label").unwrap();
                     let text = PropertyStr::wrap(&node, Role::App, "text", 0).unwrap();
                     text.set(atom, &s.value_as_string());
 
                     // Hide the selected setting editbox
                     // of the selected setting, if there's one
                     if !_was_active {
-                        let node = old_node.clone().lookup_node("/value_editbox").unwrap();
+                        let node = old_node.lookup_node("/value_editbox").unwrap();
                         node.set_property_bool(atom, Role::App, "is_active", false).unwrap();
                         node.set_property_bool(atom, Role::App, "is_focused", false).unwrap();
                         node.set_property_f32(atom, Role::App, "font_size", 0.).unwrap();
@@ -1220,7 +1220,6 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         matches!(lock.clone().unwrap().get_value(), PropertyValue::Bool(_));
                     if !is_bool {
                         old_node
-                            .clone()
                             .lookup_node("/confirm_btn_bg")
                             .unwrap()
                             .set_property_bool(atom, Role::App, "is_visible", false)
@@ -1238,31 +1237,27 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
                 if is_bool {
                     // Hide the setting value label (set its text empty)
-                    let editbox = setting_root2.clone().lookup_node("/value_label").unwrap();
+                    let editbox = setting_root2.lookup_node("/value_label").unwrap();
                     let label_text = PropertyStr::wrap(&editbox, Role::App, "text", 0).unwrap();
 
                     let value = setting_clone2.get_value();
 
                     setting_root2
-                        .clone()
                         .lookup_node("/value_bg_bool_true")
                         .unwrap()
                         .set_property_bool(atom, Role::App, "is_visible", false)
                         .unwrap();
                     setting_root2
-                        .clone()
                         .lookup_node("/value_bg_bool_false")
                         .unwrap()
                         .set_property_bool(atom, Role::App, "is_visible", false)
                         .unwrap();
                     setting_root2
-                        .clone()
                         .lookup_node("/bool_icon_bg_true")
                         .unwrap()
                         .set_property_bool(atom, Role::App, "is_visible", false)
                         .unwrap();
                     setting_root2
-                        .clone()
                         .lookup_node("/bool_icon_bg_false")
                         .unwrap()
                         .set_property_bool(atom, Role::App, "is_visible", false)
@@ -1276,19 +1271,17 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         label_text.set(atom, "TRUE");
 
                         setting_root2
-                            .clone()
                             .lookup_node("/value_bg_bool_true")
                             .unwrap()
                             .set_property_bool(atom, Role::App, "is_visible", true)
                             .unwrap();
                         setting_root2
-                            .clone()
                             .lookup_node("/bool_icon_bg_true")
                             .unwrap()
                             .set_property_bool(atom, Role::App, "is_visible", true)
                             .unwrap();
 
-                        let node = setting_root2.clone().lookup_node("/value_label").unwrap();
+                        let node = setting_root2.lookup_node("/value_label").unwrap();
                         node.set_property_f32_vec(
                             atom,
                             Role::App,
@@ -1304,19 +1297,17 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                         label_text.set(atom, "FALSE");
 
                         setting_root2
-                            .clone()
                             .lookup_node("/value_bg_bool_false")
                             .unwrap()
                             .set_property_bool(atom, Role::App, "is_visible", true)
                             .unwrap();
                         setting_root2
-                            .clone()
                             .lookup_node("/bool_icon_bg_false")
                             .unwrap()
                             .set_property_bool(atom, Role::App, "is_visible", true)
                             .unwrap();
 
-                        let node = setting_root2.clone().lookup_node("/value_label").unwrap();
+                        let node = setting_root2.lookup_node("/value_label").unwrap();
                         node.set_property_f32_vec(
                             atom,
                             Role::App,
@@ -1328,12 +1319,12 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 } else {
                     // Hide the setting value label (set its text empty)
                     // TODO?: Visilibity property on labels
-                    let editbox = setting_root2.clone().lookup_node("/value_label").unwrap();
+                    let editbox = setting_root2.lookup_node("/value_label").unwrap();
                     let label_text = PropertyStr::wrap(&editbox, Role::App, "text", 0).unwrap();
                     label_text.set(atom, "");
 
                     // Show the editbox
-                    let node = setting_root2.clone().lookup_node("/value_editbox").unwrap();
+                    let node = setting_root2.lookup_node("/value_editbox").unwrap();
                     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
                     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
                     node.set_property_f32(atom, Role::App, "font_size", 16.).unwrap();
@@ -1349,7 +1340,6 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
                     // Show confirm button
                     setting_root2
-                        .clone()
                         .lookup_node("/confirm_btn_bg")
                         .unwrap()
                         .set_property_bool(atom, Role::App, "is_visible", true)
@@ -1371,7 +1361,7 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
                 app.tasks.lock().unwrap().push(listen_click);
 
                 let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-                setting_layer_node.clone().link(node.clone());
+                setting_layer_node.link(node.clone());
             }
         }
 
@@ -1379,25 +1369,25 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             // Switch icon
             let node = create_vector_art("switch_btn_bg");
             let prop = node.get_property("rect").unwrap();
-            prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+            prop.set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
+            prop.set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
+            prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 3, 0.).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
             let shape = shape::create_switch([0., 0.94, 1., 1.]).scaled(10.);
             let node = node
                 .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                 .await;
-            setting_layer_node.clone().link(node);
+            setting_layer_node.link(node);
         } else {
             // Confirm button
             let node = create_vector_art("confirm_btn_bg");
             let prop = node.get_property("rect").unwrap();
-            prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+            prop.set_expr(atom, Role::App, 0, cc.compile("w - 50").unwrap()).unwrap();
+            prop.set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
+            prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 3, 0.).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
             node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
 
@@ -1405,19 +1395,19 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
             let node = node
                 .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
                 .await;
-            setting_layer_node.clone().link(node.clone());
+            setting_layer_node.link(node.clone());
 
             let node = create_button("confirm_btn");
             node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
             let prop = node.get_property("rect").unwrap();
-            prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 100").unwrap()).unwrap();
-            prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 2, 100.).unwrap();
-            prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+            prop.set_expr(atom, Role::App, 0, cc.compile("w - 100").unwrap()).unwrap();
+            prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+            prop.set_f32(atom, Role::App, 2, 100.).unwrap();
+            prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
             node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
             let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-            setting_layer_node.clone().link(node.clone());
+            setting_layer_node.link(node.clone());
 
             // Handle confirm button click
             {
@@ -1447,10 +1437,10 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         // Reset icon
         let node = create_vector_art("reset_btn_bg");
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 100").unwrap()).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 0.).unwrap();
+        prop.set_expr(atom, Role::App, 0, cc.compile("w - 100").unwrap()).unwrap();
+        prop.set_f32(atom, Role::App, 1, SETTING_LABEL_LINESPACE / 2.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 0.).unwrap();
         node.set_property_bool(atom, Role::App, "is_visible", !setting.is_default()).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
@@ -1458,19 +1448,19 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         let node = node
             .setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone()))
             .await;
-        setting_layer_node.clone().link(node);
+        setting_layer_node.link(node);
 
         let node = create_button("reset_btn");
         node.set_property_bool(atom, Role::App, "is_active", !setting.is_default()).unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.clone().set_expr(atom, Role::App, 0, cc.compile("w - 115").unwrap()).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 50.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
+        prop.set_expr(atom, Role::App, 0, cc.compile("w - 115").unwrap()).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 50.).unwrap();
+        prop.set_f32(atom, Role::App, 3, SETTING_LABEL_LINESPACE).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
 
         let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-        setting_layer_node.clone().link(node.clone());
+        setting_layer_node.link(node.clone());
 
         // Handle reset button click
         {
@@ -1489,11 +1479,11 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
 
                     // Show the selected setting value label (set its text empty)
                     // of the selected setting, if there's one
-                    let node = sg_root2.clone().lookup_node("/value_label").unwrap();
+                    let node = sg_root2.lookup_node("/value_label").unwrap();
                     let text = PropertyStr::wrap(&node, Role::App, "text", 0).unwrap();
                     text.set(atom, setting2.value_as_string());
 
-                    let node = sg_root2.clone().lookup_node("/value_editbox").unwrap();
+                    let node = sg_root2.lookup_node("/value_editbox").unwrap();
                     node.set_property_str(atom, Role::App, "text", setting2.value_as_string())
                         .unwrap();
 
@@ -1511,13 +1501,13 @@ pub async fn make(app: &App, window: SceneNodePtr, _ex: ExecutorPtr) {
         }
     }
 
-    let settings_node = app.sg_root.clone().lookup_node("/window/settings_layer").unwrap();
+    let settings_node = app.sg_root.lookup_node("/window/settings_layer").unwrap();
     settings_node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
 
     // Searchbar results count
-    let node = app.sg_root.clone().lookup_node("/window/settings_layer/settings").unwrap();
+    let node = app.sg_root.lookup_node("/window/settings_layer/settings").unwrap();
     let counter_text = node.get_children().len().to_string();
-    let node = app.sg_root.clone().lookup_node("/window/settings_layer/search_count").unwrap();
+    let node = app.sg_root.lookup_node("/window/settings_layer/search_count").unwrap();
     node.set_property_str(atom, Role::App, "text", &counter_text).unwrap();
 }
 
@@ -1525,7 +1515,7 @@ fn refresh_setting(setting: Arc<Setting>, sn: SceneNodePtr) {
     let atom = &mut PropertyAtomicGuard::new();
     let is_bool = matches!(setting.get_value(), PropertyValue::Bool(_));
 
-    let node = sn.clone().lookup_node("/key_label").unwrap();
+    let node = sn.lookup_node("/key_label").unwrap();
     if setting.clone().is_default() {
         node.set_property_f32_vec(atom, Role::App, "text_color", vec![0.65, 0.87, 0.83, 1.])
             .unwrap();
@@ -1533,9 +1523,9 @@ fn refresh_setting(setting: Arc<Setting>, sn: SceneNodePtr) {
         node.set_property_f32_vec(atom, Role::App, "text_color", vec![1., 1., 1., 1.]).unwrap();
     }
 
-    let node = sn.clone().lookup_node("/reset_btn_bg").unwrap();
+    let node = sn.lookup_node("/reset_btn_bg").unwrap();
     node.set_property_bool(atom, Role::App, "is_visible", !setting.clone().is_default()).unwrap();
-    let node = sn.clone().lookup_node("/reset_btn").unwrap();
+    let node = sn.lookup_node("/reset_btn").unwrap();
     node.set_property_bool(atom, Role::App, "is_active", !is_bool && !setting.clone().is_default())
         .unwrap();
 }
@@ -1548,7 +1538,7 @@ async fn update_setting(
 ) {
     let atom = &mut PropertyAtomicGuard::new();
 
-    if let Some(node) = sn.clone().lookup_node("/value_editbox") {
+    if let Some(node) = sn.lookup_node("/value_editbox") {
         node.set_property_f32(atom, Role::App, "font_size", 0.).unwrap();
         node.set_property_bool(atom, Role::App, "is_active", false).unwrap();
         node.set_property_bool(atom, Role::App, "is_focused", false).unwrap();
@@ -1559,10 +1549,10 @@ async fn update_setting(
             let value_str = editz_text.get();
             let parsed = value_str.parse::<u32>();
             if let Ok(value) = parsed {
-                if let Some(node) = sn.clone().lookup_node("/value_label") {
+                if let Some(node) = sn.lookup_node("/value_label") {
                     node.set_property_str(atom, Role::App, "text", value_str).unwrap();
                 }
-                if let Some(node) = sn.clone().lookup_node("/confirm_btn_bg") {
+                if let Some(node) = sn.lookup_node("/confirm_btn_bg") {
                     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
                 }
                 setting.node.set_property_u32(atom, Role::User, "value", value).unwrap();
@@ -1574,10 +1564,10 @@ async fn update_setting(
             let value_str = editz_text.get();
             let parsed = value_str.parse::<f32>();
             if let Ok(value) = parsed {
-                if let Some(node) = sn.clone().lookup_node("/value_label") {
+                if let Some(node) = sn.lookup_node("/value_label") {
                     node.set_property_str(atom, Role::App, "text", value_str).unwrap();
                 }
-                if let Some(node) = sn.clone().lookup_node("/confirm_btn_bg") {
+                if let Some(node) = sn.lookup_node("/confirm_btn_bg") {
                     node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
                 }
                 setting.node.set_property_f32(atom, Role::User, "value", value).unwrap();
@@ -1587,10 +1577,10 @@ async fn update_setting(
         }
         PropertyValue::Str(_) => {
             let value_str = editz_text.get();
-            if let Some(node) = sn.clone().lookup_node("/value_label") {
+            if let Some(node) = sn.lookup_node("/value_label") {
                 node.set_property_str(atom, Role::App, "text", &value_str).unwrap();
             }
-            if let Some(node) = sn.clone().lookup_node("/confirm_btn_bg") {
+            if let Some(node) = sn.lookup_node("/confirm_btn_bg") {
                 node.set_property_bool(atom, Role::App, "is_visible", false).unwrap();
             }
             setting.node.set_property_str(atom, Role::User, "value", value_str).unwrap();

+ 130 - 130
bin/app/src/app/schema/test.rs

@@ -55,7 +55,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     let atom = &mut PropertyAtomicGuard::new();
 
     let window_scale = PropertyFloat32::wrap(
-        &app.sg_root.clone().lookup_node("/setting/scale").unwrap(),
+        &app.sg_root.lookup_node("/setting/scale").unwrap(),
         Role::Internal,
         "value",
         0,
@@ -65,10 +65,10 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     // Create a layer called view
     let layer_node = create_layer("view");
     let prop = layer_node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
     let layer_node =
         layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
@@ -77,10 +77,10 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     // Create a bg mesh
     let node = create_vector_art("bg");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
 
     let c = if LIGHTMODE { 1. } else { 0. };
@@ -102,17 +102,17 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     );
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     /*
     // Create button bg
     let node = create_vector_art("btnbg");
     let prop = node.get_property("rect").unwrap();
     let code = cc.compile("w - 210").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 200.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 60.).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_f32(atom, Role::App, 1, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 60.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     // Setup the pimpl
@@ -135,32 +135,32 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     let shape = VectorShape { verts, indices };
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create the button
     let node = create_button("btn");
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     let prop = node.get_property("rect").unwrap();
     let code = cc.compile("w - 220").unwrap();
-    prop.clone().set_expr(atom, Role::App, 0, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 200.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 60.).unwrap();
+    prop.set_expr(atom, Role::App, 0, code).unwrap();
+    prop.set_f32(atom, Role::App, 1, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 60.).unwrap();
 
     //let (sender, btn_click_recvr) = async_channel::unbounded();
     //let slot_click = Slot { name: "button_clicked".to_string(), notify: sender };
     //node.register("click", slot_click).unwrap();
 
     let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create another mesh
     let node = create_vector_art("box");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 60.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 60.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 60.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 60.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     // Setup the pimpl
@@ -183,17 +183,17 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     let shape = VectorShape { verts, indices };
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Debugging tool
     let node = create_vector_art("debugtool");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
     let code = cc.compile("h/2").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     let code = cc.compile("h/2 - 200").unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
 
     let mut shape = VectorShape::new();
@@ -213,15 +213,15 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     );
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Another debug tool for the chatedit
     let node = create_vector_art("debugtool-chatedit");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 300. - 5.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 400. + 10.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 300. - 5.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_f32(atom, Role::App, 3, 400. + 10.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
 
     let mut shape = VectorShape::new();
@@ -241,28 +241,28 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     );
     let node =
         node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // Create KING GNU!
     let node = create_image("king");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 80.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 10.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 60.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 60.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 80.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 60.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 60.).unwrap();
     node.set_property_str(atom, Role::App, "path", KING_PATH).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     let node = node.setup(|me| Image::new(me, app.render_api.clone(), app.ex.clone())).await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
     */
 
     // Create some text
     let node = create_text("label");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 100.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 100.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 2000.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 100.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 100.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 2000.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", 40.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 60.).unwrap();
     node.set_property_str(
@@ -276,10 +276,10 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     .unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
 
     let node = node
@@ -293,7 +293,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     /*
     // Text edit
@@ -301,20 +301,20 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 150.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 150.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 380.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 150.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 150.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 380.).unwrap();
     //let code = vec![Op::Sub((
     //    Box::new(Op::LoadVar("h".to_string())),
     //    Box::new(Op::ConstFloat32(60.)),
     //))];
-    //prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
+    //prop.set_expr(atom, Role::App, 1, code).unwrap();
     //let code = vec![Op::Sub((
     //    Box::new(Op::LoadVar("w".to_string())),
     //    Box::new(Op::ConstFloat32(120.)),
     //))];
-    //prop.clone().set_expr(atom, Role::App, 2, code).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 60.).unwrap();
+    //prop.set_expr(atom, Role::App, 2, code).unwrap();
+    prop.set_f32(atom, Role::App, 3, 60.).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", 40.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 20.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 40.).unwrap();
@@ -322,40 +322,40 @@ pub async fn make(app: &App, window: SceneNodePtr) {
         .unwrap();
     let prop = node.get_property("text_color").unwrap();
     if LIGHTMODE {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
     let prop = node.get_property("cursor_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_ascent", 40.).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_descent", 40.).unwrap();
     node.set_property_f32(atom, Role::App, "select_ascent", 60.).unwrap();
     node.set_property_f32(atom, Role::App, "select_descent", 60.).unwrap();
     let prop = node.get_property("hi_bg_color").unwrap();
     if LIGHTMODE {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 0.5).unwrap();
     }
     let prop = node.get_property("selected").unwrap();
-    prop.clone().set_null(atom, Role::App, 0).unwrap();
-    prop.clone().set_null(atom, Role::App, 1).unwrap();
+    prop.set_null(atom, Role::App, 0).unwrap();
+    prop.set_null(atom, Role::App, 1).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
 
@@ -390,17 +390,17 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
 
     // ChatView
     let node = create_chatview("chatty");
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 10.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 10.).unwrap();
     let code = cc.compile("h/2").unwrap();
-    prop.clone().set_expr(atom, Role::App, 1, code).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
+    prop.set_expr(atom, Role::App, 1, code).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     let code = cc.compile("h/2 - 200").unwrap();
-    prop.clone().set_expr(atom, Role::App, 3, code).unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 20.).unwrap();
     node.set_property_f32(atom, Role::App, "timestamp_font_size", 10.).unwrap();
     node.set_property_f32(atom, Role::App, "timestamp_width", 80.).unwrap();
@@ -410,21 +410,21 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
 
     let prop = node.get_property("timestamp_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 3, 0.5).unwrap();
     let prop = node.get_property("text_color").unwrap();
     if LIGHTMODE {
-        prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else {
-        prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
 
     let prop = node.get_property("nick_colors").unwrap();
@@ -447,15 +447,15 @@ pub async fn make(app: &App, window: SceneNodePtr) {
 
     let prop = node.get_property("hi_bg_color").unwrap();
     if LIGHTMODE {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     } else {
-        prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-        prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+        prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     }
 
     let db = sled::open(CHATDB_PATH).expect("cannot open sleddb");
@@ -476,7 +476,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
     */
 
     /*
@@ -486,20 +486,20 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
 
     let prop = node.get_property("height_range").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 400.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 400.).unwrap();
 
     let prop = node.get_property("rect").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 100.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 300.).unwrap();
-    prop.clone().set_expr(atom, Role::App, 2, expr::load_var("parent_w")).unwrap();
-    //prop.clone().set_f32(atom, Role::App, 3, 50.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 100.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 300.).unwrap();
+    prop.set_expr(atom, Role::App, 2, expr::load_var("parent_w")).unwrap();
+    //prop.set_f32(atom, Role::App, 3, 50.).unwrap();
 
     node.set_property_bool(atom, Role::App, "debug", true).unwrap();
 
     let prop = node.get_property("padding").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 20.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 20.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 20.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 20.).unwrap();
 
     node.set_property_f32(atom, Role::App, "baseline", 34.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 40.).unwrap();
@@ -507,38 +507,38 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     #[cfg(target_os = "android")]
     {
         let prop = node.get_property("padding").unwrap();
-        prop.clone().set_f32(atom, Role::App, 0, 80.).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, 80.).unwrap();
+        prop.set_f32(atom, Role::App, 0, 80.).unwrap();
+        prop.set_f32(atom, Role::App, 1, 80.).unwrap();
 
         node.set_property_f32(atom, Role::App, "font_size", 60.).unwrap();
     }
 
     //node.set_property_str(atom, Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
     let prop = node.get_property("text_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     let prop = node.get_property("text_hi_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.44).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.96).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.44).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.96).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     let prop = node.get_property("cursor_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.816).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.627).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.816).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.627).unwrap();
+    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_ascent", 35.).unwrap();
     node.set_property_f32(atom, Role::App, "cursor_descent", 20.).unwrap();
     node.set_property_f32(atom, Role::App, "select_ascent", 35.).unwrap();
     node.set_property_f32(atom, Role::App, "select_descent", 20.).unwrap();
     node.set_property_f32(atom, Role::App, "handle_descent", 25.).unwrap();
     let prop = node.get_property("hi_bg_color").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 2, 0.5).unwrap();
-    prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+    prop.set_f32(atom, Role::App, 0, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 1, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 2, 0.5).unwrap();
+    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 3).unwrap();
     let node = node
         .setup(|me| {
@@ -551,6 +551,6 @@ pub async fn make(app: &App, window: SceneNodePtr) {
             )
         })
         .await;
-    layer_node.clone().link(node);
+    layer_node.link(node);
     */
 }

+ 16 - 16
bin/app/src/main.rs

@@ -263,7 +263,7 @@ static GOD: OnceLock<God> = OnceLock::new();
 async fn load_plugins(ex: ExecutorPtr, sg_root: SceneNodePtr, cv: Arc<CondVar>) {
     let plugin = SceneNode::new("plugin", SceneNodeType::PluginRoot);
     let plugin = plugin.setup_null();
-    sg_root.clone().link(plugin.clone());
+    sg_root.link(plugin.clone());
 
     let darkirc = create_darkirc("darkirc");
     let darkirc = darkirc
@@ -289,7 +289,7 @@ async fn load_plugins(ex: ExecutorPtr, sg_root: SceneNodePtr, cv: Arc<CondVar>)
 
             let node_path = format!("/window/{channel}_chat_layer/content/chatty");
             t!("Attempting to relay message to {node_path}");
-            let Some(chatview) = sg_root2.clone().lookup_node(&node_path) else {
+            let Some(chatview) = sg_root2.lookup_node(&node_path) else {
                 d!("Ignoring message since {node_path} doesn't exist");
                 continue
             };
@@ -309,26 +309,26 @@ async fn load_plugins(ex: ExecutorPtr, sg_root: SceneNodePtr, cv: Arc<CondVar>)
 
             // Apply coloring when you get a message
             let chat_path = format!("/window/{channel}_chat_layer");
-            let chat_layer = sg_root2.clone().lookup_node(chat_path).unwrap();
+            let chat_layer = sg_root2.lookup_node(chat_path).unwrap();
             if chat_layer.get_property_bool("is_visible").unwrap() {
                 continue
             }
 
             let node_path = format!("/window/menu_layer/{channel}_channel_label");
-            let menu_label = sg_root2.clone().lookup_node(&node_path).unwrap();
+            let menu_label = sg_root2.lookup_node(&node_path).unwrap();
             let prop = menu_label.get_property("text_color").unwrap();
             if msg.contains(&darkirc_nick.get()) {
                 // Nick highlight
-                prop.clone().set_f32(atom, Role::App, 0, 0.56).unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, 0.61).unwrap();
-                prop.clone().set_f32(atom, Role::App, 2, 1.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+                prop.set_f32(atom, Role::App, 0, 0.56).unwrap();
+                prop.set_f32(atom, Role::App, 1, 0.61).unwrap();
+                prop.set_f32(atom, Role::App, 2, 1.).unwrap();
+                prop.set_f32(atom, Role::App, 3, 1.).unwrap();
             } else {
                 // Normal channel activity
-                prop.clone().set_f32(atom, Role::App, 0, 0.36).unwrap();
-                prop.clone().set_f32(atom, Role::App, 1, 1.).unwrap();
-                prop.clone().set_f32(atom, Role::App, 2, 0.51).unwrap();
-                prop.clone().set_f32(atom, Role::App, 3, 1.).unwrap();
+                prop.set_f32(atom, Role::App, 0, 0.36).unwrap();
+                prop.set_f32(atom, Role::App, 1, 1.).unwrap();
+                prop.set_f32(atom, Role::App, 2, 0.51).unwrap();
+                prop.set_f32(atom, Role::App, 3, 1.).unwrap();
             }
         }
     });
@@ -338,10 +338,10 @@ async fn load_plugins(ex: ExecutorPtr, sg_root: SceneNodePtr, cv: Arc<CondVar>)
     let sg_root2 = sg_root.clone();
     let listen_connect = ex.spawn(async move {
         cv.wait().await;
-        let net0 = sg_root2.clone().lookup_node("/window/netstatus_layer/net0").unwrap();
-        let net1 = sg_root2.clone().lookup_node("/window/netstatus_layer/net1").unwrap();
-        let net2 = sg_root2.clone().lookup_node("/window/netstatus_layer/net2").unwrap();
-        let net3 = sg_root2.clone().lookup_node("/window/netstatus_layer/net3").unwrap();
+        let net0 = sg_root2.lookup_node("/window/netstatus_layer/net0").unwrap();
+        let net1 = sg_root2.lookup_node("/window/netstatus_layer/net1").unwrap();
+        let net2 = sg_root2.lookup_node("/window/netstatus_layer/net2").unwrap();
+        let net3 = sg_root2.lookup_node("/window/netstatus_layer/net3").unwrap();
 
         let net0_is_visible = PropertyBool::wrap(&net0, Role::App, "is_visible", 0).unwrap();
         let net1_is_visible = PropertyBool::wrap(&net1, Role::App, "is_visible", 0).unwrap();

+ 5 - 10
bin/app/src/net.rs

@@ -156,8 +156,7 @@ impl ZeroMQAdapter {
             Command::GetChildren => {
                 let node_path: ScenePath = String::decode(&mut cur).unwrap().parse()?;
                 debug!(target: "req", "{cmd:?}({node_path})");
-                let node =
-                    self.sg_root.clone().lookup_node(node_path).ok_or(Error::NodeNotFound)?;
+                let node = self.sg_root.lookup_node(node_path).ok_or(Error::NodeNotFound)?;
 
                 let children: Vec<_> = node
                     .get_children()
@@ -183,8 +182,7 @@ impl ZeroMQAdapter {
             Command::GetProperties => {
                 let node_path: ScenePath = String::decode(&mut cur).unwrap().parse()?;
                 debug!(target: "req", "{cmd:?}({node_path})");
-                let node =
-                    self.sg_root.clone().lookup_node(node_path).ok_or(Error::NodeNotFound)?;
+                let node = self.sg_root.lookup_node(node_path).ok_or(Error::NodeNotFound)?;
 
                 VarInt(node.props.len() as u64).encode(&mut reply).unwrap();
                 for prop in &node.props {
@@ -213,8 +211,7 @@ impl ZeroMQAdapter {
                 let node_path: ScenePath = String::decode(&mut cur).unwrap().parse()?;
                 let prop_name = String::decode(&mut cur).unwrap();
                 debug!(target: "req", "{cmd:?}({node_path}, {prop_name})");
-                let node =
-                    self.sg_root.clone().lookup_node(node_path).ok_or(Error::NodeNotFound)?;
+                let node = self.sg_root.lookup_node(node_path).ok_or(Error::NodeNotFound)?;
 
                 let prop = node.get_property(&prop_name).ok_or(Error::PropertyNotFound)?;
                 prop.typ.encode(&mut reply).unwrap();
@@ -242,8 +239,7 @@ impl ZeroMQAdapter {
                 let prop_type = PropertyType::decode(&mut cur).unwrap();
                 debug!(target: "req", "{cmd:?}({node_path}, {prop_name}, {prop_i}, {prop_type:?})");
 
-                let node =
-                    self.sg_root.clone().lookup_node(node_path).ok_or(Error::NodeNotFound)?;
+                let node = self.sg_root.lookup_node(node_path).ok_or(Error::NodeNotFound)?;
                 let prop = node.get_property(&prop_name).ok_or(Error::PropertyNotFound)?;
 
                 let atom = &mut self.render_api.make_guard();
@@ -566,8 +562,7 @@ impl ZeroMQAdapter {
                 let arg_data = Vec::<u8>::decode(&mut cur).unwrap();
                 debug!(target: "req", "{cmd:?}({node_path}, {method_name}, ...)");
 
-                let node =
-                    self.sg_root.clone().lookup_node(node_path).ok_or(Error::NodeNotFound)?;
+                let node = self.sg_root.lookup_node(node_path).ok_or(Error::NodeNotFound)?;
                 let result = node.call_method(&method_name, arg_data).await?;
                 result.encode(&mut reply).unwrap();
             }

+ 1 - 1
bin/app/src/plugin/darkirc.rs

@@ -184,7 +184,7 @@ impl DarkIrc {
         let nick = PropertyStr::wrap(node_ref, Role::Internal, "nick", 0).unwrap();
 
         let setting_root = Arc::new(SceneNode::new("setting", SceneNodeType::SettingRoot));
-        node_ref.clone().link(setting_root.clone());
+        node_ref.link(setting_root.clone());
 
         i!("Starting DarkIRC backend");
         let evgr_path = get_evgrdb_path();

+ 1 - 1
bin/app/src/plugin/mod.rs

@@ -85,7 +85,7 @@ impl PluginSettings {
         match node {
             Some(n) => {
                 let node_ptr = Arc::new(n);
-                self.setting_root.clone().link(node_ptr.clone().into());
+                self.setting_root.link(node_ptr.clone().into());
                 Some(node_ptr)
             }
             None => None,

+ 42 - 38
bin/app/src/prop/mod.rs

@@ -364,13 +364,13 @@ impl Property {
     // Set
 
     /// This will clear all values, resetting them to the default
-    pub fn clear_values(self: Arc<Self>, atom: &mut PropertyAtomicGuard, role: Role) {
+    pub fn clear_values(self: &Arc<Self>, atom: &mut PropertyAtomicGuard, role: Role) {
         {
             let vals = &mut self.vals.lock().unwrap();
             vals.clear();
             vals.resize(self.array_len, PropertyValue::Unset);
         }
-        atom.add(self, role, ModifyAction::Clear);
+        atom.add(self.clone(), role, ModifyAction::Clear);
     }
 
     fn set_raw_value(&self, i: usize, val: PropertyValue) -> Result<()> {
@@ -387,7 +387,7 @@ impl Property {
     }
 
     pub fn unset(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -399,12 +399,12 @@ impl Property {
             }
             vals[i] = PropertyValue::Unset;
         }
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
 
     pub fn set_null(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -420,23 +420,23 @@ impl Property {
         vals[i] = PropertyValue::Null;
         drop(vals);
 
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
 
     pub fn set_bool(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
         val: bool,
     ) -> Result<()> {
         self.set_raw_value(i, PropertyValue::Bool(val))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_u32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -455,11 +455,11 @@ impl Property {
             }
         }
         self.set_raw_value(i, PropertyValue::Uint32(val))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_f32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -478,22 +478,22 @@ impl Property {
             }
         }
         self.set_raw_value(i, PropertyValue::Float32(val))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_str<S: Into<String>>(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
         val: S,
     ) -> Result<()> {
         self.set_raw_value(i, PropertyValue::Str(val.into()))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_enum<S: Into<String>>(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -507,22 +507,22 @@ impl Property {
             return Err(Error::PropertyWrongEnumItem)
         }
         self.set_raw_value(i, PropertyValue::Enum(val.into()))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_node_id(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
         val: SceneNodeId,
     ) -> Result<()> {
         self.set_raw_value(i, PropertyValue::SceneNodeId(val))?;
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
     pub fn set_expr(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
@@ -538,12 +538,12 @@ impl Property {
             }
             vals[i] = PropertyValue::SExpr(Arc::new(val));
         }
-        atom.add(self, role, ModifyAction::Set(i));
+        atom.add(self.clone(), role, ModifyAction::Set(i));
         Ok(())
     }
 
     pub fn set_f32_vec(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: Vec<f32>,
@@ -567,30 +567,30 @@ impl Property {
         Ok(())
     }
     pub fn set_cache_f32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
         val: f32,
     ) -> Result<()> {
         self.set_cache(i, PropertyValue::Float32(val))?;
-        atom.add(self, role, ModifyAction::SetCache(vec![i]));
+        atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
         Ok(())
     }
     pub fn set_cache_u32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         i: usize,
         val: u32,
     ) -> Result<()> {
         self.set_cache(i, PropertyValue::Uint32(val))?;
-        atom.add(self, role, ModifyAction::SetCache(vec![i]));
+        atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
         Ok(())
     }
 
     pub fn set_cache_f32_multi(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         changes: Vec<(usize, f32)>,
@@ -600,11 +600,11 @@ impl Property {
             self.set_cache(idx, PropertyValue::Float32(val))?;
             idxs.push(idx);
         }
-        atom.add(self, role, ModifyAction::SetCache(idxs));
+        atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
         Ok(())
     }
     pub fn set_cache_u32_range(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         changes: Vec<(usize, u32)>,
@@ -614,14 +614,14 @@ impl Property {
             self.set_cache(idx, PropertyValue::Uint32(val))?;
             idxs.push(idx);
         }
-        atom.add(self, role, ModifyAction::SetCache(idxs));
+        atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
         Ok(())
     }
 
     // Push
 
     fn push_value(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         value: PropertyValue,
@@ -635,15 +635,19 @@ impl Property {
         vals.push(value);
         drop(vals);
 
-        atom.add(self, role, ModifyAction::Push(i));
+        atom.add(self.clone(), role, ModifyAction::Push(i));
         Ok(i)
     }
 
-    pub fn push_null(self: Arc<Self>, atom: &mut PropertyAtomicGuard, role: Role) -> Result<usize> {
+    pub fn push_null(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+    ) -> Result<usize> {
         self.push_value(atom, role, PropertyValue::Null)
     }
     pub fn push_bool(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: bool,
@@ -651,7 +655,7 @@ impl Property {
         self.push_value(atom, role, PropertyValue::Bool(val))
     }
     pub fn push_u32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: u32,
@@ -661,7 +665,7 @@ impl Property {
         self.push_value(atom, role, PropertyValue::Uint32(val))
     }
     pub fn push_f32(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: f32,
@@ -669,7 +673,7 @@ impl Property {
         self.push_value(atom, role, PropertyValue::Float32(val))
     }
     pub fn push_str<S: Into<String>>(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: S,
@@ -677,7 +681,7 @@ impl Property {
         self.push_value(atom, role, PropertyValue::Str(val.into()))
     }
     pub fn push_enum<S: Into<String>>(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: S,
@@ -685,7 +689,7 @@ impl Property {
         self.push_value(atom, role, PropertyValue::Enum(val.into()))
     }
     pub fn push_node_id(
-        self: Arc<Self>,
+        self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: SceneNodeId,

+ 3 - 3
bin/app/src/scene.rs

@@ -192,7 +192,7 @@ impl SceneNode {
         self.pimpl.get().unwrap()
     }
 
-    pub fn link(self: Arc<Self>, child: SceneNodePtr) {
+    pub fn link(self: &Arc<Self>, child: SceneNodePtr) {
         let mut childs_parent = child.parent.write().unwrap();
         assert!(childs_parent.is_none());
         *childs_parent = Some(Arc::downgrade(&self));
@@ -206,11 +206,11 @@ impl SceneNode {
         self.children.read().unwrap().clone()
     }
 
-    pub fn lookup_node<P: Into<ScenePath>>(self: Arc<Self>, path: P) -> Option<SceneNodePtr> {
+    pub fn lookup_node<P: Into<ScenePath>>(self: &Arc<Self>, path: P) -> Option<SceneNodePtr> {
         let path: ScenePath = path.into();
         let mut path = path.0;
         if path.is_empty() {
-            return Some(self)
+            return Some(self.clone())
         }
         let child_name = path.pop_front().unwrap();
         for child in self.get_children() {

+ 1 - 1
bin/app/src/ui/win.rs

@@ -74,7 +74,7 @@ impl Window {
         let locale = PropertyStr::wrap(node_ref, Role::Internal, "locale", 0).unwrap();
         let screen_size = PropertyDimension::wrap(node_ref, Role::Internal, "screen_size").unwrap();
         let scale = PropertyFloat32::wrap(
-            &setting_root.clone().lookup_node("/scale").unwrap(),
+            &setting_root.lookup_node("/scale").unwrap(),
             Role::Internal,
             "value",
             0,