From 9e8bc77cd4e5efe293dd477ed43a19d87c44a1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Moreno?= Date: Sat, 11 Nov 2017 12:11:19 +0100 Subject: [PATCH] notification in a thread to avoid interface lock --- src/app.rs | 62 ++++++++++++++++++++++++++++++++++---------------- src/backend.rs | 5 ++++ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/app.rs b/src/app.rs index 990cc732..c7b351e0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -19,6 +19,7 @@ use std::sync::mpsc::channel; use std::sync::mpsc::{Sender, Receiver}; use std::collections::HashMap; use std::process::Command; +use std::thread; use gio::ApplicationExt; use glib; @@ -879,33 +880,39 @@ impl AppOp { let mut body = msg.body.clone(); body.truncate(80); - let window: gtk::Window = self.gtk_builder - .get_object("main_window") - .expect("Couldn't find main_window in ui file."); - let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel(); self.backend.send(BKCommand::GetUserInfoAsync(msg.sender.clone(), tx)).unwrap(); + let bk = self.backend.clone(); + let m = msg.clone(); gtk::timeout_add(50, move || match rx.try_recv() { Err(_) => gtk::Continue(true), Ok((name, avatar)) => { let summary = format!("@{} / {}", name, roomname); - Notification::new() - .summary(&summary) - .body(&body) - .icon(&avatar) - .action("default", "default") - .show() - .unwrap() - .wait_for_action({|action| - match action { - "default" => { - window.show(); - window.present(); - }, - _ => () - } - }); + let bk = bk.clone(); + let m = m.clone(); + let body = body.clone(); + let summary = summary.clone(); + let avatar = avatar.clone(); + thread::spawn(move || { + let mut notification = Notification::new(); + notification.summary(&summary); + notification.body(&body); + notification.icon(&avatar); + notification.action("default", "default"); + + if let Ok(n) = notification.show() { + n.wait_for_action({|action| + match action { + "default" => { + bk.send(BKCommand::NotifyClicked(m)).unwrap(); + }, + _ => () + } + }); + } + }); + gtk::Continue(false) } }); @@ -1230,6 +1237,18 @@ impl AppOp { } } + pub fn notification_cliked(&mut self, msg: Message) { + self.activate(); + let mut room = None; + if let Some(r) = self.rooms.get(&msg.room) { + room = Some(r.clone()); + } + + if let Some(r) = room { + self.set_active_room(r.id, r.name); + } + } + pub fn activate(&self) { let window: gtk::Window = self.gtk_builder .get_object("main_window") @@ -1715,6 +1734,9 @@ fn backend_loop(op: Arc>, rx: Receiver) { Ok(BKResponse::SearchEnd) => { op.lock().unwrap().search_end(); } + Ok(BKResponse::NotificationClicked(msg)) => { + op.lock().unwrap().notification_cliked(msg); + } // errors Ok(BKResponse::LoginError(_)) => { diff --git a/src/backend.rs b/src/backend.rs index afc5e158..46e0d8e5 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -80,6 +80,7 @@ pub enum BKCommand { AttachFile(String, String), AttachImage(String, Vec), Search(String, Option), + NotifyClicked(Message), } #[derive(Debug)] @@ -112,6 +113,7 @@ pub enum BKResponse { Media(String), AttachedFile(Message), SearchEnd, + NotificationClicked(Message), //errors UserNameError(Error), @@ -296,6 +298,9 @@ impl Backend { let r = self.search(roomid, term); bkerror!(r, tx, BKResponse::SearchError); } + Ok(BKCommand::NotifyClicked(message)) => { + tx.send(BKResponse::NotificationClicked(message)).unwrap(); + } Ok(BKCommand::ShutDown) => { return false; }