Filter window events by window id, fixes #1118
This commit is contained in:
parent
30a0836018
commit
5e0645d1c2
1 changed files with 78 additions and 79 deletions
157
src/app.rs
157
src/app.rs
|
|
@ -325,10 +325,10 @@ pub enum Message {
|
|||
ExtractToResult(DialogResult),
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Focused(window::Id),
|
||||
Key(Modifiers, Key, Option<SmolStr>),
|
||||
Key(window::Id, Modifiers, Key, Option<SmolStr>),
|
||||
LaunchUrl(String),
|
||||
MaybeExit,
|
||||
ModifiersChanged(Modifiers),
|
||||
ModifiersChanged(window::Id, Modifiers),
|
||||
MounterItems(MounterKey, MounterItems),
|
||||
MountResult(MounterKey, MounterItem, Result<bool, String>),
|
||||
NavBarClose(Entity),
|
||||
|
|
@ -357,7 +357,7 @@ pub enum Message {
|
|||
OpenWithDialog(Option<Entity>),
|
||||
OpenWithSelection(usize),
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Overlap(OverlapNotifyEvent, window::Id),
|
||||
Overlap(window::Id, OverlapNotifyEvent),
|
||||
Paste(Option<Entity>),
|
||||
PasteContents(PathBuf, ClipboardPaste),
|
||||
PendingCancel(u64),
|
||||
|
|
@ -383,7 +383,7 @@ pub enum Message {
|
|||
SetShowDetails(bool),
|
||||
SetTypeToSearch(TypeToSearch),
|
||||
SystemThemeModeChange,
|
||||
Size(Size),
|
||||
Size(window::Id, Size),
|
||||
TabActivate(Entity),
|
||||
TabNext,
|
||||
TabPrev,
|
||||
|
|
@ -410,7 +410,6 @@ pub enum Message {
|
|||
WindowCloseRequested(window::Id),
|
||||
WindowMaximize(window::Id, bool),
|
||||
WindowNew,
|
||||
WindowUnfocus,
|
||||
ZoomDefault(Option<Entity>),
|
||||
ZoomIn(Option<Entity>),
|
||||
ZoomOut(Option<Entity>),
|
||||
|
|
@ -673,7 +672,6 @@ pub struct App {
|
|||
surface_names: HashMap<WindowId, String>,
|
||||
toasts: widget::toaster::Toasts<Message>,
|
||||
watcher_opt: Option<(Debouncer<RecommendedWatcher, FileIdMap>, HashSet<PathBuf>)>,
|
||||
pub(crate) window_id_opt: Option<window::Id>,
|
||||
windows: HashMap<window::Id, WindowKind>,
|
||||
nav_dnd_hover: Option<(Location, Instant)>,
|
||||
tab_dnd_hover: Option<(Entity, Instant)>,
|
||||
|
|
@ -1553,8 +1551,8 @@ impl App {
|
|||
Some(tab_title) => format!("{tab_title} — {}", fl!("cosmic-files")),
|
||||
None => fl!("cosmic-files"),
|
||||
};
|
||||
if let Some(window_id) = &self.window_id_opt {
|
||||
self.set_window_title(window_title, *window_id)
|
||||
if let Some(window_id) = self.core.main_window_id() {
|
||||
self.set_window_title(window_title, window_id)
|
||||
} else {
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -2099,8 +2097,6 @@ impl Application for App {
|
|||
Mode::Desktop => tab::Mode::Desktop,
|
||||
});
|
||||
|
||||
let window_id_opt = core.main_window_id();
|
||||
|
||||
// Create a dedicated thread for the compio runtime to handle operations on.
|
||||
// Supports io_uring on Linux, IOPC on Windows, and polling everywhere else.
|
||||
let (compio_tx, mut compio_rx) = mpsc::channel(1);
|
||||
|
|
@ -2156,7 +2152,6 @@ impl Application for App {
|
|||
surface_names: HashMap::new(),
|
||||
toasts: widget::toaster::Toasts::new(Message::CloseToast),
|
||||
watcher_opt: None,
|
||||
window_id_opt,
|
||||
windows: HashMap::new(),
|
||||
nav_dnd_hover: None,
|
||||
tab_dnd_hover: None,
|
||||
|
|
@ -2207,7 +2202,7 @@ impl Application for App {
|
|||
}
|
||||
|
||||
fn nav_bar(&self) -> Option<Element<cosmic::Action<Self::Message>>> {
|
||||
if !self.core().nav_bar_active() {
|
||||
if !self.core.nav_bar_active() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
@ -2235,7 +2230,7 @@ impl Application for App {
|
|||
)
|
||||
.into_container();
|
||||
|
||||
if !self.core().is_condensed() {
|
||||
if !self.core.is_condensed() {
|
||||
nav = nav.max_width(280);
|
||||
}
|
||||
|
||||
|
|
@ -2942,40 +2937,46 @@ impl Application for App {
|
|||
return dialog.update(dialog_message);
|
||||
}
|
||||
}
|
||||
Message::Key(modifiers, key, text) => {
|
||||
let entity = self.tab_model.active();
|
||||
for (key_bind, action) in self.key_binds.iter() {
|
||||
if key_bind.matches(modifiers, &key) {
|
||||
return self.update(action.message(Some(entity)));
|
||||
Message::Key(window_id, modifiers, key, text) => {
|
||||
if self.core.main_window_id() == Some(window_id) {
|
||||
let entity = self.tab_model.active();
|
||||
for (key_bind, action) in self.key_binds.iter() {
|
||||
if key_bind.matches(modifiers, &key) {
|
||||
return self.update(action.message(Some(entity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Uncaptured keys with only shift modifiers go to the search or location box
|
||||
if !modifiers.logo()
|
||||
&& !modifiers.control()
|
||||
&& !modifiers.alt()
|
||||
&& matches!(key, Key::Character(_))
|
||||
{
|
||||
if let Some(text) = text {
|
||||
match self.config.type_to_search {
|
||||
TypeToSearch::Recursive => {
|
||||
let mut term = self.search_get().unwrap_or_default().to_string();
|
||||
term.push_str(&text);
|
||||
return self.search_set_active(Some(term));
|
||||
}
|
||||
TypeToSearch::EnterPath => {
|
||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||
let location = tab.edit_location.as_ref().map_or_else(
|
||||
|| tab.location.clone(),
|
||||
|x| x.location.clone(),
|
||||
);
|
||||
// Try to add text to end of location
|
||||
if let Some(path) = location.path_opt() {
|
||||
let mut path_string = path.to_string_lossy().to_string();
|
||||
path_string.push_str(&text);
|
||||
tab.edit_location = Some(
|
||||
location.with_path(PathBuf::from(path_string)).into(),
|
||||
// Uncaptured keys with only shift modifiers go to the search or location box
|
||||
if !modifiers.logo()
|
||||
&& !modifiers.control()
|
||||
&& !modifiers.alt()
|
||||
&& matches!(key, Key::Character(_))
|
||||
{
|
||||
if let Some(text) = text {
|
||||
match self.config.type_to_search {
|
||||
TypeToSearch::Recursive => {
|
||||
let mut term =
|
||||
self.search_get().unwrap_or_default().to_string();
|
||||
term.push_str(&text);
|
||||
return self.search_set_active(Some(term));
|
||||
}
|
||||
TypeToSearch::EnterPath => {
|
||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||
let location = tab.edit_location.as_ref().map_or_else(
|
||||
|| tab.location.clone(),
|
||||
|x| x.location.clone(),
|
||||
);
|
||||
// Try to add text to end of location
|
||||
if let Some(path) = location.path_opt() {
|
||||
let mut path_string =
|
||||
path.to_string_lossy().to_string();
|
||||
path_string.push_str(&text);
|
||||
tab.edit_location = Some(
|
||||
location
|
||||
.with_path(PathBuf::from(path_string))
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2984,7 +2985,7 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
Message::MaybeExit => {
|
||||
if self.window_id_opt.is_none() && self.pending_operations.is_empty() {
|
||||
if self.core.main_window_id().is_none() && self.pending_operations.is_empty() {
|
||||
// Exit if window is closed and there are no pending operations
|
||||
process::exit(0);
|
||||
}
|
||||
|
|
@ -2995,13 +2996,15 @@ impl Application for App {
|
|||
log::warn!("failed to open {:?}: {}", url, err);
|
||||
}
|
||||
},
|
||||
Message::ModifiersChanged(modifiers) => {
|
||||
self.modifiers = modifiers;
|
||||
let entity = self.tab_model.active();
|
||||
return self.update(Message::TabMessage(
|
||||
Some(entity),
|
||||
tab::Message::ModifiersChanged(modifiers),
|
||||
));
|
||||
Message::ModifiersChanged(window_id, modifiers) => {
|
||||
if self.core.main_window_id() == Some(window_id) {
|
||||
self.modifiers = modifiers;
|
||||
let entity = self.tab_model.active();
|
||||
return self.update(Message::TabMessage(
|
||||
Some(entity),
|
||||
tab::Message::ModifiersChanged(modifiers),
|
||||
));
|
||||
}
|
||||
}
|
||||
Message::MounterItems(mounter_key, mounter_items) => {
|
||||
// Check for unmounted folders
|
||||
|
|
@ -3802,8 +3805,8 @@ impl Application for App {
|
|||
|
||||
// If that was the last tab, close window
|
||||
if self.tab_model.iter().next().is_none() {
|
||||
if let Some(window_id) = &self.window_id_opt {
|
||||
return window::close(*window_id);
|
||||
if let Some(window_id) = self.core.main_window_id() {
|
||||
return window::close(window_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3914,7 +3917,8 @@ impl Application for App {
|
|||
};
|
||||
SctkPopupSettings {
|
||||
parent: parent_id.unwrap_or(
|
||||
app.window_id_opt
|
||||
app.core
|
||||
.main_window_id()
|
||||
.unwrap_or_else(|| WindowId::NONE),
|
||||
),
|
||||
id: window_id,
|
||||
|
|
@ -4002,13 +4006,13 @@ impl Application for App {
|
|||
commands.push(self.operation(Operation::SetPermissions { path, mode }));
|
||||
}
|
||||
tab::Command::WindowDrag => {
|
||||
if let Some(window_id) = &self.window_id_opt {
|
||||
commands.push(window::drag(*window_id));
|
||||
if let Some(window_id) = self.core.main_window_id() {
|
||||
commands.push(window::drag(window_id));
|
||||
}
|
||||
}
|
||||
tab::Command::WindowToggleMaximize => {
|
||||
if let Some(window_id) = &self.window_id_opt {
|
||||
commands.push(window::toggle_maximize(*window_id));
|
||||
if let Some(window_id) = self.core.main_window_id() {
|
||||
commands.push(window::toggle_maximize(window_id));
|
||||
}
|
||||
}
|
||||
tab::Command::SetSort(location, heading_options, direction) => {
|
||||
|
|
@ -4168,7 +4172,8 @@ impl Application for App {
|
|||
return self.operation(Operation::Restore { items });
|
||||
}
|
||||
Message::WindowClose => {
|
||||
if let Some(window_id) = self.window_id_opt.take() {
|
||||
if let Some(window_id) = self.core.main_window_id() {
|
||||
self.core.set_main_window_id(None);
|
||||
return Task::batch([
|
||||
window::close(window_id),
|
||||
Task::perform(
|
||||
|
|
@ -4178,14 +4183,6 @@ impl Application for App {
|
|||
]);
|
||||
}
|
||||
}
|
||||
Message::WindowUnfocus => {
|
||||
/*TODO
|
||||
let tab_entity = self.tab_model.active();
|
||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(tab_entity) {
|
||||
tab.context_menu = None;
|
||||
}
|
||||
*/
|
||||
}
|
||||
Message::WindowCloseRequested(id) => {
|
||||
self.remove_window(&id);
|
||||
}
|
||||
|
|
@ -4621,7 +4618,7 @@ impl Application for App {
|
|||
}
|
||||
Message::None => {}
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Message::Overlap(overlap_notify_event, w_id) => match overlap_notify_event {
|
||||
Message::Overlap(w_id, overlap_notify_event) => match overlap_notify_event {
|
||||
OverlapNotifyEvent::OverlapLayerAdd {
|
||||
identifier,
|
||||
namespace,
|
||||
|
|
@ -4640,9 +4637,11 @@ impl Application for App {
|
|||
}
|
||||
_ => {}
|
||||
},
|
||||
Message::Size(size) => {
|
||||
self.size = Some(size);
|
||||
self.handle_overlap();
|
||||
Message::Size(window_id, size) => {
|
||||
if self.core.main_window_id() == Some(window_id) {
|
||||
self.size = Some(size);
|
||||
self.handle_overlap();
|
||||
}
|
||||
}
|
||||
Message::Eject => {
|
||||
#[cfg(feature = "gvfs")]
|
||||
|
|
@ -5818,6 +5817,7 @@ impl Application for App {
|
|||
struct RecentsWatcherSubscription;
|
||||
|
||||
let mut subscriptions = vec![
|
||||
//TODO: filter more events by window id
|
||||
event::listen_with(|event, status, window_id| match event {
|
||||
Event::Keyboard(KeyEvent::KeyPressed {
|
||||
key,
|
||||
|
|
@ -5825,20 +5825,19 @@ impl Application for App {
|
|||
text,
|
||||
..
|
||||
}) => match status {
|
||||
event::Status::Ignored => Some(Message::Key(modifiers, key, text)),
|
||||
event::Status::Ignored => Some(Message::Key(window_id, modifiers, key, text)),
|
||||
event::Status::Captured => None,
|
||||
},
|
||||
Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => {
|
||||
Some(Message::ModifiersChanged(modifiers))
|
||||
Some(Message::ModifiersChanged(window_id, modifiers))
|
||||
}
|
||||
Event::Window(WindowEvent::Unfocused) => Some(Message::WindowUnfocus),
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Event::Window(WindowEvent::Focused) => Some(Message::Focused(window_id)),
|
||||
Event::Window(WindowEvent::CloseRequested) => Some(Message::WindowClose),
|
||||
Event::Window(WindowEvent::Opened { position: _, size }) => {
|
||||
Some(Message::Size(size))
|
||||
Some(Message::Size(window_id, size))
|
||||
}
|
||||
Event::Window(WindowEvent::Resized(s)) => Some(Message::Size(s)),
|
||||
Event::Window(WindowEvent::Resized(s)) => Some(Message::Size(window_id, s)),
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Event::PlatformSpecific(event::PlatformSpecific::Wayland(wayland_event)) => {
|
||||
match wayland_event {
|
||||
|
|
@ -5847,7 +5846,7 @@ impl Application for App {
|
|||
}
|
||||
#[cfg(feature = "desktop")]
|
||||
WaylandEvent::OverlapNotify(event) => {
|
||||
Some(Message::Overlap(event, window_id))
|
||||
Some(Message::Overlap(window_id, event))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -6125,7 +6124,7 @@ impl Application for App {
|
|||
if !self.pending_operations.is_empty() {
|
||||
//TODO: inhibit suspend/shutdown?
|
||||
|
||||
if self.window_id_opt.is_some() {
|
||||
if self.core.main_window_id().is_some() {
|
||||
// Force refresh the UI every 100ms while an operation is active.
|
||||
if self
|
||||
.pending_operations
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue