From c8e5d986f2fd75b8fa1c3d5a80d7e1b0e2882083 Mon Sep 17 00:00:00 2001 From: Ashley Wulber <48420062+wash2@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:01:03 -0400 Subject: [PATCH] Fix context menu position (#1136) * chore: update libcosmic * fix(context menu): compensate for scroll virtual offset, and use window position --- Cargo.lock | 36 +++++++++++++------------- src/mouse_area.rs | 19 ++++++++++++-- src/tab.rs | 64 +++++++++++++++++++++++++++-------------------- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83d3637..4411125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1473,7 +1473,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1495,7 +1495,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "quote", "syn 2.0.104", @@ -1617,7 +1617,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#f4f4fb39fb000bf8458404fe1629fb07cfd07235" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#19f10525ff00d76558147ea060bd856a87122353" dependencies = [ "cosmic-config", "ron", @@ -1639,7 +1639,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.14.2" -source = "git+https://github.com/pop-os/cosmic-text.git#7646989d6f5b0d2bfe32a123e10fe13693d7c89c" +source = "git+https://github.com/pop-os/cosmic-text.git#f7033bb0433f6a9ba109007027781ba46ea9ba27" dependencies = [ "bitflags 2.9.1", "fontdb 0.23.0", @@ -1661,7 +1661,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "almost", "cosmic-config", @@ -3136,7 +3136,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.56.0", + "windows-core 0.61.2", ] [[package]] @@ -3151,7 +3151,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "dnd", "iced_accessibility", @@ -3169,7 +3169,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "accesskit", "accesskit_winit", @@ -3178,7 +3178,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "bitflags 2.9.1", "bytes", @@ -3202,7 +3202,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "futures", "iced_core", @@ -3228,7 +3228,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "bitflags 2.9.1", "bytemuck", @@ -3250,7 +3250,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3277,7 +3277,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "bytemuck", "cosmic-text", @@ -3293,7 +3293,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "as-raw-xcb-connection", "bitflags 2.9.1", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3343,7 +3343,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -4483,7 +4483,7 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#05874e8ea252be0e6115c268aef18a19019842f4" +source = "git+https://github.com/pop-os/libcosmic.git#6a5076ecb7dc51fc3d255e8cc865acfc9a7b9343" dependencies = [ "apply", "ashpd", diff --git a/src/mouse_area.rs b/src/mouse_area.rs index ff16a3b..bd171cd 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -111,6 +111,16 @@ impl<'a, Message> MouseArea<'a, Message> { self } + /// Only on wayland, on_right_press will provide window position instead of widget relative + #[must_use] + pub fn wayland_on_right_press_window_position(mut self) -> Self { + #[cfg(feature = "wayland")] + { + self.on_right_press_window_position = true; + } + self + } + /// on_right_press will provide window position instead of widget relative #[must_use] pub fn on_right_press_window_position(mut self) -> Self { @@ -513,7 +523,8 @@ fn update( state: &mut State, viewport: &Rectangle, ) -> event::Status { - let layout_bounds = layout.bounds(); + let offset = layout.virtual_offset(); + let mut layout_bounds = layout.bounds(); if let Some(message) = widget.on_resize.as_ref() { if state.viewport != Some(*viewport) { @@ -644,7 +655,11 @@ fn update( if let Some(message) = widget.on_right_press.as_ref() { if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) = event { let point_opt = if widget.on_right_press_window_position { - cursor.position_over(layout_bounds) + cursor.position_over(layout_bounds).map(|mut p| { + p.x -= offset.x; + p.y -= offset.y; + p + }) } else { cursor.position_in(layout_bounds) }; diff --git a/src/tab.rs b/src/tab.rs index 4f3f865..3e91b7e 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1552,7 +1552,7 @@ pub enum Message { ContextAction(Action), ContextMenu(Option, Option), LocationContextMenuPoint(Option), - LocationContextMenuIndex(Option), + LocationContextMenuIndex(Option, Option), LocationMenuAction(LocationMenuAction), Drag(Option), DragEnd, @@ -1579,7 +1579,7 @@ pub enum Message { ModifiersChanged(Modifiers), Open(Option), Reload, - RightClick(Option), + RightClick(Option, Option), MiddleClick(usize), Resize(Rectangle), Scroll(Viewport), @@ -3165,9 +3165,12 @@ impl Tab { } } Message::LocationContextMenuPoint(point_opt) => { + self.context_menu = point_opt; self.location_context_menu_point = point_opt; } - Message::LocationContextMenuIndex(index_opt) => { + Message::LocationContextMenuIndex(p, index_opt) => { + self.context_menu = p; + self.location_context_menu_point = p; self.location_context_menu_index = index_opt; } Message::LocationMenuAction(action) => { @@ -3588,7 +3591,7 @@ impl Tab { Some(selected_paths), )); } - Message::RightClick(click_i_opt) => { + Message::RightClick(p, click_i_opt) => { if mod_ctrl || mod_shift { self.update(Message::Click(click_i_opt), modifiers); } @@ -3993,16 +3996,7 @@ impl Tab { commands.push(Command::ContextMenu(None, self.window_id.clone())); } if let Some(point) = self.context_menu { - commands.push(Command::ContextMenu( - Some( - point - + self - .viewport_opt - .map(|v| Vector::new(v.x, v.y)) - .unwrap_or_default(), - ), - self.window_id.clone(), - )); + commands.push(Command::ContextMenu(Some(point), self.window_id.clone())); } } @@ -4566,13 +4560,18 @@ impl Tab { ); if self.location_context_menu_index.is_some() { - mouse_area = mouse_area.on_right_press(move |_point_opt| { - Message::LocationContextMenuIndex(None) - }) + mouse_area = mouse_area + .on_right_press(move |point_opt| { + Message::LocationContextMenuIndex(point_opt, None) + }) + .wayland_on_right_press_window_position() } else { - mouse_area = mouse_area.on_right_press_no_capture().on_right_press( - move |_point_opt| Message::LocationContextMenuIndex(Some(index)), - ) + mouse_area = mouse_area + .on_right_press_no_capture() + .on_right_press(move |point_opt| { + Message::LocationContextMenuIndex(point_opt, Some(index)) + }) + .wayland_on_right_press_window_position() } let mouse_area = if let Location::Path(_) = &self.location { @@ -4636,7 +4635,8 @@ impl Tab { } let mouse_area = crate::mouse_area::MouseArea::new(column) - .on_right_press(Message::LocationContextMenuPoint); + .on_right_press(Message::LocationContextMenuPoint) + .wayland_on_right_press_window_position(); let mut popover = widget::popover(mouse_area); if let (Some(point), Some(index)) = ( @@ -4831,7 +4831,10 @@ impl Tab { column = column.push( mouse_area::MouseArea::new(button) .on_right_press_no_capture() - .on_right_press(move |_point_opt| Message::RightClick(Some(i))), + .wayland_on_right_press_window_position() + .on_right_press(move |point_opt| { + Message::RightClick(point_opt, Some(i)) + }), ); } } @@ -5250,7 +5253,10 @@ impl Tab { } else { mouse_area .on_right_press_no_capture() - .on_right_press(move |_point_opt| Message::RightClick(Some(i))) + .wayland_on_right_press_window_position() + .on_right_press(move |point_opt| { + Message::RightClick(point_opt, Some(i)) + }) } }; @@ -5471,12 +5477,16 @@ impl Tab { .on_scroll(|delta| respond_to_scroll_direction(delta, self.modifiers)); if self.context_menu.is_some() { - mouse_area = mouse_area.on_right_press(move |_point_opt| { - Message::ContextMenu(None, self.window_id.clone()) - }); + mouse_area = mouse_area + .on_right_press(move |point_opt| { + Message::ContextMenu(point_opt, self.window_id.clone()) + }) + .wayland_on_right_press_window_position(); } else { let window_id = self.window_id.clone(); - mouse_area = mouse_area.on_right_press(move |p| Message::ContextMenu(p, window_id)); + mouse_area = mouse_area + .on_right_press(move |p| Message::ContextMenu(p, window_id)) + .wayland_on_right_press_window_position(); } let mut popover = widget::popover(mouse_area);