deps: Update smithay

This commit is contained in:
Victoria Brekenfeld 2022-08-31 13:01:23 +02:00
parent 9e0a6e1b5f
commit 6690e13d54
31 changed files with 572 additions and 562 deletions

39
Cargo.lock generated
View file

@ -513,8 +513,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]] [[package]]
name = "drm" name = "drm"
version = "0.6.2" version = "0.7.0"
source = "git+https://github.com/Smithay//drm-rs?rev=8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0#8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01406fcc6bf5180bf107c2922c8f37a875440c56a4d436b4c4cc8c09f433cc2d"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"bytemuck", "bytemuck",
@ -525,8 +526,9 @@ dependencies = [
[[package]] [[package]]
name = "drm-ffi" name = "drm-ffi"
version = "0.2.1" version = "0.3.0"
source = "git+https://github.com/Smithay//drm-rs?rev=8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0#8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e538131f5ca07f76483b6bcdb18f540fdfe4bb0c95742f64e7d2c5649c61bca5"
dependencies = [ dependencies = [
"drm-sys", "drm-sys",
"nix 0.24.2", "nix 0.24.2",
@ -540,8 +542,9 @@ checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
[[package]] [[package]]
name = "drm-sys" name = "drm-sys"
version = "0.1.2" version = "0.2.0"
source = "git+https://github.com/Smithay//drm-rs?rev=8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0#8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abe573f73b81a2127a5d5989e12a4ea4a4dab7800e53c73c663494d6c342a338"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -637,7 +640,8 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "gbm" name = "gbm"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/Smithay/gbm.rs?rev=b35994d#b35994de29098415cf53a45482276d3b8b658cfc" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f388f2b6aa25fbf6730726f714b3c8653b05e529defc63589d3be945df431897"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"drm", "drm",
@ -648,8 +652,9 @@ dependencies = [
[[package]] [[package]]
name = "gbm-sys" name = "gbm-sys"
version = "0.2.0" version = "0.2.1"
source = "git+https://github.com/Smithay/gbm.rs?rev=b35994d#b35994de29098415cf53a45482276d3b8b658cfc" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c366578b2e6e7caf75f1a17e64f026dddf814d39844e77e7857a4106232c7e15"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -1487,7 +1492,7 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]] [[package]]
name = "smithay" name = "smithay"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/Smithay//smithay?branch=update/drm-0.7#382ac1a0d2351222509d185e4e32231f20c1dda4" source = "git+https://github.com/Smithay//smithay?rev=6e6f1f4d#6e6f1f4d2969d10d1dc6f922f28bdd6977b3ac32"
dependencies = [ dependencies = [
"appendlist", "appendlist",
"bitflags", "bitflags",
@ -1517,6 +1522,7 @@ dependencies = [
"wayland-backend", "wayland-backend",
"wayland-egl", "wayland-egl",
"wayland-protocols 0.30.0-beta.8", "wayland-protocols 0.30.0-beta.8",
"wayland-protocols-misc",
"wayland-protocols-wlr", "wayland-protocols-wlr",
"wayland-server", "wayland-server",
"wayland-sys 0.30.0-beta.8", "wayland-sys 0.30.0-beta.8",
@ -1872,6 +1878,19 @@ dependencies = [
"wayland-server", "wayland-server",
] ]
[[package]]
name = "wayland-protocols-misc"
version = "0.1.0-beta.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b660ecc6e9709a438d9e227eedbea31d6c551672ff75eec90eeef0447c8ecc7c"
dependencies = [
"bitflags",
"wayland-backend",
"wayland-protocols 0.30.0-beta.8",
"wayland-scanner 0.30.0-beta.8",
"wayland-server",
]
[[package]] [[package]]
name = "wayland-protocols-wlr" name = "wayland-protocols-wlr"
version = "0.1.0-beta.8" version = "0.1.0-beta.8"

View file

@ -62,8 +62,4 @@ debug = true
lto = "fat" lto = "fat"
[patch."https://github.com/Smithay/smithay.git"] [patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/Smithay//smithay", branch = "update/drm-0.7" } smithay = { git = "https://github.com/Smithay//smithay", rev = "6e6f1f4d" }
[patch."https://github.com/Smithay/drm-rs.git"]
drm = { git = "https://github.com/Smithay//drm-rs", rev = "8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0" }
drm-ffi = { git = "https://github.com/Smithay//drm-rs", rev = "8b54f45831932fb1f7d6c1b9cb76ff68c342dfd0" }

View file

@ -122,8 +122,7 @@ pub fn init_backend(
if let &mut InputEvent::DeviceAdded { ref mut device } = &mut event { if let &mut InputEvent::DeviceAdded { ref mut device } = &mut event {
data.state.common.config.read_device(device); data.state.common.config.read_device(device);
} }
data.state data.state.process_input_event(event);
.process_input_event(&data.display.handle(), event);
for output in data.state.common.shell.outputs() { for output in data.state.common.shell.outputs() {
if let Err(err) = data if let Err(err) = data
.state .state
@ -934,12 +933,7 @@ impl KmsState {
} }
} }
pub fn dmabuf_imported( pub fn dmabuf_imported(&mut self, global: &DmabufGlobal, dmabuf: Dmabuf) -> Result<()> {
&mut self,
_dh: &DisplayHandle,
global: &DmabufGlobal,
dmabuf: Dmabuf,
) -> Result<()> {
use smithay::backend::renderer::ImportDma; use smithay::backend::renderer::ImportDma;
for device in self.devices.values() { for device in self.devices.values() {

View file

@ -4,12 +4,13 @@ use crate::utils::prelude::*;
use smithay::{ use smithay::{
backend::renderer::{Frame, ImportAll, ImportMem, Renderer, Texture}, backend::renderer::{Frame, ImportAll, ImportMem, Renderer, Texture},
desktop::space::{RenderElement, SpaceOutputTuple, SurfaceTree}, desktop::space::{RenderElement, SpaceOutputTuple, SurfaceTree},
input::{
pointer::{CursorImageAttributes, CursorImageStatus},
Seat,
},
reexports::wayland_server::protocol::wl_surface, reexports::wayland_server::protocol::wl_surface,
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size, Transform}, utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size, Transform},
wayland::{ wayland::compositor::{get_role, with_states},
compositor::{get_role, with_states},
seat::{CursorImageAttributes, CursorImageStatus, Seat},
},
}; };
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
@ -292,7 +293,7 @@ where
.get::<RefCell<CursorImageStatus>>() .get::<RefCell<CursorImageStatus>>()
.map(|cell| { .map(|cell| {
let mut cursor_status = cell.borrow_mut(); let mut cursor_status = cell.borrow_mut();
if let CursorImageStatus::Image(ref surface) = *cursor_status { if let CursorImageStatus::Surface(ref surface) = *cursor_status {
if !surface.alive() { if !surface.alive() {
*cursor_status = CursorImageStatus::Default; *cursor_status = CursorImageStatus::Default;
} }
@ -301,7 +302,7 @@ where
}) })
.unwrap_or(CursorImageStatus::Default); .unwrap_or(CursorImageStatus::Default);
if let CursorImageStatus::Image(wl_surface) = cursor_status { if let CursorImageStatus::Surface(wl_surface) = cursor_status {
Some(draw_surface_cursor(wl_surface.clone(), location.to_i32_round()).into()) Some(draw_surface_cursor(wl_surface.clone(), location.to_i32_round()).into())
} else if draw_default { } else if draw_default {
let seat_userdata = seat.user_data(); let seat_userdata = seat.user_data();

View file

@ -294,7 +294,7 @@ impl State {
render_ping.ping(); render_ping.ping();
} }
WinitEvent::Refresh => render_ping.ping(), WinitEvent::Refresh => render_ping.ping(),
WinitEvent::Input(event) => self.process_input_event(dh, event), WinitEvent::Input(event) => self.process_input_event(event),
_ => {} _ => {}
}; };
} }

View file

@ -362,7 +362,7 @@ pub fn init_backend(
} }
} }
} }
X11Event::Input(event) => data.state.process_x11_event(&data.display.handle(), event), X11Event::Input(event) => data.state.process_x11_event(event),
}) })
.map_err(|_| anyhow::anyhow!("Failed to insert X11 Backend into event loop"))?; .map_err(|_| anyhow::anyhow!("Failed to insert X11 Backend into event loop"))?;
@ -391,7 +391,7 @@ fn init_egl_client_side(
} }
impl State { impl State {
pub fn process_x11_event(&mut self, dh: &DisplayHandle, event: InputEvent<X11Input>) { pub fn process_x11_event(&mut self, event: InputEvent<X11Input>) {
// here we can handle special cases for x11 inputs, like mapping them to windows // here we can handle special cases for x11 inputs, like mapping them to windows
match &event { match &event {
InputEvent::PointerMotionAbsolute { event } => { InputEvent::PointerMotionAbsolute { event } => {
@ -418,7 +418,7 @@ impl State {
_ => {} _ => {}
}; };
self.process_input_event(dh, event); self.process_input_event(event);
// TODO actually figure out the output // TODO actually figure out the output
for output in self.common.shell.outputs() { for output in self.common.shell.outputs() {
self.backend self.backend

View file

@ -7,6 +7,7 @@ use crate::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub use smithay::{ pub use smithay::{
backend::input::KeyState, backend::input::KeyState,
input::keyboard::{keysyms as KeySyms, Keysym, ModifiersState},
reexports::{ reexports::{
calloop::LoopHandle, calloop::LoopHandle,
input::{ input::{
@ -15,10 +16,7 @@ pub use smithay::{
}, },
}, },
utils::{Logical, Physical, Point, Size, Transform}, utils::{Logical, Physical, Point, Size, Transform},
wayland::{ wayland::output::{Mode, Output},
output::{Mode, Output},
seat::{keysyms as KeySyms, Keysym, ModifiersState as KeyModifiers},
},
}; };
use std::{cell::RefCell, collections::HashMap, fs::OpenOptions, path::PathBuf}; use std::{cell::RefCell, collections::HashMap, fs::OpenOptions, path::PathBuf};
@ -696,6 +694,27 @@ pub enum KeyModifier {
NumLock, NumLock,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct KeyModifiers {
ctrl: bool,
alt: bool,
shift: bool,
logo: bool,
caps_lock: bool,
num_lock: bool,
}
impl PartialEq<ModifiersState> for KeyModifiers {
fn eq(&self, other: &ModifiersState) -> bool {
self.ctrl == other.ctrl
&& self.alt == other.alt
&& self.shift == other.shift
&& self.logo == other.logo
&& self.caps_lock == other.caps_lock
&& self.num_lock == other.num_lock
}
}
impl std::ops::AddAssign<KeyModifier> for KeyModifiers { impl std::ops::AddAssign<KeyModifier> for KeyModifiers {
fn add_assign(&mut self, rhs: KeyModifier) { fn add_assign(&mut self, rhs: KeyModifier) {
match rhs { match rhs {

View file

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
#![allow(non_snake_case)] #![allow(non_snake_case)]
use super::KeyModifier; use super::{KeyModifier, KeyModifiers};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub use smithay::{ pub use smithay::{
backend::input::KeyState, backend::input::KeyState,
input::keyboard::{keysyms as KeySyms, Keysym, XkbConfig as WlXkbConfig},
reexports::input::{AccelProfile, ClickMethod, ScrollMethod, TapButtonMap}, reexports::input::{AccelProfile, ClickMethod, ScrollMethod, TapButtonMap},
utils::{Logical, Physical, Point, Size, Transform}, utils::{Logical, Physical, Point, Size, Transform},
wayland::{ wayland::output::{Mode, Output},
output::{Mode, Output},
seat::{
keysyms as KeySyms, Keysym, ModifiersState as KeyModifiers, XkbConfig as WlXkbConfig,
},
},
}; };
use xkbcommon::xkb; use xkbcommon::xkb;

View file

@ -3,24 +3,25 @@
use crate::{ use crate::{
config::{Action, Config}, config::{Action, Config},
shell::{grabs::SeatMoveGrabState, Workspace}, shell::{grabs::SeatMoveGrabState, Workspace},
state::Common,
utils::prelude::*, utils::prelude::*,
}; };
use smithay::{ use smithay::{
backend::input::{Device, DeviceCapability, InputBackend, InputEvent, KeyState}, backend::input::{
desktop::{layer_map_for_output, Kind, WindowSurfaceType}, AbsolutePositionEvent, Axis, AxisSource, Device, DeviceCapability, InputBackend,
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle, Resource}, InputEvent, KeyState, PointerAxisEvent,
utils::{Buffer, Logical, Point, Rectangle, Size},
wayland::{
data_device::set_data_device_focus,
output::Output,
primary_selection::set_primary_focus,
seat::{
keysyms, ButtonEvent, CursorImageStatus, FilterResult, KeysymHandle, MotionEvent, Seat,
},
shell::wlr_layer::Layer as WlrLayer,
SERIAL_COUNTER,
}, },
desktop::{layer_map_for_output, Kind, WindowSurfaceType},
input::{
keyboard::{keysyms, FilterResult, KeysymHandle},
pointer::{AxisFrame, ButtonEvent, CursorImageStatus, MotionEvent},
Seat, SeatState,
},
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
utils::{Buffer, Logical, Point, Rectangle, Size, SERIAL_COUNTER},
wayland::{output::Output, shell::wlr_layer::Layer as WlrLayer},
}; };
use std::{cell::RefCell, collections::HashMap}; use std::{cell::RefCell, collections::HashMap};
use xkbcommon::xkb::KEY_XF86Switch_VT_12; use xkbcommon::xkb::KEY_XF86Switch_VT_12;
@ -95,8 +96,13 @@ impl Devices {
} }
} }
pub fn add_seat(dh: &DisplayHandle, config: &Config, name: String) -> Seat<State> { pub fn add_seat(
let mut seat = Seat::<State>::new(dh, name, None); dh: &DisplayHandle,
seat_state: &mut SeatState<State>,
config: &Config,
name: String,
) -> Seat<State> {
let mut seat = seat_state.new_wl_seat(dh, name, None);
let userdata = seat.user_data(); let userdata = seat.user_data();
userdata.insert_if_missing(SeatId::default); userdata.insert_if_missing(SeatId::default);
userdata.insert_if_missing(Devices::default); userdata.insert_if_missing(Devices::default);
@ -113,36 +119,15 @@ pub fn add_seat(dh: &DisplayHandle, config: &Config, name: String) -> Seat<State
// //
// So instead of doing the right thing (and initialize these capabilities as matching // So instead of doing the right thing (and initialize these capabilities as matching
// devices appear), we have to surrender to reality and just always expose a keyboard and pointer. // devices appear), we have to surrender to reality and just always expose a keyboard and pointer.
let dh_clone = dh.clone();
let conf = config.xkb_config(); let conf = config.xkb_config();
let _ = seat.add_keyboard((&conf).into(), 200, 25, move |seat, focus| { let _ = seat.add_keyboard((&conf).into(), 200, 25);
if let Some(client) = focus.and_then(|s| dh_clone.get_client(s.id()).ok()) { let _ = seat.add_pointer();
set_data_device_focus(&dh_clone, seat, Some(client));
let client2 = focus
.and_then(|s| dh_clone.get_client(s.id()).ok())
.unwrap();
set_primary_focus(&dh_clone, seat, Some(client2))
}
});
let owned_seat = seat.clone();
seat.add_pointer(move |status| {
*owned_seat
.user_data()
.get::<RefCell<CursorImageStatus>>()
.unwrap()
.borrow_mut() = status;
});
seat seat
} }
impl State { impl State {
pub fn process_input_event<B: InputBackend>( pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
&mut self,
dh: &DisplayHandle,
event: InputEvent<B>,
) {
use smithay::backend::input::Event; use smithay::backend::input::Event;
match event { match event {
@ -199,72 +184,85 @@ impl State {
if let Some(action) = seat if let Some(action) = seat
.get_keyboard() .get_keyboard()
.unwrap() .unwrap()
.input(dh, keycode, state, serial, time, |modifiers, handle| { .input(
if state == KeyState::Released self,
&& userdata.get::<SupressedKeys>().unwrap().filter(&handle) keycode,
{ state,
return FilterResult::Intercept(None); serial,
} time,
|data, modifiers, handle| {
#[cfg(feature = "debug")] if state == KeyState::Released
{ && userdata.get::<SupressedKeys>().unwrap().filter(&handle)
if self.common.seats.iter().position(|x| x == seat).unwrap()
== 0
&& self.common.egui.active
{ {
if self.common.egui.debug_state.wants_keyboard() { return FilterResult::Intercept(None);
self.common.egui.debug_state.handle_keyboard( }
&handle, #[cfg(feature = "debug")]
state == KeyState::Pressed, {
modifiers.clone(), if data.common.seats.iter().position(|x| x == seat).unwrap()
); == 0
userdata.get::<SupressedKeys>().unwrap().add(&handle); && data.common.egui.active
return FilterResult::Intercept(None); {
} if data.common.egui.debug_state.wants_keyboard() {
if self.common.egui.log_state.wants_keyboard() { data.common.egui.debug_state.handle_keyboard(
self.common.egui.log_state.handle_keyboard( &handle,
&handle, state == KeyState::Pressed,
state == KeyState::Pressed, modifiers.clone(),
modifiers.clone(), );
); userdata
userdata.get::<SupressedKeys>().unwrap().add(&handle); .get::<SupressedKeys>()
return FilterResult::Intercept(None); .unwrap()
.add(&handle);
return FilterResult::Intercept(None);
}
if data.common.egui.log_state.wants_keyboard() {
data.common.egui.log_state.handle_keyboard(
&handle,
state == KeyState::Pressed,
modifiers.clone(),
);
userdata
.get::<SupressedKeys>()
.unwrap()
.add(&handle);
return FilterResult::Intercept(None);
}
} }
} }
}
if state == KeyState::Pressed
&& (keysyms::KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12)
.contains(&handle.modified_sym())
{
if let Err(err) = self.backend.kms().switch_vt(
(handle.modified_sym() - keysyms::KEY_XF86Switch_VT_1 + 1)
as i32,
) {
slog_scope::error!(
"Failed switching virtual terminal: {}",
err
);
}
userdata.get::<SupressedKeys>().unwrap().add(&handle);
return FilterResult::Intercept(None);
}
// here we can handle global shortcuts and the like
for (binding, action) in
self.common.config.static_conf.key_bindings.iter()
{
if state == KeyState::Pressed if state == KeyState::Pressed
&& binding.modifiers == *modifiers && (keysyms::KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12)
&& handle.raw_syms().contains(&binding.key) .contains(&handle.modified_sym())
{ {
if let Err(err) = data.backend.kms().switch_vt(
(handle.modified_sym() - keysyms::KEY_XF86Switch_VT_1
+ 1)
as i32,
) {
slog_scope::error!(
"Failed switching virtual terminal: {}",
err
);
}
userdata.get::<SupressedKeys>().unwrap().add(&handle); userdata.get::<SupressedKeys>().unwrap().add(&handle);
return FilterResult::Intercept(Some(action)); return FilterResult::Intercept(None);
} }
}
FilterResult::Forward // here we can handle global shortcuts and the like
}) for (binding, action) in
data.common.config.static_conf.key_bindings.iter()
{
if state == KeyState::Pressed
&& binding.modifiers == *modifiers
&& handle.raw_syms().contains(&binding.key)
{
userdata.get::<SupressedKeys>().unwrap().add(&handle);
return FilterResult::Intercept(Some(action.clone()));
}
}
FilterResult::Forward
},
)
.flatten() .flatten()
{ {
match action { match action {
@ -302,7 +300,7 @@ impl State {
workspace as usize, workspace as usize,
) { ) {
if let Some(ptr) = seat.get_pointer() { if let Some(ptr) = seat.get_pointer() {
ptr.motion(self, dh, &motion_event); ptr.motion(self, None, &motion_event);
} }
} }
} }
@ -324,14 +322,14 @@ impl State {
self.common.shell.active_space_mut(&current_output); self.common.shell.active_space_mut(&current_output);
let focus_stack = workspace.focus_stack(seat); let focus_stack = workspace.focus_stack(seat);
if let Some(window) = workspace.tiling_layer.move_focus( if let Some(window) = workspace.tiling_layer.move_focus(
*focus, focus,
seat, seat,
&mut workspace.space, &mut workspace.space,
focus_stack.iter(), focus_stack.iter(),
) { ) {
std::mem::drop(focus_stack); std::mem::drop(focus_stack);
self.common.set_focus( Common::set_focus(
dh, self,
Some(window.toplevel().wl_surface()), Some(window.toplevel().wl_surface()),
seat, seat,
None, None,
@ -352,7 +350,7 @@ impl State {
let workspace = self.common.shell.active_space_mut(&output); let workspace = self.common.shell.active_space_mut(&output);
let focus_stack = workspace.focus_stack(seat); let focus_stack = workspace.focus_stack(seat);
workspace.tiling_layer.update_orientation( workspace.tiling_layer.update_orientation(
*orientation, orientation,
&seat, &seat,
&mut workspace.space, &mut workspace.space,
focus_stack.iter(), focus_stack.iter(),
@ -505,10 +503,9 @@ impl State {
); );
seat.get_pointer().unwrap().motion( seat.get_pointer().unwrap().motion(
self, self,
dh, under,
&MotionEvent { &MotionEvent {
location: position, location: position,
focus: under,
serial, serial,
time: event.time(), time: event.time(),
}, },
@ -530,8 +527,6 @@ impl State {
} }
} }
InputEvent::PointerMotionAbsolute { event, .. } => { InputEvent::PointerMotionAbsolute { event, .. } => {
use smithay::backend::input::PointerMotionAbsoluteEvent;
let device = event.device(); let device = event.device();
for seat in self.common.seats.clone().iter() { for seat in self.common.seats.clone().iter() {
let userdata = seat.user_data(); let userdata = seat.user_data();
@ -556,10 +551,9 @@ impl State {
); );
seat.get_pointer().unwrap().motion( seat.get_pointer().unwrap().motion(
self, self,
dh, under,
&MotionEvent { &MotionEvent {
location: position, location: position,
focus: under,
serial, serial,
time: event.time(), time: event.time(),
}, },
@ -581,10 +575,7 @@ impl State {
} }
} }
InputEvent::PointerButton { event, .. } => { InputEvent::PointerButton { event, .. } => {
use smithay::{ use smithay::backend::input::{ButtonState, PointerButtonEvent};
backend::input::{ButtonState, PointerButtonEvent},
reexports::wayland_server::protocol::wl_pointer,
};
let device = event.device(); let device = event.device();
for seat in self.common.seats.clone().iter() { for seat in self.common.seats.clone().iter() {
@ -619,106 +610,95 @@ impl State {
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let button = event.button_code(); let button = event.button_code();
let state = match event.state() { if event.state() == ButtonState::Pressed {
ButtonState::Pressed => { // change the keyboard focus unless the pointer or keyboard is grabbed
// change the keyboard focus unless the pointer or keyboard is grabbed // We test for any matching surface type here but always use the root
// We test for any matching surface type here but always use the root // (in case of a window the toplevel) surface for the focus.
// (in case of a window the toplevel) surface for the focus. // see: https://gitlab.freedesktop.org/wayland/wayland/-/issues/294
// see: https://gitlab.freedesktop.org/wayland/wayland/-/issues/294 if !seat.get_pointer().unwrap().is_grabbed()
if !seat.get_pointer().unwrap().is_grabbed() && !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false)
&& !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false) {
{ let output = active_output(seat, &self.common);
let output = active_output(seat, &self.common); let pos = seat.get_pointer().unwrap().current_location();
let pos = seat.get_pointer().unwrap().current_location(); let output_geo = output.geometry();
let output_geo = output.geometry(); let relative_pos = self
let relative_pos = self .common
.common .shell
.shell .space_relative_output_geometry(pos, &output);
.space_relative_output_geometry(pos, &output); let workspace = self.common.shell.active_space_mut(&output);
let workspace = self.common.shell.active_space_mut(&output); let layers = layer_map_for_output(&output);
let layers = layer_map_for_output(&output); let mut under = None;
let mut under = None;
if let Some(window) = workspace.get_fullscreen(&output) { if let Some(window) = workspace.get_fullscreen(&output) {
if let Some(layer) = if let Some(layer) =
layers.layer_under(WlrLayer::Overlay, relative_pos) layers.layer_under(WlrLayer::Overlay, relative_pos)
{ {
if layer.can_receive_keyboard_focus() { if layer.can_receive_keyboard_focus() {
let layer_loc = let layer_loc =
layers.layer_geometry(layer).unwrap().loc; layers.layer_geometry(layer).unwrap().loc;
under = layer under = layer
.surface_under(
pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.map(|(_, _)| layer.wl_surface().clone());
}
} else {
under = window
.surface_under( .surface_under(
pos - output_geo.loc.to_f64(), pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL, WindowSurfaceType::ALL,
) )
.map(|(_, _)| { .map(|(_, _)| layer.wl_surface().clone());
window.toplevel().wl_surface().clone()
});
} }
} else { } else {
if let Some(layer) = layers under = window
.layer_under(WlrLayer::Overlay, relative_pos) .surface_under(
.or_else(|| { pos - output_geo.loc.to_f64(),
layers.layer_under(WlrLayer::Top, relative_pos) WindowSurfaceType::ALL,
})
{
if layer.can_receive_keyboard_focus() {
let layer_loc =
layers.layer_geometry(layer).unwrap().loc;
under = layer
.surface_under(
pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.map(|(_, _)| layer.wl_surface().clone());
}
} else if let Some((window, _, _)) = workspace
.space
.surface_under(relative_pos, WindowSurfaceType::ALL)
{
under = Some(window.toplevel().wl_surface().clone());
} else if let Some(layer) =
layers.layer_under(WlrLayer::Bottom, pos).or_else(
|| layers.layer_under(WlrLayer::Background, pos),
) )
{ .map(|(_, _)| window.toplevel().wl_surface().clone());
if layer.can_receive_keyboard_focus() {
let layer_loc =
layers.layer_geometry(layer).unwrap().loc;
under = layer
.surface_under(
pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.map(|(_, _)| layer.wl_surface().clone());
}
};
} }
} else {
self.common if let Some(layer) = layers
.set_focus(dh, under.as_ref(), seat, Some(serial)); .layer_under(WlrLayer::Overlay, relative_pos)
.or_else(|| layers.layer_under(WlrLayer::Top, relative_pos))
{
if layer.can_receive_keyboard_focus() {
let layer_loc =
layers.layer_geometry(layer).unwrap().loc;
under = layer
.surface_under(
pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.map(|(_, _)| layer.wl_surface().clone());
}
} else if let Some((window, _, _)) = workspace
.space
.surface_under(relative_pos, WindowSurfaceType::ALL)
{
under = Some(window.toplevel().wl_surface().clone());
} else if let Some(layer) = layers
.layer_under(WlrLayer::Bottom, pos)
.or_else(|| layers.layer_under(WlrLayer::Background, pos))
{
if layer.can_receive_keyboard_focus() {
let layer_loc =
layers.layer_geometry(layer).unwrap().loc;
under = layer
.surface_under(
pos - output_geo.loc.to_f64()
- layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.map(|(_, _)| layer.wl_surface().clone());
}
};
} }
wl_pointer::ButtonState::Pressed
Common::set_focus(self, under.as_ref(), seat, Some(serial));
} }
ButtonState::Released => wl_pointer::ButtonState::Released,
}; };
seat.get_pointer().unwrap().button( seat.get_pointer().unwrap().button(
self, self,
dh,
&ButtonEvent { &ButtonEvent {
button, button,
state, state: event.state(),
serial, serial,
time: event.time(), time: event.time(),
}, },
@ -728,12 +708,6 @@ impl State {
} }
} }
InputEvent::PointerAxis { event, .. } => { InputEvent::PointerAxis { event, .. } => {
use smithay::{
backend::input::{Axis, AxisSource, PointerAxisEvent},
reexports::wayland_server::protocol::wl_pointer,
wayland::seat::AxisFrame,
};
let device = event.device(); let device = event.device();
for seat in self.common.seats.clone().iter() { for seat in self.common.seats.clone().iter() {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -771,13 +745,6 @@ impl State {
let userdata = seat.user_data(); let userdata = seat.user_data();
let devices = userdata.get::<Devices>().unwrap(); let devices = userdata.get::<Devices>().unwrap();
if devices.has_device(&device) { if devices.has_device(&device) {
let source = match event.source() {
AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
AxisSource::Finger => wl_pointer::AxisSource::Finger,
AxisSource::Wheel | AxisSource::WheelTilt => {
wl_pointer::AxisSource::Wheel
}
};
let horizontal_amount = let horizontal_amount =
event.amount(Axis::Horizontal).unwrap_or_else(|| { event.amount(Axis::Horizontal).unwrap_or_else(|| {
event.amount_discrete(Axis::Horizontal).unwrap_or(0.0) * 3.0 event.amount_discrete(Axis::Horizontal).unwrap_or(0.0) * 3.0
@ -789,32 +756,24 @@ impl State {
let vertical_amount_discrete = event.amount_discrete(Axis::Vertical); let vertical_amount_discrete = event.amount_discrete(Axis::Vertical);
{ {
let mut frame = AxisFrame::new(event.time()).source(source); let mut frame = AxisFrame::new(event.time()).source(event.source());
if horizontal_amount != 0.0 { if horizontal_amount != 0.0 {
frame = frame frame = frame.value(Axis::Horizontal, horizontal_amount);
.value(wl_pointer::Axis::HorizontalScroll, horizontal_amount);
if let Some(discrete) = horizontal_amount_discrete { if let Some(discrete) = horizontal_amount_discrete {
frame = frame.discrete( frame = frame.discrete(Axis::Horizontal, discrete as i32);
wl_pointer::Axis::HorizontalScroll,
discrete as i32,
);
} }
} else if source == wl_pointer::AxisSource::Finger { } else if event.source() == AxisSource::Finger {
frame = frame.stop(wl_pointer::Axis::HorizontalScroll); frame = frame.stop(Axis::Horizontal);
} }
if vertical_amount != 0.0 { if vertical_amount != 0.0 {
frame = frame = frame.value(Axis::Vertical, vertical_amount);
frame.value(wl_pointer::Axis::VerticalScroll, vertical_amount);
if let Some(discrete) = vertical_amount_discrete { if let Some(discrete) = vertical_amount_discrete {
frame = frame.discrete( frame = frame.discrete(Axis::Vertical, discrete as i32);
wl_pointer::Axis::VerticalScroll,
discrete as i32,
);
} }
} else if source == wl_pointer::AxisSource::Finger { } else if event.source() == AxisSource::Finger {
frame = frame.stop(wl_pointer::Axis::VerticalScroll); frame = frame.stop(Axis::Vertical);
} }
seat.get_pointer().unwrap().axis(self, dh, frame); seat.get_pointer().unwrap().axis(self, frame);
} }
break; break;
} }

View file

@ -68,7 +68,7 @@ fn main() -> Result<()> {
// trigger routines // trigger routines
data.state.common.shell.refresh(&data.display.handle()); data.state.common.shell.refresh(&data.display.handle());
data.state.common.refresh_focus(&data.display.handle()); state::Common::refresh_focus(&mut data.state);
// do we need to trigger another render // do we need to trigger another render
if data.state.common.dirty_flag.swap(false, Ordering::SeqCst) { if data.state.common.dirty_flag.swap(false, Ordering::SeqCst) {

View file

@ -7,12 +7,10 @@ use crate::{
use indexmap::IndexSet; use indexmap::IndexSet;
use smithay::{ use smithay::{
desktop::{PopupUngrabStrategy, Window, WindowSurfaceType}, desktop::{PopupUngrabStrategy, Window, WindowSurfaceType},
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle}, input::Seat,
utils::IsAlive, reexports::wayland_server::protocol::wl_surface::WlSurface,
wayland::{ utils::{IsAlive, Serial, SERIAL_COUNTER},
compositor::with_states, seat::Seat, shell::xdg::XdgToplevelSurfaceRoleAttributes, Serial, wayland::{compositor::with_states, shell::xdg::XdgToplevelSurfaceRoleAttributes},
SERIAL_COUNTER,
},
}; };
use std::{ use std::{
cell::{Ref, RefCell, RefMut}, cell::{Ref, RefCell, RefMut},
@ -112,15 +110,14 @@ impl ActiveFocus {
impl Shell { impl Shell {
pub fn set_focus<'a>( pub fn set_focus<'a>(
&mut self, state: &mut State,
dh: &DisplayHandle,
surface: Option<&WlSurface>, surface: Option<&WlSurface>,
active_seat: &Seat<State>, active_seat: &Seat<State>,
serial: Option<Serial>, serial: Option<Serial>,
) { ) {
// update FocusStack and notify layouts about new focus (if any window) // update FocusStack and notify layouts about new focus (if any window)
if let Some(surface) = surface { if let Some(surface) = surface {
if let Some(workspace) = self.space_for_window_mut(surface) { if let Some(workspace) = state.common.shell.space_for_window_mut(surface) {
if let Some(window) = workspace if let Some(window) = workspace
.space .space
.window_for_surface(surface, WindowSurfaceType::ALL) .window_for_surface(surface, WindowSurfaceType::ALL)
@ -136,7 +133,7 @@ impl Shell {
.and_then(|x| x.take()) .and_then(|x| x.take())
{ {
if !popup_grab.has_ended() { if !popup_grab.has_ended() {
popup_grab.ungrab(dh, PopupUngrabStrategy::All); popup_grab.ungrab(PopupUngrabStrategy::All);
} }
} }
} }
@ -148,8 +145,8 @@ impl Shell {
if let Some(keyboard) = active_seat.get_keyboard() { if let Some(keyboard) = active_seat.get_keyboard() {
ActiveFocus::set(active_seat, surface.cloned()); ActiveFocus::set(active_seat, surface.cloned());
keyboard.set_focus( keyboard.set_focus(
dh, state,
surface, surface.cloned(),
serial.unwrap_or_else(|| SERIAL_COUNTER.next_serial()), serial.unwrap_or_else(|| SERIAL_COUNTER.next_serial()),
); );
} }
@ -191,21 +188,21 @@ impl Shell {
impl Common { impl Common {
pub fn set_focus( pub fn set_focus(
&mut self, state: &mut State,
dh: &DisplayHandle,
surface: Option<&WlSurface>, surface: Option<&WlSurface>,
active_seat: &Seat<State>, active_seat: &Seat<State>,
serial: Option<Serial>, serial: Option<Serial>,
) { ) {
self.shell.set_focus(dh, surface, active_seat, serial); Shell::set_focus(state, surface, active_seat, serial);
self.shell.update_active(self.seats.iter()); state.common.shell.update_active(state.common.seats.iter());
} }
pub fn refresh_focus(&mut self, dh: &DisplayHandle) { pub fn refresh_focus(state: &mut State) {
for seat in &self.seats { let seats = state.common.seats.clone();
for seat in seats {
let mut fixup = false; let mut fixup = false;
let output = active_output(seat, &self); let output = active_output(&seat, &state.common);
let last_known_focus = ActiveFocus::get(seat); let last_known_focus = ActiveFocus::get(&seat);
if let Some(surface) = last_known_focus { if let Some(surface) = last_known_focus {
if surface.alive() { if surface.alive() {
@ -219,7 +216,7 @@ impl Common {
continue; continue;
} }
let workspace = self.shell.active_space(&output); let workspace = state.common.shell.active_space(&output);
if let Some(window) = workspace if let Some(window) = workspace
.space .space
.window_for_surface(&surface, WindowSurfaceType::ALL) .window_for_surface(&surface, WindowSurfaceType::ALL)
@ -244,24 +241,25 @@ impl Common {
.and_then(|x| x.take()) .and_then(|x| x.take())
{ {
if !popup_grab.has_ended() { if !popup_grab.has_ended() {
popup_grab.ungrab(dh, PopupUngrabStrategy::All); popup_grab.ungrab(PopupUngrabStrategy::All);
} }
} }
// update keyboard focus // update keyboard focus
let surface = self let surface = state
.common
.shell .shell
.active_space(&output) .active_space(&output)
.focus_stack(seat) .focus_stack(&seat)
.last() .last()
.map(|w| w.toplevel().wl_surface().clone()); .map(|w| w.toplevel().wl_surface().clone());
if let Some(keyboard) = seat.get_keyboard() { if let Some(keyboard) = seat.get_keyboard() {
keyboard.set_focus(dh, surface.as_ref(), SERIAL_COUNTER.next_serial()); keyboard.set_focus(state, surface.clone(), SERIAL_COUNTER.next_serial());
ActiveFocus::set(seat, surface); ActiveFocus::set(&seat, surface);
} }
} }
} }
self.shell.update_active(self.seats.iter()) state.common.shell.update_active(state.common.seats.iter())
} }
} }

View file

@ -11,34 +11,35 @@ use smithay::{
space::{RenderElement, SpaceOutputTuple}, space::{RenderElement, SpaceOutputTuple},
Kind, Window, Kind, Window,
}, },
input::{
pointer::{
AxisFrame, ButtonEvent, Focus, GrabStartData as PointerGrabStartData, MotionEvent,
PointerGrab, PointerInnerHandle,
},
Seat,
},
reexports::{ reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::State as XdgState, wayland_protocols::xdg::shell::server::xdg_toplevel::State as XdgState,
wayland_server::DisplayHandle, wayland_server::protocol::wl_surface::WlSurface,
},
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale},
wayland::{
output::Output,
seat::{
AxisFrame, ButtonEvent, MotionEvent, PointerGrab, PointerGrabStartData,
PointerInnerHandle,
},
seat::{Focus, Seat},
Serial,
}, },
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial},
wayland::output::Output,
}; };
use std::cell::RefCell; use std::cell::RefCell;
impl Shell { impl Shell {
pub fn move_request( pub fn move_request(
&mut self, state: &mut State,
window: &Window, window: &Window,
seat: &Seat<State>, seat: &Seat<State>,
serial: Serial, serial: Serial,
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
) { ) {
// TODO touch grab // TODO touch grab
if let Some(pointer) = seat.get_pointer() { if let Some(pointer) = seat.get_pointer() {
let workspace = self let workspace = state
.common
.shell
.space_for_window_mut(window.toplevel().wl_surface()) .space_for_window_mut(window.toplevel().wl_surface())
.unwrap(); .unwrap();
if workspace.fullscreen.values().any(|w| w == window) { if workspace.fullscreen.values().any(|w| w == window) {
@ -91,16 +92,25 @@ impl Shell {
let workspace_is_empty = workspace.space.windows().next().is_none(); let workspace_is_empty = workspace.space.windows().next().is_none();
if workspace_is_empty { if workspace_is_empty {
self.workspace_state state
.common
.shell
.workspace_state
.update() .update()
.add_workspace_state(&workspace_handle, WState::Hidden); .add_workspace_state(&workspace_handle, WState::Hidden);
} }
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_leave_workspace(&window, &workspace_handle); .toplevel_leave_workspace(&window, &workspace_handle);
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_leave_output(&window, &output); .toplevel_leave_output(&window, &output);
let state = MoveGrabState { let grab_state = MoveGrabState {
window: window.clone(), window: window.clone(),
was_tiled, was_tiled,
initial_cursor_location: pointer.current_location(), initial_cursor_location: pointer.current_location(),
@ -112,12 +122,12 @@ impl Shell {
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.unwrap() .unwrap()
.borrow_mut() = Some(state); .borrow_mut() = Some(grab_state);
pointer.set_grab(grab, serial, Focus::Clear); pointer.set_grab(state, grab, serial, Focus::Clear);
} }
} }
fn drop_move(&mut self, dh: &DisplayHandle, seat: &Seat<State>, output: &Output) { fn drop_move(state: &mut State, seat: &Seat<State>, output: &Output) {
if let Some(move_state) = seat if let Some(move_state) = seat
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
@ -134,16 +144,25 @@ impl Shell {
(move_state.initial_window_location.to_f64() + delta).to_i32_round(); (move_state.initial_window_location.to_f64() + delta).to_i32_round();
let surface = window.toplevel().wl_surface().clone(); let surface = window.toplevel().wl_surface().clone();
let workspace_handle = self.active_space(output).handle; let workspace_handle = state.common.shell.active_space(output).handle;
self.workspace_state state
.common
.shell
.workspace_state
.update() .update()
.remove_workspace_state(&workspace_handle, WState::Hidden); .remove_workspace_state(&workspace_handle, WState::Hidden);
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_enter_workspace(&window, &workspace_handle); .toplevel_enter_workspace(&window, &workspace_handle);
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_enter_output(&window, &output); .toplevel_enter_output(&window, &output);
let workspace = self.active_space_mut(output); let workspace = state.common.shell.active_space_mut(output);
if move_state.was_tiled { if move_state.was_tiled {
let focus_stack = workspace.focus_stack(&seat); let focus_stack = workspace.focus_stack(&seat);
workspace.tiling_layer.map_window( workspace.tiling_layer.map_window(
@ -161,10 +180,10 @@ impl Shell {
); );
} }
self.set_focus(dh, Some(&surface), &seat, None); Shell::set_focus(state, Some(&surface), &seat, None);
for window in self.active_space(output).space.windows() { for window in state.common.shell.active_space(output).space.windows() {
self.update_reactive_popups(window); state.common.shell.update_reactive_popups(window);
} }
} }
} }
@ -267,7 +286,7 @@ impl MoveGrabState {
pub struct MoveSurfaceGrab { pub struct MoveSurfaceGrab {
window: Window, window: Window,
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
seat: Seat<State>, seat: Seat<State>,
} }
@ -275,48 +294,46 @@ impl PointerGrab<State> for MoveSurfaceGrab {
fn motion( fn motion(
&mut self, &mut self,
state: &mut State, state: &mut State,
dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
_focus: Option<(WlSurface, Point<i32, Logical>)>,
event: &MotionEvent, event: &MotionEvent,
) { ) {
// While the grab is active, no client has pointer focus // While the grab is active, no client has pointer focus
handle.motion(event.location, None, event.serial, event.time); handle.motion(state, None, event);
if !self.window.alive() { if !self.window.alive() {
self.ungrab(dh, state, handle, event.serial, event.time); self.ungrab(state, handle, event.serial, event.time);
} }
} }
fn button( fn button(
&mut self, &mut self,
state: &mut State, state: &mut State,
dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
event: &ButtonEvent, event: &ButtonEvent,
) { ) {
handle.button(event.button, event.state, event.serial, event.time); handle.button(state, event);
if handle.current_pressed().is_empty() { if handle.current_pressed().is_empty() {
self.ungrab(dh, state, handle, event.serial, event.time); self.ungrab(state, handle, event.serial, event.time);
} }
} }
fn axis( fn axis(
&mut self, &mut self,
_state: &mut State, state: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
details: AxisFrame, details: AxisFrame,
) { ) {
handle.axis(details); handle.axis(state, details);
} }
fn start_data(&self) -> &PointerGrabStartData { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }
} }
impl MoveSurfaceGrab { impl MoveSurfaceGrab {
pub fn new( pub fn new(
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
window: Window, window: Window,
seat: &Seat<State>, seat: &Seat<State>,
) -> MoveSurfaceGrab { ) -> MoveSurfaceGrab {
@ -329,7 +346,6 @@ impl MoveSurfaceGrab {
fn ungrab( fn ungrab(
&mut self, &mut self,
dh: &DisplayHandle,
state: &mut State, state: &mut State,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
serial: Serial, serial: Serial,
@ -337,12 +353,11 @@ impl MoveSurfaceGrab {
) { ) {
// No more buttons are pressed, release the grab. // No more buttons are pressed, release the grab.
let output = active_output(&self.seat, &state.common); let output = active_output(&self.seat, &state.common);
let dh = dh.clone();
let seat = self.seat.clone(); let seat = self.seat.clone();
state.common.event_loop_handle.insert_idle(move |data| { state.common.event_loop_handle.insert_idle(move |data| {
data.state.common.shell.drop_move(&dh, &seat, &output); Shell::drop_move(&mut data.state, &seat, &output);
}); });
handle.unset_grab(serial, time); handle.unset_grab(state, serial, time);
} }
} }

View file

@ -3,18 +3,18 @@
use crate::utils::prelude::*; use crate::utils::prelude::*;
use smithay::{ use smithay::{
desktop::{Kind, Window}, desktop::{Kind, Window},
reexports::{ input::pointer::{
wayland_protocols::xdg::shell::server::xdg_toplevel, wayland_server::DisplayHandle, AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
PointerInnerHandle,
}, },
utils::{IsAlive, Logical, Point, Size}, reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel,
wayland_server::protocol::wl_surface::WlSurface,
},
utils::{IsAlive, Logical, Point, Serial, Size},
wayland::{ wayland::{
compositor::with_states, compositor::with_states,
seat::{
AxisFrame, ButtonEvent, MotionEvent, PointerGrab, PointerGrabStartData,
PointerInnerHandle,
},
shell::xdg::{SurfaceCachedState, ToplevelConfigure, XdgToplevelSurfaceRoleAttributes}, shell::xdg::{SurfaceCachedState, ToplevelConfigure, XdgToplevelSurfaceRoleAttributes},
Serial,
}, },
}; };
use std::{cell::RefCell, convert::TryFrom, sync::Mutex}; use std::{cell::RefCell, convert::TryFrom, sync::Mutex};
@ -78,7 +78,7 @@ impl Default for ResizeState {
} }
pub struct ResizeSurfaceGrab { pub struct ResizeSurfaceGrab {
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
window: Window, window: Window,
edges: ResizeEdge, edges: ResizeEdge,
initial_window_size: Size<i32, Logical>, initial_window_size: Size<i32, Logical>,
@ -88,17 +88,17 @@ pub struct ResizeSurfaceGrab {
impl PointerGrab<State> for ResizeSurfaceGrab { impl PointerGrab<State> for ResizeSurfaceGrab {
fn motion( fn motion(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
_focus: Option<(WlSurface, Point<i32, Logical>)>,
event: &MotionEvent, event: &MotionEvent,
) { ) {
// While the grab is active, no client has pointer focus // While the grab is active, no client has pointer focus
handle.motion(event.location, None, event.serial, event.time); handle.motion(data, None, event);
// It is impossible to get `min_size` and `max_size` of dead toplevel, so we return early. // It is impossible to get `min_size` and `max_size` of dead toplevel, so we return early.
if !self.window.alive() { if !self.window.alive() {
handle.unset_grab(event.serial, event.time); handle.unset_grab(data, event.serial, event.time);
return; return;
} }
@ -162,15 +162,14 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
fn button( fn button(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
event: &ButtonEvent, event: &ButtonEvent,
) { ) {
handle.button(event.button, event.state, event.serial, event.time); handle.button(data, event);
if handle.current_pressed().is_empty() { if handle.current_pressed().is_empty() {
// No more buttons are pressed, release the grab. // No more buttons are pressed, release the grab.
handle.unset_grab(event.serial, event.time); handle.unset_grab(data, event.serial, event.time);
// If toplevel is dead, we can't resize it, so we return early. // If toplevel is dead, we can't resize it, so we return early.
if !self.window.alive() { if !self.window.alive() {
@ -202,22 +201,21 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
fn axis( fn axis(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
details: AxisFrame, details: AxisFrame,
) { ) {
handle.axis(details) handle.axis(data, details)
} }
fn start_data(&self) -> &PointerGrabStartData { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }
} }
impl ResizeSurfaceGrab { impl ResizeSurfaceGrab {
pub fn new( pub fn new(
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
window: Window, window: Window,
edges: xdg_toplevel::ResizeEdge, edges: xdg_toplevel::ResizeEdge,
initial_window_location: Point<i32, Logical>, initial_window_location: Point<i32, Logical>,

View file

@ -2,16 +2,16 @@
use smithay::{ use smithay::{
desktop::{layer_map_for_output, space::RenderZindex, Kind, Space, Window}, desktop::{layer_map_for_output, space::RenderZindex, Kind, Space, Window},
input::{
pointer::{Focus, GrabStartData as PointerGrabStartData},
Seat,
},
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{ reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{
ResizeEdge, State as XdgState, ResizeEdge, State as XdgState,
}, },
utils::{IsAlive, Logical, Point, Rectangle}, utils::{IsAlive, Logical, Point, Rectangle, Serial},
wayland::{ wayland::{
compositor::with_states, compositor::with_states, output::Output, shell::xdg::XdgToplevelSurfaceRoleAttributes,
output::Output,
seat::{Focus, PointerGrabStartData, Seat},
shell::xdg::XdgToplevelSurfaceRoleAttributes,
Serial,
}, },
}; };
use std::{collections::HashSet, sync::Mutex}; use std::{collections::HashSet, sync::Mutex};
@ -232,14 +232,21 @@ impl FloatingLayout {
} }
pub fn resize_request( pub fn resize_request(
&mut self, state: &mut State,
space: &mut Space,
window: &Window, window: &Window,
seat: &Seat<State>, seat: &Seat<State>,
serial: Serial, serial: Serial,
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
edges: ResizeEdge, edges: ResizeEdge,
) { ) {
// it is so stupid, that we have to do this here. TODO: Refactor grabs
let workspace = state
.common
.shell
.space_for_window_mut(window.toplevel().wl_surface())
.unwrap();
let space = &mut workspace.space;
if let Some(pointer) = seat.get_pointer() { if let Some(pointer) = seat.get_pointer() {
let location = space.window_location(&window).unwrap(); let location = space.window_location(&window).unwrap();
let size = window.geometry().size; let size = window.geometry().size;
@ -247,7 +254,7 @@ impl FloatingLayout {
let grab = let grab =
grabs::ResizeSurfaceGrab::new(start_data, window.clone(), edges, location, size); grabs::ResizeSurfaceGrab::new(start_data, window.clone(), edges, location, size);
pointer.set_grab(grab, serial, Focus::Clear); pointer.set_grab(state, grab, serial, Focus::Clear);
} }
} }
} }

View file

@ -4,9 +4,9 @@ use crate::{input::ActiveOutput, state::State};
use regex::RegexSet; use regex::RegexSet;
use smithay::{ use smithay::{
desktop::{Space, Window}, desktop::{Space, Window},
input::Seat,
wayland::{ wayland::{
compositor::with_states, output::Output, seat::Seat, compositor::with_states, output::Output, shell::xdg::XdgToplevelSurfaceRoleAttributes,
shell::xdg::XdgToplevelSurfaceRoleAttributes,
}, },
}; };
use std::sync::Mutex; use std::sync::Mutex;

View file

@ -3,16 +3,17 @@
use crate::{shell::layout::Orientation, utils::prelude::*}; use crate::{shell::layout::Orientation, utils::prelude::*};
use atomic_float::AtomicF64; use atomic_float::AtomicF64;
use smithay::{ use smithay::{
reexports::wayland_server::DisplayHandle, input::pointer::{
utils::{Logical, Size}, AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
wayland::seat::{ PointerInnerHandle,
AxisFrame, ButtonEvent, MotionEvent, PointerGrab, PointerGrabStartData, PointerInnerHandle,
}, },
reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{Logical, Point, Size},
}; };
use std::sync::{atomic::Ordering, Arc}; use std::sync::{atomic::Ordering, Arc};
pub struct ResizeForkGrab { pub struct ResizeForkGrab {
pub start_data: PointerGrabStartData, pub start_data: PointerGrabStartData<State>,
pub orientation: Orientation, pub orientation: Orientation,
pub initial_size: Size<i32, Logical>, pub initial_size: Size<i32, Logical>,
pub initial_ratio: f64, pub initial_ratio: f64,
@ -22,13 +23,13 @@ pub struct ResizeForkGrab {
impl PointerGrab<State> for ResizeForkGrab { impl PointerGrab<State> for ResizeForkGrab {
fn motion( fn motion(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
_focus: Option<(WlSurface, Point<i32, Logical>)>,
event: &MotionEvent, event: &MotionEvent,
) { ) {
// While the grab is active, no client has pointer focus // While the grab is active, no client has pointer focus
handle.motion(event.location, None, event.serial, event.time); handle.motion(data, None, event);
let delta = event.location - self.start_data.location; let delta = event.location - self.start_data.location;
let delta = match self.orientation { let delta = match self.orientation {
@ -43,29 +44,27 @@ impl PointerGrab<State> for ResizeForkGrab {
fn button( fn button(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
event: &ButtonEvent, event: &ButtonEvent,
) { ) {
handle.button(event.button, event.state, event.serial, event.time); handle.button(data, event);
if handle.current_pressed().is_empty() { if handle.current_pressed().is_empty() {
// No more buttons are pressed, release the grab. // No more buttons are pressed, release the grab.
handle.unset_grab(event.serial, event.time); handle.unset_grab(data, event.serial, event.time);
} }
} }
fn axis( fn axis(
&mut self, &mut self,
_data: &mut State, data: &mut State,
_dh: &DisplayHandle,
handle: &mut PointerInnerHandle<'_, State>, handle: &mut PointerInnerHandle<'_, State>,
details: AxisFrame, details: AxisFrame,
) { ) {
handle.axis(details) handle.axis(data, details)
} }
fn start_data(&self) -> &PointerGrabStartData { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }
} }

View file

@ -9,14 +9,14 @@ use atomic_float::AtomicF64;
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
use smithay::{ use smithay::{
desktop::{layer_map_for_output, Kind, Space, Window}, desktop::{layer_map_for_output, Kind, Space, Window},
input::{
pointer::{Focus, GrabStartData as PointerGrabStartData},
Seat,
},
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{ reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{
ResizeEdge, State as XdgState, ResizeEdge, State as XdgState,
}, },
utils::{IsAlive, Rectangle}, utils::{IsAlive, Rectangle, Serial},
wayland::{
seat::{Focus, PointerGrabStartData, Seat},
Serial,
},
}; };
use std::{ use std::{
cell::RefCell, cell::RefCell,
@ -233,18 +233,26 @@ impl TilingLayout {
} }
pub fn resize_request( pub fn resize_request(
&mut self, state: &mut State,
space: &mut Space,
window: &Window, window: &Window,
seat: &Seat<State>, seat: &Seat<State>,
serial: Serial, serial: Serial,
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
edges: ResizeEdge, edges: ResizeEdge,
) { ) {
// it is so stupid, that we have to do this here. TODO: Refactor grabs
let workspace = state
.common
.shell
.space_for_window_mut(window.toplevel().wl_surface())
.unwrap();
let space = &mut workspace.space;
let trees = &mut workspace.tiling_layer.trees;
if let Some(pointer) = seat.get_pointer() { if let Some(pointer) = seat.get_pointer() {
if let Some(info) = window.user_data().get::<RefCell<WindowInfo>>() { if let Some(info) = window.user_data().get::<RefCell<WindowInfo>>() {
let output = info.borrow().output; let output = info.borrow().output;
let tree = TilingLayout::active_tree(&mut self.trees, output); let tree = TilingLayout::active_tree(trees, output);
let mut node_id = info.borrow().node.clone(); let mut node_id = info.borrow().node.clone();
while let Some((fork, child)) = TilingLayout::find_fork(tree, node_id) { while let Some((fork, child)) = TilingLayout::find_fork(tree, node_id) {
@ -261,18 +269,19 @@ impl TilingLayout {
| (false, Orientation::Horizontal, ResizeEdge::Top) | (false, Orientation::Horizontal, ResizeEdge::Top)
| (true, Orientation::Vertical, ResizeEdge::Right) | (true, Orientation::Vertical, ResizeEdge::Right)
| (false, Orientation::Vertical, ResizeEdge::Left) => { | (false, Orientation::Vertical, ResizeEdge::Left) => {
if let Some(output) = space.outputs().nth(output) { let output = space.outputs().nth(output).cloned();
if let Some(output) = output {
let grab = ResizeForkGrab { let grab = ResizeForkGrab {
start_data, start_data,
orientation: *orientation, orientation: *orientation,
initial_ratio: ratio.load(Ordering::SeqCst), initial_ratio: ratio.load(Ordering::SeqCst),
initial_size: layer_map_for_output(output) initial_size: layer_map_for_output(&output)
.non_exclusive_zone() .non_exclusive_zone()
.size, .size,
ratio: ratio.clone(), ratio: ratio.clone(),
}; };
pointer.set_grab(grab, serial, Focus::Clear); pointer.set_grab(state, grab, serial, Focus::Clear);
} }
return; return;
} }

View file

@ -2,19 +2,18 @@ use std::{cell::Cell, mem::MaybeUninit};
use smithay::{ use smithay::{
desktop::{layer_map_for_output, LayerSurface, PopupManager, Window, WindowSurfaceType}, desktop::{layer_map_for_output, LayerSurface, PopupManager, Window, WindowSurfaceType},
input::{pointer::MotionEvent, Seat},
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle}, reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
utils::{Logical, Point, Rectangle}, utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
wayland::{ wayland::{
compositor::with_states, compositor::with_states,
output::Output, output::Output,
seat::{MotionEvent, Seat},
shell::{ shell::{
wlr_layer::{ wlr_layer::{
KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState, KeyboardInteractivity, Layer, LayerSurfaceCachedState, WlrLayerShellState,
}, },
xdg::XdgShellState, xdg::XdgShellState,
}, },
SERIAL_COUNTER,
}, },
}; };
@ -372,7 +371,6 @@ impl Shell {
geometry.loc.y + (geometry.size.h / 2), geometry.loc.y + (geometry.size.h / 2),
)) ))
.to_f64(), .to_f64(),
focus: None, // This should actually be a surface, if there is one in the center
serial: SERIAL_COUNTER.next_serial(), serial: SERIAL_COUNTER.next_serial(),
time: 0, time: 0,
}); });
@ -593,16 +591,18 @@ impl Shell {
.refresh(Some(&self.workspace_state)); .refresh(Some(&self.workspace_state));
} }
pub fn map_window(&mut self, window: &Window, output: &Output, dh: &DisplayHandle) { pub fn map_window(state: &mut State, window: &Window, output: &Output) {
let pos = self let pos = state
.common
.shell
.pending_windows .pending_windows
.iter() .iter()
.position(|(w, _)| w == window) .position(|(w, _)| w == window)
.unwrap(); .unwrap();
let (window, seat) = self.pending_windows.remove(pos); let (window, seat) = state.common.shell.pending_windows.remove(pos);
let surface = window.toplevel().wl_surface().clone(); let surface = window.toplevel().wl_surface().clone();
let workspace = match &self.workspace_mode { let workspace = match &state.common.shell.workspace_mode {
WorkspaceMode::OutputBound => { WorkspaceMode::OutputBound => {
let active = output let active = output
.user_data() .user_data()
@ -610,18 +610,27 @@ impl Shell {
.unwrap() .unwrap()
.active .active
.get(); .get();
&mut self.spaces[active] &mut state.common.shell.spaces[active]
} }
WorkspaceMode::Global { active, .. } => &mut self.spaces[*active], WorkspaceMode::Global { active, .. } => &mut state.common.shell.spaces[*active],
}; };
self.workspace_state state
.common
.shell
.workspace_state
.update() .update()
.remove_workspace_state(&workspace.handle, WState::Hidden); .remove_workspace_state(&workspace.handle, WState::Hidden);
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_enter_workspace(&window, &workspace.handle); .toplevel_enter_workspace(&window, &workspace.handle);
self.toplevel_info_state state
.common
.shell
.toplevel_info_state
.toplevel_enter_output(&window, &output); .toplevel_enter_output(&window, &output);
if layout::should_be_floating(&window) || self.floating_default { if layout::should_be_floating(&window) || state.common.shell.floating_default {
workspace workspace
.floating_layer .floating_layer
.map_window(&mut workspace.space, window, &seat, None); .map_window(&mut workspace.space, window, &seat, None);
@ -635,20 +644,22 @@ impl Shell {
); );
} }
self.set_focus(dh, Some(&surface), &seat, None); Shell::set_focus(state, Some(&surface), &seat, None);
for window in self.active_space(output).space.windows() { for window in state.common.shell.active_space(output).space.windows() {
self.update_reactive_popups(window); state.common.shell.update_reactive_popups(window);
} }
} }
pub fn map_layer(&mut self, layer_surface: &LayerSurface, dh: &DisplayHandle) { pub fn map_layer(state: &mut State, layer_surface: &LayerSurface) {
let pos = self let pos = state
.common
.shell
.pending_layers .pending_layers
.iter() .iter()
.position(|(l, _, _)| l == layer_surface) .position(|(l, _, _)| l == layer_surface)
.unwrap(); .unwrap();
let (layer_surface, output, seat) = self.pending_layers.remove(pos); let (layer_surface, output, seat) = state.common.shell.pending_layers.remove(pos);
let surface = layer_surface.wl_surface(); let surface = layer_surface.wl_surface();
let wants_focus = { let wants_focus = {
@ -660,10 +671,11 @@ impl Shell {
}; };
let mut map = layer_map_for_output(&output); let mut map = layer_map_for_output(&output);
map.map_layer(dh, &layer_surface).unwrap(); map.map_layer(&state.common.display_handle, &layer_surface)
.unwrap();
if wants_focus { if wants_focus {
self.set_focus(dh, Some(surface), &seat, None) Shell::set_focus(state, Some(surface), &seat, None)
} }
} }

View file

@ -5,17 +5,14 @@ use crate::{
}; };
use smithay::{ use smithay::{
desktop::{Kind, Space, Window}, desktop::{Kind, Space, Window, WindowSurfaceType},
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
reexports::{ reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge}, wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge},
wayland_server::DisplayHandle, wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle},
},
utils::IsAlive,
wayland::{
output::Output,
seat::{PointerGrabStartData, Seat},
Serial,
}, },
utils::{IsAlive, Serial},
wayland::output::Output,
}; };
use std::collections::HashMap; use std::collections::HashMap;
@ -81,35 +78,27 @@ impl Workspace {
} }
pub fn resize_request( pub fn resize_request(
&mut self, state: &mut State,
window: &Window, surface: &WlSurface,
seat: &Seat<State>, seat: &Seat<State>,
serial: Serial, serial: Serial,
start_data: PointerGrabStartData, start_data: PointerGrabStartData<State>,
edges: ResizeEdge, edges: ResizeEdge,
) { ) {
if self.fullscreen.values().any(|w| w == window) { let workspace = state.common.shell.space_for_window_mut(surface).unwrap();
let window = workspace
.space
.window_for_surface(surface, WindowSurfaceType::TOPLEVEL)
.unwrap()
.clone();
if workspace.fullscreen.values().any(|w| w == &window) {
return; return;
} }
if self.floating_layer.windows.contains(window) { if workspace.floating_layer.windows.contains(&window) {
self.floating_layer.resize_request( FloatingLayout::resize_request(state, &window, seat, serial, start_data.clone(), edges)
&mut self.space, } else if workspace.tiling_layer.windows.contains(&window) {
window, TilingLayout::resize_request(state, &window, seat, serial, start_data, edges)
seat,
serial,
start_data.clone(),
edges,
)
}
if self.tiling_layer.windows.contains(window) {
self.tiling_layer.resize_request(
&mut self.space,
window,
seat,
serial,
start_data,
edges,
)
} }
} }

View file

@ -13,6 +13,7 @@ use crate::{
}; };
use smithay::{ use smithay::{
backend::drm::DrmNode, backend::drm::DrmNode,
input::{Seat, SeatState},
reexports::{ reexports::{
calloop::{LoopHandle, LoopSignal}, calloop::{LoopHandle, LoopSignal},
wayland_server::{ wayland_server::{
@ -27,7 +28,6 @@ use smithay::{
dmabuf::DmabufState, dmabuf::DmabufState,
output::{Mode as OutputMode, Output, OutputManagerState, Scale}, output::{Mode as OutputMode, Output, OutputManagerState, Scale},
primary_selection::PrimarySelectionState, primary_selection::PrimarySelectionState,
seat::{Seat, SeatState},
shm::ShmState, shm::ShmState,
viewporter::ViewporterState, viewporter::ViewporterState,
}, },
@ -66,6 +66,7 @@ pub struct Common {
pub config: Config, pub config: Config,
pub socket: OsString, pub socket: OsString,
pub display_handle: DisplayHandle,
pub event_loop_handle: LoopHandle<'static, Data>, pub event_loop_handle: LoopHandle<'static, Data>,
pub event_loop_signal: LoopSignal, pub event_loop_signal: LoopSignal,
@ -307,12 +308,12 @@ impl State {
let output_configuration_state = OutputConfigurationState::new(dh, |_| true); let output_configuration_state = OutputConfigurationState::new(dh, |_| true);
let primary_selection_state = PrimarySelectionState::new::<Self, _>(dh, None); let primary_selection_state = PrimarySelectionState::new::<Self, _>(dh, None);
let shm_state = ShmState::new::<Self, _>(dh, vec![], None); let shm_state = ShmState::new::<Self, _>(dh, vec![], None);
let seat_state = SeatState::<Self>::new(); let mut seat_state = SeatState::<Self>::new();
let viewporter_state = ViewporterState::new::<Self, _>(dh, None); let viewporter_state = ViewporterState::new::<Self, _>(dh, None);
let wl_drm_state = WlDrmState; let wl_drm_state = WlDrmState;
let shell = Shell::new(&config, dh); let shell = Shell::new(&config, dh);
let initial_seat = crate::input::add_seat(dh, &config, "seat-0".into()); let initial_seat = crate::input::add_seat(dh, &mut seat_state, &config, "seat-0".into());
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
let dirty_flag = Arc::new(AtomicBool::new(false)); let dirty_flag = Arc::new(AtomicBool::new(false));
@ -323,6 +324,7 @@ impl State {
common: Common { common: Common {
config, config,
socket, socket,
display_handle: dh.clone(),
event_loop_handle: handle, event_loop_handle: handle,
event_loop_signal: signal, event_loop_signal: signal,

View file

@ -1,14 +1,13 @@
use crate::{ use crate::input::{ActiveOutput, SeatId};
input::{ActiveOutput, SeatId},
state::Common,
};
use smithay::{ use smithay::{
input::Seat,
utils::{Logical, Rectangle, Transform}, utils::{Logical, Rectangle, Transform},
wayland::{output::Output, seat::Seat}, wayland::output::Output,
}; };
use std::cell::RefCell; use std::cell::RefCell;
pub use crate::state::State; pub use crate::shell::{Shell, Workspace};
pub use crate::state::{Common, State};
pub use crate::wayland::handlers::xdg_shell::popup::update_reactive_popups; pub use crate::wayland::handlers::xdg_shell::popup::update_reactive_popups;
pub trait OutputExt { pub trait OutputExt {

View file

@ -5,7 +5,7 @@ use smithay::{
backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state}, backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state},
delegate_compositor, delegate_compositor,
desktop::{layer_map_for_output, Kind, LayerSurface, PopupKind, WindowSurfaceType}, desktop::{layer_map_for_output, Kind, LayerSurface, PopupKind, WindowSurfaceType},
reexports::wayland_server::{protocol::wl_surface::WlSurface, DisplayHandle}, reexports::wayland_server::protocol::wl_surface::WlSurface,
wayland::{ wayland::{
compositor::{with_states, CompositorHandler, CompositorState}, compositor::{with_states, CompositorHandler, CompositorState},
shell::{ shell::{
@ -19,8 +19,9 @@ use smithay::{
use std::sync::Mutex; use std::sync::Mutex;
impl State { impl State {
fn early_import_surface(&mut self, dh: &DisplayHandle, surface: &WlSurface) { fn early_import_surface(&mut self, surface: &WlSurface) {
let mut import_nodes = std::collections::HashSet::new(); let mut import_nodes = std::collections::HashSet::new();
let dh = &self.common.display_handle;
for output in self.common.shell.outputs_for_surface(&surface) { for output in self.common.shell.outputs_for_surface(&surface) {
if let BackendData::Kms(ref mut kms_state) = &mut self.backend { if let BackendData::Kms(ref mut kms_state) = &mut self.backend {
if let Some(target) = kms_state.target_node_for_output(&output) { if let Some(target) = kms_state.target_node_for_output(&output) {
@ -75,11 +76,7 @@ impl State {
} }
} }
fn layer_surface_ensure_inital_configure( fn layer_surface_ensure_inital_configure(&mut self, surface: &LayerSurface) -> bool {
&mut self,
surface: &LayerSurface,
dh: &DisplayHandle,
) -> bool {
// send the initial configure if relevant // send the initial configure if relevant
let initial_configure_sent = with_states(surface.wl_surface(), |states| { let initial_configure_sent = with_states(surface.wl_surface(), |states| {
states states
@ -92,7 +89,7 @@ impl State {
}); });
if !initial_configure_sent { if !initial_configure_sent {
// compute initial dimensions by mapping // compute initial dimensions by mapping
self.common.shell.map_layer(&surface, dh); Shell::map_layer(self, &surface);
// this will also send a configure // this will also send a configure
} }
initial_configure_sent initial_configure_sent
@ -104,7 +101,7 @@ impl CompositorHandler for State {
&mut self.common.compositor_state &mut self.common.compositor_state
} }
fn commit(&mut self, dh: &DisplayHandle, surface: &WlSurface) { fn commit(&mut self, surface: &WlSurface) {
// first load the buffer for various smithay helper functions // first load the buffer for various smithay helper functions
on_commit_buffer_handler(surface); on_commit_buffer_handler(surface);
@ -125,7 +122,7 @@ impl CompositorHandler for State {
}) })
{ {
let output = active_output(&seat, &self.common); let output = active_output(&seat, &self.common);
self.common.shell.map_window(&window, &output, dh); Shell::map_window(self, &window, &output);
} else { } else {
return; return;
} }
@ -141,7 +138,7 @@ impl CompositorHandler for State {
.find(|(layer_surface, _, _)| layer_surface.wl_surface() == surface) .find(|(layer_surface, _, _)| layer_surface.wl_surface() == surface)
.cloned() .cloned()
{ {
if !self.layer_surface_ensure_inital_configure(&layer_surface, dh) { if !self.layer_surface_ensure_inital_configure(&layer_surface) {
return; return;
} }
}; };
@ -188,7 +185,7 @@ impl CompositorHandler for State {
// We need to know every potential output for importing to the right gpu and scheduling a render, // We need to know every potential output for importing to the right gpu and scheduling a render,
// so call this only after every potential surface map operation has been done. // so call this only after every potential surface map operation has been done.
self.early_import_surface(dh, surface); self.early_import_surface(surface);
// and refresh smithays internal state // and refresh smithays internal state
self.common.shell.popups.commit(surface); self.common.shell.popups.commit(surface);
@ -202,6 +199,7 @@ impl CompositorHandler for State {
map.layer_for_surface(surface, WindowSurfaceType::ALL) map.layer_for_surface(surface, WindowSurfaceType::ALL)
.is_some() .is_some()
}) { }) {
let dh = &self.common.display_handle;
layer_map_for_output(output).arrange(dh); layer_map_for_output(output).arrange(dh);
} }

View file

@ -3,13 +3,11 @@
use crate::state::State; use crate::state::State;
use smithay::{ use smithay::{
delegate_data_device, delegate_data_device,
input::Seat,
reexports::wayland_server::protocol::{wl_data_source::WlDataSource, wl_surface::WlSurface}, reexports::wayland_server::protocol::{wl_data_source::WlDataSource, wl_surface::WlSurface},
utils::IsAlive, utils::IsAlive,
wayland::{ wayland::data_device::{
data_device::{ ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler,
ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler,
},
seat::Seat,
}, },
}; };
use std::cell::RefCell; use std::cell::RefCell;

View file

@ -4,7 +4,6 @@ use crate::state::{BackendData, State};
use smithay::{ use smithay::{
backend::{allocator::dmabuf::Dmabuf, renderer::ImportDma}, backend::{allocator::dmabuf::Dmabuf, renderer::ImportDma},
delegate_dmabuf, delegate_dmabuf,
reexports::wayland_server::DisplayHandle,
wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError}, wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError},
}; };
@ -15,13 +14,12 @@ impl DmabufHandler for State {
fn dmabuf_imported( fn dmabuf_imported(
&mut self, &mut self,
dh: &DisplayHandle,
global: &DmabufGlobal, global: &DmabufGlobal,
dmabuf: Dmabuf, dmabuf: Dmabuf,
) -> Result<(), ImportError> { ) -> Result<(), ImportError> {
match &mut self.backend { match &mut self.backend {
BackendData::Kms(ref mut state) => state BackendData::Kms(ref mut state) => state
.dmabuf_imported(dh, global, dmabuf) .dmabuf_imported(global, dmabuf)
.map_err(|_| ImportError::Failed), .map_err(|_| ImportError::Failed),
BackendData::Winit(ref mut state) => state BackendData::Winit(ref mut state) => state
.backend .backend

View file

@ -15,13 +15,13 @@ use smithay::{
}, },
}, },
desktop::{draw_window, draw_window_popups, space::RenderElement, Kind, Window}, desktop::{draw_window, draw_window_popups, space::RenderElement, Kind, Window},
input::pointer::CursorImageStatus,
reexports::wayland_server::{protocol::wl_output::WlOutput, DisplayHandle, Resource}, reexports::wayland_server::{protocol::wl_output::WlOutput, DisplayHandle, Resource},
utils::{IsAlive, Size, Transform}, utils::{IsAlive, Size, Transform},
wayland::{ wayland::{
compositor::{get_children, with_states, SurfaceAttributes}, compositor::{get_children, with_states, SurfaceAttributes},
dmabuf::get_dmabuf, dmabuf::get_dmabuf,
output::Output, output::Output,
seat::CursorImageStatus,
}, },
}; };
@ -201,7 +201,7 @@ impl ExportDmabufHandler for State {
.get::<RefCell<CursorImageStatus>>() .get::<RefCell<CursorImageStatus>>()
.map(|cell| { .map(|cell| {
let mut cursor_status = cell.borrow_mut(); let mut cursor_status = cell.borrow_mut();
if let CursorImageStatus::Image(ref surface) = *cursor_status { if let CursorImageStatus::Surface(ref surface) = *cursor_status {
if !surface.alive() { if !surface.alive() {
*cursor_status = CursorImageStatus::Default; *cursor_status = CursorImageStatus::Default;
} }

View file

@ -4,7 +4,7 @@ use crate::utils::prelude::*;
use smithay::{ use smithay::{
delegate_layer_shell, delegate_layer_shell,
desktop::{LayerSurface, PopupKind}, desktop::{LayerSurface, PopupKind},
reexports::wayland_server::{protocol::wl_output::WlOutput, DisplayHandle}, reexports::wayland_server::protocol::wl_output::WlOutput,
wayland::{ wayland::{
output::Output, output::Output,
shell::{ shell::{
@ -23,7 +23,6 @@ impl WlrLayerShellHandler for State {
fn new_layer_surface( fn new_layer_surface(
&mut self, &mut self,
_dh: &DisplayHandle,
surface: WlrLayerSurface, surface: WlrLayerSurface,
wl_output: Option<WlOutput>, wl_output: Option<WlOutput>,
_layer: Layer, _layer: Layer,
@ -42,7 +41,7 @@ impl WlrLayerShellHandler for State {
)); ));
} }
fn new_popup(&mut self, _dh: &DisplayHandle, _parent: WlrLayerSurface, popup: PopupSurface) { fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
let positioner = popup.with_pending_state(|state| state.positioner); let positioner = popup.with_pending_state(|state| state.positioner);
self.common.shell.unconstrain_popup(&popup, &positioner); self.common.shell.unconstrain_popup(&popup, &positioner);

View file

@ -3,13 +3,44 @@
use crate::state::State; use crate::state::State;
use smithay::{ use smithay::{
delegate_seat, delegate_seat,
wayland::seat::{SeatHandler, SeatState}, input::{pointer::CursorImageStatus, SeatHandler, SeatState},
reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource},
wayland::{data_device::set_data_device_focus, primary_selection::set_primary_focus},
}; };
use std::cell::RefCell;
impl SeatHandler for State { impl SeatHandler for State {
type KeyboardFocus = WlSurface;
type PointerFocus = WlSurface;
fn seat_state(&mut self) -> &mut SeatState<Self> { fn seat_state(&mut self) -> &mut SeatState<Self> {
&mut self.common.seat_state &mut self.common.seat_state
} }
fn cursor_image(
&mut self,
seat: &smithay::input::Seat<Self>,
image: smithay::input::pointer::CursorImageStatus,
) {
*seat
.user_data()
.get::<RefCell<CursorImageStatus>>()
.unwrap()
.borrow_mut() = image;
}
fn focus_changed(
&mut self,
seat: &smithay::input::Seat<Self>,
focused: Option<&Self::KeyboardFocus>,
) {
let dh = &self.common.display_handle;
if let Some(client) = focused.and_then(|s| dh.get_client(s.id()).ok()) {
set_data_device_focus(dh, seat, Some(client));
let client2 = focused.and_then(|s| dh.get_client(s.id()).ok()).unwrap();
set_primary_focus(dh, seat, Some(client2))
}
}
} }
delegate_seat!(State); delegate_seat!(State);

View file

@ -2,8 +2,8 @@
use smithay::{ use smithay::{
desktop::{Kind, Window}, desktop::{Kind, Window},
input::Seat,
reexports::wayland_server::DisplayHandle, reexports::wayland_server::DisplayHandle,
wayland::seat::Seat,
}; };
use crate::{ use crate::{
@ -18,7 +18,7 @@ impl ToplevelManagementHandler for State {
&mut self.common.shell.toplevel_management_state &mut self.common.shell.toplevel_management_state
} }
fn activate(&mut self, dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) { fn activate(&mut self, _dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) {
if let Some(idx) = self if let Some(idx) = self
.common .common
.shell .shell
@ -30,8 +30,7 @@ impl ToplevelManagementHandler for State {
if self.common.shell.active_space(&output).idx != idx { if self.common.shell.active_space(&output).idx != idx {
self.common.shell.activate(&seat, &output, idx as usize); self.common.shell.activate(&seat, &output, idx as usize);
} }
self.common Common::set_focus(self, Some(window.toplevel().wl_surface()), &seat, None);
.set_focus(dh, Some(window.toplevel().wl_surface()), &seat, None);
} }
} }

View file

@ -7,35 +7,35 @@ use smithay::{
Kind, PopupGrab, PopupKeyboardGrab, PopupKind, PopupPointerGrab, PopupUngrabStrategy, Kind, PopupGrab, PopupKeyboardGrab, PopupKind, PopupPointerGrab, PopupUngrabStrategy,
Window, WindowSurfaceType, Window, WindowSurfaceType,
}, },
input::{
pointer::{Focus, GrabStartData as PointerGrabStartData},
Seat,
},
reexports::{ reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel, wayland_protocols::xdg::shell::server::xdg_toplevel,
wayland_server::{ wayland_server::protocol::{wl_output::WlOutput, wl_seat::WlSeat, wl_surface::WlSurface},
protocol::{wl_output::WlOutput, wl_seat::WlSeat, wl_surface::WlSurface},
DisplayHandle,
},
}, },
utils::Serial,
wayland::{ wayland::{
output::Output, output::Output,
seat::{Focus, PointerGrabStartData, Seat},
shell::xdg::{ shell::xdg::{
Configure, PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, Configure, PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler,
XdgShellState, XdgShellState,
}, },
Serial,
}, },
}; };
use std::cell::Cell; use std::cell::Cell;
pub mod popup; pub mod popup;
pub type PopupGrabData = Cell<Option<PopupGrab>>; pub type PopupGrabData = Cell<Option<PopupGrab<State>>>;
impl XdgShellHandler for State { impl XdgShellHandler for State {
fn xdg_shell_state(&mut self) -> &mut XdgShellState { fn xdg_shell_state(&mut self) -> &mut XdgShellState {
&mut self.common.shell.xdg_shell_state &mut self.common.shell.xdg_shell_state
} }
fn new_toplevel(&mut self, _dh: &DisplayHandle, surface: ToplevelSurface) { fn new_toplevel(&mut self, surface: ToplevelSurface) {
super::mark_dirty_on_drop(&self.common, surface.wl_surface()); super::mark_dirty_on_drop(&self.common, surface.wl_surface());
let seat = &self.common.last_active_seat; let seat = &self.common.last_active_seat;
@ -48,12 +48,7 @@ impl XdgShellHandler for State {
// We will position the window after the first commit, when we know its size hints // We will position the window after the first commit, when we know its size hints
} }
fn new_popup( fn new_popup(&mut self, surface: PopupSurface, positioner: PositionerState) {
&mut self,
_dh: &DisplayHandle,
surface: PopupSurface,
positioner: PositionerState,
) {
super::mark_dirty_on_drop(&self.common, surface.wl_surface()); super::mark_dirty_on_drop(&self.common, surface.wl_surface());
surface.with_pending_state(|state| { surface.with_pending_state(|state| {
@ -75,7 +70,7 @@ impl XdgShellHandler for State {
} }
} }
fn ack_configure(&mut self, _dh: &DisplayHandle, surface: WlSurface, configure: Configure) { fn ack_configure(&mut self, surface: WlSurface, configure: Configure) {
if let Configure::Toplevel(configure) = configure { if let Configure::Toplevel(configure) = configure {
// If we would re-position the window inside the grab we would get a weird jittery animation. // If we would re-position the window inside the grab we would get a weird jittery animation.
// We only want to resize once the client has acknoledged & commited the new size, // We only want to resize once the client has acknoledged & commited the new size,
@ -95,13 +90,14 @@ impl XdgShellHandler for State {
} }
} }
fn grab(&mut self, dh: &DisplayHandle, surface: PopupSurface, seat: WlSeat, serial: Serial) { fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
let seat = Seat::from_resource(&seat).unwrap(); let seat = Seat::from_resource(&seat).unwrap();
let ret = self let dh = &self.common.display_handle;
.common let ret =
.shell self.common
.popups .shell
.grab_popup(dh, surface.into(), &seat, serial); .popups
.grab_popup(dh, surface.wl_surface().clone(), &seat, serial);
if let Ok(mut grab) = ret { if let Ok(mut grab) = ret {
if let Some(keyboard) = seat.get_keyboard() { if let Some(keyboard) = seat.get_keyboard() {
@ -109,11 +105,15 @@ impl XdgShellHandler for State {
&& !(keyboard.has_grab(serial) && !(keyboard.has_grab(serial)
|| keyboard.has_grab(grab.previous_serial().unwrap_or(serial))) || keyboard.has_grab(grab.previous_serial().unwrap_or(serial)))
{ {
grab.ungrab(dh, PopupUngrabStrategy::All); grab.ungrab(PopupUngrabStrategy::All);
return; return;
} }
self.common Common::set_focus(
.set_focus(dh, grab.current_grab().as_ref(), &seat, Some(serial)); self,
grab.current_grab().as_ref().map(|x| &x.0),
&seat,
Some(serial),
);
keyboard.set_grab(PopupKeyboardGrab::new(&grab), serial); keyboard.set_grab(PopupKeyboardGrab::new(&grab), serial);
} }
@ -123,10 +123,10 @@ impl XdgShellHandler for State {
|| pointer || pointer
.has_grab(grab.previous_serial().unwrap_or_else(|| grab.serial()))) .has_grab(grab.previous_serial().unwrap_or_else(|| grab.serial())))
{ {
grab.ungrab(dh, PopupUngrabStrategy::All); grab.ungrab(PopupUngrabStrategy::All);
return; return;
} }
pointer.set_grab(PopupPointerGrab::new(&grab), serial, Focus::Keep); pointer.set_grab(self, PopupPointerGrab::new(&grab), serial, Focus::Keep);
} }
seat.user_data() seat.user_data()
@ -140,7 +140,6 @@ impl XdgShellHandler for State {
fn reposition_request( fn reposition_request(
&mut self, &mut self,
_dh: &DisplayHandle,
surface: PopupSurface, surface: PopupSurface,
positioner: PositionerState, positioner: PositionerState,
token: u32, token: u32,
@ -161,13 +160,7 @@ impl XdgShellHandler for State {
} }
} }
fn move_request( fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
&mut self,
_dh: &DisplayHandle,
surface: ToplevelSurface,
seat: WlSeat,
serial: Serial,
) {
let seat = Seat::from_resource(&seat).unwrap(); let seat = Seat::from_resource(&seat).unwrap();
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) { if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
let workspace = self let workspace = self
@ -181,15 +174,12 @@ impl XdgShellHandler for State {
.unwrap() .unwrap()
.clone(); .clone();
self.common Shell::move_request(self, &window, &seat, serial, start_data);
.shell
.move_request(&window, &seat, serial, start_data);
} }
} }
fn resize_request( fn resize_request(
&mut self, &mut self,
_dh: &DisplayHandle,
surface: ToplevelSurface, surface: ToplevelSurface,
seat: WlSeat, seat: WlSeat,
serial: Serial, serial: Serial,
@ -197,22 +187,11 @@ impl XdgShellHandler for State {
) { ) {
let seat = Seat::from_resource(&seat).unwrap(); let seat = Seat::from_resource(&seat).unwrap();
if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) { if let Some(start_data) = check_grab_preconditions(&seat, surface.wl_surface(), serial) {
let workspace = self Workspace::resize_request(self, surface.wl_surface(), &seat, serial, start_data, edges);
.common
.shell
.space_for_window_mut(surface.wl_surface())
.unwrap();
let window = workspace
.space
.window_for_surface(surface.wl_surface(), WindowSurfaceType::TOPLEVEL)
.unwrap()
.clone();
workspace.resize_request(&window, &seat, serial, start_data, edges);
} }
} }
fn maximize_request(&mut self, _dh: &DisplayHandle, surface: ToplevelSurface) { fn maximize_request(&mut self, surface: ToplevelSurface) {
let surface = surface.wl_surface(); let surface = surface.wl_surface();
let seat = &self.common.last_active_seat; let seat = &self.common.last_active_seat;
let output = active_output(seat, &self.common); let output = active_output(seat, &self.common);
@ -227,7 +206,7 @@ impl XdgShellHandler for State {
} }
} }
fn unmaximize_request(&mut self, _dh: &DisplayHandle, surface: ToplevelSurface) { fn unmaximize_request(&mut self, surface: ToplevelSurface) {
let surface = surface.wl_surface(); let surface = surface.wl_surface();
if let Some(workspace) = self.common.shell.space_for_window_mut(surface) { if let Some(workspace) = self.common.shell.space_for_window_mut(surface) {
@ -240,12 +219,7 @@ impl XdgShellHandler for State {
} }
} }
fn fullscreen_request( fn fullscreen_request(&mut self, surface: ToplevelSurface, output: Option<WlOutput>) {
&mut self,
_dh: &DisplayHandle,
surface: ToplevelSurface,
output: Option<WlOutput>,
) {
let output = output let output = output
.as_ref() .as_ref()
.and_then(Output::from_resource) .and_then(Output::from_resource)
@ -265,7 +239,7 @@ impl XdgShellHandler for State {
} }
} }
fn unfullscreen_request(&mut self, _dh: &DisplayHandle, surface: ToplevelSurface) { fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
let surface = surface.wl_surface(); let surface = surface.wl_surface();
if let Some(workspace) = self.common.shell.space_for_window_mut(surface) { if let Some(workspace) = self.common.shell.space_for_window_mut(surface) {
let window = workspace let window = workspace
@ -282,7 +256,7 @@ fn check_grab_preconditions(
seat: &Seat<State>, seat: &Seat<State>,
surface: &WlSurface, surface: &WlSurface,
serial: Serial, serial: Serial,
) -> Option<PointerGrabStartData> { ) -> Option<PointerGrabStartData<State>> {
use smithay::reexports::wayland_server::Resource; use smithay::reexports::wayland_server::Resource;
// TODO: touch resize. // TODO: touch resize.

View file

@ -106,7 +106,7 @@ where
drm: &wl_drm::WlDrm, drm: &wl_drm::WlDrm,
request: wl_drm::Request, request: wl_drm::Request,
data: &DrmInstanceData, data: &DrmInstanceData,
dh: &DisplayHandle, _dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>, data_init: &mut DataInit<'_, D>,
) { ) {
match request { match request {
@ -161,7 +161,7 @@ where
dma.add_plane(name, 0, offset0 as u32, stride0 as u32, Modifier::Invalid); dma.add_plane(name, 0, offset0 as u32, stride0 as u32, Modifier::Invalid);
match dma.build() { match dma.build() {
Some(dmabuf) => { Some(dmabuf) => {
match state.dmabuf_imported(dh, &data.dmabuf_global, dmabuf.clone()) { match state.dmabuf_imported(&data.dmabuf_global, dmabuf.clone()) {
Ok(_) => { Ok(_) => {
// import was successful // import was successful
data_init.init(id, dmabuf); data_init.init(id, dmabuf);

View file

@ -2,13 +2,14 @@
use smithay::{ use smithay::{
desktop::Window, desktop::Window,
input::{Seat, SeatHandler},
reexports::wayland_server::{ reexports::wayland_server::{
backend::{ClientId, GlobalId, ObjectId}, backend::{ClientId, GlobalId, ObjectId},
protocol::wl_surface::WlSurface, protocol::wl_surface::WlSurface,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
}, },
utils::{Logical, Rectangle}, utils::{Logical, Rectangle},
wayland::{output::Output, seat::Seat}, wayland::output::Output,
}; };
pub use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1 as ManagementCapabilities; pub use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1 as ManagementCapabilities;
@ -25,7 +26,7 @@ pub struct ToplevelManagementState {
} }
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait ToplevelManagementHandler: ToplevelInfoHandler { pub trait ToplevelManagementHandler: ToplevelInfoHandler + SeatHandler {
fn toplevel_management_state(&mut self) -> &mut ToplevelManagementState; fn toplevel_management_state(&mut self) -> &mut ToplevelManagementState;
fn activate(&mut self, dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) {} fn activate(&mut self, dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) {}