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