Merge pull request #1631 from jasonrhansen/close-context-menu
fix: close context menus in various cases
This commit is contained in:
commit
f9d4ca4867
2 changed files with 99 additions and 48 deletions
98
src/app.rs
98
src/app.rs
|
|
@ -28,7 +28,7 @@ use cosmic::{
|
||||||
event,
|
event,
|
||||||
futures::{self, SinkExt},
|
futures::{self, SinkExt},
|
||||||
keyboard::{Event as KeyEvent, Key, Modifiers},
|
keyboard::{Event as KeyEvent, Key, Modifiers},
|
||||||
stream,
|
mouse, stream,
|
||||||
widget::scrollable,
|
widget::scrollable,
|
||||||
window::{self, Event as WindowEvent, Id as WindowId},
|
window::{self, Event as WindowEvent, Id as WindowId},
|
||||||
},
|
},
|
||||||
|
|
@ -369,6 +369,7 @@ pub enum Message {
|
||||||
ModifiersChanged(window::Id, Modifiers),
|
ModifiersChanged(window::Id, Modifiers),
|
||||||
MounterItems(MounterKey, MounterItems),
|
MounterItems(MounterKey, MounterItems),
|
||||||
MountResult(MounterKey, MounterItem, Result<bool, String>),
|
MountResult(MounterKey, MounterItem, Result<bool, String>),
|
||||||
|
Mouse(window::Id, mouse::Button),
|
||||||
MoveTo(Option<Entity>),
|
MoveTo(Option<Entity>),
|
||||||
MoveToResult(DialogResult),
|
MoveToResult(DialogResult),
|
||||||
NavBarClose(Entity),
|
NavBarClose(Entity),
|
||||||
|
|
@ -1554,6 +1555,21 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close_context_menus(&mut self) -> Task<Message> {
|
||||||
|
let active = self.tab_model.active();
|
||||||
|
if let Some(tab) = self.tab_model.data_mut::<Tab>(active) {
|
||||||
|
tab.location_context_menu_index = None;
|
||||||
|
if tab.context_menu.is_some() {
|
||||||
|
return self.update(Message::TabMessage(
|
||||||
|
Some(active),
|
||||||
|
tab::Message::ContextMenu(None, None),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
fn update_nav_model(&mut self) {
|
fn update_nav_model(&mut self) {
|
||||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||||
|
|
||||||
|
|
@ -2594,11 +2610,12 @@ impl Application for App {
|
||||||
self.set_show_context(false);
|
self.set_show_context(false);
|
||||||
return cosmic::task::message(cosmic::action::app(Message::SetShowDetails(false)));
|
return cosmic::task::message(cosmic::action::app(Message::SetShowDetails(false)));
|
||||||
}
|
}
|
||||||
if self.search_get().is_some() {
|
|
||||||
// Close search if open
|
|
||||||
return self.search_set_active(None);
|
|
||||||
}
|
|
||||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
|
if tab.location_context_menu_index.is_some() {
|
||||||
|
tab.location_context_menu_index = None;
|
||||||
|
return Task::none();
|
||||||
|
}
|
||||||
|
|
||||||
if tab.context_menu.is_some() {
|
if tab.context_menu.is_some() {
|
||||||
return self.update(Message::TabMessage(
|
return self.update(Message::TabMessage(
|
||||||
Some(entity),
|
Some(entity),
|
||||||
|
|
@ -2621,6 +2638,11 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.search_get().is_some() {
|
||||||
|
// Close search if open
|
||||||
|
return self.search_set_active(None);
|
||||||
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3304,6 +3326,12 @@ impl Application for App {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Message::Mouse(window_id, _button) => {
|
||||||
|
// Close context menu when clicking outside.
|
||||||
|
if self.core.main_window_id() == Some(window_id) {
|
||||||
|
return self.close_context_menus();
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::MoveTo(entity_opt) => {
|
Message::MoveTo(entity_opt) => {
|
||||||
let selected_paths: Box<[_]> = self.selected_paths(entity_opt).collect();
|
let selected_paths: Box<[_]> = self.selected_paths(entity_opt).collect();
|
||||||
return self.move_to(&selected_paths);
|
return self.move_to(&selected_paths);
|
||||||
|
|
@ -4046,14 +4074,18 @@ impl Application for App {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Message::SearchActivate => {
|
Message::SearchActivate => {
|
||||||
return if self.search_get().is_none() {
|
let mut tasks = vec![self.close_context_menus()];
|
||||||
self.search_set_active(Some(String::new()))
|
|
||||||
|
if self.search_get().is_none() {
|
||||||
|
tasks.push(self.search_set_active(Some(String::new())));
|
||||||
} else {
|
} else {
|
||||||
widget::text_input::focus(self.search_id.clone())
|
tasks.push(widget::text_input::focus(self.search_id.clone()));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return Task::batch(tasks);
|
||||||
}
|
}
|
||||||
Message::SearchClear => {
|
Message::SearchClear => {
|
||||||
return self.search_set_active(None);
|
return Task::batch([self.close_context_menus(), self.search_set_active(None)]);
|
||||||
}
|
}
|
||||||
Message::SearchInput(input) => {
|
Message::SearchInput(input) => {
|
||||||
return self.search_set_active(Some(input));
|
return self.search_set_active(Some(input));
|
||||||
|
|
@ -4074,18 +4106,7 @@ impl Application for App {
|
||||||
return self.update_config();
|
return self.update_config();
|
||||||
}
|
}
|
||||||
Message::TabActivate(entity) => {
|
Message::TabActivate(entity) => {
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = vec![self.close_context_menus()];
|
||||||
|
|
||||||
// Close old context menu
|
|
||||||
let active = self.tab_model.active();
|
|
||||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(active)
|
|
||||||
&& tab.context_menu.is_some()
|
|
||||||
{
|
|
||||||
tasks.push(self.update(Message::TabMessage(
|
|
||||||
Some(active),
|
|
||||||
tab::Message::ContextMenu(None, None),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate new tab
|
// Activate new tab
|
||||||
self.tab_model.activate(entity);
|
self.tab_model.activate(entity);
|
||||||
|
|
@ -4316,6 +4337,7 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
tab::Command::OpenFile(paths) => commands.push(self.open_file(&paths)),
|
tab::Command::OpenFile(paths) => commands.push(self.open_file(&paths)),
|
||||||
tab::Command::OpenInNewTab(path) => {
|
tab::Command::OpenInNewTab(path) => {
|
||||||
|
commands.push(self.close_context_menus());
|
||||||
commands.push(self.open_tab(Location::Path(path), false, None));
|
commands.push(self.open_tab(Location::Path(path), false, None));
|
||||||
}
|
}
|
||||||
tab::Command::OpenInNewWindow(path) => match env::current_exe() {
|
tab::Command::OpenInNewWindow(path) => match env::current_exe() {
|
||||||
|
|
@ -4772,25 +4794,21 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NavMenuAction::OpenInNewTab(entity) => {
|
NavMenuAction::OpenInNewTab(entity) => {
|
||||||
match self.nav_model.data::<Location>(entity) {
|
let open_task = match self.nav_model.data::<Location>(entity) {
|
||||||
Some(Location::Network(uri, display_name, path)) => {
|
Some(Location::Network(uri, display_name, path)) => self.open_tab(
|
||||||
return self.open_tab(
|
Location::Network(uri.clone(), display_name.clone(), path.clone()),
|
||||||
Location::Network(uri.clone(), display_name.clone(), path.clone()),
|
false,
|
||||||
false,
|
None,
|
||||||
None,
|
),
|
||||||
);
|
|
||||||
}
|
|
||||||
Some(Location::Path(path)) => {
|
Some(Location::Path(path)) => {
|
||||||
return self.open_tab(Location::Path(path.clone()), false, None);
|
self.open_tab(Location::Path(path.clone()), false, None)
|
||||||
}
|
}
|
||||||
Some(Location::Recents) => {
|
Some(Location::Recents) => self.open_tab(Location::Recents, false, None),
|
||||||
return self.open_tab(Location::Recents, false, None);
|
Some(Location::Trash) => self.open_tab(Location::Trash, false, None),
|
||||||
}
|
_ => Task::none(),
|
||||||
Some(Location::Trash) => {
|
};
|
||||||
return self.open_tab(Location::Trash, false, None);
|
|
||||||
}
|
return Task::batch([self.close_context_menus(), open_task]);
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the selected path in a new cosmic-files window.
|
// Open the selected path in a new cosmic-files window.
|
||||||
|
|
@ -6185,6 +6203,10 @@ impl Application for App {
|
||||||
let mut subscriptions = vec![
|
let mut subscriptions = vec![
|
||||||
//TODO: filter more events by window id
|
//TODO: filter more events by window id
|
||||||
event::listen_with(|event, status, window_id| match event {
|
event::listen_with(|event, status, window_id| match event {
|
||||||
|
Event::Mouse(mouse::Event::ButtonPressed(button)) => match status {
|
||||||
|
event::Status::Ignored => Some(Message::Mouse(window_id, button)),
|
||||||
|
event::Status::Captured => None,
|
||||||
|
},
|
||||||
Event::Keyboard(KeyEvent::KeyPressed {
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
key,
|
key,
|
||||||
modifiers,
|
modifiers,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use cosmic::{
|
||||||
event,
|
event,
|
||||||
futures::{self, SinkExt},
|
futures::{self, SinkExt},
|
||||||
keyboard::{Event as KeyEvent, Key, Modifiers, key::Named},
|
keyboard::{Event as KeyEvent, Key, Modifiers, key::Named},
|
||||||
stream,
|
mouse, stream,
|
||||||
widget::scrollable,
|
widget::scrollable,
|
||||||
window,
|
window,
|
||||||
},
|
},
|
||||||
|
|
@ -468,6 +468,7 @@ enum Message {
|
||||||
Key(Modifiers, Key, Option<SmolStr>),
|
Key(Modifiers, Key, Option<SmolStr>),
|
||||||
ModifiersChanged(Modifiers),
|
ModifiersChanged(Modifiers),
|
||||||
MounterItems(MounterKey, MounterItems),
|
MounterItems(MounterKey, MounterItems),
|
||||||
|
Mouse(window::Id, mouse::Button),
|
||||||
NewFolder,
|
NewFolder,
|
||||||
NotifyEvents(Vec<DebouncedEvent>),
|
NotifyEvents(Vec<DebouncedEvent>),
|
||||||
NotifyWatcher(WatcherWrapper),
|
NotifyWatcher(WatcherWrapper),
|
||||||
|
|
@ -854,6 +855,15 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close_context_menus(&mut self) -> Task<Message> {
|
||||||
|
self.tab.location_context_menu_index = None;
|
||||||
|
if self.tab.context_menu.is_some() {
|
||||||
|
return self.update(Message::TabMessage(tab::Message::ContextMenu(None, None)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
fn update_nav_model(&mut self) {
|
fn update_nav_model(&mut self) {
|
||||||
let mut nav_model = segmented_button::ModelBuilder::default();
|
let mut nav_model = segmented_button::ModelBuilder::default();
|
||||||
|
|
||||||
|
|
@ -1300,9 +1310,9 @@ impl Application for App {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.search_get().is_some() {
|
if self.tab.location_context_menu_index.is_some() {
|
||||||
// Close search if open
|
self.tab.location_context_menu_index = None;
|
||||||
return self.search_set(None);
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tab.context_menu.is_some() {
|
if self.tab.context_menu.is_some() {
|
||||||
|
|
@ -1315,6 +1325,11 @@ impl Application for App {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.search_get().is_some() {
|
||||||
|
// Close search if open
|
||||||
|
return self.search_set(None);
|
||||||
|
}
|
||||||
|
|
||||||
let had_focused_button = self.tab.select_focus_id().is_some();
|
let had_focused_button = self.tab.select_focus_id().is_some();
|
||||||
if self.tab.select_none() {
|
if self.tab.select_none() {
|
||||||
if had_focused_button {
|
if had_focused_button {
|
||||||
|
|
@ -1529,6 +1544,12 @@ impl Application for App {
|
||||||
|
|
||||||
return Task::batch(commands);
|
return Task::batch(commands);
|
||||||
}
|
}
|
||||||
|
Message::Mouse(window_id, _button) => {
|
||||||
|
// Close context menu when clicking outside.
|
||||||
|
if self.core.main_window_id() == Some(window_id) {
|
||||||
|
return self.close_context_menus();
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::NewFolder => {
|
Message::NewFolder => {
|
||||||
if let Some(path) = self.tab.location.path_opt() {
|
if let Some(path) = self.tab.location.path_opt() {
|
||||||
self.dialog_pages.push_back(DialogPage::NewFolder {
|
self.dialog_pages.push_back(DialogPage::NewFolder {
|
||||||
|
|
@ -1686,14 +1707,18 @@ impl Application for App {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
Message::SearchActivate => {
|
Message::SearchActivate => {
|
||||||
return if self.search_get().is_none() {
|
let mut tasks = vec![self.close_context_menus()];
|
||||||
self.search_set(Some(String::new()))
|
|
||||||
|
if self.search_get().is_none() {
|
||||||
|
tasks.push(self.search_set(Some(String::new())));
|
||||||
} else {
|
} else {
|
||||||
widget::text_input::focus(self.search_id.clone())
|
tasks.push(widget::text_input::focus(self.search_id.clone()));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
return Task::batch(tasks);
|
||||||
}
|
}
|
||||||
Message::SearchClear => {
|
Message::SearchClear => {
|
||||||
return self.search_set(None);
|
return Task::batch([self.close_context_menus(), self.search_set(None)]);
|
||||||
}
|
}
|
||||||
Message::SearchInput(input) => {
|
Message::SearchInput(input) => {
|
||||||
return self.search_set(Some(input));
|
return self.search_set(Some(input));
|
||||||
|
|
@ -1974,7 +1999,11 @@ impl Application for App {
|
||||||
struct WatcherSubscription;
|
struct WatcherSubscription;
|
||||||
struct TimeSubscription;
|
struct TimeSubscription;
|
||||||
let mut subscriptions = vec![
|
let mut subscriptions = vec![
|
||||||
event::listen_with(|event, status, _window_id| match event {
|
event::listen_with(|event, status, window_id| match event {
|
||||||
|
Event::Mouse(mouse::Event::ButtonPressed(button)) => match status {
|
||||||
|
event::Status::Ignored => Some(Message::Mouse(window_id, button)),
|
||||||
|
event::Status::Captured => None,
|
||||||
|
},
|
||||||
Event::Keyboard(KeyEvent::KeyPressed {
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
key,
|
key,
|
||||||
modifiers,
|
modifiers,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue