[fractal] Refactor message menu



commit 372e2714a698e1e38d0c046a0536f320e37e332b
Author: Christopher Davis <brainblasted disroot org>
Date:   Sat Nov 7 12:59:23 2020 -0800

    Refactor message menu
    
    Previously our message menu had a strange API where we used
    the pointer of the screen instead of the coordinates of
    the relevant event, and automatically showed on "new".
    
    This commit refactors the message menu to use the coords
    of the event and only show using an explicit "show_at_coords()" function if not triggered
    by a GtkMenuButton.
    
    Fixes https://gitlab.gnome.org/GNOME/fractal/-/issues/555

 fractal-gtk/src/widgets/media_viewer.rs |  2 +-
 fractal-gtk/src/widgets/message.rs      | 34 ++++++++++++----------------
 fractal-gtk/src/widgets/message_menu.rs | 39 ++++++++++-----------------------
 3 files changed, 27 insertions(+), 48 deletions(-)
---
diff --git a/fractal-gtk/src/widgets/media_viewer.rs b/fractal-gtk/src/widgets/media_viewer.rs
index 43d52f3b..d85d7e20 100644
--- a/fractal-gtk/src/widgets/media_viewer.rs
+++ b/fractal-gtk/src/widgets/media_viewer.rs
@@ -566,7 +566,7 @@ impl Data {
         let admin = self.admins.get(&self.uid).copied().unwrap_or_default();
         let redactable = admin != 0 || self.uid == msg.sender;
         let event_id = msg.id.as_ref();
-        let menu = MessageMenu::new(event_id, &mtype, &redactable, None, None);
+        let menu = MessageMenu::new(event_id, &mtype, &redactable, None);
         let popover = &menu.get_popover();
         let menu_button = self
             .builder
diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs
index d391a0a0..d7b0548a 100644
--- a/fractal-gtk/src/widgets/message.rs
+++ b/fractal-gtk/src/widgets/message.rs
@@ -559,7 +559,7 @@ impl MessageBox {
 
             let evid = msg.id.as_ref();
             let redactable = msg.redactable;
-            let menu = MessageMenu::new(evid, &RowType::Video, &redactable, None, None);
+            let menu = MessageMenu::new(evid, &RowType::Video, &redactable, None);
             menu_button.set_popover(Some(&menu.get_popover()));
 
             let clip_container = ClipContainer::new();
@@ -701,29 +701,23 @@ impl MessageBox {
             self.eventbox.upcast_ref::<gtk::Widget>()
         };
 
-        let eventbox = &self.eventbox;
         let id = msg.id.clone();
-        widget.connect_button_press_event(
-            clone!(@weak eventbox => @default-return Inhibit(false), move |w, e| {
-                if e.get_button() == 3 {
-                    MessageMenu::new(id.as_ref(), &mtype, &redactable, Some(&eventbox), Some(w));
-                    Inhibit(true)
-                } else {
-                    Inhibit(false)
-                }
-            }),
-        );
+        widget.connect_button_press_event(move |w, e| {
+            if e.triggers_context_menu() {
+                let menu = MessageMenu::new(id.as_ref(), &mtype, &redactable, Some(w));
+                let coords = e.get_position();
+                menu.show_at_coords(w, coords);
+                Inhibit(true)
+            } else {
+                Inhibit(false)
+            }
+        });
 
         let id = msg.id.clone();
         self.gesture
-            .connect_pressed(clone!(@weak eventbox, @weak widget => move |_, _, _| {
-                MessageMenu::new(
-                    id.as_ref(),
-                    &mtype,
-                    &redactable,
-                    Some(&eventbox),
-                    Some(&widget),
-                );
+            .connect_pressed(clone!(@weak widget => move |_, x, y| {
+                let menu = MessageMenu::new(id.as_ref(), &mtype, &redactable, Some(&widget));
+                menu.show_at_coords(&widget, (x, y));
             }));
         None
     }
diff --git a/fractal-gtk/src/widgets/message_menu.rs b/fractal-gtk/src/widgets/message_menu.rs
index 6a5e1db5..2e8b579a 100644
--- a/fractal-gtk/src/widgets/message_menu.rs
+++ b/fractal-gtk/src/widgets/message_menu.rs
@@ -125,7 +125,6 @@ impl MessageMenu {
         id: Option<&EventId>,
         mtype: &RowType,
         redactable: &bool,
-        widget: Option<&gtk::EventBox>,
         label: Option<&gtk::Widget>,
     ) -> MessageMenu {
         let menu = MessageMenu {
@@ -136,35 +135,21 @@ impl MessageMenu {
         if let Some(label) = label {
             menu.connect_copy_selected_text(label);
         }
-        if let Some(widget) = widget {
-            menu.show(widget);
-        }
         menu
     }
 
-    fn show(&self, w: &gtk::EventBox) {
-        gdk::Display::get_default()
-            .and_then(|disp| disp.get_default_seat())
-            .and_then(|seat| seat.get_pointer())
-            .map(|ptr| {
-                let win = w.get_window()?;
-                let (_, x, y, _) = win.get_device_position(&ptr);
-
-                let rect = gtk::Rectangle {
-                    x,
-                    y,
-                    width: 0,
-                    height: 0,
-                };
-
-                self.widgets.popover.set_relative_to(Some(w));
-                self.widgets.popover.set_pointing_to(&rect);
-                self.widgets.popover.set_position(gtk::PositionType::Bottom);
-
-                self.widgets.popover.popup();
-
-                Some(true)
-            });
+    pub fn show_at_coords<T: glib::IsA<gtk::Widget>>(&self, w: &T, coords: (f64, f64)) {
+        let rect = gtk::Rectangle {
+            x: coords.0 as i32,
+            y: coords.1 as i32,
+            width: 0,
+            height: 0,
+        };
+
+        self.widgets.popover.set_pointing_to(&rect);
+        self.widgets.popover.set_relative_to(Some(w));
+        self.widgets.popover.set_position(gtk::PositionType::Bottom);
+        self.widgets.popover.popup();
     }
 
     /* This should also be a action, but for some reason we need to set again the selection on the


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