diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 6411a1c6..b9e1b04c 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,4 +1,4 @@ -use super::{surface::RESIZE_BORDER, CosmicSurface}; +use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface}; use crate::{ backend::render::cursor::{CursorShape, CursorState}, shell::{ @@ -104,36 +104,18 @@ pub struct CosmicStackInternal { } impl CosmicStackInternal { - pub fn swap_focus(&self, focus: Focus) -> Focus { - unsafe { - std::mem::transmute::( - self.pointer_entered.swap(focus as u8, Ordering::SeqCst), - ) - } + pub fn swap_focus(&self, focus: Option) -> Option { + let value = focus.map_or(0, |x| x as u8); + unsafe { Focus::from_u8(self.pointer_entered.swap(value, Ordering::SeqCst)) } } - pub fn current_focus(&self) -> Focus { - unsafe { std::mem::transmute::(self.pointer_entered.load(Ordering::SeqCst)) } + pub fn current_focus(&self) -> Option { + unsafe { Focus::from_u8(self.pointer_entered.load(Ordering::SeqCst)) } } } pub const TAB_HEIGHT: i32 = 24; -#[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Focus { - None, - Header, - ResizeTop, - ResizeLeft, - ResizeRight, - ResizeBottom, - ResizeTopRight, - ResizeTopLeft, - ResizeBottomRight, - ResizeBottomLeft, -} - #[derive(Debug, Clone)] pub enum MoveResult { Handled, @@ -165,7 +147,7 @@ impl CosmicStack { group_focused: Arc::new(AtomicBool::new(false)), scroll_to_focus: Arc::new(AtomicBool::new(false)), previous_keyboard: Arc::new(AtomicUsize::new(0)), - pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)), + pointer_entered: Arc::new(AtomicU8::new(0)), reenter: Arc::new(AtomicBool::new(false)), potential_drag: Arc::new(Mutex::new(None)), override_alive: Arc::new(AtomicBool::new(true)), @@ -1131,46 +1113,13 @@ impl PointerTarget for CosmicStack { let mut event = event.clone(); self.0.with_program(|p| { let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]; - let geo = active_window.geometry(); - let loc = event.location.to_i32_round::(); - let (_old_focus, shape) = if loc.y - geo.loc.y < 0 && loc.x - geo.loc.x < 0 { - ( - p.swap_focus(Focus::ResizeTopLeft), - CursorShape::NorthWestResize, - ) - } else if loc.y - geo.loc.y < 0 && loc.x - geo.loc.x >= geo.size.w { - ( - p.swap_focus(Focus::ResizeTopRight), - CursorShape::NorthEastResize, - ) - } else if loc.y - geo.loc.y < 0 { - (p.swap_focus(Focus::ResizeTop), CursorShape::NorthResize) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h && loc.x - geo.loc.x < 0 { - ( - p.swap_focus(Focus::ResizeBottomLeft), - CursorShape::SouthWestResize, - ) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h - && loc.x - geo.loc.x >= geo.size.w - { - ( - p.swap_focus(Focus::ResizeBottomRight), - CursorShape::SouthEastResize, - ) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h { - (p.swap_focus(Focus::ResizeBottom), CursorShape::SouthResize) - } else if loc.x - geo.loc.x < 0 { - (p.swap_focus(Focus::ResizeLeft), CursorShape::WestResize) - } else if loc.x - geo.loc.x >= geo.size.w { - (p.swap_focus(Focus::ResizeRight), CursorShape::EastResize) - } else if loc.y - geo.loc.y < TAB_HEIGHT { - (p.swap_focus(Focus::Header), CursorShape::Default) - } else { + let Some(next) = Focus::under(active_window, TAB_HEIGHT, event.location) else { return; }; + let _old_focus = p.swap_focus(Some(next)); let cursor_state = seat.user_data().get::().unwrap(); - cursor_state.set_shape(shape); + cursor_state.set_shape(next.cursor_shape()); let cursor_status = seat .user_data() .get::>() @@ -1192,36 +1141,13 @@ impl PointerTarget for CosmicStack { self.0.with_program(|p| { let active = p.active.load(Ordering::SeqCst); let active_window = &p.windows.lock().unwrap()[active]; - let geo = active_window.geometry(); - let loc = event.location.to_i32_round::(); - let (next, shape) = if loc.y - geo.loc.y < 0 && loc.x - geo.loc.x < 0 { - (Focus::ResizeTopLeft, CursorShape::NorthWestResize) - } else if loc.y - geo.loc.y < 0 && loc.x - geo.loc.x >= geo.size.w { - (Focus::ResizeTopRight, CursorShape::NorthEastResize) - } else if loc.y - geo.loc.y < 0 { - (Focus::ResizeTop, CursorShape::NorthResize) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h && loc.x - geo.loc.x < 0 { - (Focus::ResizeBottomLeft, CursorShape::SouthWestResize) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h - && loc.x - geo.loc.x >= geo.size.w - { - (Focus::ResizeBottomRight, CursorShape::SouthEastResize) - } else if loc.y - geo.loc.y >= TAB_HEIGHT + geo.size.h { - (Focus::ResizeBottom, CursorShape::SouthResize) - } else if loc.x - geo.loc.x < 0 { - (Focus::ResizeLeft, CursorShape::WestResize) - } else if loc.x - geo.loc.x >= geo.size.w { - (Focus::ResizeRight, CursorShape::EastResize) - } else if (loc.y - geo.loc.y) < TAB_HEIGHT { - (Focus::Header, CursorShape::Default) - } else { + let Some(next) = Focus::under(active_window, TAB_HEIGHT, event.location) else { return; }; - - let _previous = p.swap_focus(next); + let _previous = p.swap_focus(Some(next)); let cursor_state = seat.user_data().get::().unwrap(); - cursor_state.set_shape(shape); + cursor_state.set_shape(next.cursor_shape()); let cursor_status = seat .user_data() .get::>() @@ -1278,14 +1204,13 @@ impl PointerTarget for CosmicStack { fn button(&self, seat: &Seat, data: &mut State, event: &ButtonEvent) { match self.0.with_program(|p| p.current_focus()) { - Focus::Header => { + Some(Focus::Header) => { self.0.with_program(|p| { *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); }); PointerTarget::button(&self.0, seat, data, event) } - Focus::None => {} - x => { + Some(x) => { let serial = event.serial; let seat = seat.clone(); let Some(surface) = self.0.with_program(|p| { @@ -1309,24 +1234,25 @@ impl PointerTarget for CosmicStack { Focus::ResizeBottomRight => ResizeEdge::BOTTOM_RIGHT, Focus::ResizeLeft => ResizeEdge::LEFT, Focus::ResizeRight => ResizeEdge::RIGHT, - Focus::Header | Focus::None => unreachable!(), + Focus::Header => unreachable!(), }, ) }); } + None => {} } } fn axis(&self, seat: &Seat, data: &mut State, frame: AxisFrame) { match self.0.with_program(|p| p.current_focus()) { - Focus::Header => PointerTarget::axis(&self.0, seat, data, frame), + Some(Focus::Header) => PointerTarget::axis(&self.0, seat, data, frame), _ => {} } } fn frame(&self, seat: &Seat, data: &mut State) { match self.0.with_program(|p| p.current_focus()) { - Focus::Header => PointerTarget::frame(&self.0, seat, data), + Some(Focus::Header) => PointerTarget::frame(&self.0, seat, data), _ => {} } } @@ -1335,7 +1261,7 @@ impl PointerTarget for CosmicStack { self.0.with_program(|p| { let cursor_state = seat.user_data().get::().unwrap(); cursor_state.set_shape(CursorShape::Default); - let _previous = p.swap_focus(Focus::None); + let _previous = p.swap_focus(None); }); PointerTarget::leave(&self.0, seat, data, serial, time); diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 3e749eac..fe68d8ac 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -110,7 +110,11 @@ pub enum Focus { } impl Focus { - fn under(surface: &CosmicSurface, location: Point) -> Option { + pub fn under( + surface: &CosmicSurface, + header_height: i32, + location: Point, + ) -> Option { let loc = location.to_i32_round::(); let geo = surface.geometry(); if loc.y < 0 && loc.x < 0 { @@ -119,24 +123,24 @@ impl Focus { Some(Focus::ResizeTopRight) } else if loc.y < 0 { Some(Focus::ResizeTop) - } else if loc.y >= SSD_HEIGHT + geo.size.h && loc.x < 0 { + } else if loc.y >= header_height + geo.size.h && loc.x < 0 { Some(Focus::ResizeBottomLeft) - } else if loc.y >= SSD_HEIGHT + geo.size.h && loc.x >= geo.size.w { + } else if loc.y >= header_height + geo.size.h && loc.x >= geo.size.w { Some(Focus::ResizeBottomRight) - } else if loc.y >= SSD_HEIGHT + geo.size.h { + } else if loc.y >= header_height + geo.size.h { Some(Focus::ResizeBottom) } else if loc.x < 0 { Some(Focus::ResizeLeft) } else if loc.x >= geo.size.w { Some(Focus::ResizeRight) - } else if loc.y < SSD_HEIGHT { + } else if loc.y < header_height { Some(Focus::Header) } else { None } } - fn cursor_shape(&self) -> CursorShape { + pub fn cursor_shape(&self) -> CursorShape { match self { Focus::ResizeTopLeft => CursorShape::NorthWestResize, Focus::ResizeTopRight => CursorShape::NorthEastResize, @@ -149,22 +153,23 @@ impl Focus { Focus::Header => CursorShape::Default, } } + + pub unsafe fn from_u8(value: u8) -> Option { + match value { + 0 => None, + focus => unsafe { Some(std::mem::transmute::(focus)) }, + } + } } impl CosmicWindowInternal { pub fn swap_focus(&self, focus: Option) -> Option { let value = focus.map_or(0, |x| x as u8); - match self.pointer_entered.swap(value, Ordering::SeqCst) { - 0 => None, - focus => unsafe { Some(std::mem::transmute::(focus)) }, - } + unsafe { Focus::from_u8(self.pointer_entered.swap(value, Ordering::SeqCst)) } } pub fn current_focus(&self) -> Option { - match self.pointer_entered.load(Ordering::SeqCst) { - 0 => None, - focus => unsafe { Some(std::mem::transmute::(focus)) }, - } + unsafe { Focus::from_u8(self.pointer_entered.load(Ordering::SeqCst)) } } pub fn has_ssd(&self, pending: bool) -> bool { @@ -659,7 +664,7 @@ impl PointerTarget for CosmicWindow { let mut event = event.clone(); self.0.with_program(|p| { if p.has_ssd(false) { - let Some(next) = Focus::under(&p.window, event.location) else { + let Some(next) = Focus::under(&p.window, SSD_HEIGHT, event.location) else { return; }; let old_focus = p.swap_focus(Some(next)); @@ -683,7 +688,7 @@ impl PointerTarget for CosmicWindow { let mut event = event.clone(); self.0.with_program(|p| { if p.has_ssd(false) { - let Some(next) = Focus::under(&p.window, event.location) else { + let Some(next) = Focus::under(&p.window, SSD_HEIGHT, event.location) else { return; }; let _previous = p.swap_focus(Some(next));