feat: avoid overlap with panel
This commit is contained in:
parent
6f5168ccc4
commit
42c0d58c6c
2 changed files with 149 additions and 29 deletions
45
Cargo.lock
generated
45
Cargo.lock
generated
|
|
@ -1211,18 +1211,19 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-client-toolkit"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?rev=c8d3a1c#c8d3a1c3d40d16235f4720969a54ed570ec7a976"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?rev=d218c76#d218c76b58c7a3b20dd5e7943f93fc306a1b81b8"
|
||||
dependencies = [
|
||||
"cosmic-protocols",
|
||||
"libc",
|
||||
"smithay-client-toolkit",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"atomicwrites",
|
||||
"cosmic-config-derive",
|
||||
|
|
@ -1241,7 +1242,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
@ -1311,7 +1312,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-protocols"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?rev=c8d3a1c#c8d3a1c3d40d16235f4720969a54ed570ec7a976"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?rev=d218c76#d218c76b58c7a3b20dd5e7943f93fc306a1b81b8"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"wayland-backend",
|
||||
|
|
@ -1348,7 +1349,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-theme"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"almost",
|
||||
"cosmic-config",
|
||||
|
|
@ -2766,7 +2767,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"dnd",
|
||||
"iced_accessibility",
|
||||
|
|
@ -2784,7 +2785,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_accessibility"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_winit",
|
||||
|
|
@ -2793,10 +2794,11 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytes",
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
"glam",
|
||||
"log",
|
||||
|
|
@ -2807,7 +2809,6 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"rustc-hash 2.1.0",
|
||||
"serde",
|
||||
"smithay-client-toolkit",
|
||||
"smol_str",
|
||||
"thiserror 1.0.69",
|
||||
"web-time",
|
||||
|
|
@ -2817,7 +2818,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_core",
|
||||
|
|
@ -2843,7 +2844,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_graphics"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytemuck",
|
||||
|
|
@ -2865,7 +2866,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_renderer"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"iced_graphics",
|
||||
"iced_tiny_skia",
|
||||
|
|
@ -2877,14 +2878,14 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_runtime"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
"iced_core",
|
||||
"iced_futures",
|
||||
"raw-window-handle",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror 1.0.69",
|
||||
"window_clipboard",
|
||||
]
|
||||
|
|
@ -2892,7 +2893,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_tiny_skia"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cosmic-text",
|
||||
|
|
@ -2908,11 +2909,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_wgpu"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"as-raw-xcb-connection",
|
||||
"bitflags 2.6.0",
|
||||
"bytemuck",
|
||||
"cosmic-client-toolkit",
|
||||
"futures",
|
||||
"glam",
|
||||
"guillotiere",
|
||||
|
|
@ -2925,7 +2927,6 @@ dependencies = [
|
|||
"resvg",
|
||||
"rustc-hash 2.1.0",
|
||||
"rustix 0.38.41",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror 1.0.69",
|
||||
"tiny-xlib",
|
||||
"wayland-backend",
|
||||
|
|
@ -2939,8 +2940,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_widget"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
"iced_renderer",
|
||||
"iced_runtime",
|
||||
|
|
@ -2948,7 +2950,6 @@ dependencies = [
|
|||
"once_cell",
|
||||
"ouroboros",
|
||||
"rustc-hash 2.1.0",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror 1.0.69",
|
||||
"unicode-segmentation",
|
||||
"window_clipboard",
|
||||
|
|
@ -2957,8 +2958,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_winit"
|
||||
version = "0.14.0-dev"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"cosmic-client-toolkit",
|
||||
"dnd",
|
||||
"iced_futures",
|
||||
"iced_graphics",
|
||||
|
|
@ -2966,7 +2968,6 @@ dependencies = [
|
|||
"log",
|
||||
"raw-window-handle",
|
||||
"rustc-hash 2.1.0",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror 1.0.69",
|
||||
"tracing",
|
||||
"wasm-bindgen-futures",
|
||||
|
|
@ -3542,7 +3543,7 @@ checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
|
|||
[[package]]
|
||||
name = "libcosmic"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#de0c1921f71a2cbd26a653fa2bbf7e5f948a36fc"
|
||||
source = "git+https://github.com/pop-os/libcosmic.git#b524ccb0a46b1ca585db09638c33e39e79829716"
|
||||
dependencies = [
|
||||
"apply",
|
||||
"ashpd 0.9.2",
|
||||
|
|
|
|||
133
src/app.rs
133
src/app.rs
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#[cfg(feature = "wayland")]
|
||||
use cosmic::iced::{
|
||||
event::wayland::{Event as WaylandEvent, OutputEvent},
|
||||
event::wayland::{Event as WaylandEvent, OutputEvent, OverlapNotifyEvent},
|
||||
platform_specific::runtime::wayland::layer_surface::{
|
||||
IcedMargin, IcedOutput, SctkLayerSurfaceSettings,
|
||||
},
|
||||
|
|
@ -12,6 +12,8 @@ use cosmic::iced::{
|
|||
},
|
||||
Limits,
|
||||
};
|
||||
#[cfg(feature = "wayland")]
|
||||
use cosmic::iced_winit::commands::overlap_notify::overlap_notify;
|
||||
use cosmic::{
|
||||
app::{self, context_drawer, message, Core, Task},
|
||||
cosmic_config, cosmic_theme, executor,
|
||||
|
|
@ -22,15 +24,17 @@ use cosmic::{
|
|||
keyboard::{Event as KeyEvent, Key, Modifiers},
|
||||
stream,
|
||||
window::{self, Event as WindowEvent, Id as WindowId},
|
||||
Alignment, Event, Length, Size, Subscription,
|
||||
Alignment, Background, Border, Event, Length, Point, Rectangle, Size, Subscription,
|
||||
},
|
||||
iced_runtime::clipboard,
|
||||
style, theme,
|
||||
widget::{
|
||||
self,
|
||||
dnd_destination::DragId,
|
||||
horizontal_space,
|
||||
menu::{action::MenuAction, key_bind::KeyBind},
|
||||
segmented_button::{self, Entity},
|
||||
vertical_space,
|
||||
},
|
||||
Application, ApplicationExt, Element,
|
||||
};
|
||||
|
|
@ -303,6 +307,8 @@ pub enum Message {
|
|||
OpenWithBrowse,
|
||||
OpenWithDialog(Option<Entity>),
|
||||
OpenWithSelection(usize),
|
||||
#[cfg(all(feature = "desktop", feature = "wayland"))]
|
||||
Overlap(OverlapNotifyEvent, window::Id),
|
||||
Paste(Option<Entity>),
|
||||
PasteContents(PathBuf, ClipboardPaste),
|
||||
PendingCancel(u64),
|
||||
|
|
@ -321,6 +327,7 @@ pub enum Message {
|
|||
SearchClear,
|
||||
SearchInput(String),
|
||||
SystemThemeModeChange(cosmic_theme::ThemeMode),
|
||||
Size(Size),
|
||||
TabActivate(Entity),
|
||||
TabNext,
|
||||
TabPrev,
|
||||
|
|
@ -500,18 +507,21 @@ pub struct App {
|
|||
dialog_pages: VecDeque<DialogPage>,
|
||||
dialog_text_input: widget::Id,
|
||||
key_binds: HashMap<KeyBind, Action>,
|
||||
margin: HashMap<window::Id, (i32, i32, i32, i32)>,
|
||||
modifiers: Modifiers,
|
||||
mounter_items: HashMap<MounterKey, MounterItems>,
|
||||
network_drive_connecting: Option<(MounterKey, String)>,
|
||||
network_drive_input: String,
|
||||
#[cfg(feature = "notify")]
|
||||
notification_opt: Option<Arc<Mutex<notify_rust::NotificationHandle>>>,
|
||||
overlap: HashMap<String, (window::Id, Rectangle)>,
|
||||
pending_operation_id: u64,
|
||||
pending_operations: BTreeMap<u64, (Operation, Controller)>,
|
||||
progress_operations: BTreeSet<u64>,
|
||||
complete_operations: BTreeMap<u64, Operation>,
|
||||
failed_operations: BTreeMap<u64, (Operation, Controller, String)>,
|
||||
search_id: widget::Id,
|
||||
size: Option<Size>,
|
||||
#[cfg(feature = "wayland")]
|
||||
surface_ids: HashMap<WlOutput, WindowId>,
|
||||
#[cfg(feature = "wayland")]
|
||||
|
|
@ -637,6 +647,57 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_overlap(&mut self) {
|
||||
let Some((bl, br, tl, tr)) = self.size.as_ref().map(|s| {
|
||||
(
|
||||
Rectangle::new(
|
||||
Point::new(0., s.height / 2.),
|
||||
Size::new(s.width / 2., s.height / 2.),
|
||||
),
|
||||
Rectangle::new(
|
||||
Point::new(s.width / 2., s.height / 2.),
|
||||
Size::new(s.width / 2., s.height / 2.),
|
||||
),
|
||||
Rectangle::new(Point::new(0., 0.), Size::new(s.width / 2., s.height / 2.)),
|
||||
Rectangle::new(
|
||||
Point::new(s.width / 2., 0.),
|
||||
Size::new(s.width / 2., s.height / 2.),
|
||||
),
|
||||
)
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut overlaps: HashMap<_, _> = self
|
||||
.windows
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|k| (*k, (0, 0, 0, 0)))
|
||||
.collect();
|
||||
for (w_id, overlap) in self.overlap.values() {
|
||||
let tl = tl.intersects(overlap);
|
||||
let tr = tr.intersects(overlap);
|
||||
let bl = bl.intersects(overlap);
|
||||
let br = br.intersects(overlap);
|
||||
let Some((top, left, bottom, right)) = overlaps.get_mut(&w_id) else {
|
||||
continue;
|
||||
};
|
||||
if tl && tr {
|
||||
*top += overlap.height as i32;
|
||||
}
|
||||
if tl && bl {
|
||||
*left += overlap.width as i32;
|
||||
}
|
||||
if bl && br {
|
||||
*bottom += overlap.height as i32;
|
||||
}
|
||||
if tr && br {
|
||||
*right += overlap.width as i32;
|
||||
}
|
||||
}
|
||||
self.margin = overlaps;
|
||||
}
|
||||
|
||||
fn open_tab_entity(
|
||||
&mut self,
|
||||
location: Location,
|
||||
|
|
@ -1450,18 +1511,21 @@ impl Application for App {
|
|||
dialog_pages: VecDeque::new(),
|
||||
dialog_text_input: widget::Id::unique(),
|
||||
key_binds,
|
||||
margin: HashMap::new(),
|
||||
modifiers: Modifiers::empty(),
|
||||
mounter_items: HashMap::new(),
|
||||
network_drive_connecting: None,
|
||||
network_drive_input: String::new(),
|
||||
#[cfg(feature = "notify")]
|
||||
notification_opt: None,
|
||||
overlap: HashMap::new(),
|
||||
pending_operation_id: 0,
|
||||
pending_operations: BTreeMap::new(),
|
||||
progress_operations: BTreeSet::new(),
|
||||
complete_operations: BTreeMap::new(),
|
||||
failed_operations: BTreeMap::new(),
|
||||
search_id: widget::Id::unique(),
|
||||
size: None,
|
||||
#[cfg(feature = "wayland")]
|
||||
surface_ids: HashMap::new(),
|
||||
#[cfg(feature = "wayland")]
|
||||
|
|
@ -3278,6 +3342,8 @@ impl Application for App {
|
|||
exclusive_zone: 0,
|
||||
size_limits: Limits::NONE.min_width(1.0).min_height(1.0),
|
||||
}),
|
||||
#[cfg(feature = "wayland")]
|
||||
overlap_notify(surface_id, true),
|
||||
]);
|
||||
}
|
||||
OutputEvent::Removed => {
|
||||
|
|
@ -3303,6 +3369,30 @@ impl Application for App {
|
|||
return Task::perform(async move { cosmic }, |cosmic| message::cosmic(cosmic));
|
||||
}
|
||||
Message::None => {}
|
||||
#[cfg(all(feature = "desktop", feature = "wayland"))]
|
||||
Message::Overlap(overlap_notify_event, w_id) => match overlap_notify_event {
|
||||
OverlapNotifyEvent::OverlapLayerAdd {
|
||||
identifier,
|
||||
namespace,
|
||||
logical_rect,
|
||||
exclusive,
|
||||
..
|
||||
} => {
|
||||
if exclusive > 0 || namespace == "Dock" || namespace == "Panel" {
|
||||
self.overlap.insert(identifier, (w_id, logical_rect));
|
||||
self.handle_overlap();
|
||||
}
|
||||
}
|
||||
OverlapNotifyEvent::OverlapLayerRemove { identifier } => {
|
||||
self.overlap.remove(&identifier);
|
||||
self.handle_overlap();
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Message::Size(size) => {
|
||||
self.size = Some(size);
|
||||
self.handle_overlap();
|
||||
}
|
||||
}
|
||||
|
||||
Task::none()
|
||||
|
|
@ -3720,8 +3810,11 @@ impl Application for App {
|
|||
widget::row::with_children(vec![
|
||||
widget::icon(app.icon.clone()).size(32).into(),
|
||||
if app.is_default {
|
||||
widget::text::body(fl!("default-app", name = app.name.as_str()))
|
||||
.into()
|
||||
widget::text::body(fl!(
|
||||
"default-app",
|
||||
name = Some(app.name.as_str())
|
||||
))
|
||||
.into()
|
||||
} else {
|
||||
widget::text::body(app.name.to_string()).into()
|
||||
},
|
||||
|
|
@ -4165,8 +4258,26 @@ impl Application for App {
|
|||
// The toaster is added on top of an empty element to ensure that it does not override context menus
|
||||
tab_column =
|
||||
tab_column.push(widget::toaster(&self.toasts, widget::horizontal_space()));
|
||||
|
||||
return tab_column.into();
|
||||
return if let Some(margin) = self.margin.get(&id) {
|
||||
if margin.0 != 0 || margin.2 != 0 {
|
||||
tab_column = widget::column::with_children(vec![
|
||||
vertical_space().height(margin.0 as f32).into(),
|
||||
tab_column.into(),
|
||||
vertical_space().height(margin.2 as f32).into(),
|
||||
])
|
||||
}
|
||||
if margin.1 != 0 || margin.3 != 0 {
|
||||
Element::from(widget::row::with_children(vec![
|
||||
horizontal_space().width(margin.1 as f32).into(),
|
||||
tab_column.into(),
|
||||
horizontal_space().width(margin.3 as f32).into(),
|
||||
]))
|
||||
} else {
|
||||
tab_column.into()
|
||||
}
|
||||
} else {
|
||||
tab_column.into()
|
||||
};
|
||||
}
|
||||
Some(WindowKind::DesktopViewOptions) => self.desktop_view_options(),
|
||||
Some(WindowKind::Preview(entity_opt, kind)) => self.preview(entity_opt, kind, false),
|
||||
|
|
@ -4193,7 +4304,7 @@ impl Application for App {
|
|||
struct TrashWatcherSubscription;
|
||||
|
||||
let mut subscriptions = vec![
|
||||
event::listen_with(|event, status, _window_id| match event {
|
||||
event::listen_with(|event, status, window_id| match event {
|
||||
Event::Keyboard(KeyEvent::KeyPressed { key, modifiers, .. }) => match status {
|
||||
event::Status::Ignored => Some(Message::Key(modifiers, key)),
|
||||
event::Status::Captured => None,
|
||||
|
|
@ -4202,12 +4313,20 @@ impl Application for App {
|
|||
Some(Message::Modifiers(modifiers))
|
||||
}
|
||||
Event::Window(WindowEvent::CloseRequested) => Some(Message::WindowClose),
|
||||
Event::Window(WindowEvent::Opened { position: _, size }) => {
|
||||
Some(Message::Size(size))
|
||||
}
|
||||
Event::Window(WindowEvent::Resized(s)) => Some(Message::Size(s)),
|
||||
#[cfg(feature = "wayland")]
|
||||
Event::PlatformSpecific(event::PlatformSpecific::Wayland(wayland_event)) => {
|
||||
match wayland_event {
|
||||
WaylandEvent::Output(output_event, output) => {
|
||||
Some(Message::OutputEvent(output_event, output))
|
||||
}
|
||||
#[cfg(feature = "desktop")]
|
||||
WaylandEvent::OverlapNotify(event) => {
|
||||
Some(Message::Overlap(event, window_id))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue