diff --git a/Cargo.lock b/Cargo.lock index 2c259ad2..f82c4f8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1110,7 +1110,6 @@ dependencies = [ "gstreamer-pbutils", "gstreamer-play", "gstreamer-video", - "gtk-macros", "gtk4", "html-escape", "html2pango", @@ -1923,12 +1922,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "gtk-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5bf7748fd4cd0b2490df8debcc911809dbcbee4ece9531b96c29a9c729de5a" - [[package]] name = "gtk4" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index fcb4fefc..3acc8f5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ log = "0.4" mime = "0.3.16" tracing-subscriber = "0.3" gettext-rs = { version = "0.7", features = ["gettext-system"] } -gtk-macros = "0.3" once_cell = "1.5" serde = "1.0.130" serde_json = "1.0" diff --git a/src/application.rs b/src/application.rs index ee3b8fdf..dec91c6c 100644 --- a/src/application.rs +++ b/src/application.rs @@ -4,7 +4,6 @@ use gettextrs::gettext; use gio::{ApplicationFlags, Settings}; use glib::{clone, WeakRef}; use gtk::{gio, glib, prelude::*, subclass::prelude::*}; -use gtk_macros::action; use log::{debug, info}; use ruma::{OwnedRoomId, RoomId}; @@ -107,42 +106,42 @@ impl Application { } fn setup_gactions(&self) { - // Quit - action!( - self, - "quit", - clone!(@weak self as app => move |_, _| { - // This is needed to trigger the delete event - // and saving the window state - app.get_main_window().close(); - app.quit(); - }) - ); - - // About - action!( - self, - "about", - clone!(@weak self as app => move |_, _| { - app.show_about_dialog(); - }) - ); - - action!( - self, - "new-session", - clone!(@weak self as app => move |_, _| { - app.get_main_window().switch_to_greeter_page(); - }) - ); - - action!( - self, - "show-login", - clone!(@weak self as app => move |_, _| { - app.get_main_window().switch_to_login_page(); - }) - ); + self.add_action_entries([ + // Quit + gio::ActionEntry::builder("quit") + .activate(|app: &Application, _, _| { + // This is needed to trigger the delete event + // and saving the window state + app.get_main_window().close(); + app.quit(); + }) + .build(), + // About + gio::ActionEntry::builder("about") + .activate(|app: &Application, _, _| { + app.show_about_dialog(); + }) + .build(), + gio::ActionEntry::builder("new-session") + .activate(|app: &Application, _, _| { + app.get_main_window().switch_to_greeter_page(); + }) + .build(), + gio::ActionEntry::builder("show-login") + .activate(|app: &Application, _, _| { + app.get_main_window().switch_to_login_page(); + }) + .build(), + gio::ActionEntry::builder("show-room") + .parameter_type(Some(&AppShowRoomPayload::static_variant_type())) + .activate(|app: &Application, _, v| { + if let Some(payload) = v.and_then(|v| v.get::()) { + app.get_main_window() + .show_room(&payload.session_id, &payload.room_id); + } + }) + .build(), + ]); let show_sessions_action = gio::SimpleAction::new("show-sessions", None); show_sessions_action.connect_activate(clone!(@weak self as app => move |_, _| { @@ -157,17 +156,6 @@ impl Application { }), ); show_sessions_action.set_enabled(win.has_sessions()); - - action!( - self, - "show-room", - Some(&AppShowRoomPayload::static_variant_type()), - clone!(@weak self as app => move |_, v| { - if let Some(payload) = v.and_then(|v| v.get::()) { - app.get_main_window().show_room(&payload.session_id, &payload.room_id); - } - }) - ); } /// Sets up keyboard shortcuts for application and window actions. diff --git a/src/session/room/event/event_actions.rs b/src/session/room/event/event_actions.rs index 06d91fa3..9d20d6af 100644 --- a/src/session/room/event/event_actions.rs +++ b/src/session/room/event/event_actions.rs @@ -77,26 +77,30 @@ where }; let action_group = gio::SimpleActionGroup::new(); - // View Event Source - gtk_macros::action!( - &action_group, - "view-source", - clone!(@weak self as widget, @weak event => move |_, _| { - let window = widget.root().unwrap().downcast().unwrap(); - let dialog = EventSourceDialog::new(&window, &event); - dialog.show(); - }) - ); + if event.raw().is_some() { + action_group.add_action_entries([ + // View Event Source + gio::ActionEntry::builder("view-source") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { + let window = widget.root().unwrap().downcast().unwrap(); + let dialog = EventSourceDialog::new(&window, &event); + dialog.show(); + })) + .build(), + ]); + } - // Create a permalink - if event.event_id().is_some() { - gtk_macros::action!( - &action_group, - "permalink", - clone!(@weak self as widget, @weak event => move |_, _| { - let matrix_room = event.room().matrix_room(); - let event_id = event.event_id().unwrap(); - spawn!(clone!(@weak widget => async move { + if let Some(event) = event + .downcast_ref::() + .filter(|event| event.event_id().is_some()) + { + action_group.add_action_entries([ + // Create a permalink + gio::ActionEntry::builder("permalink") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { + let matrix_room = event.room().matrix_room(); + let event_id = event.event_id().unwrap(); + spawn!(clone!(@weak widget => async move { let handle = spawn_tokio!(async move { matrix_room.matrix_to_event_permalink(event_id).await }); @@ -112,14 +116,10 @@ where } }) ); - }) - ); - } + })) + .build() + ]); - if let Some(event) = event - .downcast_ref::() - .filter(|event| event.event_id().is_some()) - { if let TimelineItemContent::Message(message) = event.content() { let user_id = event .room() @@ -137,147 +137,143 @@ where .min_level_for_room_action(&RoomAction::Redact) <= user.power_level() { - gtk_macros::action!( - &action_group, - "remove", - clone!(@weak event, => move |_, _| { + action_group.add_action_entries([gio::ActionEntry::builder("remove") + .activate(clone!(@weak event, => move |_, _, _| { if let Some(event_id) = event.event_id() { event.room().redact(event_id, None); } - }) - ); + })) + .build()]); } - // Send/redact a reaction - gtk_macros::action!( - &action_group, - "toggle-reaction", - Some(&String::static_variant_type()), - clone!(@weak event => move |_, variant| { - let key: String = variant.unwrap().get().unwrap(); - let room = event.room(); + action_group.add_action_entries([ + // Send/redact a reaction + gio::ActionEntry::builder("toggle-reaction") + .parameter_type(Some(&String::static_variant_type())) + .activate(clone!(@weak event => move |_, _, variant| { + let key: String = variant.unwrap().get().unwrap(); + let room = event.room(); - let reaction_group = event.reactions().reaction_group_by_key(&key); + let reaction_group = event.reactions().reaction_group_by_key(&key); - if let Some(reaction_key) = reaction_group.and_then(|group| group.user_reaction_event_key()) { - // The user already sent that reaction, redact it if it has been sent. - if let EventKey::EventId(reaction_id) = reaction_key { - room.redact(reaction_id, None); + if let Some(reaction_key) = reaction_group.and_then(|group| group.user_reaction_event_key()) { + // The user already sent that reaction, redact it if it has been sent. + if let EventKey::EventId(reaction_id) = reaction_key { + room.redact(reaction_id, None); + } + } else if let Some(event_id) = event.event_id() { + // The user didn't send that reaction, send it. + room.send_reaction(key, event_id); } - } else if let Some(event_id) = event.event_id() { - // The user didn't send that reaction, send it. - room.send_reaction(key, event_id); - } - }) - ); - - // Reply - gtk_macros::action!( - &action_group, - "reply", - None, - clone!(@weak event, @weak self as widget => move |_, _| { - if let Some(event_id) = event.event_id() { - let _ = widget.activate_action( - "room-history.reply", - Some(&event_id.as_str().to_variant()) - ); - } - }) - ); + })) + .build(), + // Reply + gio::ActionEntry::builder("reply") + .activate(clone!(@weak event, @weak self as widget => move |_, _, _| { + if let Some(event_id) = event.event_id() { + let _ = widget.activate_action( + "room-history.reply", + Some(&event_id.as_str().to_variant()) + ); + } + })) + .build() + ]); match message.msgtype() { - // Copy Text-Message MessageType::Text(text_message) => { + // Copy text message. let body = text_message.body.clone(); - gtk_macros::action!( - &action_group, - "copy-text", - clone!(@weak self as widget => move |_, _| { + action_group.add_action_entries([gio::ActionEntry::builder("copy-text") + .activate(clone!(@weak self as widget => move |_, _, _| { widget.clipboard().set_text(&body); toast!(widget, gettext("Message copied to clipboard")); - }) - ); + })) + .build()]); } MessageType::File(_) => { - // Save message's file - gtk_macros::action!( - &action_group, - "file-save", - clone!(@weak self as widget, @weak event => move |_, _| { - widget.save_event_file(event); - }) - ); + // Save message's file. + action_group.add_action_entries([gio::ActionEntry::builder("file-save") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { + widget.save_event_file(event); + })) + .build()]); } MessageType::Emote(message) => { + // Copy text message. let message = message.clone(); - gtk_macros::action!( - &action_group, - "copy-text", - clone!(@weak self as widget, @weak event => move |_, _| { + action_group.add_action_entries([gio::ActionEntry::builder("copy-text") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { let display_name = event.sender().display_name(); - let message = display_name + " " + &message.body; + let message = format!("{display_name} {}", message.body); widget.clipboard().set_text(&message); toast!(widget, gettext("Message copied to clipboard")); - }) - ); + })) + .build()]); } + MessageType::Notice(message) => { + // Copy text message. + let body = message.body.clone(); + action_group.add_action_entries([gio::ActionEntry::builder("copy-text") + .activate(clone!(@weak self as widget => move |_, _, _| { + widget.clipboard().set_text(&body); + toast!(widget, gettext("Message copied to clipboard")); + })) + .build()]); + } MessageType::Image(_) => { - // Copy the texture to the clipboard. - gtk_macros::action!( - &action_group, - "copy-image", - clone!(@weak self as widget, @weak event => move |_, _| { - let texture = widget.texture().expect("A widget with an image should have a texture"); + action_group.add_action_entries([ + // Copy the texture to the clipboard. + gio::ActionEntry::builder("copy-image") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { + let texture = widget.texture().expect("A widget with an image should have a texture"); - match texture { - EventTexture::Original(texture) => { - widget.clipboard().set_texture(&texture); - toast!(widget, gettext("Image copied to clipboard")); + match texture { + EventTexture::Original(texture) => { + widget.clipboard().set_texture(&texture); + toast!(widget, gettext("Image copied to clipboard")); + } + EventTexture::Thumbnail(texture) => { + widget.clipboard().set_texture(&texture); + toast!(widget, gettext("Thumbnail copied to clipboard")); + } } - EventTexture::Thumbnail(texture) => { - widget.clipboard().set_texture(&texture); - toast!(widget, gettext("Thumbnail copied to clipboard")); - } - } - }) - ); - - // Save the image to a file. - gtk_macros::action!( - &action_group, - "save-image", - clone!(@weak self as widget, @weak event => move |_, _| { - widget.save_event_file(event); - }) - ); + }) + ).build(), + // Save the image to a file. + gio::ActionEntry::builder("save-image") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { + widget.save_event_file(event); + }) + ).build() + ]); } MessageType::Video(_) => { - gtk_macros::action!( - &action_group, - "save-video", - clone!(@weak self as widget, @weak event => move |_, _| { + // Save the video to a file. + action_group.add_action_entries([gio::ActionEntry::builder("save-video") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { widget.save_event_file(event); - }) - ); + })) + .build()]); } MessageType::Audio(_) => { - gtk_macros::action!( - &action_group, - "save-audio", - clone!(@weak self as widget, @weak event => move |_, _| { + // Save the audio to a file. + action_group.add_action_entries([gio::ActionEntry::builder("save-audio") + .activate(clone!(@weak self as widget, @weak event => move |_, _, _| { widget.save_event_file(event); - }) - ); + })) + .build()]); } _ => {} } } } + self.insert_action_group("event", Some(&action_group)); + Some(action_group) }