Skip to content

Commit c795c9d

Browse files
committed
working right-click menu
1 parent 6528bbf commit c795c9d

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

src/tab.rs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use futures::io::BufReader;
55
use futures::prelude::*;
66
use futures::task::LocalSpawnExt;
77
use gtk::gdk::prelude::*;
8+
use gtk::gio;
89
use gtk::glib;
910
use gtk::prelude::*;
1011
use gtk::subclass::prelude::*;
@@ -28,7 +29,8 @@ pub mod imp {
2829
pub(crate) history: RefCell<Vec<HistoryItem>>,
2930
pub(crate) scroll_win: gtk::ScrolledWindow,
3031
pub(crate) clamp: adw::Clamp,
31-
pub(crate) event_ctrlr_click: RefCell<Option<gtk::GestureClick>>,
32+
pub(crate) left_click_ctrl: RefCell<Option<gtk::GestureClick>>,
33+
pub(crate) right_click_ctrl: RefCell<Option<gtk::GestureClick>>,
3234
pub(crate) req_handle: RefCell<Option<RemoteHandle<()>>>,
3335
}
3436

@@ -56,8 +58,10 @@ pub mod imp {
5658
self.clamp.set_tightening_threshold(720);
5759
self.clamp.set_child(Some(&self.scroll_win));
5860

59-
self.event_ctrlr_click
60-
.replace(Some(gtk::GestureClick::new()));
61+
self.left_click_ctrl
62+
.replace(Some(gtk::GestureClick::builder().button(1).build()));
63+
self.right_click_ctrl
64+
.replace(Some(gtk::GestureClick::builder().button(3).build()));
6165
self.gemini_client
6266
.replace(gemini::ClientBuilder::new().redirect(true).build());
6367
}
@@ -119,7 +123,8 @@ impl Tab {
119123
.cursor_visible(false)
120124
.wrap_mode(gtk::WrapMode::WordChar)
121125
.build();
122-
text_view.add_controller(imp.event_ctrlr_click.borrow().as_ref().unwrap());
126+
text_view.add_controller(imp.left_click_ctrl.borrow().as_ref().unwrap());
127+
text_view.add_controller(imp.right_click_ctrl.borrow().as_ref().unwrap());
123128

124129
imp.scroll_win.set_child(Some(&text_view));
125130
imp.draw_ctx.replace(Some(DrawCtx::new(text_view, config)));
@@ -160,15 +165,25 @@ impl Tab {
160165
// FIXME: emit action
161166
Ok(())
162167
}
163-
fn handle_right_click(&self, _x: f64, _y: f64) {
164-
// FIXME: if let Some(menu) = widget.dynamic_cast_ref::<gtk::PopoverMenu>() {
165-
// // let (x, y) = Self::coords_in_widget(text_view);
166-
167-
// // if let Ok(handler) = Self::extract_linkhandler(text_view, (x as f64, y as f64)) {
168-
// // let url = handler.url();
169-
// // /*FIXME: Self::extend_textview_menu(&menu, url.to_owned(), in_chan.clone());*/
170-
// // }
171-
// }
168+
fn handle_right_click(&self, x: f64, y: f64) -> Result<()> {
169+
let imp = self.imp();
170+
let draw_ctx = imp.draw_ctx.borrow();
171+
let text_view = &draw_ctx.as_ref().unwrap().text_view;
172+
let link = Self::extract_linkhandler(draw_ctx.as_ref().unwrap(), x, y)?;
173+
174+
let menu = gio::Menu::new();
175+
menu.insert(
176+
0,
177+
Some("Open Link In New Tab"),
178+
Some(&format!("win.open-in-new-tab(\"{}\")", link.as_str())),
179+
);
180+
menu.insert(
181+
1,
182+
Some("Copy Link"),
183+
Some(&format!("win.set-clipboard(\"{}\")", link.as_str())),
184+
);
185+
text_view.set_extra_menu(Some(&menu));
186+
Ok(())
172187
}
173188
fn spawn_req(&self, fut: impl Future<Output = ()> + 'static) {
174189
let imp = self.imp();
@@ -300,18 +315,25 @@ impl Tab {
300315
fn bind_signals(&self) {
301316
let imp = self.imp();
302317
let this = self.clone();
303-
let event_ctrlr_click = imp.event_ctrlr_click.borrow();
304-
let event_ctrlr_click = event_ctrlr_click.as_ref().unwrap();
305-
event_ctrlr_click.connect_released(move |_gsclick, _buttoni, x, y| {
318+
let left_click_ctrl = imp.left_click_ctrl.borrow();
319+
let left_click_ctrl = left_click_ctrl.as_ref().unwrap();
320+
left_click_ctrl.connect_released(move |_ctrl, _n_press, x, y| {
306321
if let Err(e) = this.handle_click(x, y) {
307322
info!("{}", e);
308323
};
309324
});
310325

311326
let this = self.clone();
312-
event_ctrlr_click.connect_pressed(move |_gsclick, _buttoni, x, y| {
313-
this.handle_right_click(x, y);
314-
});
327+
imp.right_click_ctrl
328+
.borrow()
329+
.as_ref()
330+
.unwrap()
331+
.connect_pressed(move |_ctrl, _n_press, x, y| {
332+
info!("oke");
333+
if let Err(e) = this.handle_right_click(x, y) {
334+
info!("{}", e);
335+
};
336+
});
315337
}
316338
fn extract_linkhandler(draw_ctx: &DrawCtx, x: f64, y: f64) -> Result<String> {
317339
info!("Extracting linkhandler from clicked text");

src/window.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use adw::subclass::application_window::AdwApplicationWindowImpl;
33
use anyhow::Context;
44
use futures::prelude::*;
55
use glib::clone;
6+
use gtk::gdk;
67
use gtk::gio;
78
use gtk::glib;
89
use gtk::subclass::prelude::*;
@@ -115,6 +116,26 @@ impl Window {
115116
clone!(@weak self as this => move |_,v| this.open_omni(v.unwrap().get::<String>().unwrap().as_str())),
116117
);
117118
self.add_action(&act_open_page);
119+
120+
let act_open_url = gio::SimpleAction::new("open-url", Some(glib::VariantTy::STRING));
121+
act_open_url.connect_activate(
122+
clone!(@weak self as this => move |_,v| this.open_url_str(v.unwrap().get::<String>().unwrap().as_str())),
123+
);
124+
self.add_action(&act_open_url);
125+
126+
let act_open_in_new_tab =
127+
gio::SimpleAction::new("open-in-new-tab", Some(glib::VariantTy::STRING));
128+
act_open_in_new_tab.connect_activate(
129+
clone!(@weak self as this => move |_,v| this.open_in_new_tab(v.unwrap().get::<String>().unwrap().as_str())),
130+
);
131+
self.add_action(&act_open_in_new_tab);
132+
133+
let act_set_clipboard =
134+
gio::SimpleAction::new("set-clipboard", Some(glib::VariantTy::STRING));
135+
act_set_clipboard.connect_activate(
136+
clone!(@weak self as this => move |_,v| this.set_clipboard(v.unwrap().get::<String>().unwrap().as_str())),
137+
);
138+
self.add_action(&act_set_clipboard);
118139
}
119140
fn add_tab(&self) {
120141
let imp = self.imp();
@@ -233,6 +254,20 @@ impl Window {
233254
Err(e) => error!("Failed to parse url: {:?}", e),
234255
}
235256
}
257+
fn open_url_str(&self, v: &str) {
258+
let url = Url::parse(v);
259+
match url {
260+
Ok(url) => self.open_url(url),
261+
Err(e) => error!("Failed to parse url: {:?}", e),
262+
}
263+
}
264+
fn open_in_new_tab(&self, v: &str) {
265+
self.add_tab();
266+
self.open_url_str(v);
267+
}
268+
fn set_clipboard(&self, v: &str) {
269+
gdk::Display::default().unwrap().clipboard().set_text(v);
270+
}
236271
//TODO: Reintroduce colors
237272
//fn set_special_color_from_hash(&self, hash: u64) {
238273
// let color1 = Color(

0 commit comments

Comments
 (0)