mirror of
https://github.com/italicsjenga/muda.git
synced 2024-12-23 20:11:29 +11:00
fix(linux): add submenus, text items, native items at runtime
This commit is contained in:
parent
943beda6df
commit
7520e19645
|
@ -20,8 +20,8 @@ struct MenuEntry {
|
||||||
// multiple times, and thus can't be used in multiple windows, each entry
|
// multiple times, and thus can't be used in multiple windows, each entry
|
||||||
// keeps a vector of a [`gtk::MenuItem`] or a tuple of [`gtk::MenuItem`] and [`gtk::Menu`] if its a menu
|
// keeps a vector of a [`gtk::MenuItem`] or a tuple of [`gtk::MenuItem`] and [`gtk::Menu`] if its a menu
|
||||||
// and push to it every time [`Menu::init_for_gtk_window`] is called.
|
// and push to it every time [`Menu::init_for_gtk_window`] is called.
|
||||||
native_items: Option<Rc<RefCell<Vec<gtk::MenuItem>>>>,
|
native_items: Option<Vec<gtk::MenuItem>>,
|
||||||
native_menus: Option<Rc<RefCell<Vec<(gtk::MenuItem, gtk::Menu)>>>>,
|
native_menus: Option<Vec<(gtk::MenuItem, gtk::Menu)>>,
|
||||||
entries: Option<Vec<Rc<RefCell<MenuEntry>>>>,
|
entries: Option<Vec<Rc<RefCell<MenuEntry>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ struct InnerMenu {
|
||||||
// keeps a hashmap of window pointer as the key and a tuple of [`gtk::MenuBar`] and [`gtk::Box`] as the value
|
// keeps a hashmap of window pointer as the key and a tuple of [`gtk::MenuBar`] and [`gtk::Box`] as the value
|
||||||
// and push to it every time `Menu::init_for_gtk_window` is called.
|
// and push to it every time `Menu::init_for_gtk_window` is called.
|
||||||
native_menus: HashMap<isize, (Option<gtk::MenuBar>, Rc<gtk::Box>)>,
|
native_menus: HashMap<isize, (Option<gtk::MenuBar>, Rc<gtk::Box>)>,
|
||||||
accel_group: gtk::AccelGroup,
|
accel_group: Rc<gtk::AccelGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -56,21 +56,38 @@ impl Menu {
|
||||||
Self(Rc::new(RefCell::new(InnerMenu {
|
Self(Rc::new(RefCell::new(InnerMenu {
|
||||||
entries: Vec::new(),
|
entries: Vec::new(),
|
||||||
native_menus: HashMap::new(),
|
native_menus: HashMap::new(),
|
||||||
accel_group: gtk::AccelGroup::new(),
|
accel_group: Rc::new(gtk::AccelGroup::new()),
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
||||||
|
let label = label.as_ref().to_string();
|
||||||
|
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.as_ref().to_string(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu,
|
||||||
native_menus: Some(Rc::new(RefCell::new(Vec::new()))),
|
native_menus: Some(Vec::new()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
self.0.borrow_mut().entries.push(entry.clone());
|
|
||||||
Submenu(entry)
|
let mut inner = self.0.borrow_mut();
|
||||||
|
for (_, (menu_bar, _)) in inner.native_menus.iter() {
|
||||||
|
if let Some(menu_bar) = menu_bar {
|
||||||
|
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
||||||
|
menu_bar.append(&item);
|
||||||
|
entry
|
||||||
|
.borrow_mut()
|
||||||
|
.native_menus
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.push((item, submenu));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner.entries.push(entry.clone());
|
||||||
|
Submenu(entry, Rc::clone(&inner.accel_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_for_gtk_window<W>(&self, window: &W) -> Rc<gtk::Box>
|
pub fn init_for_gtk_window<W>(&self, window: &W) -> Rc<gtk::Box>
|
||||||
|
@ -87,6 +104,7 @@ impl Menu {
|
||||||
let menu_bar = gtk::MenuBar::new();
|
let menu_bar = gtk::MenuBar::new();
|
||||||
let vbox = gtk::Box::new(Orientation::Vertical, 0);
|
let vbox = gtk::Box::new(Orientation::Vertical, 0);
|
||||||
window.add(&vbox);
|
window.add(&vbox);
|
||||||
|
vbox.show();
|
||||||
inner
|
inner
|
||||||
.native_menus
|
.native_menus
|
||||||
.insert(window.as_ptr() as _, (Some(menu_bar), Rc::new(vbox)));
|
.insert(window.as_ptr() as _, (Some(menu_bar), Rc::new(vbox)));
|
||||||
|
@ -112,11 +130,11 @@ impl Menu {
|
||||||
&inner.entries,
|
&inner.entries,
|
||||||
&inner.accel_group,
|
&inner.accel_group,
|
||||||
);
|
);
|
||||||
window.add_accel_group(&inner.accel_group);
|
window.add_accel_group(&*inner.accel_group);
|
||||||
|
|
||||||
// Show the menubar on the window
|
// Show the menubar on the window
|
||||||
vbox.pack_start(menu_bar.as_ref().unwrap(), false, false, 0);
|
vbox.pack_start(menu_bar.as_ref().unwrap(), false, false, 0);
|
||||||
vbox.show_all();
|
menu_bar.as_ref().unwrap().show();
|
||||||
|
|
||||||
Rc::clone(vbox)
|
Rc::clone(vbox)
|
||||||
}
|
}
|
||||||
|
@ -132,7 +150,7 @@ impl Menu {
|
||||||
// Remove the [`gtk::Menubar`] from the widget tree
|
// Remove the [`gtk::Menubar`] from the widget tree
|
||||||
unsafe { menu_bar.destroy() };
|
unsafe { menu_bar.destroy() };
|
||||||
// Detach the accelerators from the window
|
// Detach the accelerators from the window
|
||||||
window.remove_accel_group(&inner.accel_group);
|
window.remove_accel_group(&*inner.accel_group);
|
||||||
// Remove the removed [`gtk::Menubar`] from our cache
|
// Remove the removed [`gtk::Menubar`] from our cache
|
||||||
let vbox = Rc::clone(vbox);
|
let vbox = Rc::clone(vbox);
|
||||||
inner
|
inner
|
||||||
|
@ -171,7 +189,7 @@ impl Menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Submenu(Rc<RefCell<MenuEntry>>);
|
pub struct Submenu(Rc<RefCell<MenuEntry>>, Rc<gtk::AccelGroup>);
|
||||||
|
|
||||||
impl Submenu {
|
impl Submenu {
|
||||||
pub fn label(&self) -> String {
|
pub fn label(&self) -> String {
|
||||||
|
@ -181,7 +199,7 @@ impl Submenu {
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
let label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for (item, _) in entry.native_menus.as_ref().unwrap().borrow().iter() {
|
for (item, _) in entry.native_menus.as_ref().unwrap() {
|
||||||
item.set_label(&to_gtk_menemenoic(&label));
|
item.set_label(&to_gtk_menemenoic(&label));
|
||||||
}
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
|
@ -194,27 +212,37 @@ impl Submenu {
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
entry.enabled = true;
|
entry.enabled = true;
|
||||||
for (item, _) in entry.native_menus.as_ref().unwrap().borrow().iter() {
|
for (item, _) in entry.native_menus.as_ref().unwrap() {
|
||||||
item.set_sensitive(enabled);
|
item.set_sensitive(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
pub fn add_submenu(&mut self, label: impl AsRef<str>, enabled: bool) -> Submenu {
|
||||||
|
let label = label.as_ref().to_string();
|
||||||
|
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.as_ref().to_string(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
entries: Some(Vec::new()),
|
entries: Some(Vec::new()),
|
||||||
r#type: MenuEntryType::Submenu,
|
r#type: MenuEntryType::Submenu,
|
||||||
native_menus: Some(Rc::new(RefCell::new(Vec::new()))),
|
native_menus: Some(Vec::new()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
self.0
|
|
||||||
|
let mut inner = self.0.borrow_mut();
|
||||||
|
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
||||||
|
let (item, submenu) = create_gtk_submenu(&label, enabled);
|
||||||
|
menu.append(&item);
|
||||||
|
entry
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.entries
|
.native_menus
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.push(entry.clone());
|
.push((item, submenu));
|
||||||
Submenu(entry)
|
}
|
||||||
|
|
||||||
|
inner.entries.as_mut().unwrap().push(entry.clone());
|
||||||
|
Submenu(entry, Rc::clone(&self.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_text_item(
|
pub fn add_text_item(
|
||||||
|
@ -223,31 +251,50 @@ impl Submenu {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
accelerator: Option<&str>,
|
accelerator: Option<&str>,
|
||||||
) -> TextMenuItem {
|
) -> TextMenuItem {
|
||||||
|
let label = label.as_ref().to_string();
|
||||||
|
let id = COUNTER.next();
|
||||||
|
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
label: label.as_ref().to_string(),
|
label: label.clone(),
|
||||||
enabled,
|
enabled,
|
||||||
r#type: MenuEntryType::Text,
|
r#type: MenuEntryType::Text,
|
||||||
item_id: Some(COUNTER.next()),
|
item_id: Some(id),
|
||||||
accelerator: accelerator.map(|s| s.to_string()),
|
accelerator: accelerator.map(|s| s.to_string()),
|
||||||
native_items: Some(Rc::new(RefCell::new(Vec::new()))),
|
native_items: Some(Vec::new()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
self.0
|
|
||||||
.borrow_mut()
|
let mut inner = self.0.borrow_mut();
|
||||||
.entries
|
|
||||||
.as_mut()
|
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
||||||
.unwrap()
|
let item = create_gtk_text_menu_item(
|
||||||
.push(entry.clone());
|
&label,
|
||||||
|
enabled,
|
||||||
|
&accelerator.map(|s| s.to_string()),
|
||||||
|
id,
|
||||||
|
&*self.1,
|
||||||
|
);
|
||||||
|
menu.append(&item);
|
||||||
|
entry.borrow_mut().native_items.as_mut().unwrap().push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
inner.entries.as_mut().unwrap().push(entry.clone());
|
||||||
TextMenuItem(entry)
|
TextMenuItem(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_native_item(&mut self, item: NativeMenuItem) {
|
pub fn add_native_item(&mut self, item: NativeMenuItem) {
|
||||||
|
let mut inner = self.0.borrow_mut();
|
||||||
|
|
||||||
|
for (_, menu) in inner.native_menus.as_ref().unwrap() {
|
||||||
|
item.add_to_gtk_menu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
let entry = Rc::new(RefCell::new(MenuEntry {
|
let entry = Rc::new(RefCell::new(MenuEntry {
|
||||||
r#type: MenuEntryType::Native,
|
r#type: MenuEntryType::Native,
|
||||||
native_menu_item: Some(item),
|
native_menu_item: Some(item),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
self.0.borrow_mut().entries.as_mut().unwrap().push(entry);
|
inner.entries.as_mut().unwrap().push(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +309,7 @@ impl TextMenuItem {
|
||||||
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
pub fn set_label(&mut self, label: impl AsRef<str>) {
|
||||||
let label = label.as_ref().to_string();
|
let label = label.as_ref().to_string();
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.native_items.as_ref().unwrap().borrow().iter() {
|
for item in entry.native_items.as_ref().unwrap() {
|
||||||
item.set_label(&to_gtk_menemenoic(&label));
|
item.set_label(&to_gtk_menemenoic(&label));
|
||||||
}
|
}
|
||||||
entry.label = label;
|
entry.label = label;
|
||||||
|
@ -274,7 +321,7 @@ impl TextMenuItem {
|
||||||
|
|
||||||
pub fn set_enabled(&mut self, enabled: bool) {
|
pub fn set_enabled(&mut self, enabled: bool) {
|
||||||
let mut entry = self.0.borrow_mut();
|
let mut entry = self.0.borrow_mut();
|
||||||
for item in entry.native_items.as_ref().unwrap().borrow().iter() {
|
for item in entry.native_items.as_ref().unwrap() {
|
||||||
item.set_sensitive(enabled);
|
item.set_sensitive(enabled);
|
||||||
}
|
}
|
||||||
entry.enabled = enabled;
|
entry.enabled = enabled;
|
||||||
|
@ -285,37 +332,61 @@ impl TextMenuItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_entries_to_menu<M>(
|
fn add_entries_to_menu<M: IsA<gtk::MenuShell>>(
|
||||||
gtk_menu: &M,
|
gtk_menu: &M,
|
||||||
entries: &Vec<Rc<RefCell<MenuEntry>>>,
|
entries: &Vec<Rc<RefCell<MenuEntry>>>,
|
||||||
accel_group: >k::AccelGroup,
|
accel_group: >k::AccelGroup,
|
||||||
) where
|
) {
|
||||||
M: IsA<gtk::MenuShell>,
|
|
||||||
{
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let mut entry = entry.borrow_mut();
|
let mut entry = entry.borrow_mut();
|
||||||
match entry.r#type {
|
match entry.r#type {
|
||||||
MenuEntryType::Submenu => {
|
MenuEntryType::Submenu => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic(&to_gtk_menemenoic(&entry.label));
|
let (item, submenu) = create_gtk_submenu(&entry.label, entry.enabled);
|
||||||
gtk_menu.append(>k_item);
|
gtk_menu.append(&item);
|
||||||
gtk_item.set_sensitive(entry.enabled);
|
add_entries_to_menu(&submenu, entry.entries.as_ref().unwrap(), accel_group);
|
||||||
let gtk_menu = gtk::Menu::new();
|
entry.native_menus.as_mut().unwrap().push((item, submenu));
|
||||||
gtk_item.set_submenu(Some(>k_menu));
|
|
||||||
add_entries_to_menu(>k_menu, entry.entries.as_ref().unwrap(), accel_group);
|
|
||||||
entry
|
|
||||||
.native_menus
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.borrow_mut()
|
|
||||||
.push((gtk_item, gtk_menu));
|
|
||||||
}
|
}
|
||||||
MenuEntryType::Text => {
|
MenuEntryType::Text => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic(&to_gtk_menemenoic(&entry.label));
|
let item = create_gtk_text_menu_item(
|
||||||
gtk_menu.append(>k_item);
|
&entry.label,
|
||||||
gtk_item.set_sensitive(entry.enabled);
|
entry.enabled,
|
||||||
if let Some(accelerator) = &entry.accelerator {
|
&entry.accelerator,
|
||||||
|
entry.item_id.unwrap(),
|
||||||
|
accel_group,
|
||||||
|
);
|
||||||
|
gtk_menu.append(&item);
|
||||||
|
entry.native_items.as_mut().unwrap().push(item);
|
||||||
|
}
|
||||||
|
MenuEntryType::Native => entry
|
||||||
|
.native_menu_item
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.add_to_gtk_menu(gtk_menu),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_gtk_submenu(label: &str, enabled: bool) -> (gtk::MenuItem, gtk::Menu) {
|
||||||
|
let item = gtk::MenuItem::with_mnemonic(&to_gtk_menemenoic(label));
|
||||||
|
item.set_sensitive(enabled);
|
||||||
|
let menu = gtk::Menu::new();
|
||||||
|
item.set_submenu(Some(&menu));
|
||||||
|
item.show();
|
||||||
|
(item, menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_gtk_text_menu_item(
|
||||||
|
label: &str,
|
||||||
|
enabled: bool,
|
||||||
|
accelerator: &Option<String>,
|
||||||
|
id: u64,
|
||||||
|
accel_group: >k::AccelGroup,
|
||||||
|
) -> gtk::MenuItem {
|
||||||
|
let item = gtk::MenuItem::with_mnemonic(&to_gtk_menemenoic(label));
|
||||||
|
item.set_sensitive(enabled);
|
||||||
|
if let Some(accelerator) = accelerator {
|
||||||
let (key, modifiers) = gtk::accelerator_parse(&to_gtk_accelerator(accelerator));
|
let (key, modifiers) = gtk::accelerator_parse(&to_gtk_accelerator(accelerator));
|
||||||
gtk_item.add_accelerator(
|
item.add_accelerator(
|
||||||
"activate",
|
"activate",
|
||||||
accel_group,
|
accel_group,
|
||||||
key,
|
key,
|
||||||
|
@ -323,117 +394,116 @@ fn add_entries_to_menu<M>(
|
||||||
gtk::AccelFlags::VISIBLE,
|
gtk::AccelFlags::VISIBLE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
item.connect_activate(move |_| {
|
||||||
let id = entry.item_id.unwrap();
|
|
||||||
gtk_item.connect_activate(move |_| {
|
|
||||||
let _ = crate::MENU_CHANNEL.0.send(crate::MenuEvent { id });
|
let _ = crate::MENU_CHANNEL.0.send(crate::MenuEvent { id });
|
||||||
});
|
});
|
||||||
entry
|
item.show();
|
||||||
.native_items
|
item
|
||||||
.as_mut()
|
}
|
||||||
.unwrap()
|
|
||||||
.borrow_mut()
|
impl NativeMenuItem {
|
||||||
.push(gtk_item);
|
fn add_to_gtk_menu<M: IsA<gtk::MenuShell>>(&self, gtk_menu: &M) {
|
||||||
}
|
match self {
|
||||||
MenuEntryType::Native => match entry.native_menu_item.as_ref().unwrap() {
|
|
||||||
NativeMenuItem::Copy => {
|
NativeMenuItem::Copy => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("_Copy");
|
let item = gtk::MenuItem::with_mnemonic("_Copy");
|
||||||
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>X");
|
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>X");
|
||||||
gtk_item
|
item.child()
|
||||||
.child()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast::<gtk::AccelLabel>()
|
.downcast::<gtk::AccelLabel>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_accel(key, modifiers);
|
.set_accel(key, modifiers);
|
||||||
gtk_item.connect_activate(move |_| {
|
item.connect_activate(move |_| {
|
||||||
// TODO: wayland
|
// TODO: wayland
|
||||||
if let Ok(xdo) = libxdo::XDo::new(None) {
|
if let Ok(xdo) = libxdo::XDo::new(None) {
|
||||||
let _ = xdo.send_keysequence("ctrl+c", 0);
|
let _ = xdo.send_keysequence("ctrl+c", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::Cut => {
|
NativeMenuItem::Cut => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("Cu_t");
|
let item = gtk::MenuItem::with_mnemonic("Cu_t");
|
||||||
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>X");
|
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>X");
|
||||||
gtk_item
|
item.child()
|
||||||
.child()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast::<gtk::AccelLabel>()
|
.downcast::<gtk::AccelLabel>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_accel(key, modifiers);
|
.set_accel(key, modifiers);
|
||||||
gtk_item.connect_activate(move |_| {
|
item.connect_activate(move |_| {
|
||||||
// TODO: wayland
|
// TODO: wayland
|
||||||
if let Ok(xdo) = libxdo::XDo::new(None) {
|
if let Ok(xdo) = libxdo::XDo::new(None) {
|
||||||
let _ = xdo.send_keysequence("ctrl+x", 0);
|
let _ = xdo.send_keysequence("ctrl+x", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::Paste => {
|
NativeMenuItem::Paste => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("_Paste");
|
let item = gtk::MenuItem::with_mnemonic("_Paste");
|
||||||
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>V");
|
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>V");
|
||||||
gtk_item
|
item.child()
|
||||||
.child()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast::<gtk::AccelLabel>()
|
.downcast::<gtk::AccelLabel>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_accel(key, modifiers);
|
.set_accel(key, modifiers);
|
||||||
gtk_item.connect_activate(move |_| {
|
item.connect_activate(move |_| {
|
||||||
// TODO: wayland
|
// TODO: wayland
|
||||||
if let Ok(xdo) = libxdo::XDo::new(None) {
|
if let Ok(xdo) = libxdo::XDo::new(None) {
|
||||||
let _ = xdo.send_keysequence("ctrl+v", 0);
|
let _ = xdo.send_keysequence("ctrl+v", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::SelectAll => {
|
NativeMenuItem::SelectAll => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("Select _All");
|
let item = gtk::MenuItem::with_mnemonic("Select _All");
|
||||||
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>A");
|
let (key, modifiers) = gtk::accelerator_parse("<Ctrl>A");
|
||||||
gtk_item
|
item.child()
|
||||||
.child()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast::<gtk::AccelLabel>()
|
.downcast::<gtk::AccelLabel>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_accel(key, modifiers);
|
.set_accel(key, modifiers);
|
||||||
gtk_item.connect_activate(move |_| {
|
item.connect_activate(move |_| {
|
||||||
// TODO: wayland
|
// TODO: wayland
|
||||||
if let Ok(xdo) = libxdo::XDo::new(None) {
|
if let Ok(xdo) = libxdo::XDo::new(None) {
|
||||||
let _ = xdo.send_keysequence("ctrl+a", 0);
|
let _ = xdo.send_keysequence("ctrl+a", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::Separator => {
|
NativeMenuItem::Separator => {
|
||||||
gtk_menu.append(>k::SeparatorMenuItem::new());
|
gtk_menu.append(>k::SeparatorMenuItem::new());
|
||||||
}
|
}
|
||||||
NativeMenuItem::Minimize => {
|
NativeMenuItem::Minimize => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("_Minimize");
|
let item = gtk::MenuItem::with_mnemonic("_Minimize");
|
||||||
gtk_item.connect_activate(move |m| {
|
item.connect_activate(move |m| {
|
||||||
if let Some(window) = m.window() {
|
if let Some(window) = m.window() {
|
||||||
window.iconify()
|
window.iconify()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::CloseWindow => {
|
NativeMenuItem::CloseWindow => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("C_lose Window");
|
let item = gtk::MenuItem::with_mnemonic("C_lose Window");
|
||||||
gtk_item.connect_activate(move |m| {
|
item.connect_activate(move |m| {
|
||||||
if let Some(window) = m.window() {
|
if let Some(window) = m.window() {
|
||||||
window.destroy()
|
window.destroy()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
NativeMenuItem::Quit => {
|
NativeMenuItem::Quit => {
|
||||||
let gtk_item = gtk::MenuItem::with_mnemonic("_Quit");
|
let item = gtk::MenuItem::with_mnemonic("_Quit");
|
||||||
gtk_item.connect_activate(move |_| {
|
item.connect_activate(move |_| {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
});
|
});
|
||||||
gtk_menu.append(>k_item);
|
item.show();
|
||||||
|
gtk_menu.append(&item);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue