Enable context menu popups in dialog, close context menu when location changes
This commit is contained in:
parent
e1bc0abaab
commit
a6e369df0f
3 changed files with 84 additions and 13 deletions
|
|
@ -3871,7 +3871,7 @@ impl Application for App {
|
||||||
);
|
);
|
||||||
commands.push(self.update(Message::Surface(
|
commands.push(self.update(Message::Surface(
|
||||||
cosmic::surface::action::app_popup(
|
cosmic::surface::action::app_popup(
|
||||||
move |app: &mut crate::App| -> SctkPopupSettings {
|
move |app: &mut App| -> SctkPopupSettings {
|
||||||
let anchor_rect = Rectangle {
|
let anchor_rect = Rectangle {
|
||||||
x: point.x as i32,
|
x: point.x as i32,
|
||||||
y: point.y as i32,
|
y: point.y as i32,
|
||||||
|
|
|
||||||
|
|
@ -497,6 +497,7 @@ struct App {
|
||||||
title: String,
|
title: String,
|
||||||
accept_label: DialogLabel,
|
accept_label: DialogLabel,
|
||||||
choices: Vec<DialogChoice>,
|
choices: Vec<DialogChoice>,
|
||||||
|
context_menu_window: Option<window::Id>,
|
||||||
context_page: ContextPage,
|
context_page: ContextPage,
|
||||||
dialog_pages: VecDeque<DialogPage>,
|
dialog_pages: VecDeque<DialogPage>,
|
||||||
dialog_text_input: widget::Id,
|
dialog_text_input: widget::Id,
|
||||||
|
|
@ -957,6 +958,7 @@ impl Application for App {
|
||||||
title,
|
title,
|
||||||
accept_label: DialogLabel::from(accept_label),
|
accept_label: DialogLabel::from(accept_label),
|
||||||
choices: Vec::new(),
|
choices: Vec::new(),
|
||||||
|
context_menu_window: None,
|
||||||
context_page: ContextPage::Preview(None, PreviewKind::Selected),
|
context_page: ContextPage::Preview(None, PreviewKind::Selected),
|
||||||
dialog_pages: VecDeque::new(),
|
dialog_pages: VecDeque::new(),
|
||||||
dialog_text_input: widget::Id::unique(),
|
dialog_text_input: widget::Id::unique(),
|
||||||
|
|
@ -1603,6 +1605,75 @@ impl Application for App {
|
||||||
tab::Command::ChangeLocation(_tab_title, _tab_path, _selection_paths) => {
|
tab::Command::ChangeLocation(_tab_title, _tab_path, _selection_paths) => {
|
||||||
commands.push(Task::batch([self.update_watcher(), self.rescan_tab()]));
|
commands.push(Task::batch([self.update_watcher(), self.rescan_tab()]));
|
||||||
}
|
}
|
||||||
|
tab::Command::ContextMenu(point_opt) => {
|
||||||
|
#[cfg(feature = "wayland")]
|
||||||
|
match point_opt {
|
||||||
|
Some(point) => {
|
||||||
|
if crate::is_wayland() {
|
||||||
|
// Open context menu
|
||||||
|
use cctk::wayland_protocols::xdg::shell::client::xdg_positioner::{
|
||||||
|
Anchor, Gravity,
|
||||||
|
};
|
||||||
|
use cosmic::iced_runtime::platform_specific::wayland::popup::{
|
||||||
|
SctkPopupSettings, SctkPositioner,
|
||||||
|
};
|
||||||
|
use cosmic::iced::Rectangle;
|
||||||
|
let window_id = window::Id::unique();
|
||||||
|
self.context_menu_window = Some(window_id.clone());
|
||||||
|
let autosize_id = widget::Id::unique();
|
||||||
|
commands.push(self.update(Message::Surface(
|
||||||
|
cosmic::surface::action::app_popup(
|
||||||
|
move |app: &mut App| -> SctkPopupSettings {
|
||||||
|
let anchor_rect = Rectangle {
|
||||||
|
x: point.x as i32,
|
||||||
|
y: point.y as i32,
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
};
|
||||||
|
let positioner = SctkPositioner {
|
||||||
|
size: None,
|
||||||
|
anchor_rect,
|
||||||
|
anchor: Anchor::None,
|
||||||
|
gravity: Gravity::BottomRight,
|
||||||
|
reactive: true,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
SctkPopupSettings {
|
||||||
|
parent: app.flags.window_id,
|
||||||
|
id: window_id,
|
||||||
|
positioner,
|
||||||
|
parent_size: None,
|
||||||
|
grab: true,
|
||||||
|
close_with_children: false,
|
||||||
|
input_zone: None,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(Box::new(move |app: &App| {
|
||||||
|
widget::autosize::autosize(
|
||||||
|
menu::context_menu(
|
||||||
|
&app.tab,
|
||||||
|
&app.key_binds,
|
||||||
|
&app.modifiers,
|
||||||
|
)
|
||||||
|
.map(Message::TabMessage)
|
||||||
|
.map(cosmic::Action::App),
|
||||||
|
autosize_id.clone(),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if let Some(window_id) = self.context_menu_window.take() {
|
||||||
|
commands.push(self.update(Message::Surface(
|
||||||
|
cosmic::surface::action::destroy_popup(window_id),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
tab::Command::Iced(iced_command) => {
|
tab::Command::Iced(iced_command) => {
|
||||||
commands.push(iced_command.0.map(|tab_message| {
|
commands.push(iced_command.0.map(|tab_message| {
|
||||||
cosmic::action::app(Message::TabMessage(tab_message))
|
cosmic::action::app(Message::TabMessage(tab_message))
|
||||||
|
|
|
||||||
24
src/tab.rs
24
src/tab.rs
|
|
@ -3879,18 +3879,6 @@ impl Tab {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check for wayland
|
|
||||||
if self.context_menu != last_context_menu {
|
|
||||||
if last_context_menu.is_some() {
|
|
||||||
commands.push(Command::ContextMenu(None));
|
|
||||||
}
|
|
||||||
if let Some(point) = self.context_menu {
|
|
||||||
commands.push(Command::ContextMenu(Some(
|
|
||||||
point + self.offset_opt.unwrap_or_default(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change directory if requested
|
// Change directory if requested
|
||||||
if let Some(mut location) = cd {
|
if let Some(mut location) = cd {
|
||||||
if matches!(self.mode, Mode::Desktop) {
|
if matches!(self.mode, Mode::Desktop) {
|
||||||
|
|
@ -3935,6 +3923,18 @@ impl Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update context menu popup
|
||||||
|
if self.context_menu != last_context_menu {
|
||||||
|
if last_context_menu.is_some() {
|
||||||
|
commands.push(Command::ContextMenu(None));
|
||||||
|
}
|
||||||
|
if let Some(point) = self.context_menu {
|
||||||
|
commands.push(Command::ContextMenu(Some(
|
||||||
|
point + self.offset_opt.unwrap_or_default(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commands
|
commands
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue