[fractal/ui-refactor: 3/15] Remove op field in App




commit 4fd8d815df28cc66229638710ffcc927a743f716
Author: Alejandro Domínguez <adomu net-c com>
Date:   Mon Oct 12 06:04:21 2020 +0200

    Remove op field in App

 fractal-gtk/src/app/connect/account.rs         | 65 +++++++++--------
 fractal-gtk/src/app/connect/autocomplete.rs    |  4 +-
 fractal-gtk/src/app/connect/direct.rs          | 70 +++++++++---------
 fractal-gtk/src/app/connect/directory.rs       |  8 +--
 fractal-gtk/src/app/connect/invite.rs          | 99 ++++++++++++--------------
 fractal-gtk/src/app/connect/join_room.rs       |  8 +--
 fractal-gtk/src/app/connect/language.rs        |  5 +-
 fractal-gtk/src/app/connect/leave_room.rs      |  5 +-
 fractal-gtk/src/app/connect/markdown.rs        |  7 +-
 fractal-gtk/src/app/connect/new_room.rs        |  8 +--
 fractal-gtk/src/app/connect/roomlist_search.rs | 15 ++--
 fractal-gtk/src/app/connect/send.rs            |  8 +--
 fractal-gtk/src/app/mod.rs                     | 38 ++++++----
 13 files changed, 166 insertions(+), 174 deletions(-)
---
diff --git a/fractal-gtk/src/app/connect/account.rs b/fractal-gtk/src/app/connect/account.rs
index 83f81777..f5d3d51d 100644
--- a/fractal-gtk/src/app/connect/account.rs
+++ b/fractal-gtk/src/app/connect/account.rs
@@ -2,13 +2,12 @@ use gio::ActionMapExt;
 use glib::clone;
 use gtk::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 use crate::actions::{AccountSettings, StateExt};
 
 impl App {
     pub fn connect_account_settings(&self) {
-        let op = &self.op;
         let builder = &self.ui.builder;
         let cancel_password = self
             .ui
@@ -72,7 +71,7 @@ impl App {
             .expect("Can't find account_settings_delete_btn in ui file.");
 
         let window = self.main_window.upcast_ref::<gtk::Window>();
-        let actions = AccountSettings::new(&window, op.clone());
+        let actions = AccountSettings::new(&window, app::get_op().clone());
         let container = self
             .ui
             .builder
@@ -103,29 +102,34 @@ impl App {
         }
 
         let button = name_btn.clone();
-        name_entry.connect_property_text_notify(clone!(@strong op => move |w| {
+        name_entry.connect_property_text_notify(move |w| {
             let username = w.get_text();
-            if !username.is_empty() && op.try_lock()
-                .ok()
-                .and_then(|guard| guard.login_data.clone())
-                .and_then(|login_data| login_data.username)
-                .filter(|u| *u != username)
-                .is_some()
+            if !username.is_empty()
+                && app::get_op()
+                    .try_lock()
+                    .ok()
+                    .and_then(|guard| guard.login_data.clone())
+                    .and_then(|login_data| login_data.username)
+                    .filter(|u| *u != username)
+                    .is_some()
             {
                 button.show();
                 return;
             }
             button.hide();
-        }));
+        });
 
         let button = name_btn.clone();
         name_entry.connect_activate(move |_w| {
             let _ = button.emit("clicked", &[]);
         });
 
-        name_btn.connect_clicked(clone!(@strong op => move |_w| {
-            op.lock().unwrap().update_username_account_settings();
-        }));
+        name_btn.connect_clicked(move |_w| {
+            app::get_op()
+                .lock()
+                .unwrap()
+                .update_username_account_settings();
+        });
 
         /*
         fn update_password_strength(builder: &gtk::Builder) {
@@ -181,24 +185,25 @@ impl App {
         }
 
         /* Passsword dialog */
-        password_btn.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().show_password_dialog();
-        }));
+        password_btn.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().show_password_dialog();
+        });
 
-        password_dialog.connect_delete_event(clone!(@strong op => move |_, _| {
-            op.lock().unwrap().close_password_dialog();
+        password_dialog.connect_delete_event(move |_, _| {
+            app::get_op().lock().unwrap().close_password_dialog();
             glib::signal::Inhibit(true)
-        }));
+        });
 
         /* Headerbar */
-        cancel_password.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().close_password_dialog();
-        }));
+        cancel_password.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().close_password_dialog();
+        });
 
-        confirm_password.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().set_new_password();
-            op.lock().unwrap().close_password_dialog();
-        }));
+        confirm_password.connect_clicked(move |_| {
+            let mut op = app::get_op().lock().unwrap();
+            op.set_new_password();
+            op.close_password_dialog();
+        });
 
         /* Body */
         verify_password.connect_property_text_notify(clone!(@strong builder => move |_| {
@@ -221,8 +226,8 @@ impl App {
             }),
         );
 
-        destruction_btn.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().account_destruction();
-        }));
+        destruction_btn.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().account_destruction();
+        });
     }
 }
diff --git a/fractal-gtk/src/app/connect/autocomplete.rs b/fractal-gtk/src/app/connect/autocomplete.rs
index d7c0b9e1..29c27743 100644
--- a/fractal-gtk/src/app/connect/autocomplete.rs
+++ b/fractal-gtk/src/app/connect/autocomplete.rs
@@ -2,7 +2,7 @@ use gtk::prelude::*;
 
 use crate::widgets;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_autocomplete(&self) {
@@ -21,8 +21,8 @@ impl App {
             .builder
             .get_object("main_window")
             .expect("Can't find main_window in ui file.");
+        let op = app::get_op().clone();
 
-        let op = self.op.clone();
         widgets::Autocomplete::new(op, window, self.ui.sventry.view.clone(), popover, listbox)
             .connect();
     }
diff --git a/fractal-gtk/src/app/connect/direct.rs b/fractal-gtk/src/app/connect/direct.rs
index 14e71019..5d3b34a5 100644
--- a/fractal-gtk/src/app/connect/direct.rs
+++ b/fractal-gtk/src/app/connect/direct.rs
@@ -4,12 +4,10 @@ use gtk::prelude::*;
 use glib::source::Continue;
 use std::sync::{Arc, Mutex};
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_direct_chat(&self) {
-        let op = &self.op;
-
         let cancel = self
             .ui
             .builder
@@ -54,7 +52,7 @@ impl App {
         // this is used to cancel the timeout and not search for every key input. We'll wait 500ms
         // without key release event to launch the search
         let source_id: Arc<Mutex<Option<glib::source::SourceId>>> = Arc::new(Mutex::new(None));
-        to_chat_entry.connect_key_release_event(clone!(@strong op => move |entry, _| {
+        to_chat_entry.connect_key_release_event(move |entry, _| {
             {
                 let mut id = source_id.lock().unwrap();
                 if let Some(sid) = id.take() {
@@ -62,8 +60,9 @@ impl App {
                 }
             }
 
-            let sid = glib::timeout_add_local(500, clone!(
-                @strong op,
+            let sid = glib::timeout_add_local(
+                500,
+                clone!(
                 @strong entry,
                 @strong source_id
                 => move || {
@@ -74,57 +73,54 @@ impl App {
                         if let Some(text) =
                             buffer.get_text(&start, &end, false).map(|gstr| gstr.to_string())
                         {
-                            op.lock().unwrap().search_invite_user(text);
+                            app::get_op().lock().unwrap().search_invite_user(text);
                         }
                     }
 
                     *(source_id.lock().unwrap()) = None;
                     Continue(false)
-                }));
+                }),
+            );
 
             *(source_id.lock().unwrap()) = Some(sid);
             glib::signal::Inhibit(false)
-        }));
+        });
 
-        to_chat_entry.connect_focus_in_event(
-            clone!(@strong op, @strong to_chat_entry_box => move |_, _| {
-                to_chat_entry_box.get_style_context().add_class("message-input-focused");
+        to_chat_entry.connect_focus_in_event(clone!(@strong to_chat_entry_box => move |_, _| {
+            to_chat_entry_box.get_style_context().add_class("message-input-focused");
 
-                op.lock().unwrap().remove_invite_user_dialog_placeholder();
+            app::get_op().lock().unwrap().remove_invite_user_dialog_placeholder();
 
-                Inhibit(false)
-            }),
-        );
+            Inhibit(false)
+        }));
 
-        to_chat_entry.connect_focus_out_event(
-            clone!(@strong op, @strong to_chat_entry_box => move |_, _| {
-                to_chat_entry_box.get_style_context().remove_class("message-input-focused");
+        to_chat_entry.connect_focus_out_event(clone!(@strong to_chat_entry_box => move |_, _| {
+            to_chat_entry_box.get_style_context().remove_class("message-input-focused");
 
-                op.lock().unwrap().set_invite_user_dialog_placeholder();
+            app::get_op().lock().unwrap().set_invite_user_dialog_placeholder();
 
-                Inhibit(false)
-            }),
-        );
+            Inhibit(false)
+        }));
 
         if let Some(buffer) = to_chat_entry.get_buffer() {
-            buffer.connect_delete_range(clone!(@strong op => move |_, _, _| {
-                glib::idle_add_local(clone!(@strong op => move || {
-                    op.lock().unwrap().detect_removed_invite();
+            buffer.connect_delete_range(move |_, _, _| {
+                glib::idle_add_local(move || {
+                    app::get_op().lock().unwrap().detect_removed_invite();
                     Continue(false)
-                }));
-            }));
+                });
+            });
         }
 
-        dialog.connect_delete_event(clone!(@strong op => move |_, _| {
-            op.lock().unwrap().close_direct_chat_dialog();
+        dialog.connect_delete_event(move |_, _| {
+            app::get_op().lock().unwrap().close_direct_chat_dialog();
             glib::signal::Inhibit(true)
-        }));
-        cancel.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().close_direct_chat_dialog();
-        }));
+        });
+        cancel.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().close_direct_chat_dialog();
+        });
         invite.set_sensitive(false);
-        invite.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().start_chat();
-        }));
+        invite.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().start_chat();
+        });
     }
 }
diff --git a/fractal-gtk/src/app/connect/directory.rs b/fractal-gtk/src/app/connect/directory.rs
index a648b652..48bf7798 100644
--- a/fractal-gtk/src/app/connect/directory.rs
+++ b/fractal-gtk/src/app/connect/directory.rs
@@ -5,7 +5,7 @@ use crate::util::i18n::i18n;
 use gtk::prelude::*;
 use libhandy::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 use crate::appop::RoomSearchPagination;
 
 impl App {
@@ -103,16 +103,14 @@ impl App {
             .get_object::<gtk::ScrolledWindow>("directory_scroll")
             .expect("Can't find directory_scroll in ui file.");
 
-        let mut op = self.op.clone();
         scroll.connect_edge_reached(move |_, dir| {
             if dir == gtk::PositionType::Bottom {
-                op.lock().unwrap().load_more_rooms();
+                app::get_op().lock().unwrap().load_more_rooms();
             }
         });
 
-        op = self.op.clone();
         q.connect_activate(move |_| {
-            let mut op = op.lock().unwrap();
+            let mut op = app::get_op().lock().unwrap();
             op.directory_pagination = RoomSearchPagination::Initial;
             op.search_rooms();
         });
diff --git a/fractal-gtk/src/app/connect/invite.rs b/fractal-gtk/src/app/connect/invite.rs
index 8c5f4166..0db031ce 100644
--- a/fractal-gtk/src/app/connect/invite.rs
+++ b/fractal-gtk/src/app/connect/invite.rs
@@ -4,11 +4,10 @@ use gtk::prelude::*;
 use glib::source::Continue;
 use std::sync::{Arc, Mutex};
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_invite_dialog(&self) {
-        let op = self.op.clone();
         let dialog = self
             .ui
             .builder
@@ -25,25 +24,23 @@ impl App {
             .get_object::<gtk::Button>("invite_reject")
             .expect("Can't find invite_reject in ui file.");
 
-        reject.connect_clicked(clone!(@strong dialog, @strong op => move |_| {
-            op.lock().unwrap().accept_inv(false);
+        reject.connect_clicked(clone!(@strong dialog => move |_| {
+            app::get_op().lock().unwrap().accept_inv(false);
             dialog.hide();
         }));
-        dialog.connect_delete_event(clone!(@strong dialog, @strong op => move |_, _| {
-            op.lock().unwrap().accept_inv(false);
+        dialog.connect_delete_event(clone!(@strong dialog => move |_, _| {
+            app::get_op().lock().unwrap().accept_inv(false);
             dialog.hide();
             glib::signal::Inhibit(true)
         }));
 
-        accept.connect_clicked(clone!(@strong dialog, @strong op => move |_| {
-            op.lock().unwrap().accept_inv(true);
+        accept.connect_clicked(clone!(@strong dialog => move |_| {
+            app::get_op().lock().unwrap().accept_inv(true);
             dialog.hide();
         }));
     }
 
     pub fn connect_invite_user(&self) {
-        let op = &self.op;
-
         let cancel = self
             .ui
             .builder
@@ -88,7 +85,7 @@ impl App {
         // this is used to cancel the timeout and not search for every key input. We'll wait 500ms
         // without key release event to launch the search
         let source_id: Arc<Mutex<Option<glib::source::SourceId>>> = Arc::new(Mutex::new(None));
-        invite_entry.connect_key_release_event(clone!(@strong op => move |entry, _| {
+        invite_entry.connect_key_release_event(move |entry, _| {
             {
                 let mut id = source_id.lock().unwrap();
                 if let Some(sid) = id.take() {
@@ -96,67 +93,59 @@ impl App {
                 }
             }
 
-            let sid = glib::timeout_add_local(500, clone!(
-                @strong op,
-                @strong entry,
-                @strong source_id
-                => move || {
-                    if let Some(buffer) = entry.get_buffer() {
-                        let start = buffer.get_start_iter();
-                        let end = buffer.get_end_iter();
-
-                        if let Some(text) = buffer.get_text(&start, &end, false).map(|gstr| 
gstr.to_string()) {
-                            op.lock().unwrap().search_invite_user(text);
-                        }
+            let sid = glib::timeout_add_local(500, clone!(@strong entry, @strong source_id => move || {
+                if let Some(buffer) = entry.get_buffer() {
+                    let start = buffer.get_start_iter();
+                    let end = buffer.get_end_iter();
+
+                    if let Some(text) = buffer.get_text(&start, &end, false).map(|gstr| gstr.to_string()) {
+                        app::get_op().lock().unwrap().search_invite_user(text);
                     }
+                }
 
-                    *(source_id.lock().unwrap()) = None;
-                    Continue(false)
-                }));
+                *(source_id.lock().unwrap()) = None;
+                Continue(false)
+            }));
 
             *(source_id.lock().unwrap()) = Some(sid);
             glib::signal::Inhibit(false)
-        }));
+        });
 
-        invite_entry.connect_focus_in_event(
-            clone!(@strong op, @strong invite_entry_box => move |_, _| {
-                invite_entry_box.get_style_context().add_class("message-input-focused");
+        invite_entry.connect_focus_in_event(clone!(@strong invite_entry_box => move |_, _| {
+            invite_entry_box.get_style_context().add_class("message-input-focused");
 
-                op.lock().unwrap().remove_invite_user_dialog_placeholder();
+            app::get_op().lock().unwrap().remove_invite_user_dialog_placeholder();
 
-                Inhibit(false)
-            }),
-        );
+            Inhibit(false)
+        }));
 
-        invite_entry.connect_focus_out_event(
-            clone!(@strong op, @strong invite_entry_box => move |_, _| {
-                invite_entry_box.get_style_context().remove_class("message-input-focused");
+        invite_entry.connect_focus_out_event(clone!(@strong invite_entry_box => move |_, _| {
+            invite_entry_box.get_style_context().remove_class("message-input-focused");
 
-                op.lock().unwrap().set_invite_user_dialog_placeholder();
+            app::get_op().lock().unwrap().set_invite_user_dialog_placeholder();
 
-                Inhibit(false)
-            }),
-        );
+            Inhibit(false)
+        }));
 
         if let Some(buffer) = invite_entry.get_buffer() {
-            buffer.connect_delete_range(clone!(@strong op => move |_, _, _| {
-                glib::idle_add_local(clone!(@strong op => move || {
-                    op.lock().unwrap().detect_removed_invite();
+            buffer.connect_delete_range(move |_, _, _| {
+                glib::idle_add_local(move || {
+                    app::get_op().lock().unwrap().detect_removed_invite();
                     Continue(false)
-                }));
-            }));
+                });
+            });
         }
 
-        dialog.connect_delete_event(clone!(@strong op => move |_, _| {
-            op.lock().unwrap().close_invite_dialog();
+        dialog.connect_delete_event(move |_, _| {
+            app::get_op().lock().unwrap().close_invite_dialog();
             glib::signal::Inhibit(true)
-        }));
-        cancel.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().close_invite_dialog();
-        }));
+        });
+        cancel.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().close_invite_dialog();
+        });
         invite.set_sensitive(false);
-        invite.connect_clicked(clone!(@strong op => move |_| {
-            op.lock().unwrap().invite();
-        }));
+        invite.connect_clicked(move |_| {
+            app::get_op().lock().unwrap().invite();
+        });
     }
 }
diff --git a/fractal-gtk/src/app/connect/join_room.rs b/fractal-gtk/src/app/connect/join_room.rs
index 2a96c419..3d97e04f 100644
--- a/fractal-gtk/src/app/connect/join_room.rs
+++ b/fractal-gtk/src/app/connect/join_room.rs
@@ -1,7 +1,7 @@
 use glib::clone;
 use gtk::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_join_room_dialog(&self) {
@@ -36,17 +36,15 @@ impl App {
             glib::signal::Inhibit(true)
         }));
 
-        let op = self.op.clone();
         confirm.connect_clicked(clone!(@strong entry, @strong dialog => move |_| {
             dialog.hide();
-            op.lock().unwrap().join_to_room();
+            app::get_op().lock().unwrap().join_to_room();
             entry.set_text("");
         }));
 
-        let op = self.op.clone();
         entry.connect_activate(clone!(@strong dialog => move |entry| {
             dialog.hide();
-            op.lock().unwrap().join_to_room();
+            app::get_op().lock().unwrap().join_to_room();
             entry.set_text("");
         }));
         entry.connect_changed(clone!(@strong confirm => move |entry| {
diff --git a/fractal-gtk/src/app/connect/language.rs b/fractal-gtk/src/app/connect/language.rs
index 0a54e88f..a539cfd9 100644
--- a/fractal-gtk/src/app/connect/language.rs
+++ b/fractal-gtk/src/app/connect/language.rs
@@ -1,4 +1,4 @@
-use crate::app::{App, RUNTIME};
+use crate::app::{self, App, RUNTIME};
 use crate::backend::{room, HandleError};
 use glib::object::Cast;
 use gtk::prelude::*;
@@ -14,7 +14,6 @@ impl App {
             .and_then(|gtk_buffer| TextBuffer::get_from_gtk_text_buffer(&gtk_buffer))
             .and_then(|gs_buffer| gs_buffer.get_spell_checker())
         {
-            let op = self.op.clone();
             let _signal_handler = checker.connect_property_language_notify(move |checker| {
                 if let Some(lang_code) = checker
                     .get_language()
@@ -24,7 +23,7 @@ impl App {
                     /*If the checker is modified by fn set_language in fractal-gtk/src/appop/room.rs
                     due to the user switching rooms, the op mutex is locked already.
                     If the checker is modified by gtk due to the user switching the language, the op mutex 
is unlocked. */
-                    if let Ok(op) = op.try_lock() {
+                    if let Ok(op) = app::get_op().try_lock() {
                         if let (Some(active_room), Some(login_data)) = (op.active_room.clone(), 
op.login_data.as_ref()) {
                             let session_client = login_data.session_client.clone();
                             let uid = login_data.uid.clone();
diff --git a/fractal-gtk/src/app/connect/leave_room.rs b/fractal-gtk/src/app/connect/leave_room.rs
index d11ca737..9bead08e 100644
--- a/fractal-gtk/src/app/connect/leave_room.rs
+++ b/fractal-gtk/src/app/connect/leave_room.rs
@@ -1,7 +1,7 @@
 use glib::clone;
 use gtk::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_leave_room_dialog(&self) {
@@ -29,10 +29,9 @@ impl App {
             glib::signal::Inhibit(true)
         }));
 
-        let op = self.op.clone();
         confirm.connect_clicked(clone!(@strong dialog => move |_| {
             dialog.hide();
-            op.lock().unwrap().really_leave_active_room();
+            app::get_op().lock().unwrap().really_leave_active_room();
         }));
     }
 }
diff --git a/fractal-gtk/src/app/connect/markdown.rs b/fractal-gtk/src/app/connect/markdown.rs
index c18f6555..cc74571b 100644
--- a/fractal-gtk/src/app/connect/markdown.rs
+++ b/fractal-gtk/src/app/connect/markdown.rs
@@ -4,7 +4,7 @@ use sourceview4::prelude::*;
 
 use crate::util;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_markdown(&self) {
@@ -36,9 +36,8 @@ impl App {
         md_popover_btn.set_popover(Some(&popover));
 
         let md_active = util::get_markdown_schema();
-        let op = self.op.clone();
         if md_active {
-            op.lock().unwrap().md_enabled = true;
+            app::get_op().lock().unwrap().md_enabled = true;
             markdown_switch.set_active(true);
             md_img.set_from_icon_name(Some("format-indent-more-symbolic"), gtk::IconSize::Menu);
             txt.get_style_context().remove_class("dim-label");
@@ -52,7 +51,7 @@ impl App {
 
         markdown_switch.connect_property_active_notify(
             clone!(@strong markdown_switch => move |_| {
-                op.lock().unwrap().md_enabled = markdown_switch.get_active();
+                app::get_op().lock().unwrap().md_enabled = markdown_switch.get_active();
 
                 if markdown_switch.get_active() {
                     md_img.set_from_icon_name(
diff --git a/fractal-gtk/src/app/connect/new_room.rs b/fractal-gtk/src/app/connect/new_room.rs
index 862b39d6..e20e004a 100644
--- a/fractal-gtk/src/app/connect/new_room.rs
+++ b/fractal-gtk/src/app/connect/new_room.rs
@@ -1,7 +1,7 @@
 use glib::clone;
 use gtk::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_new_room_dialog(&self) {
@@ -48,20 +48,18 @@ impl App {
             }),
         );
 
-        let op = self.op.clone();
         confirm.connect_clicked(
             clone!(@strong entry, @strong dialog, @strong private => move |_| {
                 dialog.hide();
-                op.lock().unwrap().create_new_room();
+                app::get_op().lock().unwrap().create_new_room();
                 entry.set_text("");
                 private.set_active(true);
             }),
         );
 
-        let op = self.op.clone();
         entry.connect_activate(clone!(@strong dialog => move |entry| {
             dialog.hide();
-            op.lock().unwrap().create_new_room();
+            app::get_op().lock().unwrap().create_new_room();
             entry.set_text("");
             private.set_active(true);
         }));
diff --git a/fractal-gtk/src/app/connect/roomlist_search.rs b/fractal-gtk/src/app/connect/roomlist_search.rs
index 6f1b6e00..608d08b0 100644
--- a/fractal-gtk/src/app/connect/roomlist_search.rs
+++ b/fractal-gtk/src/app/connect/roomlist_search.rs
@@ -1,12 +1,10 @@
 use glib::clone;
 use gtk::prelude::*;
 
-use crate::app::App;
+use crate::app::{self, App};
 
 impl App {
     pub fn connect_roomlist_search(&self) {
-        let op = &self.op;
-
         let search_btn = self
             .ui
             .builder
@@ -33,11 +31,12 @@ impl App {
             }),
         );
 
-        search_entry.connect_search_changed(clone!(@strong op => move |entry| {
-            op.lock().unwrap().filter_rooms(
-                Some(entry.get_text().to_string())
-            );
-        }));
+        search_entry.connect_search_changed(move |entry| {
+            app::get_op()
+                .lock()
+                .unwrap()
+                .filter_rooms(Some(entry.get_text().to_string()));
+        });
 
         // hidding left and right boxes to align with top buttons
         let boxes = search_bar.get_children()[0]
diff --git a/fractal-gtk/src/app/connect/send.rs b/fractal-gtk/src/app/connect/send.rs
index 6fd2fd12..1926d1a8 100644
--- a/fractal-gtk/src/app/connect/send.rs
+++ b/fractal-gtk/src/app/connect/send.rs
@@ -4,7 +4,7 @@ use gtk::prelude::*;
 use sourceview4::BufferExt;
 
 use crate::actions::activate_action;
-use crate::app::App;
+use crate::app::{self, App};
 
 const MAX_INPUT_HEIGHT: i32 = 100;
 
@@ -43,17 +43,15 @@ impl App {
             _ => Inhibit(false),
         });
 
-        let mut op = self.op.clone();
         msg_entry.connect_key_release_event(move |_, ev| {
             if ev.get_keyval().to_unicode().is_some() {
-                op.lock().unwrap().send_typing();
+                app::get_op().lock().unwrap().send_typing();
             }
             Inhibit(false)
         });
 
-        op = self.op.clone();
         msg_entry.connect_paste_clipboard(move |_| {
-            attach::paste(op.clone());
+            attach::paste(app::get_op().clone());
         });
 
         msg_entry.connect_focus_in_event(clone!(@strong msg_entry_box => move |_, _| {
diff --git a/fractal-gtk/src/app/mod.rs b/fractal-gtk/src/app/mod.rs
index f5e4b3ed..f1e7a1e2 100644
--- a/fractal-gtk/src/app/mod.rs
+++ b/fractal-gtk/src/app/mod.rs
@@ -24,7 +24,9 @@ mod windowstate;
 use windowstate::WindowState;
 
 type GlobalAppOp = Arc<Mutex<AppOp>>;
+type UpdateApp = Box<dyn FnOnce(&mut AppOp)>;
 
+static mut APP_TX: Option<glib::Sender<UpdateApp>> = None;
 static mut OP: Option<GlobalAppOp> = None;
 
 lazy_static! {
@@ -34,11 +36,10 @@ lazy_static! {
 #[macro_export]
 macro_rules! APPOP {
     ($fn: ident, ($($x:ident),*) ) => {{
-        let ctx = glib::MainContext::default();
-        ctx.invoke(move || {
-            $( let $x = $x.clone(); )*
-            crate::app::get_op().lock().unwrap().$fn($($x),*);
-        });
+        $( let $x = $x.clone(); )*
+        let _ = crate::app::get_app_tx().send(Box::new(move |op| {
+            crate::appop::AppOp::$fn(op, $($x),*);
+        }));
     }};
     ($fn: ident) => {{
         APPOP!($fn, ( ) );
@@ -51,9 +52,6 @@ pub struct App {
     main_window: libhandy::ApplicationWindow,
     /* Add widget directly here in place of uibuilder::UI*/
     ui: uibuilder::UI,
-
-    // TODO: Remove op needed in connect, but since it is global we could remove it form here
-    op: GlobalAppOp,
 }
 
 pub type AppRef = Rc<App>;
@@ -77,12 +75,21 @@ impl App {
             gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
         );
 
+        let (app_tx, app_rx) = glib::MainContext::channel(Default::default());
         let ui = uibuilder::UI::new();
 
         unsafe {
             OP = Some(Arc::new(Mutex::new(AppOp::new(ui.clone()))));
+            APP_TX = Some(app_tx);
         }
 
+        let op = get_op();
+        app_rx.attach(None, move |update_op: UpdateApp| {
+            update_op(&mut op.lock().unwrap());
+
+            glib::Continue(true)
+        });
+
         let window: libhandy::ApplicationWindow = ui
             .builder
             .get_object("main_window")
@@ -164,7 +171,6 @@ impl App {
         let app = AppRef::new(Self {
             main_window: window,
             ui,
-            op: get_op().clone(),
         });
 
         app.connect_gtk();
@@ -185,7 +191,7 @@ impl App {
 
         app.main_window
             .connect_property_has_toplevel_focus_notify(clone!(@weak app => move |_| {
-                app.op.lock().unwrap().mark_active_room_messages();
+                get_op().lock().unwrap().mark_active_room_messages();
             }));
 
         app.main_window.connect_delete_event(move |window, _| {
@@ -198,7 +204,7 @@ impl App {
             Inhibit(false)
         });
 
-        app.op.lock().unwrap().init();
+        get_op().lock().unwrap().init();
 
         // When the application is shut down we drop our app struct
         let app_container = RefCell::new(Some(app));
@@ -217,10 +223,18 @@ impl App {
     }
 
     fn on_shutdown(self: AppRef) {
-        self.op.lock().unwrap().quit();
+        get_op().lock().unwrap().quit();
     }
 }
 
 pub fn get_op() -> &'static GlobalAppOp {
     unsafe { OP.as_ref().expect("Fatal: AppOp has not been initialized") }
 }
+
+pub fn get_app_tx() -> &'static glib::Sender<UpdateApp> {
+    unsafe {
+        APP_TX
+            .as_ref()
+            .expect("Fatal: AppRuntime has not been initialized")
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]