Skip to content

Commit 83bdc4d

Browse files
authored
Merge pull request #1389 from pop-os/subwindow-modifiers
Track and use modifiers per sub-window, fixes #1152
2 parents b5ee054 + fc79b0e commit 83bdc4d

File tree

1 file changed

+89
-66
lines changed

1 file changed

+89
-66
lines changed

src/app.rs

Lines changed: 89 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,20 @@ impl PartialEq for WatcherWrapper {
661661
}
662662
}
663663

664+
struct Window {
665+
kind: WindowKind,
666+
modifiers: Modifiers,
667+
}
668+
669+
impl Window {
670+
fn new(kind: WindowKind) -> Self {
671+
Self {
672+
kind,
673+
modifiers: Modifiers::empty(),
674+
}
675+
}
676+
}
677+
664678
// The [`App`] stores application-specific state.
665679
pub struct App {
666680
core: Core,
@@ -709,7 +723,7 @@ pub struct App {
709723
Debouncer<RecommendedWatcher, RecommendedCache>,
710724
FxHashSet<PathBuf>,
711725
)>,
712-
windows: FxHashMap<window::Id, WindowKind>,
726+
windows: FxHashMap<window::Id, Window>,
713727
nav_dnd_hover: Option<(Location, Instant)>,
714728
tab_dnd_hover: Option<(Entity, Instant)>,
715729
nav_drag_id: DragId,
@@ -935,9 +949,9 @@ impl App {
935949
dialog.set_accept_label(fl!("extract-here"));
936950
self.windows.insert(
937951
dialog.window_id(),
938-
WindowKind::FileDialog(Some(
952+
Window::new(WindowKind::FileDialog(Some(
939953
paths.iter().map(|x| x.as_ref().to_path_buf()).collect(),
940-
)),
954+
))),
941955
);
942956
self.file_dialog_opt = Some(dialog);
943957
Task::batch([set_title_task, dialog_task])
@@ -1178,8 +1192,8 @@ impl App {
11781192
}
11791193

11801194
fn remove_window(&mut self, id: &window::Id) {
1181-
if let Some(window_kind) = self.windows.remove(id) {
1182-
match window_kind {
1195+
if let Some(window) = self.windows.remove(id) {
1196+
match window.kind {
11831197
WindowKind::ContextMenu(entity, _) => {
11841198
// Close context menu
11851199
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
@@ -2704,7 +2718,8 @@ impl Application for App {
27042718
}
27052719

27062720
let (id, command) = window::open(settings);
2707-
self.windows.insert(id, WindowKind::DesktopViewOptions);
2721+
self.windows
2722+
.insert(id, Window::new(WindowKind::DesktopViewOptions));
27082723
return command.map(|_id| cosmic::action::none());
27092724
}
27102725
Message::DesktopDialogs(show) => {
@@ -2732,14 +2747,14 @@ impl Application for App {
27322747

27332748
let (id, command) = window::open(settings);
27342749
self.windows
2735-
.insert(id, WindowKind::Dialogs(widget::Id::unique()));
2750+
.insert(id, Window::new(WindowKind::Dialogs(widget::Id::unique())));
27362751
return command.map(|_id| cosmic::Action::None);
27372752
}
27382753

27392754
let tasks = self
27402755
.windows
27412756
.iter()
2742-
.filter(|(_, kind)| matches!(*kind, WindowKind::Dialogs(_)))
2757+
.filter(|(_, window)| matches!(window.kind, WindowKind::Dialogs(_)))
27432758
.map(|(id, _)| window::close(*id));
27442759
return Task::batch(tasks);
27452760
}
@@ -2929,9 +2944,10 @@ impl Application for App {
29292944
DialogResult::Open(selected_paths) => {
29302945
let mut archive_paths = None;
29312946
if let Some(file_dialog) = &self.file_dialog_opt {
2932-
let window = self.windows.remove(&file_dialog.window_id());
2933-
if let Some(WindowKind::FileDialog(paths)) = window {
2934-
archive_paths = paths;
2947+
if let Some(window) = self.windows.remove(&file_dialog.window_id()) {
2948+
if let WindowKind::FileDialog(paths) = window.kind {
2949+
archive_paths = paths;
2950+
}
29352951
}
29362952
}
29372953
if let Some(archive_paths) = archive_paths {
@@ -3021,6 +3037,9 @@ impl Application for App {
30213037
if self.core.main_window_id() == Some(window_id) || in_surface_ids {
30223038
self.modifiers = modifiers;
30233039
}
3040+
if let Some(window) = self.windows.get_mut(&window_id) {
3041+
window.modifiers = modifiers;
3042+
}
30243043
}
30253044
Message::MounterItems(mounter_key, mounter_items) => {
30263045
// Check for unmounted folders
@@ -3612,10 +3631,10 @@ impl Application for App {
36123631
let (id, command) = window::open(settings);
36133632
self.windows.insert(
36143633
id,
3615-
WindowKind::Preview(
3634+
Window::new(WindowKind::Preview(
36163635
entity_opt,
36173636
PreviewKind::Location(Location::Path(path)),
3618-
),
3637+
)),
36193638
);
36203639
commands.push(command.map(|_id| cosmic::action::none()));
36213640
}
@@ -3912,7 +3931,10 @@ impl Application for App {
39123931
let window_id = WindowId::unique();
39133932
self.windows.insert(
39143933
window_id,
3915-
WindowKind::ContextMenu(entity, widget::Id::unique()),
3934+
Window::new(WindowKind::ContextMenu(
3935+
entity,
3936+
widget::Id::unique(),
3937+
)),
39163938
);
39173939
commands.push(self.update(Message::Surface(
39183940
cosmic::surface::action::app_popup(
@@ -3952,8 +3974,8 @@ impl Application for App {
39523974
} else {
39533975
// Destroy previous popup
39543976
let mut window_ids = Vec::new();
3955-
for (window_id, window_kind) in &self.windows {
3956-
if let WindowKind::ContextMenu(e, _) = window_kind {
3977+
for (window_id, window) in &self.windows {
3978+
if let WindowKind::ContextMenu(e, _) = &window.kind {
39573979
if *e == entity {
39583980
window_ids.push(*window_id);
39593981
}
@@ -4565,7 +4587,8 @@ impl Application for App {
45654587
widget::Id::unique(),
45664588
Some(surface_id),
45674589
);
4568-
self.windows.insert(surface_id, WindowKind::Desktop(entity));
4590+
self.windows
4591+
.insert(surface_id, Window::new(WindowKind::Desktop(entity)));
45694592
return Task::batch([
45704593
command,
45714594
get_layer_surface(SctkLayerSurfaceSettings {
@@ -4666,7 +4689,7 @@ impl Application for App {
46664689
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
46674690
Message::Focused(id) => {
46684691
if let Some(w) = self.windows.get(&id) {
4669-
match w {
4692+
match &w.kind {
46704693
WindowKind::Desktop(entity) => self.tab_model.activate(*entity),
46714694
_ => {}
46724695
};
@@ -5696,66 +5719,66 @@ impl Application for App {
56965719

56975720
fn view_window(&self, id: WindowId) -> Element<'_, Self::Message> {
56985721
let content = match self.windows.get(&id) {
5699-
Some(WindowKind::ContextMenu(entity, id)) => {
5700-
match self.tab_model.data::<Tab>(*entity) {
5722+
Some(window) => match &window.kind {
5723+
WindowKind::ContextMenu(entity, id) => match self.tab_model.data::<Tab>(*entity) {
57015724
Some(tab) => {
57025725
return widget::autosize::autosize(
5703-
menu::context_menu(tab, &self.key_binds, &self.modifiers)
5726+
menu::context_menu(tab, &self.key_binds, &window.modifiers)
57045727
.map(|x| Message::TabMessage(Some(*entity), x)),
57055728
id.clone(),
57065729
)
57075730
.into();
57085731
}
57095732
None => widget::text("Unknown tab ID").into(),
5710-
}
5711-
}
5712-
Some(WindowKind::Desktop(entity)) => {
5713-
let mut tab_column = widget::column::with_capacity(3);
5733+
},
5734+
WindowKind::Desktop(entity) => {
5735+
let mut tab_column = widget::column::with_capacity(3);
57145736

5715-
let tab_view = match self.tab_model.data::<Tab>(*entity) {
5716-
Some(tab) => tab
5717-
.view(&self.key_binds, &self.modifiers)
5718-
.map(move |message| Message::TabMessage(Some(*entity), message)),
5719-
None => widget::vertical_space().into(),
5720-
};
5737+
let tab_view = match self.tab_model.data::<Tab>(*entity) {
5738+
Some(tab) => tab
5739+
.view(&self.key_binds, &window.modifiers)
5740+
.map(move |message| Message::TabMessage(Some(*entity), message)),
5741+
None => widget::vertical_space().into(),
5742+
};
57215743

5722-
tab_column = tab_column.push(tab_view);
5723-
5724-
// The toaster is added on top of an empty element to ensure that it does not override context menus
5725-
tab_column =
5726-
tab_column.push(widget::toaster(&self.toasts, widget::horizontal_space()));
5727-
return if let Some(margin) = self.margin.get(&id) {
5728-
if margin.0 >= 0. || margin.2 >= 0. {
5729-
tab_column = widget::column::with_children([
5730-
vertical_space().height(margin.0).into(),
5731-
tab_column.into(),
5732-
vertical_space().height(margin.2).into(),
5733-
]);
5734-
}
5735-
if margin.1 >= 0. || margin.3 >= 0. {
5736-
Element::from(widget::row::with_children([
5737-
horizontal_space().width(margin.1).into(),
5738-
tab_column.into(),
5739-
horizontal_space().width(margin.3).into(),
5740-
]))
5744+
tab_column = tab_column.push(tab_view);
5745+
5746+
// The toaster is added on top of an empty element to ensure that it does not override context menus
5747+
tab_column =
5748+
tab_column.push(widget::toaster(&self.toasts, widget::horizontal_space()));
5749+
return if let Some(margin) = self.margin.get(&id) {
5750+
if margin.0 >= 0. || margin.2 >= 0. {
5751+
tab_column = widget::column::with_children([
5752+
vertical_space().height(margin.0).into(),
5753+
tab_column.into(),
5754+
vertical_space().height(margin.2).into(),
5755+
]);
5756+
}
5757+
if margin.1 >= 0. || margin.3 >= 0. {
5758+
Element::from(widget::row::with_children([
5759+
horizontal_space().width(margin.1).into(),
5760+
tab_column.into(),
5761+
horizontal_space().width(margin.3).into(),
5762+
]))
5763+
} else {
5764+
tab_column.into()
5765+
}
57415766
} else {
57425767
tab_column.into()
5743-
}
5744-
} else {
5745-
tab_column.into()
5746-
};
5747-
}
5748-
Some(WindowKind::DesktopViewOptions) => self.desktop_view_options(),
5749-
Some(WindowKind::Dialogs(id)) => match self.dialog() {
5750-
Some(element) => return widget::autosize::autosize(element, id.clone()).into(),
5751-
None => widget::horizontal_space().into(),
5752-
},
5753-
Some(WindowKind::Preview(entity_opt, kind)) => self
5754-
.preview(entity_opt, kind, false)
5755-
.map(|x| Message::TabMessage(*entity_opt, x)),
5756-
Some(WindowKind::FileDialog(..)) => match &self.file_dialog_opt {
5757-
Some(dialog) => return dialog.view(id),
5758-
None => widget::text("Unknown window ID").into(),
5768+
};
5769+
}
5770+
WindowKind::DesktopViewOptions => self.desktop_view_options(),
5771+
WindowKind::Dialogs(id) => match self.dialog() {
5772+
Some(element) => return widget::autosize::autosize(element, id.clone()).into(),
5773+
None => widget::horizontal_space().into(),
5774+
},
5775+
WindowKind::Preview(entity_opt, kind) => self
5776+
.preview(entity_opt, kind, false)
5777+
.map(|x| Message::TabMessage(*entity_opt, x)),
5778+
WindowKind::FileDialog(..) => match &self.file_dialog_opt {
5779+
Some(dialog) => return dialog.view(id),
5780+
None => widget::text("Unknown window ID").into(),
5781+
},
57595782
},
57605783
None => {
57615784
//TODO: distinct views per monitor in desktop mode

0 commit comments

Comments
 (0)