I have just added functionality to show context menu to a ColumnView but in this case the PopupMenu is not focusable, so keyboard navigation continues on the underlying window.
Popover menu
<interface>
<menu id="plan-menu">
<section>
<item>
<attribute name="label">Remove</attribute>
<attribute name="action">plan.remove</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">View airport</attribute>
<attribute name="action">plan.view</attribute>
</item>
<item>
<attribute name="label">Show on map</attribute>
<attribute name="action">plan.show_on_map</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Find airports near</attribute>
<attribute name="action">plan.find_airports_near</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Find navaids near</attribute>
<attribute name="action">plan.find_navaids_near</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Find fixes near</attribute>
<attribute name="action">plan.find_fixes_near</attribute>
</item>
</section>
</menu>
</interface>
let builder = Builder::from_resource("/com/shartrec/kelpie_planner/plan_popover.ui");
let menu = builder.object::<MenuModel>("plan-menu");
match menu {
Some(popover) => {
let popover = PopoverMenu::builder()
.menu_model(&popover)
.has_arrow(false)
.build();
popover.set_parent(&self.plan_window.get());
let _ = self.popover.replace(Some(popover));
}
None => error!(" Not a popover"),
}
// Enable context menu key
let ev_key = gtk::EventControllerKey::new();
ev_key.connect_key_pressed(clone!(#[weak(rename_to = view)] self, #[upgrade_or] Propagation::Proceed,
move | _event, key_val, _key_code, modifier | {
if key_val == Key::Menu && modifier == ModifierType::empty() {
if view.get_selected_location().is_some() {
// Need to get selected row x, y but that's not supported for ColumnViews
let rect = Rectangle::new(50, 1, 1, 1);
if let Some(popover) = view.popover.borrow().as_ref() {
popover.set_pointing_to(Some(&rect));
popover.popup();
// Add some debugging
let r = popover.grab_focus();
println!("Grab focus {:?}", r); **// this prints false**
println!("Focusable {:?}", popover.is_focusable()); **// this prints false**
};
}
Propagation::Stop
} else {
Propagation::Proceed
}
}));
self.plan_window.add_controller(ev_key);
I use the same technique elsewhere for other views and don’t have this problem.