xwayland: Add initial support
This commit is contained in:
parent
78ffe3a93d
commit
1d28574088
23 changed files with 781 additions and 185 deletions
|
|
@ -29,6 +29,7 @@ use smithay::{
|
|||
compositor::{with_surface_tree_downward, TraversalAction},
|
||||
seat::WaylandFocus,
|
||||
},
|
||||
xwayland::{xwm::X11Relatable, X11Surface},
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
|
|
@ -483,6 +484,15 @@ impl SpaceElement for CosmicMapped {
|
|||
}
|
||||
}
|
||||
|
||||
impl X11Relatable for CosmicMapped {
|
||||
fn is_window(&self, window: &X11Surface) -> bool {
|
||||
match self.active_window() {
|
||||
CosmicSurface::X11(surface) => &surface == window,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardTarget<State> for CosmicMapped {
|
||||
fn enter(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ use smithay::{
|
|||
wayland::{
|
||||
compositor::{with_states, SurfaceData},
|
||||
seat::WaylandFocus,
|
||||
shell::xdg::XdgToplevelSurfaceData,
|
||||
shell::xdg::{ToplevelSurface, XdgToplevelSurfaceData},
|
||||
},
|
||||
xwayland::X11Surface,
|
||||
xwayland::{xwm::X11Relatable, X11Surface},
|
||||
};
|
||||
|
||||
space_elements! {
|
||||
|
|
@ -41,6 +41,24 @@ space_elements! {
|
|||
X11=X11Surface,
|
||||
}
|
||||
|
||||
impl From<ToplevelSurface> for CosmicSurface {
|
||||
fn from(s: ToplevelSurface) -> Self {
|
||||
CosmicSurface::Wayland(Window::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Window> for CosmicSurface {
|
||||
fn from(w: Window) -> Self {
|
||||
CosmicSurface::Wayland(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<X11Surface> for CosmicSurface {
|
||||
fn from(s: X11Surface) -> Self {
|
||||
CosmicSurface::X11(s)
|
||||
}
|
||||
}
|
||||
|
||||
pub const SSD_HEIGHT: i32 = 48;
|
||||
|
||||
impl CosmicSurface {
|
||||
|
|
@ -577,3 +595,12 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl X11Relatable for CosmicSurface {
|
||||
fn is_window(&self, window: &X11Surface) -> bool {
|
||||
match self {
|
||||
CosmicSurface::X11(surface) => surface == window,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{
|
||||
shell::Shell,
|
||||
state::State,
|
||||
utils::{
|
||||
iced::{IcedElement, Program},
|
||||
|
|
@ -30,13 +31,14 @@ use smithay::{
|
|||
output::Output,
|
||||
render_elements,
|
||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{
|
||||
fmt,
|
||||
hash::Hash,
|
||||
sync::{
|
||||
atomic::{AtomicU8, Ordering},
|
||||
Arc,
|
||||
Arc, Mutex,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -55,10 +57,23 @@ impl fmt::Debug for CosmicWindow {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct CosmicWindowInternal {
|
||||
pub(super) window: CosmicSurface,
|
||||
/// TODO: This needs to be per seat
|
||||
pointer_entered: Arc<AtomicU8>,
|
||||
last_seat: Arc<Mutex<Option<(Seat<State>, Serial)>>>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for CosmicWindowInternal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("CosmicWindowInternal")
|
||||
.field("window", &self.window)
|
||||
.field("pointer_entered", &self.pointer_entered)
|
||||
// skip seat to avoid loop
|
||||
.field("last_seat", &"...")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
|
|
@ -98,6 +113,7 @@ impl CosmicWindow {
|
|||
CosmicWindowInternal {
|
||||
window,
|
||||
pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)),
|
||||
last_seat: Arc::new(Mutex::new(None)),
|
||||
},
|
||||
(width, SSD_HEIGHT),
|
||||
handle,
|
||||
|
|
@ -136,18 +152,49 @@ pub enum Message {
|
|||
impl Program for CosmicWindowInternal {
|
||||
type Message = Message;
|
||||
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||
/*
|
||||
fn update(
|
||||
&mut self,
|
||||
message: Self::Message,
|
||||
loop_handle: &LoopHandle<'static, crate::state::Data>,
|
||||
) -> Command<Self::Message> {
|
||||
match message {
|
||||
Message::DragStart => match &self.window {
|
||||
CosmicWindowSurface::Wayland(window) => self
|
||||
.with_program(|internal| internal.loop_handle())
|
||||
.insert_idle(|data| {}),
|
||||
CosmicWindowSurface::X11(surface) => {}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Message::DragStart => {
|
||||
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
|
||||
if let Some(surface) = self.window.wl_surface() {
|
||||
loop_handle.insert_idle(move |data| {
|
||||
Shell::move_request(&mut data.state, &surface, &seat, serial);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Maximize => {
|
||||
if let Some((seat, _serial)) = self.last_seat.lock().unwrap().clone() {
|
||||
if let Some(surface) = self.window.wl_surface() {
|
||||
loop_handle.insert_idle(move |data| {
|
||||
if let Some(mapped) = data
|
||||
.state
|
||||
.common
|
||||
.shell
|
||||
.element_for_wl_surface(&surface)
|
||||
.cloned()
|
||||
{
|
||||
if let Some(workspace) =
|
||||
data.state.common.shell.space_for_mut(&mapped)
|
||||
{
|
||||
let output = seat.active_output();
|
||||
let (window, _) = mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(&surface))
|
||||
.unwrap();
|
||||
workspace.maximize_request(&window, &output)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Close => self.window.close(),
|
||||
}
|
||||
*/
|
||||
Command::none()
|
||||
}
|
||||
|
||||
|
|
@ -155,21 +202,23 @@ impl Program for CosmicWindowInternal {
|
|||
let radius = 8.;
|
||||
let (w, h) = (target.width() as f32, target.height() as f32);
|
||||
|
||||
let mut pb = PathBuilder::new();
|
||||
pb.move_to(0., h); // lower-left
|
||||
if !(self.window.is_maximized() || self.window.is_fullscreen()) {
|
||||
let mut pb = PathBuilder::new();
|
||||
pb.move_to(0., h); // lower-left
|
||||
|
||||
// upper-left rounded corner
|
||||
pb.line_to(0., radius);
|
||||
pb.quad_to(0., 0., radius, 0.);
|
||||
// upper-left rounded corner
|
||||
pb.line_to(0., radius);
|
||||
pb.quad_to(0., 0., radius, 0.);
|
||||
|
||||
// upper-right rounded corner
|
||||
pb.line_to(w - radius, 0.);
|
||||
pb.quad_to(w, 0., w, radius);
|
||||
// upper-right rounded corner
|
||||
pb.line_to(w - radius, 0.);
|
||||
pb.quad_to(w, 0., w, radius);
|
||||
|
||||
pb.line_to(w, h); // lower-right
|
||||
pb.line_to(w, h); // lower-right
|
||||
|
||||
let path = pb.finish();
|
||||
target.push_clip(&path);
|
||||
let path = pb.finish();
|
||||
target.push_clip(&path);
|
||||
}
|
||||
|
||||
if self.window.is_activated() {
|
||||
target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 30, 30, 30));
|
||||
|
|
@ -387,7 +436,12 @@ impl PointerTarget<State> for CosmicWindow {
|
|||
|
||||
fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {
|
||||
match self.0.with_program(|p| p.current_focus()) {
|
||||
Focus::Header => PointerTarget::button(&self.0, seat, data, event),
|
||||
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::Window => self
|
||||
.0
|
||||
.with_program(|p| PointerTarget::button(&p.window, seat, data, event)),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use smithay::{
|
|||
},
|
||||
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||
utils::{Logical, Point},
|
||||
xwayland::xwm,
|
||||
};
|
||||
|
||||
use crate::state::State;
|
||||
|
|
@ -43,6 +44,22 @@ impl From<ResizeEdge> for xdg_toplevel::ResizeEdge {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<xwm::ResizeEdge> for ResizeEdge {
|
||||
#[inline]
|
||||
fn from(x: xwm::ResizeEdge) -> Self {
|
||||
match x {
|
||||
xwm::ResizeEdge::Top => ResizeEdge::TOP,
|
||||
xwm::ResizeEdge::Bottom => ResizeEdge::BOTTOM,
|
||||
xwm::ResizeEdge::Left => ResizeEdge::LEFT,
|
||||
xwm::ResizeEdge::Right => ResizeEdge::RIGHT,
|
||||
xwm::ResizeEdge::TopLeft => ResizeEdge::TOP_LEFT,
|
||||
xwm::ResizeEdge::BottomLeft => ResizeEdge::BOTTOM_LEFT,
|
||||
xwm::ResizeEdge::TopRight => ResizeEdge::TOP_RIGHT,
|
||||
xwm::ResizeEdge::BottomRight => ResizeEdge::BOTTOM_RIGHT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ResizeGrab {
|
||||
Floating(ResizeSurfaceGrab),
|
||||
Tiling(ResizeForkGrab),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use smithay::{
|
|||
desktop::{layer_map_for_output, space::SpaceElement, Space},
|
||||
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
||||
output::Output,
|
||||
utils::{Logical, Point, Rectangle, Serial, Size},
|
||||
utils::{Logical, Point, Rectangle, Size},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
|
@ -196,7 +196,6 @@ impl FloatingLayout {
|
|||
&mut self,
|
||||
mapped: &CosmicMapped,
|
||||
seat: &Seat<State>,
|
||||
_serial: Serial,
|
||||
start_data: PointerGrabStartData<State>,
|
||||
edges: ResizeEdge,
|
||||
) -> Option<ResizeSurfaceGrab> {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use smithay::{
|
|||
desktop::{layer_map_for_output, space::SpaceElement, PopupKind},
|
||||
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
||||
output::Output,
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial},
|
||||
utils::{IsAlive, Logical, Point, Rectangle, Scale},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::Arc};
|
||||
|
|
@ -928,7 +928,6 @@ impl TilingLayout {
|
|||
&self,
|
||||
mapped: &CosmicMapped,
|
||||
_seat: &Seat<State>,
|
||||
_serial: Serial,
|
||||
start_data: PointerGrabStartData<State>,
|
||||
edges: ResizeEdge,
|
||||
) -> Option<ResizeForkGrab> {
|
||||
|
|
|
|||
170
src/shell/mod.rs
170
src/shell/mod.rs
|
|
@ -4,12 +4,19 @@ use std::{cell::RefCell, collections::HashMap};
|
|||
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||
use smithay::{
|
||||
desktop::{layer_map_for_output, LayerSurface, PopupManager, WindowSurfaceType},
|
||||
input::Seat,
|
||||
input::{
|
||||
pointer::{Focus, GrabStartData as PointerGrabStartData},
|
||||
Seat,
|
||||
},
|
||||
output::Output,
|
||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
utils::{Logical, Point, Rectangle},
|
||||
reexports::{
|
||||
wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
|
||||
x11rb::protocol::xproto::Window as X11Window,
|
||||
},
|
||||
utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER},
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
seat::WaylandFocus,
|
||||
shell::{
|
||||
wlr_layer::{
|
||||
KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState,
|
||||
|
|
@ -17,6 +24,7 @@ use smithay::{
|
|||
xdg::XdgShellState,
|
||||
},
|
||||
},
|
||||
xwayland::X11Surface,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -42,6 +50,7 @@ pub use self::workspace::*;
|
|||
use self::{
|
||||
element::CosmicWindow,
|
||||
focus::target::KeyboardFocusTarget,
|
||||
grabs::ResizeEdge,
|
||||
layout::{floating::FloatingLayout, tiling::TilingLayout},
|
||||
};
|
||||
|
||||
|
|
@ -52,6 +61,7 @@ pub struct Shell {
|
|||
pub floating_default: bool,
|
||||
pub pending_windows: Vec<(CosmicSurface, Seat<State>)>,
|
||||
pub pending_layers: Vec<(LayerSurface, Output, Seat<State>)>,
|
||||
pub override_redirect_windows: Vec<OverrideRedirectWindow>,
|
||||
|
||||
// wayland_state
|
||||
pub layer_shell_state: WlrLayerShellState,
|
||||
|
|
@ -61,6 +71,11 @@ pub struct Shell {
|
|||
pub workspace_state: WorkspaceState<State>,
|
||||
}
|
||||
|
||||
pub struct OverrideRedirectWindow {
|
||||
pub surface: X11Surface,
|
||||
pub above: Option<X11Window>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WorkspaceSet {
|
||||
active: usize,
|
||||
|
|
@ -431,6 +446,7 @@ impl Shell {
|
|||
|
||||
pending_windows: Vec::new(),
|
||||
pending_layers: Vec::new(),
|
||||
override_redirect_windows: Vec::new(),
|
||||
|
||||
layer_shell_state,
|
||||
toplevel_info_state,
|
||||
|
|
@ -871,12 +887,18 @@ impl Shell {
|
|||
.into_iter()
|
||||
}
|
||||
|
||||
pub fn element_for_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
|
||||
pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> {
|
||||
self.workspaces
|
||||
.spaces()
|
||||
.find_map(|w| w.element_for_surface(surface))
|
||||
}
|
||||
|
||||
pub fn element_for_wl_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
|
||||
self.workspaces
|
||||
.spaces()
|
||||
.find_map(|w| w.element_for_wl_surface(surface))
|
||||
}
|
||||
|
||||
pub fn space_for(&self, mapped: &CosmicMapped) -> Option<&Workspace> {
|
||||
self.workspaces
|
||||
.spaces()
|
||||
|
|
@ -996,6 +1018,24 @@ impl Shell {
|
|||
.map(mapped.clone(), &seat, focus_stack.iter());
|
||||
}
|
||||
|
||||
if let CosmicSurface::X11(surface) = window {
|
||||
let geometry = workspace.element_geometry(&mapped);
|
||||
if let Err(err) = surface.configure(geometry) {
|
||||
slog_scope::warn!("Failed to configure X11 surface ({:?}): {}", surface, err);
|
||||
};
|
||||
if let Some(xwm) = state
|
||||
.common
|
||||
.xwayland_state
|
||||
.values_mut()
|
||||
.flat_map(|state| state.xwm.as_mut())
|
||||
.find(|xwm| Some(xwm.id()) == surface.xwm_id())
|
||||
{
|
||||
if let Err(err) = xwm.update_stacking_order_downwards(workspace.mapped()) {
|
||||
slog_scope::warn!("Failed to update Xwayland stacking order: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shell::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None);
|
||||
|
||||
let active_space = state.common.shell.active_space(output);
|
||||
|
|
@ -1004,6 +1044,28 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_override_redirect(state: &mut State, window: X11Surface) {
|
||||
let seat = state.common.last_active_seat().clone();
|
||||
let mut pos = window.geometry().loc;
|
||||
let output = state
|
||||
.common
|
||||
.shell
|
||||
.outputs()
|
||||
.find(|o| o.geometry().contains(pos))
|
||||
.cloned()
|
||||
.unwrap_or_else(|| seat.active_output());
|
||||
pos -= output.geometry().loc;
|
||||
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
.override_redirect_windows
|
||||
.push(OverrideRedirectWindow {
|
||||
surface: window,
|
||||
above: None,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn map_layer(state: &mut State, layer_surface: &LayerSurface) {
|
||||
let pos = state
|
||||
.common
|
||||
|
|
@ -1125,6 +1187,71 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_request(
|
||||
state: &mut State,
|
||||
surface: &WlSurface,
|
||||
seat: &Seat<State>,
|
||||
serial: impl Into<Option<Serial>>,
|
||||
) {
|
||||
let serial = serial.into();
|
||||
if let Some(start_data) = check_grab_preconditions(&seat, surface, serial) {
|
||||
if let Some(mapped) = state.common.shell.element_for_wl_surface(surface).cloned() {
|
||||
if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
|
||||
let output = seat.active_output();
|
||||
let (window, _) = mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
|
||||
.unwrap();
|
||||
if let Some(grab) = workspace.move_request(&window, &seat, &output, start_data)
|
||||
{
|
||||
let handle = workspace.handle;
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_leave_workspace(&window, &handle);
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
.toplevel_info_state
|
||||
.toplevel_leave_output(&window, &output);
|
||||
seat.get_pointer().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
serial.unwrap_or_else(|| SERIAL_COUNTER.next_serial()),
|
||||
Focus::Clear,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resize_request(
|
||||
state: &mut State,
|
||||
surface: &WlSurface,
|
||||
seat: &Seat<State>,
|
||||
serial: impl Into<Option<Serial>>,
|
||||
edges: ResizeEdge,
|
||||
) {
|
||||
let serial = serial.into();
|
||||
if let Some(start_data) = check_grab_preconditions(&seat, surface, serial) {
|
||||
if let Some(mapped) = state.common.shell.element_for_wl_surface(surface).cloned() {
|
||||
if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
|
||||
if let Some(grab) = workspace.resize_request(&mapped, &seat, start_data, edges)
|
||||
{
|
||||
seat.get_pointer().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
serial.unwrap_or_else(|| SERIAL_COUNTER.next_serial()),
|
||||
Focus::Clear,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn workspace_set_idx<'a>(
|
||||
|
|
@ -1136,3 +1263,38 @@ fn workspace_set_idx<'a>(
|
|||
state.set_workspace_name(&handle, format!("{}", idx));
|
||||
state.set_workspace_coordinates(&handle, [Some(idx as u32), Some(output_pos as u32), None]);
|
||||
}
|
||||
|
||||
pub fn check_grab_preconditions(
|
||||
seat: &Seat<State>,
|
||||
surface: &WlSurface,
|
||||
serial: Option<Serial>,
|
||||
) -> Option<PointerGrabStartData<State>> {
|
||||
use smithay::reexports::wayland_server::Resource;
|
||||
|
||||
// TODO: touch resize.
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
|
||||
// Check that this surface has a click grab.
|
||||
if !match serial {
|
||||
Some(serial) => pointer.has_grab(serial),
|
||||
None => pointer.is_grabbed(),
|
||||
} {
|
||||
return None;
|
||||
}
|
||||
|
||||
let start_data = pointer.grab_start_data().unwrap();
|
||||
|
||||
// If the focus was for a different surface, ignore the request.
|
||||
if start_data.focus.is_none()
|
||||
|| !start_data
|
||||
.focus
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.0
|
||||
.same_client_as(&surface.id())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(start_data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,8 @@ use smithay::{
|
|||
desktop::{layer_map_for_output, space::SpaceElement, LayerSurface},
|
||||
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
||||
output::Output,
|
||||
reexports::{
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel::ResizeEdge,
|
||||
wayland_server::protocol::wl_surface::WlSurface,
|
||||
},
|
||||
utils::{
|
||||
Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
|
||||
},
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size},
|
||||
wayland::{seat::WaylandFocus, shell::wlr_layer::Layer},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -38,7 +33,7 @@ use std::collections::HashMap;
|
|||
use super::{
|
||||
element::CosmicMapped,
|
||||
focus::{FocusStack, FocusStackMut},
|
||||
grabs::ResizeGrab,
|
||||
grabs::{ResizeEdge, ResizeGrab},
|
||||
CosmicMappedRenderElement, CosmicSurface,
|
||||
};
|
||||
|
||||
|
|
@ -84,7 +79,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
pub fn commit(&mut self, surface: &WlSurface) {
|
||||
if let Some(mapped) = self.element_for_surface(surface) {
|
||||
if let Some(mapped) = self.element_for_wl_surface(surface) {
|
||||
mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface))
|
||||
|
|
@ -127,7 +122,14 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn element_for_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
|
||||
pub fn element_for_surface(&self, surface: &CosmicSurface) -> Option<&CosmicMapped> {
|
||||
self.floating_layer
|
||||
.mapped()
|
||||
.chain(self.tiling_layer.mapped().map(|(_, w, _)| w))
|
||||
.find(|e| e.windows().any(|(w, _)| &w == surface))
|
||||
}
|
||||
|
||||
pub fn element_for_wl_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
|
||||
self.floating_layer
|
||||
.mapped()
|
||||
.chain(self.tiling_layer.mapped().map(|(_, w, _)| w))
|
||||
|
|
@ -270,7 +272,6 @@ impl Workspace {
|
|||
&mut self,
|
||||
mapped: &CosmicMapped,
|
||||
seat: &Seat<State>,
|
||||
serial: Serial,
|
||||
start_data: PointerGrabStartData<State>,
|
||||
edges: ResizeEdge,
|
||||
) -> Option<ResizeGrab> {
|
||||
|
|
@ -278,14 +279,13 @@ impl Workspace {
|
|||
return None;
|
||||
}
|
||||
|
||||
let edges = edges.into();
|
||||
if self.floating_layer.mapped().any(|m| m == mapped) {
|
||||
self.floating_layer
|
||||
.resize_request(mapped, seat, serial, start_data.clone(), edges)
|
||||
.resize_request(mapped, seat, start_data.clone(), edges)
|
||||
.map(Into::into)
|
||||
} else if self.tiling_layer.mapped().any(|(_, m, _)| m == mapped) {
|
||||
self.tiling_layer
|
||||
.resize_request(mapped, seat, serial, start_data, edges)
|
||||
.resize_request(mapped, seat, start_data, edges)
|
||||
.map(Into::into)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -297,13 +297,12 @@ impl Workspace {
|
|||
window: &CosmicSurface,
|
||||
seat: &Seat<State>,
|
||||
output: &Output,
|
||||
_serial: Serial,
|
||||
start_data: PointerGrabStartData<State>,
|
||||
) -> Option<MoveSurfaceGrab> {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
let pos = pointer.current_location();
|
||||
|
||||
let mapped = self.element_for_surface(&window.wl_surface()?)?.clone();
|
||||
let mapped = self.element_for_surface(&window)?.clone();
|
||||
let mut initial_window_location = self.element_geometry(&mapped).unwrap().loc;
|
||||
|
||||
if mapped.is_fullscreen() || mapped.is_maximized() {
|
||||
|
|
@ -390,6 +389,10 @@ impl Workspace {
|
|||
.chain(self.tiling_layer.windows().map(|(_, w, _)| w))
|
||||
}
|
||||
|
||||
pub fn is_floating(&self, mapped: &CosmicMapped) -> bool {
|
||||
self.floating_layer.mapped().any(|m| m == mapped)
|
||||
}
|
||||
|
||||
pub fn render_output<R>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue