Skip to content

Commit

Permalink
fix: overlap notify
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 committed Nov 25, 2024
1 parent ad41a71 commit eaede14
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
11 changes: 10 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use smithay::{

use anyhow::{Context, Result};
use state::State;
use std::{env, ffi::OsString, os::unix::process::CommandExt, process, sync::Arc};
use std::{env, ffi::OsString, os::unix::process::CommandExt, process, sync::Arc, time::Duration};
use tracing::{error, info, warn};
use wayland::protocols::overlap_notify::OverlapNotifyState;

use crate::wayland::handlers::compositor::client_compositor_state;

Expand Down Expand Up @@ -111,6 +112,14 @@ fn main() -> Result<()> {
warn!(?err, "Failed to watch theme");
}

_ = event_loop.handle().insert_source(
calloop::timer::Timer::from_duration(Duration::from_millis(500)),
|_, _, state| {
OverlapNotifyState::refresh(state);
calloop::timer::TimeoutAction::ToDuration(Duration::from_millis(500))
},
);

// run the event loop
event_loop.run(None, &mut state, |state| {
// shall we shut down?
Expand Down
46 changes: 29 additions & 17 deletions src/wayland/protocols/overlap_notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use cosmic_protocols::{
zcosmic_toplevel_info_v1::ZcosmicToplevelInfoV1,
},
};
use rand::distributions::{Alphanumeric, DistString};
use smithay::{
desktop::{layer_map_for_output, LayerSurface},
output::Output,
Expand All @@ -29,7 +28,7 @@ use smithay::{
shell::wlr_layer::{ExclusiveZone, Layer},
},
};
use wayland_backend::server::GlobalId;
use wayland_backend::server::{GlobalId, ObjectId};

use crate::utils::prelude::{RectExt, RectGlobalExt, RectLocalExt};

Expand Down Expand Up @@ -112,6 +111,9 @@ impl OverlapNotifyState {
}

for other_surface in map.layers().filter(|s| *s != layer_surface) {
if other_surface.wl_surface().id() == layer_surface.wl_surface().id() {
continue;
}
let other_geo = other_surface.bbox().as_local().to_global(&output);
if let Some(intersection) = layer_geo.intersection(other_geo) {
// relative to window location
Expand Down Expand Up @@ -168,9 +170,9 @@ impl LayerOverlapNotificationDataInternal {
);
}
}
for (layer_surface, (exclusive, layer, overlap)) in &self.last_snapshot.layer_overlaps {
for (_, (identifier, exclusive, layer, overlap)) in &self.last_snapshot.layer_overlaps {
new_notification.layer_enter(
layer_surface.clone(),
identifier.clone(),
if *exclusive { 1 } else { 0 },
match layer {
Layer::Background => WlrLayer::Background,
Expand Down Expand Up @@ -204,7 +206,12 @@ impl LayerOverlapNotificationDataInternal {
}
}
for (toplevel, overlap) in &new_snapshot.toplevel_overlaps {
if !self.last_snapshot.toplevel_overlaps.contains_key(toplevel) {
if !self
.last_snapshot
.toplevel_overlaps
.get(toplevel)
.is_some_and(|old_overlap| old_overlap == overlap)
{
if let Ok(toplevel) = toplevel.upgrade() {
for notification in &notifications {
notification.toplevel_enter(
Expand All @@ -219,22 +226,24 @@ impl LayerOverlapNotificationDataInternal {
}
}

for layer_surface in self.last_snapshot.layer_overlaps.keys() {
if new_snapshot.layer_overlaps.contains_key(layer_surface) {
for (layer_surface, (identifier, ..)) in &self.last_snapshot.layer_overlaps {
if !new_snapshot.layer_overlaps.contains_key(layer_surface) {
for notification in &notifications {
notification.layer_leave(layer_surface.clone());
notification.layer_leave(identifier.clone());
}
}
}
for (layer_surface, (exclusive, layer, overlap)) in &new_snapshot.layer_overlaps {
for (layer_surface, (identifier, exclusive, layer, overlap)) in &new_snapshot.layer_overlaps
{
if !self
.last_snapshot
.layer_overlaps
.contains_key(layer_surface)
.get(layer_surface)
.is_some_and(|(_, _, _, old_overlap)| old_overlap == overlap)
{
for notification in &notifications {
notification.layer_enter(
layer_surface.clone(),
identifier.clone(),
if *exclusive { 1 } else { 0 },
match layer {
Layer::Background => WlrLayer::Background,
Expand All @@ -258,7 +267,7 @@ impl LayerOverlapNotificationDataInternal {
#[derive(Debug, Default, Clone)]
struct OverlapSnapshot {
toplevel_overlaps: HashMap<Weak<ExtForeignToplevelHandleV1>, Rectangle<i32, Logical>>,
layer_overlaps: HashMap<String, (bool, Layer, Rectangle<i32, Logical>)>,
layer_overlaps: HashMap<ObjectId, (String, bool, Layer, Rectangle<i32, Logical>)>,
}

impl OverlapSnapshot {
Expand All @@ -284,18 +293,21 @@ impl OverlapSnapshot {
ExclusiveZone::Exclusive(_)
);
let layer = layer_surface.layer();
let identifier = layer_surface.user_data().get_or_insert(Identifier::default);
let id = layer_surface.wl_surface().id();
let identifier = layer_surface
.user_data()
.get_or_insert(|| Identifier::from(id.clone()));

self.layer_overlaps
.insert(identifier.0.clone(), (exclusive, layer, overlap));
.insert(id, (identifier.0.clone(), exclusive, layer, overlap));
}
}

struct Identifier(String);

impl Default for Identifier {
fn default() -> Self {
Identifier(Alphanumeric.sample_string(&mut rand::thread_rng(), 32))
impl From<ObjectId> for Identifier {
fn from(value: ObjectId) -> Self {
Identifier(value.to_string())
}
}

Expand Down

0 comments on commit eaede14

Please sign in to comment.